Browse Source

add locking for sx127x spi and more register access

ugv_io
Alex Mikhalev 6 years ago
parent
commit
4e436cfb7c
  1. 2
      components/sx127x_driver/sx127x_driver.c
  2. 2
      components/sx127x_driver/sx127x_internal.h
  3. 50
      components/sx127x_driver/sx127x_registers.c
  4. 13
      components/sx127x_driver/sx127x_registers.h
  5. 24
      main/ugv_main.c

2
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); gpio_set_level(config->rst_io_num, 1);
vTaskDelay(SX127X_RESET_DELAY); vTaskDelay(SX127X_RESET_DELAY);
hndl->spi_mutex = xSemaphoreCreateMutex();
spi_bus_config_t bus_config = { spi_bus_config_t bus_config = {
.mosi_io_num = config->mosi_io_num, .mosi_io_num = config->mosi_io_num,
.miso_io_num = config->miso_io_num, .miso_io_num = config->miso_io_num,

2
components/sx127x_driver/sx127x_internal.h

@ -17,6 +17,7 @@
#define SX127X_MAX_TRANSFER (256) #define SX127X_MAX_TRANSFER (256)
#define SX127X_RESET_DELAY (pdMS_TO_TICKS(15)) #define SX127X_RESET_DELAY (pdMS_TO_TICKS(15))
#define SX127X_MUTEX_TIMOUT (pdMS_TO_TICKS(100))
#ifdef NODEBUG #ifdef NODEBUG
@ -71,6 +72,7 @@ typedef enum sx127x_task_state {
typedef struct sx127x { typedef struct sx127x {
sx127x_config_t config; sx127x_config_t config;
spi_device_handle_t device_handle; spi_device_handle_t device_handle;
SemaphoreHandle_t spi_mutex;
TaskHandle_t task_handle; TaskHandle_t task_handle;
_Atomic(sx127x_task_state_t) task_state; _Atomic(sx127x_task_state_t) task_state;
// binary semaphore which is given when an interrupt is received from the // binary semaphore which is given when an interrupt is received from the

50
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.rxlength = 8;
trans.tx_data[0] = to_slave; 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); esp_err_t ret = spi_device_transmit(hndl->device_handle, &trans);
xSemaphoreGive(hndl->spi_mutex);
SX127X_ERROR_CHECK2(ret, spi_device_transmit); SX127X_ERROR_CHECK2(ret, spi_device_transmit);
if (from_slave) { if (from_slave) {
*from_slave = trans.rx_data[0]; *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 // PA BOOST
SX127X_CHECK(tx_power >= 2 && tx_power <= 20, "invalid tx_power: %d", SX127X_CHECK(tx_power >= 2 && tx_power <= 20, "invalid tx_power: %d",
ESP_ERR_INVALID_ARG, tx_power); 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 { } else {
// RFO // RFO
SX127X_CHECK(tx_power <= 14, "invalid tx_power: %d", ESP_ERR_INVALID_ARG, 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_optimize = 0xc3;
detection_threshold = 0x0a; detection_threshold = 0x0a;
} }
SX127X_ERROR_CHECK( SX127X_ERROR_CHECK(sx127x_write_register(hndl, SX127X_REG_DETECTION_OPTIMIZE,
sx127x_write_register(hndl, SX127X_REG_DETECTION_OPTIMIZE, detection_optimize)); detection_optimize));
SX127X_ERROR_CHECK(sx127x_write_register(hndl, SX127X_REG_DETECTION_THRESHOLD, SX127X_ERROR_CHECK(sx127x_write_register(hndl, SX127X_REG_DETECTION_THRESHOLD,
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) { 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; hndl->config.sync_word = sync_word;
return ESP_OK; return ESP_OK;
} }
@ -210,7 +218,8 @@ esp_err_t sx127x_read_pkt_rssi(sx127x_t *hndl, int32_t *rssi) {
uint8_t rssi_val; uint8_t rssi_val;
uint64_t freq = hndl->config.frequency; uint64_t freq = hndl->config.frequency;
int32_t min_rssi = (freq < 868E6) ? -164 : -157; 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; *rssi = min_rssi + rssi_val;
return ESP_OK; return ESP_OK;
} }
@ -224,6 +233,25 @@ esp_err_t sx127x_read_pkt_snr(sx127x_t *hndl, int8_t *snr) {
return ESP_OK; 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) { esp_err_t sx127x_write_fifo(sx127x_t *hndl, const char *data, size_t data_len) {
spi_transaction_t trans; spi_transaction_t trans;
memset(&trans, 0, sizeof(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.rxlength = 0;
trans.rx_buffer = NULL; 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); esp_err_t ret = spi_device_transmit(hndl->device_handle, &trans);
xSemaphoreGive(hndl->spi_mutex);
SX127X_ERROR_CHECK2(ret, spi_device_transmit); SX127X_ERROR_CHECK2(ret, spi_device_transmit);
ESP_LOGV(SX127X_TAG, "sx127x_write_fifo(%.*s)", data_len, data); ESP_LOGV(SX127X_TAG, "sx127x_write_fifo(%.*s)", data_len, data);
return ESP_OK; 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.rxlength = 0; // match length
trans.rx_buffer = data_out; 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); esp_err_t ret = spi_device_transmit(hndl->device_handle, &trans);
xSemaphoreGive(hndl->spi_mutex);
SX127X_ERROR_CHECK2(ret, spi_device_transmit); SX127X_ERROR_CHECK2(ret, spi_device_transmit);
ESP_LOGV(SX127X_TAG, "sx127x_read_fifo(%.*s)", data_len, data_out); ESP_LOGV(SX127X_TAG, "sx127x_read_fifo(%.*s)", data_len, data_out);
return ESP_OK; return ESP_OK;

13
components/sx127x_driver/sx127x_registers.h

@ -17,6 +17,7 @@ typedef enum sx127x_reg {
SX127X_REG_RX_NB_BYTES = 0x13, SX127X_REG_RX_NB_BYTES = 0x13,
SX127X_REG_PKT_SNR_VALUE = 0x19, SX127X_REG_PKT_SNR_VALUE = 0x19,
SX127X_REG_PKT_RSSI_VALUE = 0x1a, SX127X_REG_PKT_RSSI_VALUE = 0x1a,
SX127X_REG_RSSI_VALUE = 0x1b,
SX127X_REG_MODEM_CONFIG_1 = 0x1d, SX127X_REG_MODEM_CONFIG_1 = 0x1d,
SX127X_REG_MODEM_CONFIG_2 = 0x1e, SX127X_REG_MODEM_CONFIG_2 = 0x1e,
SX127X_REG_PREAMBLE_MSB = 0x20, 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_PAYLOAD_CRC_ERROR_MASK 0x20
#define SX127X_IRQ_RX_DONE_MASK 0x40 #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_read_register(sx127x_hndl hdnl, sx127x_reg_t reg,
esp_err_t sx127x_write_register(sx127x_hndl hdnl, sx127x_reg_t reg, uint8_t value); 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, esp_err_t sx127x_single_transfer(sx127x_hndl hdnl, sx127x_reg_t addr,
uint8_t to_slave, uint8_t *from_slave); uint8_t to_slave, uint8_t *from_slave);
@ -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_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_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_write_fifo(sx127x_hndl hdnl, const char *data,
esp_err_t sx127x_read_fifo(sx127x_hndl hdnl, char *data_out,
size_t data_len); size_t data_len);
esp_err_t sx127x_read_fifo(sx127x_hndl hdnl, char *data_out, size_t data_len);

24
main/ugv_main.c

@ -7,6 +7,7 @@
#include <u8g2.h> #include <u8g2.h>
#include "sx127x_driver.h" #include "sx127x_driver.h"
#include "sx127x_registers.h"
#include "u8g2_esp32_hal.h" #include "u8g2_esp32_hal.h"
const char *TAG = "uas-ugv"; const char *TAG = "uas-ugv";
@ -62,8 +63,8 @@ void setup(void) {
sx127x_config_t lora_config = SX127X_CONFIG_DEFAULT; sx127x_config_t lora_config = SX127X_CONFIG_DEFAULT;
lora_config.tx_power = 17; lora_config.tx_power = 17;
lora_config.spreading_factor = 11; lora_config.spreading_factor = 12;
lora_config.signal_bandwidth = 125E3; lora_config.signal_bandwidth = 10E3;
lora_config.sync_word = 0x34; lora_config.sync_word = 0x34;
lora_config.crc = SX127X_CRC_ENABLED; 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) { void loop(void) {
ESP_LOGI(TAG, "loop"); ESP_LOGI(TAG, "loop");
u8g2_FirstPage(&u8g2); u8g2_FirstPage(&u8g2);
sx127x_recv_packet(lora, &rx_packet, 0); sx127x_recv_packet(lora, &rx_packet, 0);
sx127x_read_rssi(lora, &lora_rssi);
sx127x_read_lna_gain(lora, &lora_lna_gain);
do { do {
u8g2_DrawRFrame(&u8g2, 0, 0, OLED_W, OLED_H, 4); u8g2_DrawRFrame(&u8g2, 0, 0, OLED_W, OLED_H, 4);
multi_heap_info_t heap_info; multi_heap_info_t heap_info;
heap_caps_get_info(&heap_info, MALLOC_CAP_DEFAULT); heap_caps_get_info(&heap_info, MALLOC_CAP_DEFAULT);
u8g2_SetFont(&u8g2, u8g2_font_4x6_mf); u8g2_SetFont(&u8g2, u8g2_font_4x6_tr);
u8g2_DrawStr(&u8g2, 4, 8, "Hello World!"); u8g2_DrawStr(&u8g2, 4, 8, "=====UAS UGV=====");
char buf[32]; char buf[32];
memset(buf, 0, 32); memset(buf, 0, 32);
snprintf(buf, 32, "heap allc/free %d/%d", heap_info.total_allocated_bytes, snprintf(buf, 32, "heap allc/free %d/%d", heap_info.total_allocated_bytes,
heap_info.total_free_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) { if (rx_packet.data_len) {
ESP_LOGI(TAG, "lora received packet (len %d, rssi: %d, snr: %f): %.*s\n", 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.rssi, rx_packet.snr * 0.25f,
rx_packet.data_len, rx_packet.data); 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, snprintf(buf, 40, "lora pkt(rssi: %d, snr: %f)", rx_packet.rssi,
rx_packet.snr * 0.25f); 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); 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)); } while (u8g2_NextPage(&u8g2));
vTaskDelay(pdMS_TO_TICKS(1000)); vTaskDelay(pdMS_TO_TICKS(1000));
} }

Loading…
Cancel
Save