#include "sx127x_driver.h" #include "sx127x_internal.h" #include "sx127x_registers.h" #include #include const char *SX127X_TAG = "sx127x"; 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; memcpy(&handle->config, config, sizeof(sx127x_config_t)); ret = gpio_set_direction(config->rst_io_num, GPIO_MODE_OUTPUT); SX127X_ERROR_CHECK2(ret, gpio_set_direction) // perform reset gpio_set_level(config->rst_io_num, 0); vTaskDelay(RESET_DELAY); gpio_set_level(config->rst_io_num, 1); vTaskDelay(RESET_DELAY); 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}; ret = spi_bus_initialize(config->spi_host, &bus_config, 1); SX127X_ERROR_CHECK2(ret, spi_bus_initialize) spi_device_interface_config_t device_config = { .command_bits = 0, .address_bits = 8, .dummy_bits = 0, .mode = 0, .duty_cycle_pos = 0, .cs_ena_pretrans = 0, .cs_ena_posttrans = 0, .clock_speed_hz = SPI_CLOCK_HZ, // 8mhz .input_delay_ns = 0, .spics_io_num = config->cs_io_num, .flags = 0, .queue_size = 8, .pre_cb = NULL, .post_cb = NULL, }; ret = spi_bus_add_device(config->spi_host, &device_config, &handle->device_handle); SX127X_ERROR_CHECK2(ret, spi_bus_add_device) // read version and check that it is compatible uint8_t version; ret = sx127x_read_register(handle, REG_VERSION, &version); SX127X_ERROR_CHECK2(ret, sx127x_read_register); SX127X_CHECK(version == 0x12, "unsupported version %#x", ESP_ERR_INVALID_VERSION, version); ret = sx127x_sleep(handle); SX127X_ERROR_CHECK(ret); ret = sx127x_set_frequency(handle, config->frequency); SX127X_ERROR_CHECK(ret); ret = sx127x_write_register(handle, REG_FIFO_TX_BASE_ADDR, 0); SX127X_ERROR_CHECK(ret); sx127x_write_register(handle, REG_FIFO_RX_BASE_ADDR, 0); SX127X_ERROR_CHECK(ret); uint8_t reg_lna; ret = sx127x_read_register(handle, REG_LNA, ®_lna); SX127X_ERROR_CHECK(ret); reg_lna |= 0x03; // set LNA boost ret = sx127x_write_register(handle, REG_LNA, reg_lna); SX127X_ERROR_CHECK(ret); // set auto AGC ret = sx127x_write_register(handle, REG_MODEM_CONFIG_3, CONFIG3_AUTO_AGC); SX127X_ERROR_CHECK(ret); ret = sx127x_set_tx_power(handle, config->tx_power, true); SX127X_ERROR_CHECK(ret); ret = sx127x_set_spreading_factor(handle, config->spreading_factor); SX127X_ERROR_CHECK(ret); ret = sx127x_set_sync_word(handle, config->sync_word); SX127X_ERROR_CHECK(ret); ret = sx127x_set_crc(handle, config->crc); SX127X_ERROR_CHECK(ret); ret = sx127x_standby(handle); ESP_ERROR_CHECK(ret); *handle_ptr = handle; return ESP_OK; } esp_err_t sx127x_free(sx127x_t *handle) { esp_err_t ret; if (handle->task_handle) { ret = sx127x_stop(handle); SX127X_ERROR_CHECK(ret); } ret = spi_bus_remove_device(handle->device_handle); SX127X_ERROR_CHECK2(ret, spi_bus_remove_device) ret = spi_bus_free(handle->config.spi_host); SX127X_ERROR_CHECK2(ret, spi_bus_free) free(handle); return ESP_OK; } void sx127x_isr(void *arg) { sx127x_t *handle = (sx127x_t *)arg; ESP_LOGI(SX127X_TAG, "sx127x_isr"); } void sx127x_task(void *arg) { sx127x_t *handle = (sx127x_t *)arg; while (handle->task_running) { vTaskDelay(pdMS_TO_TICKS(10)); } } esp_err_t sx127x_start(sx127x_t *handle) { esp_err_t ret; SX127X_CHECK(handle->task_handle == NULL, "task already running", ESP_ERR_INVALID_STATE); ret = sx127x_write_register(handle, REG_DIO_MAPPING_1, 0x00); SX127X_ERROR_CHECK(ret); gpio_config_t irq_io_config; irq_io_config.intr_type = GPIO_INTR_POSEDGE; irq_io_config.mode = GPIO_MODE_INPUT; irq_io_config.pin_bit_mask = (1ULL << handle->config.irq_io_num); irq_io_config.pull_down_en = 0; irq_io_config.pull_up_en = 0; ret = gpio_config(&irq_io_config); SX127X_ERROR_CHECK2(ret, gpio_config) ret = gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1); SX127X_ERROR_CHECK2(ret, gpio_install_isr_service); 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; } 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); ret = gpio_isr_handler_remove(handle->config.irq_io_num); SX127X_ERROR_CHECK2(ret, gpio_isr_handler_remove); gpio_uninstall_isr_service(); return ESP_OK; }