Skip to content

Commit

Permalink
add hall sensor interrupt based driver
Browse files Browse the repository at this point in the history
  • Loading branch information
txgk committed Jul 12, 2023
1 parent f9d12dc commit 8298728
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 88 deletions.
120 changes: 38 additions & 82 deletions esp32-project-nosedive/main/driver-hall.c
Original file line number Diff line number Diff line change
@@ -1,96 +1,51 @@
#include "nosedive.h"
#include "driver-hall.h"

static volatile int64_t hall_measurement_time = 0;
static volatile int hall_value = 0;
static volatile bool hall_intr_triggered = false;
#define HALL_SAMPLES_COUNT 100
#define HALL_MEASUREMENT_PERIOD_US 5000000

// #define TIMER_RESOLUTION 1000000 // 1 MHz
// #define ALARM_PERIOD 1000000 // 1 s
static volatile _Atomic int64_t hall_samples[HALL_SAMPLES_COUNT];
static volatile _Atomic int64_t last_sample_time = 0;
static volatile _Atomic size_t hall_iter = 0;
static volatile _Atomic bool hall_in_use = false;
static volatile double hall_freq = 0;

// static gptimer_handle_t gptimer = NULL;

// static bool IRAM_ATTR
// register_hall_switch(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
// {
// BaseType_t high_task_awoken = pdFALSE;
// return high_task_awoken == pdTRUE;
// }

// static void IRAM_ATTR
// hall_handler(void *dummy)
// {
// hall_intr_triggered = true;
// }

static bool
hall_initialize(void)
void IRAM_ATTR
hall_take_sample(void *dummy)
{
#ifdef READ_HALL_AS_ANALOG_PIN
adc_oneshot_unit_init_cfg_t adc2_init_cfg = {.unit_id = ADC_UNIT_2};
adc_oneshot_new_unit(&adc2_init_cfg, &adc2_handle);
adc_oneshot_chan_cfg_t hall_adc_cfg = {.bitwidth = ADC_BITWIDTH_DEFAULT, .atten = ADC_ATTEN_DB_11};
adc_oneshot_config_channel(adc2_handle, HALL_ADC_CHANNEL, &hall_adc_cfg);
#else
gpio_config_t hall_cfg = {
(1ULL << HALL_PIN),
GPIO_MODE_INPUT,
GPIO_PULLUP_DISABLE,
GPIO_PULLDOWN_DISABLE,
GPIO_INTR_DISABLE,
};
gpio_config(&hall_cfg);
#endif
// gpio_config_t hall_cfg = {
// (1ULL << HALL_PIN),
// GPIO_MODE_INPUT,
// GPIO_PULLUP_DISABLE,
// GPIO_PULLDOWN_DISABLE,
// GPIO_INTR_ANYEDGE,
// };
// gpio_install_isr_service(0);
// gpio_isr_handler_add(HALL_PIN, &hall_handler, NULL);

// esp_intr_alloc(ETS_GPIO_INTR_SOURCE, ESP_INTR_FLAG_IRAM, &hall_handler, NULL, NULL);

// gptimer_config_t gptimer_cfg = {
// .clk_src = GPTIMER_CLK_SRC_DEFAULT,
// .direction = GPTIMER_COUNT_UP,
// .resolution_hz = TIMER_RESOLUTION,
// };
// gptimer_new_timer(&gptimer_cfg, &gptimer);
// gptimer_event_callbacks_t callbacks_cfg = {
// .on_alarm = &register_hall_switch,
// };
// gptimer_register_event_callbacks(gptimer, &callbacks_cfg, NULL);
// gptimer_enable(gptimer);
// gptimer_alarm_config_t alarm_cfg = {
// .alarm_count = ALARM_PERIOD,
// };
// gptimer_set_alarm_action(gptimer, &alarm_cfg);
// gptimer_enable(gptimer);
return true;
hall_in_use = true;
last_sample_time = esp_timer_get_time();
hall_samples[hall_iter] = last_sample_time;
hall_iter = (hall_iter + 1) % HALL_SAMPLES_COUNT;
size_t fresh_samples_count = 0;
int64_t oldest_sample_time = last_sample_time;
for (size_t i = 0; i < HALL_SAMPLES_COUNT; ++i) {
if (last_sample_time - hall_samples[i] < HALL_MEASUREMENT_PERIOD_US) {
fresh_samples_count += 1;
if (hall_samples[i] < oldest_sample_time) {
oldest_sample_time = hall_samples[i];
}
}
}
// Частота = множитель мкс * кол-во измерений за период / период съёма измерений в мкс
hall_freq = 1000000.0 * fresh_samples_count / (last_sample_time - oldest_sample_time);
hall_in_use = false;
}

