142 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <esp_log.h>
 | |
| #include <freertos/FreeRTOS.h>
 | |
| #include <freertos/queue.h>
 | |
| #include <freertos/semphr.h>
 | |
| #include <freertos/task.h>
 | |
| 
 | |
| // TODO: these should be in Kconfig
 | |
| #define TASK_STACK_SIZE (2 * 1024)
 | |
| #define TASK_PRIORITY 3
 | |
| #define RX_QUEUE_LEN 8
 | |
| #define TX_QUEUE_LEN 8
 | |
| 
 | |
| #define SX127X_MAX_TRANSFER (256)
 | |
| #define RESET_DELAY (pdMS_TO_TICKS(15))
 | |
| 
 | |
| // 8mhz
 | |
| #define SPI_CLOCK_HZ (8 * 1000 * 1000)
 | |
| 
 | |
| #define REG_FIFO 0x00
 | |
| #define REG_OP_MODE 0x01
 | |
| #define REG_FRF_MSB 0x06
 | |
| #define REG_FRF_MID 0x07
 | |
| #define REG_FRF_LSB 0x08
 | |
| #define REG_PA_CONFIG 0x09
 | |
| #define REG_OCP 0x0b
 | |
| #define REG_LNA 0x0c
 | |
| #define REG_FIFO_ADDR_PTR 0x0d
 | |
| #define REG_FIFO_TX_BASE_ADDR 0x0e
 | |
| #define REG_FIFO_RX_BASE_ADDR 0x0f
 | |
| #define REG_FIFO_RX_CURRENT_ADDR 0x10
 | |
| #define REG_IRQ_FLAGS 0x12
 | |
| #define REG_RX_NB_BYTES 0x13
 | |
| #define REG_PKT_SNR_VALUE 0x19
 | |
| #define REG_PKT_RSSI_VALUE 0x1a
 | |
| #define REG_MODEM_CONFIG_1 0x1d
 | |
| #define REG_MODEM_CONFIG_2 0x1e
 | |
| #define REG_PREAMBLE_MSB 0x20
 | |
| #define REG_PREAMBLE_LSB 0x21
 | |
| #define REG_PAYLOAD_LENGTH 0x22
 | |
| #define REG_MODEM_CONFIG_3 0x26
 | |
| #define REG_FREQ_ERROR_MSB 0x28
 | |
| #define REG_FREQ_ERROR_MID 0x29
 | |
| #define REG_FREQ_ERROR_LSB 0x2a
 | |
| #define REG_RSSI_WIDEBAND 0x2c
 | |
| #define REG_DETECTION_OPTIMIZE 0x31
 | |
| #define REG_INVERTIQ 0x33
 | |
| #define REG_DETECTION_THRESHOLD 0x37
 | |
| #define REG_SYNC_WORD 0x39
 | |
| #define REG_INVERTIQ2 0x3b
 | |
| #define REG_DIO_MAPPING_1 0x40
 | |
| #define REG_VERSION 0x42
 | |
| #define REG_PA_DAC 0x4d
 | |
| 
 | |
| 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
 | |
| 
 | |
| // PA config
 | |
| #define PA_BOOST 0x80
 | |
| 
 | |
| // IRQ masks
 | |
| #define IRQ_TX_DONE_MASK 0x08
 | |
| #define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
 | |
| #define IRQ_RX_DONE_MASK 0x40
 | |
| 
 | |
| #ifdef NODEBUG
 | |
| #define SX127X_CHECK(check, str, ret_val, ...) \
 | |
|   if (!(check)) {                              \
 | |
|     ESP_LOGE(SX127X_TAG, str, ##__VA_ARGS__);  \
 | |
|     return (ret_val);                          \
 | |
|   }
 | |
| #define SX127X_ERROR_CHECK(ret)    \
 | |
|   {                                \
 | |
|     esp_err_t _error_code = (ret); \
 | |
|     if (_error_code != ESP_OK) {   \
 | |
|       return _error_code;          \
 | |
|     }                              \
 | |
|   }
 | |
| #define SX127X_ERROR_CHECK2(ret, fun) SX127X_CHECK(ret)
 | |
| #else
 | |
| #define SX127X_CHECK(check, str, ret_val, ...)                         \
 | |
|   if (!(check)) {                                                      \
 | |
|     ESP_LOGE(SX127X_TAG, "%s:%d: check %s failed: " str, __FUNCTION__, \
 | |
|              __LINE__, #check, ##__VA_ARGS__);                         \
 | |
|     return (ret_val);                                                  \
 | |
|   }
 | |
| #define SX127X_ERROR_CHECK(ret)                                      \
 | |
|   {                                                                  \
 | |
|     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);                            \
 | |
|       return _error_code;                                            \
 | |
|     }                                                                \
 | |
|   }
 | |
| #define SX127X_ERROR_CHECK2(ret, fun)                                 \
 | |
|   {                                                                   \
 | |
|     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 failed: %s (%d)", __FUNCTION__, \
 | |
|                __LINE__, #fun, _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;
 | |
| 
 | |
| typedef struct sx127x {
 | |
|   sx127x_config_t     config;
 | |
|   spi_device_handle_t device_handle;
 | |
|   TaskHandle_t        task_handle;
 | |
|   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;
 | |
| } sx127x_t;
 | |
| 
 | |
| const char *SX127X_TAG;
 |