diff --git a/components/sx127x_driver/sx127x_driver.c b/components/sx127x_driver/sx127x_driver.c index bec3f3e..cb60196 100644 --- a/components/sx127x_driver/sx127x_driver.c +++ b/components/sx127x_driver/sx127x_driver.c @@ -81,6 +81,8 @@ esp_err_t sx127x_init(const sx127x_config_t *config, sx127x_t **handle_ptr) { gpio_set_level(config->rst_io_num, 1); vTaskDelay(SX127X_RESET_DELAY); + hndl->spi_mutex = xSemaphoreCreateMutex(); + spi_bus_config_t bus_config = { .mosi_io_num = config->mosi_io_num, .miso_io_num = config->miso_io_num, diff --git a/components/sx127x_driver/sx127x_internal.h b/components/sx127x_driver/sx127x_internal.h index 93ffcc9..3e9c9b1 100644 --- a/components/sx127x_driver/sx127x_internal.h +++ b/components/sx127x_driver/sx127x_internal.h @@ -17,6 +17,7 @@ #define SX127X_MAX_TRANSFER (256) #define SX127X_RESET_DELAY (pdMS_TO_TICKS(15)) +#define SX127X_MUTEX_TIMOUT (pdMS_TO_TICKS(100)) #ifdef NODEBUG @@ -71,6 +72,7 @@ typedef enum sx127x_task_state { typedef struct sx127x { sx127x_config_t config; spi_device_handle_t device_handle; + SemaphoreHandle_t spi_mutex; TaskHandle_t task_handle; _Atomic(sx127x_task_state_t) task_state; // binary semaphore which is given when an interrupt is received from the diff --git a/components/sx127x_driver/sx127x_registers.c b/components/sx127x_driver/sx127x_registers.c index b3e700c..06dd0b1 100644 --- a/components/sx127x_driver/sx127x_registers.c +++ b/components/sx127x_driver/sx127x_registers.c @@ -23,7 +23,13 @@ esp_err_t sx127x_single_transfer(sx127x_t *hndl, sx127x_reg_t addr, trans.rxlength = 8; trans.tx_data[0] = to_slave; + BaseType_t pdRet = xSemaphoreTake(hndl->spi_mutex, SX127X_MUTEX_TIMOUT); + if (pdRet != pdTRUE) { + ESP_LOGE(SX127X_TAG, "timeout on spi_mutex"); + return ESP_ERR_TIMEOUT; + } esp_err_t ret = spi_device_transmit(hndl->device_handle, &trans); + xSemaphoreGive(hndl->spi_mutex); SX127X_ERROR_CHECK2(ret, spi_device_transmit); if (from_slave) { *from_slave = trans.rx_data[0]; @@ -67,7 +73,8 @@ esp_err_t sx127x_set_tx_power(sx127x_t *hndl, uint8_t tx_power, // PA BOOST SX127X_CHECK(tx_power >= 2 && tx_power <= 20, "invalid tx_power: %d", ESP_ERR_INVALID_ARG, tx_power); - ret = sx127x_write_register(hndl, SX127X_REG_PA_CONFIG, SX127X_PA_BOOST | (tx_power - 2)); + ret = sx127x_write_register(hndl, SX127X_REG_PA_CONFIG, + SX127X_PA_BOOST | (tx_power - 2)); } else { // RFO SX127X_CHECK(tx_power <= 14, "invalid tx_power: %d", ESP_ERR_INVALID_ARG, @@ -93,8 +100,8 @@ esp_err_t sx127x_set_spreading_factor(sx127x_t *hndl, detection_optimize = 0xc3; detection_threshold = 0x0a; } - SX127X_ERROR_CHECK( - sx127x_write_register(hndl, SX127X_REG_DETECTION_OPTIMIZE, detection_optimize)); + SX127X_ERROR_CHECK(sx127x_write_register(hndl, SX127X_REG_DETECTION_OPTIMIZE, + detection_optimize)); SX127X_ERROR_CHECK(sx127x_write_register(hndl, SX127X_REG_DETECTION_THRESHOLD, detection_threshold)); @@ -185,7 +192,8 @@ uint64_t sx127x_reg_to_bw(uint8_t bandwidth_reg) { } esp_err_t sx127x_set_sync_word(sx127x_t *hndl, uint8_t sync_word) { - SX127X_ERROR_CHECK(sx127x_write_register(hndl, SX127X_REG_SYNC_WORD, sync_word)); + SX127X_ERROR_CHECK( + sx127x_write_register(hndl, SX127X_REG_SYNC_WORD, sync_word)); hndl->config.sync_word = sync_word; return ESP_OK; } @@ -210,7 +218,8 @@ esp_err_t sx127x_read_pkt_rssi(sx127x_t *hndl, int32_t *rssi) { uint8_t rssi_val; uint64_t freq = hndl->config.frequency; int32_t min_rssi = (freq < 868E6) ? -164 : -157; - SX127X_ERROR_CHECK(sx127x_read_register(hndl, SX127X_REG_PKT_RSSI_VALUE, &rssi_val)) + SX127X_ERROR_CHECK( + sx127x_read_register(hndl, SX127X_REG_PKT_RSSI_VALUE, &rssi_val)) *rssi = min_rssi + rssi_val; return ESP_OK; } @@ -224,6 +233,25 @@ esp_err_t sx127x_read_pkt_snr(sx127x_t *hndl, int8_t *snr) { return ESP_OK; } +esp_err_t sx127x_read_rssi(sx127x_t *hndl, int32_t *rssi) { + SX127X_CHECK(rssi != NULL, "rssi can not be NULL", ESP_ERR_INVALID_ARG); + uint8_t rssi_val; + uint64_t freq = hndl->config.frequency; + int32_t min_rssi = (freq < 868E6) ? -164 : -157; + SX127X_ERROR_CHECK( + sx127x_read_register(hndl, SX127X_REG_RSSI_VALUE, &rssi_val)) + *rssi = min_rssi + rssi_val; + return ESP_OK; +} + +esp_err_t sx127x_read_lna_gain(sx127x_t *hndl, uint8_t *lna_gain) { + SX127X_CHECK(lna_gain != NULL, "rssi can not be NULL", ESP_ERR_INVALID_ARG); + uint8_t lna_val; + SX127X_ERROR_CHECK(sx127x_read_register(hndl, SX127X_REG_LNA, &lna_val)) + *lna_gain = (lna_val >> 4) & 0x07; + return ESP_OK; +} + esp_err_t sx127x_write_fifo(sx127x_t *hndl, const char *data, size_t data_len) { spi_transaction_t trans; memset(&trans, 0, sizeof(trans)); @@ -234,7 +262,13 @@ esp_err_t sx127x_write_fifo(sx127x_t *hndl, const char *data, size_t data_len) { trans.rxlength = 0; trans.rx_buffer = NULL; + BaseType_t pdRet = xSemaphoreTake(hndl->spi_mutex, SX127X_MUTEX_TIMOUT); + if (pdRet != pdTRUE) { + ESP_LOGE(SX127X_TAG, "timeout on spi_mutex"); + return ESP_ERR_TIMEOUT; + } esp_err_t ret = spi_device_transmit(hndl->device_handle, &trans); + xSemaphoreGive(hndl->spi_mutex); SX127X_ERROR_CHECK2(ret, spi_device_transmit); ESP_LOGV(SX127X_TAG, "sx127x_write_fifo(%.*s)", data_len, data); return ESP_OK; @@ -250,7 +284,13 @@ esp_err_t sx127x_read_fifo(sx127x_t *hndl, char *data_out, size_t data_len) { trans.rxlength = 0; // match length trans.rx_buffer = data_out; + BaseType_t pdRet = xSemaphoreTake(hndl->spi_mutex, SX127X_MUTEX_TIMOUT); + if (pdRet != pdTRUE) { + ESP_LOGE(SX127X_TAG, "timeout on spi_mutex"); + return ESP_ERR_TIMEOUT; + } esp_err_t ret = spi_device_transmit(hndl->device_handle, &trans); + xSemaphoreGive(hndl->spi_mutex); SX127X_ERROR_CHECK2(ret, spi_device_transmit); ESP_LOGV(SX127X_TAG, "sx127x_read_fifo(%.*s)", data_len, data_out); return ESP_OK; diff --git a/components/sx127x_driver/sx127x_registers.h b/components/sx127x_driver/sx127x_registers.h index 334d386..e0e7f32 100644 --- a/components/sx127x_driver/sx127x_registers.h +++ b/components/sx127x_driver/sx127x_registers.h @@ -17,6 +17,7 @@ typedef enum sx127x_reg { SX127X_REG_RX_NB_BYTES = 0x13, SX127X_REG_PKT_SNR_VALUE = 0x19, SX127X_REG_PKT_RSSI_VALUE = 0x1a, + SX127X_REG_RSSI_VALUE = 0x1b, SX127X_REG_MODEM_CONFIG_1 = 0x1d, SX127X_REG_MODEM_CONFIG_2 = 0x1e, SX127X_REG_PREAMBLE_MSB = 0x20, @@ -61,8 +62,10 @@ typedef enum sx127x_op_mode { #define SX127X_IRQ_PAYLOAD_CRC_ERROR_MASK 0x20 #define SX127X_IRQ_RX_DONE_MASK 0x40 -esp_err_t sx127x_read_register(sx127x_hndl hdnl, sx127x_reg_t reg, uint8_t *value); -esp_err_t sx127x_write_register(sx127x_hndl hdnl, sx127x_reg_t reg, uint8_t value); +esp_err_t sx127x_read_register(sx127x_hndl hdnl, sx127x_reg_t reg, + uint8_t *value); +esp_err_t sx127x_write_register(sx127x_hndl hdnl, sx127x_reg_t reg, + uint8_t value); esp_err_t sx127x_single_transfer(sx127x_hndl hdnl, sx127x_reg_t addr, uint8_t to_slave, uint8_t *from_slave); @@ -76,10 +79,10 @@ esp_err_t sx127x_set_tx_power(sx127x_hndl hdnl, uint8_t tx_power, sx127x_pa_boost_t pa_boost); esp_err_t sx127x_set_spreading_factor(sx127x_hndl hdnl, - uint8_t spreading_factor); + uint8_t spreading_factor); esp_err_t sx127x_set_signal_bandwidth(sx127x_hndl hdnl, - uint64_t signal_bandwidth); + uint64_t signal_bandwidth); uint8_t sx127x_bw_to_reg(uint64_t bandwidth); uint64_t sx127x_reg_to_bw(uint8_t bandwidth_reg); @@ -89,7 +92,9 @@ esp_err_t sx127x_set_crc(sx127x_hndl hdnl, sx127x_crc_t crc); esp_err_t sx127x_read_pkt_rssi(sx127x_hndl hdnl, int32_t *rssi); esp_err_t sx127x_read_pkt_snr(sx127x_hndl hdnl, int8_t *snr); +esp_err_t sx127x_read_rssi(sx127x_hndl hdnl, int32_t *rssi); +esp_err_t sx127x_read_lna_gain(sx127x_hndl hdnl, uint8_t *lna_gain); -esp_err_t sx127x_write_fifo(sx127x_hndl hdnl, const char *data, size_t data_len); -esp_err_t sx127x_read_fifo(sx127x_hndl hdnl, char *data_out, - size_t data_len); +esp_err_t sx127x_write_fifo(sx127x_hndl hdnl, const char *data, + size_t data_len); +esp_err_t sx127x_read_fifo(sx127x_hndl hdnl, char *data_out, size_t data_len); diff --git a/main/ugv_main.c b/main/ugv_main.c index f41114d..09670fb 100644 --- a/main/ugv_main.c +++ b/main/ugv_main.c @@ -7,6 +7,7 @@ #include #include "sx127x_driver.h" +#include "sx127x_registers.h" #include "u8g2_esp32_hal.h" const char *TAG = "uas-ugv"; @@ -62,8 +63,8 @@ void setup(void) { sx127x_config_t lora_config = SX127X_CONFIG_DEFAULT; lora_config.tx_power = 17; - lora_config.spreading_factor = 11; - lora_config.signal_bandwidth = 125E3; + lora_config.spreading_factor = 12; + lora_config.signal_bandwidth = 10E3; lora_config.sync_word = 0x34; lora_config.crc = SX127X_CRC_ENABLED; @@ -120,34 +121,41 @@ void loraTask(void *params) { } } +int32_t lora_rssi; +uint8_t lora_lna_gain; + void loop(void) { ESP_LOGI(TAG, "loop"); u8g2_FirstPage(&u8g2); sx127x_recv_packet(lora, &rx_packet, 0); + sx127x_read_rssi(lora, &lora_rssi); + sx127x_read_lna_gain(lora, &lora_lna_gain); do { u8g2_DrawRFrame(&u8g2, 0, 0, OLED_W, OLED_H, 4); multi_heap_info_t heap_info; heap_caps_get_info(&heap_info, MALLOC_CAP_DEFAULT); - u8g2_SetFont(&u8g2, u8g2_font_4x6_mf); - u8g2_DrawStr(&u8g2, 4, 8, "Hello World!"); + u8g2_SetFont(&u8g2, u8g2_font_4x6_tr); + u8g2_DrawStr(&u8g2, 4, 8, "=====UAS UGV====="); char buf[32]; memset(buf, 0, 32); snprintf(buf, 32, "heap allc/free %d/%d", heap_info.total_allocated_bytes, heap_info.total_free_bytes); - u8g2_DrawStr(&u8g2, 4, 8 + 8, buf); + u8g2_DrawStr(&u8g2, 4, 2 * 8, buf); if (rx_packet.data_len) { ESP_LOGI(TAG, "lora received packet (len %d, rssi: %d, snr: %f): %.*s\n", rx_packet.data_len, rx_packet.rssi, rx_packet.snr * 0.25f, rx_packet.data_len, rx_packet.data); - u8g2_SetFont(&u8g2, u8g2_font_4x6_mf); + u8g2_SetFont(&u8g2, u8g2_font_4x6_tr); snprintf(buf, 40, "lora pkt(rssi: %d, snr: %f)", rx_packet.rssi, rx_packet.snr * 0.25f); - u8g2_DrawStr(&u8g2, 4, 8 + 8 + 8, buf); + u8g2_DrawStr(&u8g2, 4, 3 * 8, buf); snprintf(buf, 40, "%.*s", rx_packet.data_len, rx_packet.data); - u8g2_DrawStr(&u8g2, 4, 8 + 8 + 8 + 8, buf); + u8g2_DrawStr(&u8g2, 4, 4 * 8, buf); } + snprintf(buf, 40, "rssi: %d lna gain: %d", lora_rssi, lora_lna_gain); + u8g2_DrawStr(&u8g2, 4, 5 * 8, buf); } while (u8g2_NextPage(&u8g2)); vTaskDelay(pdMS_TO_TICKS(1000)); }