void IRAM_ATTR
hall_task(void *arg)
{
struct task_descriptor *task = arg;
if (hall_initialize() == true) {
while (true) {
if (xSemaphoreTake(task->mutex, portMAX_DELAY) == pdTRUE) {
hall_measurement_time = esp_timer_get_time();
#ifdef READ_HALL_AS_ANALOG_PIN
while (adc_oneshot_read(adc2_handle, HALL_ADC_CHANNEL, &hall_value) != ESP_OK) {
TASK_DELAY_MS(100);
}
#else
hall_value = gpio_get_level(HALL_PIN);
#endif
xSemaphoreGive(task->mutex);
while (true) {
if (xSemaphoreTake(task->mutex, portMAX_DELAY) == pdTRUE) {
while (hall_in_use == true);
if ((esp_timer_get_time() - last_sample_time > HALL_MEASUREMENT_PERIOD_US) && (hall_in_use == false)) {
last_sample_time = esp_timer_get_time();
hall_freq = 0;
}
TASK_DELAY_MS(task->performer_period_ms);
xSemaphoreGive(task->mutex);
}
TASK_DELAY_MS(task->performer_period_ms);
}
vTaskDelete(NULL);
}
Expand All @@ -100,11 +55,12 @@ hall_info(struct task_descriptor *task, char *dest)
{
int len = 0;
if (xSemaphoreTake(task->mutex, portMAX_DELAY) == pdTRUE) {
while (hall_in_use == true);
len = snprintf(dest, MESSAGE_SIZE_LIMIT,
"%s@%lld=%d\n",
"%s@%lld=%.2lf\n",
task->prefix,
hall_measurement_time / 1000,
hall_value
last_sample_time / 1000,
hall_freq * 60 // Convert to RPM.
);
xSemaphoreGive(task->mutex);
}
Expand Down
1 change: 1 addition & 0 deletions esp32-project-nosedive/main/driver-hall.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#ifndef DRIVER_HALL_H
#define DRIVER_HALL_H
void hall_take_sample(void *dummy);
void hall_task(void *arg);
int hall_info(struct task_descriptor *task, char *dest);
#endif // DRIVER_HALL_H
14 changes: 12 additions & 2 deletions esp32-project-nosedive/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
#include "nosedive.h"
#include "driver-pca9685.h"
#include "driver-pwm-reader.h"
#include "driver-hall.h"

volatile bool they_want_us_to_restart = false;

static volatile bool connected_to_wifi = false;

adc_oneshot_unit_handle_t adc1_handle;
adc_oneshot_unit_handle_t adc2_handle;

static inline void
setup_serial(uart_config_t *cfg, uart_port_t port, int speed, int tx_pin, int rx_pin)
Expand Down Expand Up @@ -74,6 +74,7 @@ void
app_main(void)
{
nvs_flash_init();
gpio_install_isr_service(0);

gpio_config_t power_inputs_cfg = {
.pin_bit_mask = (1ULL << KILL_SWITCH_PIN) | (1ULL << POWER_ON_PIN) | (1ULL << CURRENT_ALERT_PIN),
Expand All @@ -92,10 +93,19 @@ app_main(void)
.intr_type = GPIO_INTR_ANYEDGE,
};
gpio_config(&pwm_input_cfg);
gpio_install_isr_service(0);
gpio_isr_handler_add(PWM1_INPUT_PIN, &calculate_pwm, (void *)PWM1_INPUT_PIN);
gpio_isr_handler_add(PWM2_INPUT_PIN, &calculate_pwm, (void *)PWM2_INPUT_PIN);

gpio_config_t hall_input_cfg = {
.pin_bit_mask = (1ULL << HALL_PIN),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_POSEDGE,
};
gpio_config(&hall_input_cfg);
gpio_isr_handler_add(HALL_PIN, &hall_take_sample, NULL);

uart_config_t uart0_cfg = {0};
uart_config_t uart1_cfg = {0};
setup_serial(&uart0_cfg, UART_NUM_0, UART0_SPEED, UART0_TX_PIN, UART0_RX_PIN);
Expand Down
2 changes: 0 additions & 2 deletions esp32-project-nosedive/main/nosedive.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "esp_log.h"
#include "esp_adc/adc_oneshot.h"
// #define NOSEDIVE_USE_WIFI_STATION
// #define READ_HALL_AS_ANALOG_PIN
#ifdef NOSEDIVE_USE_WIFI_STATION
#include "../../wifi-credentials.h"
#endif
Expand Down Expand Up @@ -118,5 +117,4 @@ void get_temperature_info_string(const char *value, char *answer_buf_ptr, int *a

extern struct task_descriptor tasks[];
extern adc_oneshot_unit_handle_t adc1_handle;
extern adc_oneshot_unit_handle_t adc2_handle;
#endif // NOSEDIVE_H
4 changes: 2 additions & 2 deletions esp32-project-nosedive/main/tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ struct task_descriptor tasks[] = {
{"BME280", &bmx280_task, &bmx280_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"LIS3DH", &lis3dh_task, &lis3dh_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"MAX6675", &max6675_task, &max6675_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"HALL", &hall_task, &hall_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"RPM", &hall_task, &hall_info, 100, 500, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"PWM", &pwm_reader_task, &pwm_reader_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"TPA626", &tpa626_task, &tpa626_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"NTC", &ntc_task, &ntc_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"SPEED", &speed_task, &speed_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{"POWER", &power_task, &power_info, 1000, 1000, 2048, 1, {0}, {{0}, {0}, {0}}, NULL},
{NULL, NULL, NULL, 0, 0, 0, 0, {0}, {{0}, {0}, {0}}, NULL},
{NULL, NULL, NULL, 0, 0, 0, 0, {0}, {{0}, {0}, {0}}, NULL},
};

void
Expand Down

0 comments on commit 8298728

Please sign in to comment.