|
|
@ -27,20 +27,21 @@ static esp_err_t sx127x_write_config(sx127x_t *hndl) { |
|
|
|
ret = sx127x_set_frequency(hndl, config->frequency); |
|
|
|
ret = sx127x_set_frequency(hndl, config->frequency); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
|
|
|
|
|
|
|
|
ret = sx127x_write_register(hndl, REG_FIFO_TX_BASE_ADDR, 0); |
|
|
|
ret = sx127x_write_register(hndl, SX127X_REG_FIFO_TX_BASE_ADDR, 0); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
sx127x_write_register(hndl, REG_FIFO_RX_BASE_ADDR, 0); |
|
|
|
sx127x_write_register(hndl, SX127X_REG_FIFO_RX_BASE_ADDR, 0); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
|
|
|
|
|
|
|
|
uint8_t reg_lna; |
|
|
|
uint8_t reg_lna; |
|
|
|
ret = sx127x_read_register(hndl, REG_LNA, ®_lna); |
|
|
|
ret = sx127x_read_register(hndl, SX127X_REG_LNA, ®_lna); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
reg_lna |= 0x03; // set LNA boost
|
|
|
|
reg_lna |= 0x03; // set LNA boost
|
|
|
|
ret = sx127x_write_register(hndl, REG_LNA, reg_lna); |
|
|
|
ret = sx127x_write_register(hndl, SX127X_REG_LNA, reg_lna); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
|
|
|
|
|
|
|
|
// set auto AGC
|
|
|
|
// set auto AGC
|
|
|
|
ret = sx127x_write_register(hndl, REG_MODEM_CONFIG_3, CONFIG3_AUTO_AGC); |
|
|
|
ret = |
|
|
|
|
|
|
|
sx127x_write_register(hndl, SX127X_REG_MODEM_CONFIG_3, SX127X_CONFIG3_AUTO_AGC); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
|
|
|
|
|
|
|
|
ret = sx127x_set_tx_power(hndl, config->tx_power, true); |
|
|
|
ret = sx127x_set_tx_power(hndl, config->tx_power, true); |
|
|
@ -113,7 +114,7 @@ esp_err_t sx127x_init(const sx127x_config_t *config, sx127x_t **handle_ptr) { |
|
|
|
|
|
|
|
|
|
|
|
// read version and check that it is compatible
|
|
|
|
// read version and check that it is compatible
|
|
|
|
uint8_t version; |
|
|
|
uint8_t version; |
|
|
|
ret = sx127x_read_register(hndl, REG_VERSION, &version); |
|
|
|
ret = sx127x_read_register(hndl, SX127X_REG_VERSION, &version); |
|
|
|
SX127X_ERROR_CHECK2(ret, sx127x_read_register); |
|
|
|
SX127X_ERROR_CHECK2(ret, sx127x_read_register); |
|
|
|
SX127X_CHECK(version == 0x12, "unsupported version %#x", |
|
|
|
SX127X_CHECK(version == 0x12, "unsupported version %#x", |
|
|
|
ESP_ERR_INVALID_VERSION, version); |
|
|
|
ESP_ERR_INVALID_VERSION, version); |
|
|
@ -163,7 +164,7 @@ static void sx127x_do_tx(sx127x_t *hndl, sx127x_packet_t *packet) { |
|
|
|
esp_err_t ret; |
|
|
|
esp_err_t ret; |
|
|
|
uint8_t op_mode, irq_flags, config_2; |
|
|
|
uint8_t op_mode, irq_flags, config_2; |
|
|
|
while (atomic_load(&hndl->task_state) == SX127X_TASK_RUNNING) { |
|
|
|
while (atomic_load(&hndl->task_state) == SX127X_TASK_RUNNING) { |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, REG_OP_MODE, &op_mode)); |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, SX127X_REG_OP_MODE, &op_mode)); |
|
|
|
uint8_t mode = op_mode & SX127X_MODE; |
|
|
|
uint8_t mode = op_mode & SX127X_MODE; |
|
|
|
if (mode != SX127X_MODE_TX && mode != SX127X_MODE_FS_TX) { |
|
|
|
if (mode != SX127X_MODE_TX && mode != SX127X_MODE_FS_TX) { |
|
|
|
break; |
|
|
|
break; |
|
|
@ -173,38 +174,41 @@ static void sx127x_do_tx(sx127x_t *hndl, sx127x_packet_t *packet) { |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_standby(hndl)); |
|
|
|
_TX_CHECK(sx127x_standby(hndl)); |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_read_register(hndl, REG_IRQ_FLAGS, &irq_flags)); |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, SX127X_REG_IRQ_FLAGS, &irq_flags)); |
|
|
|
if (irq_flags & IRQ_TX_DONE_MASK) { |
|
|
|
if (irq_flags & SX127X_IRQ_TX_DONE_MASK) { |
|
|
|
// clear tx done bit
|
|
|
|
// clear tx done bit
|
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_IRQ_FLAGS, IRQ_TX_DONE_MASK)); |
|
|
|
_TX_CHECK( |
|
|
|
|
|
|
|
sx127x_write_register(hndl, SX127X_REG_IRQ_FLAGS, SX127X_IRQ_TX_DONE_MASK)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_read_register(hndl, REG_MODEM_CONFIG_2, &config_2)); |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, SX127X_REG_MODEM_CONFIG_2, &config_2)); |
|
|
|
config_2 &= ~0x01; // set explicit header mode TODO: implicit header?
|
|
|
|
config_2 &= ~0x01; // set explicit header mode TODO: implicit header?
|
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_MODEM_CONFIG_2, config_2)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_MODEM_CONFIG_2, config_2)); |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_FIFO_ADDR_PTR, 0)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_FIFO_ADDR_PTR, 0)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_PAYLOAD_LENGTH, 0)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_PAYLOAD_LENGTH, 0)); |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_write_fifo(hndl, packet->data, packet->data_len)); |
|
|
|
_TX_CHECK(sx127x_write_fifo(hndl, packet->data, packet->data_len)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_PAYLOAD_LENGTH, packet->data_len)); |
|
|
|
_TX_CHECK( |
|
|
|
|
|
|
|
sx127x_write_register(hndl, SX127X_REG_PAYLOAD_LENGTH, packet->data_len)); |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_OP_MODE, |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_OP_MODE, |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_FS_TX)); |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_FS_TX)); |
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); |
|
|
|
vTaskDelay(pdMS_TO_TICKS(1)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_OP_MODE, |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_OP_MODE, |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_TX)); |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_TX)); |
|
|
|
|
|
|
|
|
|
|
|
// wait for transmission to finish
|
|
|
|
// wait for transmission to finish
|
|
|
|
while (true) { |
|
|
|
while (true) { |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, REG_IRQ_FLAGS, &irq_flags)); |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, SX127X_REG_IRQ_FLAGS, &irq_flags)); |
|
|
|
if (irq_flags & IRQ_TX_DONE_MASK) { // if the transmission is done
|
|
|
|
if (irq_flags & SX127X_IRQ_TX_DONE_MASK) { // if the transmission is done
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
vTaskDelay(1); |
|
|
|
vTaskDelay(1); |
|
|
|
} |
|
|
|
} |
|
|
|
// clear tx done bit
|
|
|
|
// clear tx done bit
|
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_IRQ_FLAGS, IRQ_TX_DONE_MASK)); |
|
|
|
_TX_CHECK( |
|
|
|
|
|
|
|
sx127x_write_register(hndl, SX127X_REG_IRQ_FLAGS, SX127X_IRQ_TX_DONE_MASK)); |
|
|
|
|
|
|
|
|
|
|
|
error: |
|
|
|
error: |
|
|
|
if (ret != ESP_OK) { |
|
|
|
if (ret != ESP_OK) { |
|
|
@ -212,7 +216,7 @@ error: |
|
|
|
ESP_LOGE(SX127X_TAG, "tx error: %s (%d)", error_name, ret); |
|
|
|
ESP_LOGE(SX127X_TAG, "tx error: %s (%d)", error_name, ret); |
|
|
|
} |
|
|
|
} |
|
|
|
// go back to rx mode
|
|
|
|
// go back to rx mode
|
|
|
|
sx127x_write_register(hndl, REG_OP_MODE, |
|
|
|
sx127x_write_register(hndl, SX127X_REG_OP_MODE, |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_RX_CONT); |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_RX_CONT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -222,26 +226,26 @@ static void sx127x_do_rx(sx127x_t *hndl) { |
|
|
|
esp_err_t ret; |
|
|
|
esp_err_t ret; |
|
|
|
BaseType_t pdRet; |
|
|
|
BaseType_t pdRet; |
|
|
|
|
|
|
|
|
|
|
|
_TX_CHECK(sx127x_read_register(hndl, REG_IRQ_FLAGS, &irq_flags)); |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, SX127X_REG_IRQ_FLAGS, &irq_flags)); |
|
|
|
// clear irq flags
|
|
|
|
// clear irq flags
|
|
|
|
_TX_CHECK(sx127x_write_register(hndl, REG_IRQ_FLAGS, irq_flags)); |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_IRQ_FLAGS, irq_flags)); |
|
|
|
|
|
|
|
|
|
|
|
if (irq_flags & IRQ_PAYLOAD_CRC_ERROR_MASK) { |
|
|
|
if (irq_flags & SX127X_IRQ_PAYLOAD_CRC_ERROR_MASK) { |
|
|
|
ESP_LOGW(SX127X_TAG, "rx crc error"); |
|
|
|
ESP_LOGW(SX127X_TAG, "rx crc error"); |
|
|
|
goto error; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
if ((irq_flags & IRQ_RX_DONE_MASK) == 0) { |
|
|
|
if ((irq_flags & SX127X_IRQ_RX_DONE_MASK) == 0) { |
|
|
|
ESP_LOGD(SX127X_TAG, "sx127x_do_rx called but no rx done"); |
|
|
|
ESP_LOGD(SX127X_TAG, "sx127x_do_rx called but no rx done"); |
|
|
|
goto error; |
|
|
|
goto error; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sx127x_write_register(hndl, REG_OP_MODE, |
|
|
|
sx127x_write_register(hndl, SX127X_REG_OP_MODE, |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_STDBY); |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_STDBY); |
|
|
|
|
|
|
|
|
|
|
|
// TODO: implicit header receive?
|
|
|
|
// TODO: implicit header receive?
|
|
|
|
_TX_CHECK(sx127x_read_register(hndl, REG_RX_NB_BYTES, &packet_len)); |
|
|
|
_TX_CHECK(sx127x_read_register(hndl, SX127X_REG_RX_NB_BYTES, &packet_len)); |
|
|
|
_TX_CHECK( |
|
|
|
_TX_CHECK(sx127x_write_register(hndl, SX127X_REG_FIFO_ADDR_PTR, |
|
|
|
sx127x_write_register(hndl, REG_FIFO_ADDR_PTR, REG_FIFO_RX_CURRENT_ADDR)); |
|
|
|
SX127X_REG_FIFO_RX_CURRENT_ADDR)); |
|
|
|
|
|
|
|
|
|
|
|
packet.data_len = packet_len; |
|
|
|
packet.data_len = packet_len; |
|
|
|
packet.data = heap_caps_malloc( |
|
|
|
packet.data = heap_caps_malloc( |
|
|
@ -267,9 +271,9 @@ error: |
|
|
|
const char *error_name = esp_err_to_name(ret); |
|
|
|
const char *error_name = esp_err_to_name(ret); |
|
|
|
ESP_LOGE(SX127X_TAG, "rx error: %s (%d)", error_name, ret); |
|
|
|
ESP_LOGE(SX127X_TAG, "rx error: %s (%d)", error_name, ret); |
|
|
|
} |
|
|
|
} |
|
|
|
sx127x_write_register(hndl, REG_FIFO_ADDR_PTR, 0); |
|
|
|
sx127x_write_register(hndl, SX127X_REG_FIFO_ADDR_PTR, 0); |
|
|
|
// go back to rx mode
|
|
|
|
// go back to rx mode
|
|
|
|
sx127x_write_register(hndl, REG_OP_MODE, |
|
|
|
sx127x_write_register(hndl, SX127X_REG_OP_MODE, |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_RX_CONT); |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_RX_CONT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -282,7 +286,7 @@ void sx127x_task(void *arg) { |
|
|
|
sx127x_packet_t packet; |
|
|
|
sx127x_packet_t packet; |
|
|
|
|
|
|
|
|
|
|
|
// be in rx mode by default
|
|
|
|
// be in rx mode by default
|
|
|
|
sx127x_write_register(hndl, REG_OP_MODE, |
|
|
|
sx127x_write_register(hndl, SX127X_REG_OP_MODE, |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_RX_CONT); |
|
|
|
SX127X_LONG_RANGE | SX127X_MODE_RX_CONT); |
|
|
|
|
|
|
|
|
|
|
|
while (atomic_load(&hndl->task_state) == SX127X_TASK_RUNNING) { |
|
|
|
while (atomic_load(&hndl->task_state) == SX127X_TASK_RUNNING) { |
|
|
@ -328,7 +332,7 @@ esp_err_t sx127x_start(sx127x_t *hndl) { |
|
|
|
(void *)hndl, SX127X_TASK_PRIORITY, &hndl->task_handle); |
|
|
|
(void *)hndl, SX127X_TASK_PRIORITY, &hndl->task_handle); |
|
|
|
SX127X_CHECK(pdRet == pdPASS, "failed to create task", ESP_FAIL); |
|
|
|
SX127X_CHECK(pdRet == pdPASS, "failed to create task", ESP_FAIL); |
|
|
|
|
|
|
|
|
|
|
|
ret = sx127x_write_register(hndl, REG_DIO_MAPPING_1, 0x00); |
|
|
|
ret = sx127x_write_register(hndl, SX127X_REG_DIO_MAPPING_1, 0x00); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
SX127X_ERROR_CHECK(ret); |
|
|
|
|
|
|
|
|
|
|
|
gpio_config_t irq_io_config; |
|
|
|
gpio_config_t irq_io_config; |
|
|
|