Browse Source

add support for packet tx

ugv_io
Alex Mikhalev 6 years ago
parent
commit
589a819e4f
  1. 132
      components/sx127x_driver/sx127x_driver.c
  2. 8
      components/sx127x_driver/sx127x_driver.h
  3. 46
      components/sx127x_driver/sx127x_internal.h
  4. 19
      components/sx127x_driver/sx127x_registers.c
  5. 10
      components/sx127x_driver/sx127x_registers.h
  6. 22
      main/ugv_main.c

132
components/sx127x_driver/sx127x_driver.c

@ -7,12 +7,18 @@ @@ -7,12 +7,18 @@
const char *SX127X_TAG = "sx127x";
typedef struct sx127x_packet {
char * data;
size_t data_len;
} sx127x_packet_t;
esp_err_t sx127x_init(sx127x_config_t *config, sx127x_t **handle_ptr) {
esp_err_t ret;
sx127x_t *handle = malloc(sizeof(sx127x_t));
SX127X_CHECK(handle != NULL, "malloc error", ESP_ERR_NO_MEM);
handle->task_handle = NULL;
handle->task_state = SX127X_TASK_STOPPED;
memcpy(&handle->config, config, sizeof(sx127x_config_t));
ret = gpio_set_direction(config->rst_io_num, GPIO_MODE_OUTPUT);
@ -24,12 +30,15 @@ esp_err_t sx127x_init(sx127x_config_t *config, sx127x_t **handle_ptr) { @@ -24,12 +30,15 @@ esp_err_t sx127x_init(sx127x_config_t *config, sx127x_t **handle_ptr) {
gpio_set_level(config->rst_io_num, 1);
vTaskDelay(RESET_DELAY);
spi_bus_config_t bus_config = {.mosi_io_num = config->mosi_io_num,
spi_bus_config_t bus_config = {
.mosi_io_num = config->mosi_io_num,
.miso_io_num = config->miso_io_num,
.sclk_io_num = config->sck_io_num,
.quadhd_io_num = -1,
.quadwp_io_num = -1,
.max_transfer_sz = SX127X_MAX_TRANSFER};
.max_transfer_sz = SX127X_MAX_TRANSFER,
};
ret = spi_bus_initialize(config->spi_host, &bus_config, 1);
SX127X_ERROR_CHECK2(ret, spi_bus_initialize)
@ -120,14 +129,90 @@ esp_err_t sx127x_free(sx127x_t *handle) { @@ -120,14 +129,90 @@ esp_err_t sx127x_free(sx127x_t *handle) {
void sx127x_isr(void *arg) {
sx127x_t *handle = (sx127x_t *)arg;
ESP_LOGI(SX127X_TAG, "sx127x_isr");
ESP_LOGV(SX127X_TAG, "sx127x_isr");
BaseType_t hpTaskWoken;
xSemaphoreGiveFromISR(handle->intr_semaphore, &hpTaskWoken);
if (hpTaskWoken) {
portYIELD_FROM_ISR();
}
}
void sx127x_do_tx(sx127x_t *handle, sx127x_packet_t *packet) {
uint8_t op_mode, irq_flags, config_2;
while (handle->task_state == SX127X_TASK_RUNNING) {
sx127x_read_register(handle, REG_OP_MODE, &op_mode);
uint8_t mode = op_mode & SX127X_MODE;
if (mode != SX127X_MODE_TX && mode != SX127X_MODE_FS_TX) {
break;
}
vTaskDelay(1); // wait for finish transmitting
}
sx127x_standby(handle);
sx127x_read_register(handle, REG_IRQ_FLAGS, &irq_flags);
if (irq_flags & IRQ_TX_DONE_MASK) {
// clear tx done bit
sx127x_write_register(handle, REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
}
sx127x_read_register(handle, REG_MODEM_CONFIG_2, &config_2);
config_2 &= ~0x01; // set explicit header mode TODO: implicit header?
sx127x_write_register(handle, REG_MODEM_CONFIG_2, config_2);
sx127x_write_register(handle, REG_FIFO_ADDR_PTR, 0);
sx127x_write_register(handle, REG_PAYLOAD_LENGTH, 0);
sx127x_write_fifo(handle, packet->data, packet->data_len);
sx127x_write_register(handle, REG_PAYLOAD_LENGTH, packet->data_len);
sx127x_write_register(handle, REG_OP_MODE, SX127X_LONG_RANGE | SX127X_MODE_FS_TX);
vTaskDelay(pdMS_TO_TICKS(1));
sx127x_write_register(handle, REG_OP_MODE, SX127X_LONG_RANGE | SX127X_MODE_TX);
// wait for transmission to finish
while (true) {
sx127x_read_register(handle, REG_IRQ_FLAGS, &irq_flags);
if (irq_flags & IRQ_TX_DONE_MASK) { // if the transmission is done
break;
}
vTaskDelay(1);
}
// clear tx done bit
sx127x_write_register(handle, REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
// go back to rx mode
sx127x_write_register(handle, REG_OP_MODE, SX127X_LONG_RANGE | SX127X_MODE_RX_CONT);
}
void sx127x_task(void *arg) {
sx127x_t *handle = (sx127x_t *)arg;
while (handle->task_running) {
vTaskDelay(pdMS_TO_TICKS(10));
sx127x_t * handle = (sx127x_t *)arg;
TickType_t delay_time = 0;
QueueSetHandle_t qSet = xQueueCreateSet(8);
xQueueAddToSet(handle->intr_semaphore, qSet);
xQueueAddToSet(handle->tx_packet_queue, qSet);
sx127x_packet_t packet;
while (handle->task_state == SX127X_TASK_RUNNING) {
QueueSetMemberHandle_t queue = xQueueSelectFromSet(qSet, delay_time);
if (queue == handle->intr_semaphore) {
BaseType_t didRecv = xSemaphoreTake(handle->intr_semaphore, 0);
if (didRecv) {
ESP_LOGI(SX127X_TAG, "recv from isr: %d", didRecv);
}
} else if (queue == handle->tx_packet_queue) {
BaseType_t didRecv = xQueueReceive(handle->tx_packet_queue, &packet, 0);
if (didRecv) {
ESP_LOGI(SX127X_TAG, "tx packet: %.*s", packet.data_len, packet.data);
sx127x_do_tx(handle, &packet);
free(packet.data);
}
}
}
ESP_LOGI(SX127X_TAG, "sx127x_task exiting");
handle->task_state = SX127X_TASK_STOPPED;
vTaskDelete(NULL); // must delete own task
}
esp_err_t sx127x_start(sx127x_t *handle) {
@ -135,6 +220,15 @@ esp_err_t sx127x_start(sx127x_t *handle) { @@ -135,6 +220,15 @@ esp_err_t sx127x_start(sx127x_t *handle) {
SX127X_CHECK(handle->task_handle == NULL, "task already running", ESP_ERR_INVALID_STATE);
handle->intr_semaphore = xSemaphoreCreateBinary();
// handle->recv_packet_queue = xQueueCreate(8, 10);
handle->tx_packet_queue = xQueueCreate(4, sizeof(sx127x_packet_t));
handle->task_state = SX127X_TASK_RUNNING;
BaseType_t pdRet =
xTaskCreate(sx127x_task, "sx127x_task", TASK_STACK_SIZE, (void *)handle, TASK_PRIORITY, &handle->task_handle);
SX127X_CHECK(pdRet == pdPASS, "failed to create task", ESP_FAIL);
ret = sx127x_write_register(handle, REG_DIO_MAPPING_1, 0x00);
SX127X_ERROR_CHECK(ret);
@ -152,11 +246,6 @@ esp_err_t sx127x_start(sx127x_t *handle) { @@ -152,11 +246,6 @@ esp_err_t sx127x_start(sx127x_t *handle) {
ret = gpio_isr_handler_add(handle->config.irq_io_num, sx127x_isr, (void *)handle);
SX127X_ERROR_CHECK2(ret, gpio_isr_handler_add);
handle->task_running = true;
BaseType_t pdRet =
xTaskCreate(sx127x_task, "sx127x_task", TASK_STACK_SIZE, (void *)handle, TASK_PRIORITY, &handle->task_handle);
SX127X_CHECK(pdRet == pdPASS, "failed to create task", ESP_FAIL);
return ESP_OK;
}
@ -164,12 +253,29 @@ esp_err_t sx127x_stop(sx127x_t *handle) { @@ -164,12 +253,29 @@ esp_err_t sx127x_stop(sx127x_t *handle) {
esp_err_t ret;
SX127X_CHECK(handle->task_handle != NULL, "task has not been started", ESP_ERR_INVALID_STATE);
handle->task_running = false;
xTaskNotify(handle->task_handle, 0, eNoAction);
handle->task_state = SX127X_TASK_STOPPING;
xTaskNotifyGive(handle->task_handle);
ret = gpio_isr_handler_remove(handle->config.irq_io_num);
SX127X_ERROR_CHECK2(ret, gpio_isr_handler_remove);
gpio_uninstall_isr_service();
while (handle->task_state != SX127X_TASK_STOPPED) {
vTaskDelay(10);
}
handle->task_handle = NULL;
return ESP_OK;
}
esp_err_t sx127x_send_packet(sx127x_t *handle, char *data, size_t data_len) {
SX127X_CHECK(data_len < SX127_MAX_PACKET_LEN, "packet len too long: %d", ESP_FAIL, data_len);
sx127x_packet_t packet;
packet.data_len = data_len;
packet.data = heap_caps_malloc(data_len, MALLOC_CAP_DMA);
SX127X_CHECK(packet.data != NULL, "malloc error", ESP_ERR_NO_MEM);
memcpy(packet.data, data, data_len);
BaseType_t pdRet = xQueueSend(handle->tx_packet_queue, &packet, 0);
SX127X_CHECK(pdRet == pdTRUE, "tx queue full", ESP_FAIL);
return ESP_OK;
}

8
components/sx127x_driver/sx127x_driver.h

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
#include <driver/spi_master.h>
#include <stdint.h>
#define SX127X_MAX_TRANSFER (256)
#define SX127_MAX_PACKET_LEN 255
// carrier frequency type
typedef uint64_t sx127x_freq_t;
@ -76,10 +76,8 @@ esp_err_t sx127x_init(sx127x_config_t *config, sx127x_t **handle_ptr); @@ -76,10 +76,8 @@ esp_err_t sx127x_init(sx127x_config_t *config, sx127x_t **handle_ptr);
esp_err_t sx127x_free(sx127x_t *handle);
esp_err_t sx127x_sleep(sx127x_t *handle);
esp_err_t sx127x_standby(sx127x_t *handle);
esp_err_t sx127x_start(sx127x_t *handle);
esp_err_t sx127x_stop(sx127x_t *handle);
esp_err_t sx127x_send_packet(sx127x_t *handle, char *data, size_t data_len);

46
components/sx127x_driver/sx127x_internal.h

@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/queue.h>
#include <freertos/semphr.h>
#include <freertos/task.h>
#define MAX_PKT_LENGTH 255
#define SX127X_MAX_TRANSFER (256)
#define RESET_DELAY (pdMS_TO_TICKS(15))
// 8mhz
#define SPI_CLOCK_HZ (8 * 1000 * 1000)
@ -43,13 +46,18 @@ @@ -43,13 +46,18 @@
#define REG_VERSION 0x42
#define REG_PA_DAC 0x4d
// modes
#define MODE_LONG_RANGE_MODE 0x80
#define MODE_SLEEP 0x00
#define MODE_STDBY 0x01
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
typedef enum sx127x_op_mode {
SX127X_MODE_SLEEP = 0x00,
SX127X_MODE_STDBY = 0x01,
SX127X_MODE_FS_TX = 0x02,
SX127X_MODE_TX = 0x03,
SX127X_MODE_FS_RX = 0x04,
SX127X_MODE_RX_CONT = 0x05,
SX127X_MODE_RX_SINGLE = 0x06,
SX127X_MODE_CAD = 0x07,
SX127X_MODE = 0x07,
SX127X_LONG_RANGE = (1 << 7)
} sx127x_op_mode_t;
#define CONFIG2_CRC 0x04
#define CONFIG3_AUTO_AGC 0x04
@ -65,7 +73,7 @@ @@ -65,7 +73,7 @@
#ifdef NODEBUG
#define SX127X_CHECK(check, str, ret_val, ...) \
if (!(check)) { \
ESP_LOGE(SX127X_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
ESP_LOGE(SX127X_TAG, str, ##__VA_ARGS__); \
return (ret_val); \
}
#define SX127X_ERROR_CHECK(ret) \
@ -79,7 +87,7 @@ @@ -79,7 +87,7 @@
#else
#define SX127X_CHECK(check, str, ret_val, ...) \
if (!(check)) { \
ESP_LOGE(SX127X_TAG, "%s(%d): " #check ": " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
ESP_LOGE(SX127X_TAG, "%s:%d: " #check ": " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
return (ret_val); \
}
#define SX127X_ERROR_CHECK(ret) \
@ -87,7 +95,7 @@ @@ -87,7 +95,7 @@
esp_err_t _error_code = (ret); \
if (_error_code != ESP_OK) { \
const char *_error_name = esp_err_to_name(_error_code); \
ESP_LOGE(SX127X_TAG, "%s(%d): %s (%d)", __FUNCTION__, __LINE__, _error_name, _error_code); \
ESP_LOGE(SX127X_TAG, "%s:%d: %s (%d)", __FUNCTION__, __LINE__, _error_name, _error_code); \
return _error_code; \
} \
}
@ -96,17 +104,29 @@ @@ -96,17 +104,29 @@
esp_err_t _error_code = (ret); \
if (_error_code != ESP_OK) { \
const char *_error_name = esp_err_to_name(_error_code); \
ESP_LOGE(SX127X_TAG, "%s(%d): " #fun ": %s (%d)", __FUNCTION__, __LINE__, _error_name, _error_code); \
ESP_LOGE(SX127X_TAG, "%s:%d: " #fun ": %s (%d)", __FUNCTION__, __LINE__, _error_name, _error_code); \
return _error_code; \
} \
}
#endif
typedef enum sx127x_task_state {
SX127X_TASK_STOPPED = 0,
SX127X_TASK_RUNNING = 1,
SX127X_TASK_STOPPING = 2,
} sx127x_task_state_t;
struct sx127x {
sx127x_config_t config;
spi_device_handle_t device_handle;
TaskHandle_t task_handle;
bool task_running;
sx127x_task_state_t task_state;
// binary semaphore which is given when an interrupt is received from the radio
SemaphoreHandle_t intr_semaphore;
// queue of packets received from the radio
QueueHandle_t rx_packet_queue;
// queue of packets to send to the radio
QueueHandle_t tx_packet_queue;
};
const char *SX127X_TAG;

19
components/sx127x_driver/sx127x_registers.c

@ -30,11 +30,11 @@ esp_err_t sx127x_single_transfer(sx127x_t *handle, uint8_t addr, uint8_t to_slav @@ -30,11 +30,11 @@ esp_err_t sx127x_single_transfer(sx127x_t *handle, uint8_t addr, uint8_t to_slav
}
esp_err_t sx127x_sleep(sx127x_t *handle) {
return sx127x_write_register(handle, REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
return sx127x_write_register(handle, REG_OP_MODE, SX127X_LONG_RANGE | SX127X_MODE_SLEEP);
}
esp_err_t sx127x_standby(sx127x_t *handle) {
return sx127x_write_register(handle, REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
return sx127x_write_register(handle, REG_OP_MODE, SX127X_LONG_RANGE | SX127X_MODE_STDBY);
}
esp_err_t sx127x_set_frequency(sx127x_t *handle, uint64_t frequency) {
@ -182,3 +182,18 @@ esp_err_t sx127x_set_crc(sx127x_t *handle, sx127x_crc_t crc) { @@ -182,3 +182,18 @@ esp_err_t sx127x_set_crc(sx127x_t *handle, sx127x_crc_t crc) {
handle->config.crc = crc;
return ESP_OK;
}
esp_err_t sx127x_write_fifo(sx127x_t *handle, char *data, size_t data_len) {
spi_transaction_t trans;
memset(&trans, 0, sizeof(trans));
trans.flags = SPI_TRANS_USE_RXDATA;
trans.addr = REG_FIFO;
trans.length = 8 * data_len;
trans.rxlength = 0;
trans.tx_buffer = data;
esp_err_t ret = spi_device_transmit(handle->device_handle, &trans);
SX127X_ERROR_CHECK2(ret, spi_device_transmit);
ESP_LOGV(SX127X_TAG, "sx127x_write_fifo(%.*s)", data_len, data);
return ESP_OK;
}

10
components/sx127x_driver/sx127x_registers.h

@ -4,8 +4,9 @@ esp_err_t sx127x_read_register(sx127x_t *handle, uint8_t reg, uint8_t *value); @@ -4,8 +4,9 @@ esp_err_t sx127x_read_register(sx127x_t *handle, uint8_t reg, uint8_t *value);
esp_err_t sx127x_write_register(sx127x_t *handle, uint8_t reg, uint8_t value);
esp_err_t sx127x_single_transfer(sx127x_t *handle, uint8_t addr, uint8_t to_slave, uint8_t *from_slave);
uint8_t sx127x_bw_to_reg(uint64_t bandwidth);
uint64_t sx127x_reg_to_bw(uint8_t bandwidth_reg);
esp_err_t sx127x_sleep(sx127x_t *handle);
esp_err_t sx127x_standby(sx127x_t *handle);
esp_err_t sx127x_set_frequency(sx127x_t *handle, uint64_t frequency);
@ -14,7 +15,12 @@ esp_err_t sx127x_set_tx_power(sx127x_t *handle, uint8_t tx_power, sx127x_pa_boos @@ -14,7 +15,12 @@ esp_err_t sx127x_set_tx_power(sx127x_t *handle, uint8_t tx_power, sx127x_pa_boos
esp_err_t sx127x_set_spreading_factor(sx127x_t *handle, uint8_t spreading_factor);
esp_err_t sx127x_set_signal_bandwidth(sx127x_t *handle, uint64_t signal_bandwidth);
uint8_t sx127x_bw_to_reg(uint64_t bandwidth);
uint64_t sx127x_reg_to_bw(uint8_t bandwidth_reg);
esp_err_t sx127x_set_sync_word(sx127x_t *handle, uint8_t sync_word);
esp_err_t sx127x_set_crc(sx127x_t *handle, sx127x_crc_t crc);
esp_err_t sx127x_write_fifo(sx127x_t *handle, char *data, size_t data_len);
esp_err_t sx127x_read_fifo(sx127x_t *handle, char *data_out, size_t *data_len_out);

22
main/ugv_main.c

@ -38,8 +38,10 @@ struct Packet { @@ -38,8 +38,10 @@ struct Packet {
uint16_t packet_num;
void loraTask(void *params);
sx127x_t *lora;
void loraOnReceive(int packetSize);
void loraTask(void *params);
TaskHandle_t lora_task_hndl;
// packets recieved (type Packet)
@ -96,7 +98,6 @@ void setup(void) { @@ -96,7 +98,6 @@ void setup(void) {
lora_config.sync_word = 0x34;
lora_config.crc = SX127X_CRC_ENABLED;
sx127x_t *lora;
esp_err_t ret = sx127x_init(&lora_config, &lora);
if (ret != ESP_OK) {
const char *err_name = esp_err_to_name(ret);
@ -149,13 +150,18 @@ void loraTask(void *params) { @@ -149,13 +150,18 @@ void loraTask(void *params) {
}
current_time = xTaskGetTickCount();
if (current_time >= next_send) {
sprintf(outBuf, "hello world %d", packet_num);
int len = sprintf(outBuf, "hello world %d", packet_num);
if (len < 0) {
ESP_LOGE(TAG, "sprintf error: %d", len);
continue;
}
packet_num++;
// LoRa.beginPacket();
// size_t written = LoRa.write((uint8_t *)outBuf, outBufLen - 1);
// LoRa.endPacket();
// ESP_LOGI(TAG, "lora wrote %d bytes\n", written);
// LoRa.receive(0); // go back to receive mode
esp_err_t ret = sx127x_send_packet(lora, outBuf, len);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "error sending packet: %d", ret);
} else {
ESP_LOGI(TAG, "lora wrote %d bytes\n", len);
}
current_time = xTaskGetTickCount();
next_send = current_time + send_period;

Loading…
Cancel
Save