Explorar o código

add pika_hal support for ESP32, not tested yet

lyon %!s(int64=2) %!d(string=hai) anos
pai
achega
1d70e07957

+ 101 - 0
package/ESP32/pika_hal_ESP32_PWM.c

@@ -0,0 +1,101 @@
+#include "driver/ledc.h"
+#include "../PikaStdDevice/pika_hal.h"
+#include <ctype.h>
+
+#define PWM_CHANNAL_MAX LEDC_CHANNEL_MAX
+
+typedef struct 
+{
+    ledc_timer_config_t timer;
+    ledc_channel_config_t channel;
+}pika_pwm_dev_t;
+
+
+int pika_hal_platform_PWM_open(pika_dev* dev, char* name) {
+    dev->platform_data = pikaMalloc(sizeof(pika_pwm_dev_t));
+    memset(dev->platform_data, 0, sizeof(pika_pwm_dev_t));
+    pika_pwm_dev_t* platform_pwm = (pika_pwm_dev_t*)dev->platform_data;
+    /* support P0/P1 ... */
+    if (name[0] == 'P' && isdigit((int)name[1])) {
+        platform_pwm->timer.speed_mode = LEDC_LOW_SPEED_MODE;
+        platform_pwm->timer.timer_num = LEDC_TIMER_0;
+        platform_pwm->timer.duty_resolution = LEDC_TIMER_10_BIT;
+        platform_pwm->timer.freq_hz = 1000;
+        platform_pwm->timer.clk_cfg = LEDC_AUTO_CLK;
+        platform_pwm->channel.speed_mode = LEDC_LOW_SPEED_MODE;
+        platform_pwm->channel.gpio_num = fast_atoi(name + 1);
+        platform_pwm->channel.channel = platform_pwm->channel.gpio_num % PWM_CHANNAL_MAX;
+        platform_pwm->channel.timer_sel = LEDC_TIMER_0;
+        platform_pwm->channel.intr_type = LEDC_INTR_DISABLE;
+        platform_pwm->channel.duty = 100;
+        platform_pwm->channel.hpoint = 0;
+    } else {
+        __platform_printf("Error: pwm name error.\r\n");
+        __platform_printf("Require: Px (x: 0~24)\r\n");
+        return -1;
+    }
+    return 0;
+}
+
+int pika_hal_platform_PWM_close(pika_dev* dev) {
+    pikaFree(dev->platform_data, sizeof(pika_pwm_dev_t));
+    return 0;
+}
+
+int pika_hal_platform_PWM_read(pika_dev* dev, void* buf, size_t count) {
+    /* not support */
+    return -1;
+}
+
+int pika_hal_platform_PWM_write(pika_dev* dev, void* buf, size_t count) {
+    /* not support */
+    return -1;
+}
+
+int pika_hal_platform_PWM_ioctl_enable(pika_dev* dev) {
+    pika_pwm_dev_t* platform_pwm = (pika_pwm_dev_t*)dev->platform_data;
+    if (!dev->is_enabled) {
+        ledc_timer_config(&platform_pwm->timer);
+        ledc_channel_config(&platform_pwm->channel);
+        return 0;
+    }
+    return -1;
+}
+
+int pika_hal_platform_PWM_ioctl_disable(pika_dev* dev) {
+    pika_pwm_dev_t* platform_pwm = (pika_pwm_dev_t*)dev->platform_data;
+    if (dev->is_enabled) {
+        ledc_stop(platform_pwm->channel.speed_mode, platform_pwm->channel.channel, 0);
+        return 0;
+    }
+    return -1;
+}
+
+#define PERIOD_TO_FREQ(period) \
+    ((uint32_t)(pika_float)1000 * 1000 * 1000 / (pika_float)period)
+#define DUTY_TUO_DUTY_CYCLE(duty, period) \
+    (uint32_t)((pika_float)duty * (pika_float)1024 / (pika_float)period)
+
+int pika_hal_platform_PWM_ioctl_config(pika_dev* dev,
+                                       pika_hal_PWM_config* cfg) {
+    pika_pwm_dev_t* platform_pwm = (pika_pwm_dev_t*)dev->platform_data;
+    uint32_t freq = PERIOD_TO_FREQ(cfg->period);
+    uint32_t duty_cycle = DUTY_TUO_DUTY_CYCLE(cfg->duty, cfg->period);
+
+    /* not enabled */
+    if (!dev->is_enabled) {
+        // MHz
+        platform_pwm->timer.freq_hz = freq;
+        // 0 ~ 10000(0 ~ 100%)
+        platform_pwm->channel.duty = duty_cycle;
+    }
+    else if (platform_pwm->timer.freq_hz != freq ||
+        platform_pwm->channel.duty != duty_cycle) {
+        platform_pwm->timer.freq_hz = freq;
+        platform_pwm->channel.duty = duty_cycle;
+        ledc_set_freq(platform_pwm->timer.speed_mode, platform_pwm->timer.timer_num, platform_pwm->timer.freq_hz);
+        ledc_set_duty(platform_pwm->channel.speed_mode, platform_pwm->channel.channel, platform_pwm->channel.duty);
+        ledc_update_duty(platform_pwm->channel.speed_mode, platform_pwm->channel.channel);
+    }
+    return 0;
+}

+ 46 - 0
package/ESP32/pika_hal_ESP32_irq_task.c

@@ -0,0 +1,46 @@
+#include "pika_hal_ESP32_irq_task.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+
+static QueueHandle_t gpio_evt_queue = NULL;
+
+void IRAM_ATTR _ESP32_gpio_isr_handler(void *arg)
+{
+    pika_dev *dev = (pika_dev *)arg;
+    xQueueSendFromISR(gpio_evt_queue, dev, 0);
+}
+
+static void _ESP32_gpio_task(void *arg)
+{
+    pika_dev dev = {0};
+    gpio_evt_queue = xQueueCreate(10, sizeof(pika_dev));
+    for (;;)
+    {
+        if (xQueueReceive(gpio_evt_queue, &dev, portMAX_DELAY))
+        {
+            pika_hal_GPIO_config *cfg = dev.ioctl_config;
+            cfg->event_callback(&dev, cfg->event_callback_filter);
+            printf("event_callback: %p\n", cfg->event_callback);
+            // printf("event_callback_filter: %d\n", cfg->event_callback_filter);
+        }
+    }
+}
+
+int _ESP32_irq_start(void)
+{
+    static uint8_t task_created = 0;
+    if (task_created == 1)
+    {
+        return 0;
+    }
+    task_created = 1;
+
+    BaseType_t ret = xTaskCreate(_ESP32_gpio_task, (char *)"_irq_task", 4096, NULL, 12, NULL);
+
+    if (pdPASS != ret)
+    {
+        return 1;
+    }
+    return 0;
+}

+ 10 - 0
package/ESP32/pika_hal_ESP32_irq_task.h

@@ -0,0 +1,10 @@
+#ifndef __ESP32__IRQ__TASK__H
+#define __ESP32__IRQ__TASK__H
+
+#include "../PikaStdDevice/pika_hal.h"
+#include "driver/gpio.h"
+
+int _ESP32_irq_start(void);
+void _ESP32_gpio_isr_handler(void *arg);
+
+#endif