| | |
| | | #define RESP_MSG_RESP_TX_TS_IDX 30 |
| | | #define RESP_MSG_ANC_DISTOFFSET 34 |
| | | |
| | | #define TAG_KEEPTIMES 20 //æ ç¾åæ´»æ¶é´ |
| | | #define TAG_KEEPTIMES 30 //æ ç¾åæ´»æ¶é´ |
| | | #define REPORT_TAG_KEEPTIMES 30 //䏿¥åæ´»æ¶é´ |
| | | #define MAX_TAG_LIST_NUM 200 //åæ¶é讯æ ç¾æå¤§æ°é |
| | | |
| | | #define FREQ_OFFSET_MULTIPLIER (998.4e6/2.0/1024.0/131072.0) |
| | |
| | | #define ANCHOR_ID_IDX 1 |
| | | #define MAX_NEARBASE_NUM 25 |
| | | #define TAG_KEEPTIMES 30 //æ ç¾åæ´»æ¶é´ |
| | | |
| | | #define KEEP_TIMES 5 |
| | | #define TAG_NUM_IN_SYS 25 |
| | | |
| | |
| | | #define NEARBASEID_INDEX 11 |
| | | |
| | | #define TAG_KEEPTIMES 30 //æ ç¾åæ´»æ¶é´ |
| | | |
| | | #define MAX_TAG_LIST_NUM 200 //åæ¶é讯æ ç¾æå¤§æ°é |
| | | |
| | | #define FREQ_OFFSET_MULTIPLIER (998.4e6/2.0/1024.0/131072.0) |
| | |
| | | // } |
| | | // anchordata_num=j; |
| | | //} |
| | | uint16_t report_ancdist[ANC_MAX_NUM],report_ancid[ANC_MAX_NUM]; |
| | | void TagListUpdate(void) |
| | | { |
| | | uint16_t i,j=0,k=0; |
| | | for(i=0; i<taglist_num; i++) |
| | | { |
| | | { |
| | | |
| | | if(tagofflinetime[i]++<REPORT_TAG_KEEPTIMES) |
| | | { |
| | | report_ancid[k]=tagid_list[i]; |
| | | report_ancdist[k++]=(uint16_t)tagdist_list[i]; |
| | | } |
| | | if(tagofflinetime[i]++<TAG_KEEPTIMES) |
| | | { |
| | | tagid_list[j]=tagid_list[i]; |
| | |
| | | tagofflinetime[j++]=tagofflinetime[i]; |
| | | } |
| | | } |
| | | report_ancnum = k; |
| | | taglist_num=j; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "crc.h" |
| | | |
| | | |
| | | uint16_t ComputeCrc( uint16_t crc, uint8_t dataByte, uint16_t polynomial ) |
| | | { |
| | | uint8_t i; |
| | | |
| | | for( i = 0; i < 8; i++ ) |
| | | { |
| | | if( ( ( ( crc & 0x8000 ) >> 8 ) ^ ( dataByte & 0x80 ) ) != 0 ) |
| | | { |
| | | crc <<= 1; // shift left once |
| | | crc ^= polynomial; // XOR with polynomial |
| | | } |
| | | else |
| | | { |
| | | crc <<= 1; // shift left once |
| | | } |
| | | dataByte <<= 1; // Next data bit |
| | | } |
| | | return crc; |
| | | } |
| | | |
| | | |
| | | uint16_t RadioComputeCRC( uint8_t *buffer, uint8_t length, uint8_t crcType ) |
| | | { |
| | | uint8_t i = 0; |
| | | uint16_t crc = 0; |
| | | uint16_t polynomial = 0; |
| | | |
| | | polynomial = ( crcType == CRC_TYPE_IBM ) ? POLYNOMIAL_IBM : POLYNOMIAL_CCITT; |
| | | crc = ( crcType == CRC_TYPE_IBM ) ? CRC_IBM_SEED : CRC_CCITT_SEED; |
| | | for( i = 0; i < length; i++ ) |
| | | { |
| | | crc = ComputeCrc( crc, buffer[i], polynomial ); |
| | | } |
| | | if( crcType == CRC_TYPE_IBM ) |
| | | { |
| | | return crc; |
| | | } |
| | | else |
| | | { |
| | | return( ( uint16_t ) ( ~crc )); |
| | | } |
| | | } |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef _CRC_H_ |
| | | #define _CRC_H_ |
| | | |
| | | #include <stdint.h> |
| | | |
| | | // CRC types |
| | | #define CRC_TYPE_CCITT 0 |
| | | #define CRC_TYPE_IBM 1 |
| | | // Polynomial = X^16 + X^12 + X^5 + 1 |
| | | #define POLYNOMIAL_CCITT 0x1021 |
| | | // Polynomial = X^16 + X^15 + X^2 + 1 |
| | | #define POLYNOMIAL_IBM 0x8005 |
| | | // Seeds |
| | | #define CRC_IBM_SEED 0xFFFF |
| | | #define CRC_CCITT_SEED 0x1D0F |
| | | |
| | | |
| | | uint16_t RadioComputeCRC( uint8_t *buffer, uint8_t length, uint8_t crcType ); |
| | | uint16_t ComputeCrc( uint16_t crc, uint8_t dataByte, uint16_t polynomial ); |
| | | |
| | | |
| | | |
| | | #endif |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #include "delay.h" |
| | | #include <stdint.h> |
| | | //#include "stm32l0xx_hal.h" |
| | | |
| | | void Delay_Us (uint32_t delay) |
| | | { |
| | | uint8_t i=0; |
| | | uint32_t j=0; |
| | | for(i=0;i<delay;i++) |
| | | { |
| | | for(j=0;j<8;j++); |
| | | } |
| | | } |
| | | |
| | | |
| | | void Delay_Ms(uint32_t delay ) |
| | | { |
| | | uint32_t i=0; |
| | | uint32_t j=0; |
| | | |
| | | for(i=0;i<delay;i++) |
| | | { |
| | | for(j=0;j<4540;j++); |
| | | } |
| | | } |
| | | |
| | | void HAL_Delay_nMS( uint32_t Delay ) |
| | | { |
| | | Delay_Ms(Delay); |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef _DELAY_H_ |
| | | #define _DELAY_H_ |
| | | |
| | | #include<stdint.h> |
| | | |
| | | //extern volatile uint32_t TickCounter; |
| | | //extern volatile uint32_t ticktimer; |
| | | |
| | | void Delay_Us (uint32_t delay); |
| | | void Delay_Ms(uint32_t delay ); |
| | | void HAL_Delay_nMS(uint32_t Delay ); |
| | | |
| | | //#define HAL_GetTick() TickCounter |
| | | |
| | | #endif |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #include <math.h> |
| | | #include <string.h> |
| | | #include "sx126x.h" |
| | | #include "sx126x-board.h" |
| | | #include "lora_1268.h" |
| | | //#include "lora_3029.h"" |
| | | #include "user.h" |
| | | #include "sx126x-board.h" |
| | | #include "string.h" |
| | | #include "stdio.h" |
| | | #include <stdlib.h> |
| | | #include "mk_spi.h" |
| | | #include "global_param.h" |
| | | #include "dw_app_anchor.h" |
| | | #include "HIDO_TypeDef.h" |
| | | #include "PCA9555.h" |
| | | #include "mk_misc.h" |
| | | /********************************************ç»æä½**************************************************************/ |
| | | typedef enum |
| | | { |
| | | LOWPOWER, |
| | | RX, |
| | | RX_TIMEOUT, |
| | | RX_ERROR, |
| | | TX, |
| | | TX_TIMEOUT, |
| | | }States_t; |
| | | /********************************************ç»æä½**************************************************************/ |
| | | /********************************************åé**************************************************************/ |
| | | extern wg_state_enum wg_state; |
| | | |
| | | |
| | | /********************************************åé**************************************************************/ |
| | | |
| | | #define USE_MODEM_LORA |
| | | |
| | | #if defined( USE_MODEM_LORA ) |
| | | |
| | | #define LORA_BANDWIDTH 2 // [0: 125 kHz, |
| | | // 1: 250 kHz, |
| | | // 2: 500 kHz, |
| | | // 3: Reserved] |
| | | #define LORA_SPREADING_FACTOR 5 // [SF7..SF12] |
| | | #define LORA_CODINGRATE 1 // [1: 4/5, |
| | | // 2: 4/6, |
| | | // 3: 4/7, |
| | | // 4: 4/8] |
| | | #define LORA_PREAMBLE_LENGTH_T 8 // Same for Tx |
| | | #define LORA_PREAMBLE_LENGTH_R 8 // Same for Rx |
| | | //#define LORA_PREAMBLE_LENGTH 990 // Same for Tx and Rx |
| | | #define LORA_SYMBOL_TIMEOUT 0 // Symbols |
| | | #define LORA_FIX_LENGTH_PAYLOAD_ON false |
| | | #define LORA_IQ_INVERSION_ON_T false |
| | | #define LORA_IQ_INVERSION_ON_R false |
| | | |
| | | |
| | | #elif defined( USE_MODEM_FSK ) |
| | | |
| | | #define FSK_FDEV 5e3 // Hz |
| | | #define FSK_DATARATE 2.4e3 // bps |
| | | #define FSK_BANDWIDTH 20e3 // Hz >> DSB in sx126x |
| | | #define FSK_AFC_BANDWIDTH 100e3 // Hz |
| | | #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx |
| | | #define FSK_FIX_LENGTH_PAYLOAD_ON false |
| | | |
| | | #else |
| | | #error "Please define a modem in the compiler options." |
| | | #endif |
| | | |
| | | |
| | | /***loraæ¥æ¶ï¼åéåéå®ä¹******/ |
| | | |
| | | extern uint32_t current_count; |
| | | |
| | | extern uint32_t dev_id; |
| | | uint8_t yuyin_no_sleep_flag,no_rx_flag; |
| | | uint8_t lora_up_rec_flag; |
| | | static uint16_t source_id; |
| | | /***loraæ¥æ¶ï¼åéåéå®ä¹******/ |
| | | |
| | | uint32_t wg_lost_count = 10; |
| | | //static uint8_t tx_buf[10] = {0x55, 0x44, 0x33, 0x22, 0x11}; |
| | | //static uint8_t rx_buf[10] = {0x00}; |
| | | //extern uint32_t uwbled,gpsled,loraled,powerled; |
| | | extern uint8_t bat_percent,taglist_num; |
| | | //uint8_t report_ancnum; |
| | | //uint16_t report_ancdist[ANC_MAX_NUM],report_ancid[ANC_MAX_NUM]; |
| | | extern void spi_transfer_callback(void *dev, uint32_t err_code); |
| | | extern uint16_t ancidlist_rec[TAG_NUM_IN_SYS],ancidlist_send[TAG_NUM_IN_SYS],rec_ancidlist[TAG_NUM_IN_SYS]; |
| | | extern uint8_t report_ancnum; |
| | | extern uint16_t report_ancdist[ANC_MAX_NUM],report_ancid[ANC_MAX_NUM]; |
| | | //extern wg_state_enum wg_state; |
| | | extern uint32_t wg_lost_count; |
| | | uint8_t lora_sendbuffer[200]; |
| | | uint8_t seq_num; |
| | | extern uint16_t lora_up_uwb_flag; |
| | | //extern uint8_t wg_lost_count; |
| | | uint16_t wg_report_freq,wg_report_id; |
| | | uint8_t wg_report_sf; |
| | | #define WG_LOST_SWITCH_THRES 3 |
| | | #define WG_LOST_NOUWB_COUNT 60 |
| | | #define DEFAULT_WG_ID 0xFFFF |
| | | #define DEFAULT_LR_WG_ID 0xFFFE |
| | | uint8_t lora_jianting_flag = 1; |
| | | wg_state_enum wg_state = WG_Lost; |
| | | void LoraReportFreqPoll(void) |
| | | { |
| | | // wg_state = WG_Lost; |
| | | if(wg_lost_count++>WG_LOST_NOUWB_COUNT) |
| | | { |
| | | lora_jianting_flag = 0; |
| | | } else { |
| | | lora_jianting_flag = 1; |
| | | } |
| | | if(wg_state==WG_Lost) |
| | | { |
| | | static uint8_t channel_switch_count = 0; |
| | | // channel_switch_count = 10; |
| | | if(channel_switch_count++>1) |
| | | { |
| | | // channel_switch_count = 0; |
| | | // wg_report_id = DEFAULT_LR_WG_ID; |
| | | // wg_report_freq = LR_DATA_CHANNEL_FRQ; //妿䏢失龿¥å°±è¿å
¥WG管çä¿¡éã |
| | | // wg_report_sf = LR_DATA_CHANNEL_SF; |
| | | } |
| | | else |
| | | { |
| | | wg_report_id = DEFAULT_WG_ID; |
| | | wg_report_freq = REPORT_MANGE_CHANNEL_FRQ; //妿䏢失龿¥å°±è¿å
¥WG管çä¿¡éã |
| | | wg_report_sf = REPORT_CHANNEL_SF; |
| | | // wg_report_freq = TEST_MANAGE_CHANNEL_FRQ; |
| | | // wg_report_sf = TEST_MANAGE_CHANNEL_SF; |
| | | } |
| | | } else { |
| | | if(wg_lost_count>WG_LOST_SWITCH_THRES) |
| | | { |
| | | wg_state = WG_Lost; |
| | | } |
| | | } |
| | | } |
| | | static uint16_t checksum; |
| | | |
| | | //uint16_t wg_report_freq,wg_report_id; |
| | | uint8_t lora_sendbuffer[200]; |
| | | void LoraHeartBeartPoll(void) |
| | | { |
| | | |
| | | // lora_up_uwb_flag=2; |
| | | // rf_set_default_para(); |
| | | |
| | | /*****************************å¿è·³å
ä¸ä¼ å
容************************************/ |
| | | lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGHEARTBEAT; |
| | | lora_sendbuffer[MSG_LENGTH] = 14; |
| | | memcpy(&lora_sendbuffer[SOURCE_ID_IDX],&g_com_map[DEV_ID],2); |
| | | memcpy(&lora_sendbuffer[DEST_ID_IDX],&wg_report_id,2); |
| | | memcpy(&lora_sendbuffer[HB_VERSION_IDX],&g_com_map[VERSION],2); |
| | | lora_sendbuffer[HB_UWBPOWER_IDX] = g_com_map[POWER]; |
| | | lora_sendbuffer[HB_LORAPOWER_IDX] = g_com_map[LORA_POWER];//å°è·ç¦»æ ¡åæ¹ä¸ºäºTXåå°åç设置 |
| | | checksum = Checksum_u16(lora_sendbuffer,14); |
| | | memcpy(&lora_sendbuffer[14],&checksum,2); |
| | | Radio.Send(lora_sendbuffer,16); |
| | | |
| | | /*****************************å¿è·³å
ä¸ä¼ å
容*************************************/ |
| | | |
| | | } |
| | | #define HEATBEAT_UPDATE_TIME 20 |
| | | uint16_t heatbeat_count = HEATBEAT_UPDATE_TIME-1 ; |
| | | uint16_t flag_getwgresp = 0; |
| | | int16_t intheight; //æ°å |
| | | extern uint32_t dangqian_frqe; |
| | | uint16_t recnum[3]; |
| | | extern uint32_t freq_list[4]; |
| | | extern uint8_t DMA_RXBuf_BT[200]; |
| | | extern uint8_t report_ancnum; |
| | | extern uint8_t report_ancnum_bt; |
| | | uint32_t BT_SEND_lenth=0; |
| | | uint8_t BT_NUM=0; |
| | | extern uint16_t report_ancdist[ANC_MAX_NUM],report_ancid[ANC_MAX_NUM]; |
| | | extern uint8_t bat_percent; |
| | | extern uint16_t REV_RX_NUM; |
| | | extern uint16_t REV_POLL_NUM; |
| | | extern uint16_t REPLY_POLL_NUM; |
| | | uint16_t num[3]={0,0,0}; |
| | | extern uint8_t stationary_flag; |
| | | extern uint8_t SOS_KEY_STATE; |
| | | uint32_t LORA_POLL_COUNT=0; |
| | | #define GET_USERKEY gpio_pin_get_val(SOS_PIN) |
| | | void LoraReportPoll(void) |
| | | { |
| | | //// // delay_ms(100); |
| | | |
| | | ////#ifdef _USE_BAR |
| | | //// GetPressAndHeight(); |
| | | //// intheight = Height*100; |
| | | ////#endif |
| | | ////#ifdef _SMT_TEST |
| | | //// printf("æ°åå¼ï¼%d",intheight); |
| | | ////#endif |
| | | |
| | | ////// TagListUpdate(); |
| | | |
| | | //// LoraReportFreqPoll(); |
| | | //// flag_getwgresp = 0; |
| | | |
| | | // SwitchLoraSettings(478,REPORT_CHANNEL_SF,22); |
| | | |
| | | //// if(heatbeat_count++>HEATBEAT_UPDATE_TIME && WG_Connected == wg_state) //妿å¿è·³å
å°è¾¾ä¸ä¼ æ¶é´ï¼å¹¶ä¸ç½å
³å¤äºé¾æ¥ç¶æï¼å°±ä¸ä¼ å¿è·³å
|
| | | //// { |
| | | //// heatbeat_count = 0; |
| | | //// LoraHeartBeartPoll(); |
| | | //// return; |
| | | //// } |
| | | //// for(uint16_t i=0; i<report_ancnum-1; i++) |
| | | //// { |
| | | //// for(uint16_t j=0; j<report_ancnum-1-i; j++) |
| | | //// { |
| | | //// if(report_ancdist[j]>report_ancdist[j+1]) |
| | | //// { |
| | | //// uint16_t id,dist; |
| | | //// uint8_t bat; |
| | | //// id = report_ancid[j]; |
| | | //// dist = report_ancdist[j]; |
| | | //// report_ancid[j] = report_ancid[j+1]; |
| | | //// report_ancdist[j] = report_ancdist[j+1]; |
| | | //// report_ancid[j+1] = id; |
| | | //// report_ancdist[j+1] = dist; |
| | | //// } |
| | | //// } |
| | | //// } |
| | | //// |
| | | //// if(report_ancnum>LORA_REPORT_MAXANC_NUM) //èèloraä¼ è¾æ¶é´ï¼æå¤åé10个åºç«æ°æ®ã |
| | | //// { |
| | | //// report_ancnum = LORA_REPORT_MAXANC_NUM; |
| | | //// } |
| | | //// |
| | | ////#ifdef USE_GPS |
| | | //// lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGMSGTOWG_GPS; |
| | | //// lora_sendbuffer[MSG_LENGTH] = 4*report_ancnum+30; |
| | | ////#else |
| | | //// BT_NUM=DMA_RXBuf_BT[0]; |
| | | //// if(SOS_KEY_STATE) |
| | | //// { |
| | | //// BT_NUM=0; |
| | | ////// } |
| | | //// lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGMSGTOWG; |
| | | // lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGMSGTOWG_BT; |
| | | // //lora_sendbuffer[MSG_LENGTH] = 4*report_ancnum+4*BT_NUM+ANCID_IDX+3; |
| | | ////#endif |
| | | // memcpy(&lora_sendbuffer[SOURCE_ID_IDX],&g_com_map[DEV_ID],2); |
| | | // memcpy(&lora_sendbuffer[DEST_ID_IDX],&wg_report_id,2); |
| | | // lora_sendbuffer[SEQNUM_IDX] = seq_num++; |
| | | // lora_sendbuffer[BAT_IDX] = bat_percent; |
| | | //// lora_sendbuffer[STATE_IDX] = !GET_USERKEY|stationary_flag<<1; |
| | | //// //GET_USERKEYè¿ä¸ªæ¯é£ä¸ªloraââbusyé£ä¸ªå¼è |
| | | ////// lora_sendbuffer[STATE_IDX]=0x01; |
| | | ////// lora_sendbuffer[GATEWAY_CHANL]=0x02; |
| | | ////// lora_sendbuffer[CHANL_NUM]=0x03; |
| | | //// |
| | | ////#ifdef USE_GPS |
| | | //// memcpy(&lora_sendbuffer[GPS_JINGDU_IDX],&gps_jingdu,8); |
| | | //// memcpy(&lora_sendbuffer[GPS_WEIDU_IDX],&gps_jingdu,8); |
| | | //// memcpy(&lora_sendbuffer[GPS_HEIGHT_IDX],&gps_height,8); |
| | | //// lora_sendbuffer[GPS_STATE_IDX] = gps_state; |
| | | //// lora_sendbuffer[GPS_SATEL_NUM_IDX] = gps_satel_num; |
| | | //// lora_sendbuffer[GPS_SPOWER_IDX] = gps_signalpower; |
| | | //// lora_sendbuffer[GPS_CHAFENLINGQI] = gps_chafenlingqi; |
| | | ////#endif |
| | | //// memcpy(&lora_sendbuffer[BAR_HEIGHT_IDX],&intheight,2); |
| | | //// lora_sendbuffer[BT_ANCID_IDX] = report_ancnum; |
| | | //// memcpy(&lora_sendbuffer[BT_ANCID_IDX+1],report_ancid,report_ancnum*2); |
| | | //// memcpy(&lora_sendbuffer[BT_ANCID_IDX+report_ancnum*2+1],report_ancdist,report_ancnum*2); |
| | | //// uint8_t LORA_RETRANSNUSSION_BT=0; |
| | | ////// |
| | | ////// num[0]=REV_RX_NUM; |
| | | ////// num[1]=REV_POLL_NUM; |
| | | ////// num[2]=REPLY_POLL_NUM; |
| | | //// LORA_RETRANSNUSSION_BT=BT_ANCID_IDX+report_ancnum*4+1; |
| | | //// lora_sendbuffer[LORA_RETRANSNUSSION_BT] = 0x2D; //èçä¸ä¼ æ è¯ç¬¦ |
| | | |
| | | //// memcpy(&lora_sendbuffer[LORA_RETRANSNUSSION_BT+1],&DMA_RXBuf_BT[0],BT_NUM*2+1); //åºç«ID |
| | | //// memcpy(&lora_sendbuffer[LORA_RETRANSNUSSION_BT+BT_NUM*2+2],&DMA_RXBuf_BT[1+BT_NUM*2],BT_NUM*2);//åºç«è·ç¦» |
| | | //// lora_sendbuffer[MSG_LENGTH] = LORA_RETRANSNUSSION_BT+4*BT_NUM+2; |
| | | ////// } |
| | | ////// if(lora_sendbuffer[LORA_RETRANSNUSSION_BT]==0x2D) |
| | | ////// { |
| | | //// checksum = Checksum_u16(lora_sendbuffer,4*BT_NUM+4*report_ancnum+BT_ANCID_IDX+3); |
| | | //// memcpy(&lora_sendbuffer[LORA_RETRANSNUSSION_BT+BT_NUM*4+2],&checksum,2); |
| | | // BT_SEND_flag=BT_ANCID_IDX+report_ancnum*4+BT_NUM*4+5; |
| | | // Radio.Send(lora_sendbuffer,BT_SEND_flag); |
| | | //// LORA_POLL_COUNT++; |
| | | ////// LORA_3029_SINGLE_SEND(lora_sendbuffer,ANCID_IDX+report_ancnum*4+BT_NUM*4+4,0); |
| | | ////// } |
| | | ////// else |
| | | ////// { |
| | | ////// checksum = Checksum_u16(lora_sendbuffer,4*report_ancnum+ANCID_IDX); |
| | | ////// memcpy(&lora_sendbuffer[ANCID_IDX+report_ancnum*4],&checksum,2); |
| | | ////// Radio.Send(lora_sendbuffer,ANCID_IDX+report_ancnum*4+BT_NUM*4+2); |
| | | ////// } |
| | | |
| | | |
| | | #ifdef _USE_BAR |
| | | GetPressAndHeight(); |
| | | intheight = Height*100; |
| | | #endif |
| | | #ifdef _SMT_TEST |
| | | printf("æ°åå¼ï¼%d",intheight); |
| | | #endif |
| | | |
| | | // TagListUpdate(); |
| | | |
| | | LoraReportFreqPoll(); |
| | | flag_getwgresp = 0; |
| | | // wg_report_freq = REPORT_MANGE_CHANNEL_FRQ; |
| | | SwitchLoraSettings(wg_report_freq,REPORT_CHANNEL_SF,g_com_map[LORA_POWER]); |
| | | if(heatbeat_count++>HEATBEAT_UPDATE_TIME && WG_Connected == wg_state) //妿å¿è·³å
å°è¾¾ä¸ä¼ æ¶é´ï¼å¹¶ä¸ç½å
³å¤äºé¾æ¥ç¶æï¼å°±ä¸ä¼ å¿è·³å
|
| | | { |
| | | heatbeat_count = 0; |
| | | LoraHeartBeartPoll(); |
| | | return; |
| | | } |
| | | for(uint16_t i=0; i<report_ancnum-1; i++) |
| | | { |
| | | for(uint16_t j=0; j<report_ancnum-1-i; j++) |
| | | { |
| | | if(report_ancdist[j]>report_ancdist[j+1]) |
| | | { |
| | | uint16_t id,dist; |
| | | uint8_t bat; |
| | | id = report_ancid[j]; |
| | | dist = report_ancdist[j]; |
| | | report_ancid[j] = report_ancid[j+1]; |
| | | report_ancdist[j] = report_ancdist[j+1]; |
| | | report_ancid[j+1] = id; |
| | | report_ancdist[j+1] = dist; |
| | | } |
| | | } |
| | | } |
| | | if(report_ancnum>LORA_REPORT_MAXANC_NUM) //èèloraä¼ è¾æ¶é´ï¼æå¤åé10个åºç«æ°æ®ã |
| | | report_ancnum = LORA_REPORT_MAXANC_NUM; |
| | | #ifdef USE_GPS |
| | | lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGMSGTOWG_GPS; |
| | | lora_sendbuffer[MSG_LENGTH] = 4*report_ancnum+30; |
| | | #else |
| | | lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_TAGMSGTOWG; |
| | | lora_sendbuffer[MSG_LENGTH] = 4*report_ancnum+ANCID_IDX; |
| | | #endif |
| | | memcpy(&lora_sendbuffer[SOURCE_ID_IDX],&g_com_map[DEV_ID],2); |
| | | memcpy(&lora_sendbuffer[DEST_ID_IDX],&wg_report_id,2); |
| | | lora_sendbuffer[SEQNUM_IDX] = seq_num++; |
| | | lora_sendbuffer[BAT_IDX] = bat_percent; |
| | | lora_sendbuffer[STATE_IDX] = !GET_USERKEY|stationary_flag<<1; |
| | | #ifdef USE_GPS |
| | | memcpy(&lora_sendbuffer[GPS_JINGDU_IDX],&gps_jingdu,8); |
| | | memcpy(&lora_sendbuffer[GPS_WEIDU_IDX],&gps_jingdu,8); |
| | | memcpy(&lora_sendbuffer[GPS_HEIGHT_IDX],&gps_height,8); |
| | | lora_sendbuffer[GPS_STATE_IDX] = gps_state; |
| | | lora_sendbuffer[GPS_SATEL_NUM_IDX] = gps_satel_num; |
| | | lora_sendbuffer[GPS_SPOWER_IDX] = gps_signalpower; |
| | | lora_sendbuffer[GPS_CHAFENLINGQI] = gps_chafenlingqi; |
| | | #endif |
| | | memcpy(&lora_sendbuffer[BAR_HEIGHT_IDX],&intheight,2); |
| | | lora_sendbuffer[ANCNUM_IDX] = report_ancnum; |
| | | memcpy(&lora_sendbuffer[ANCID_IDX],report_ancid,report_ancnum*2); |
| | | memcpy(&lora_sendbuffer[ANCID_IDX+report_ancnum*2],report_ancdist,report_ancnum*2); |
| | | checksum = Checksum_u16(lora_sendbuffer,4*report_ancnum+ANCID_IDX); |
| | | memcpy(&lora_sendbuffer[ANCID_IDX+report_ancnum*4],&checksum,2); |
| | | Radio.Send(lora_sendbuffer,ANCID_IDX+report_ancnum*4+2); |
| | | |
| | | |
| | | } |
| | | |
| | | //static uint16_t delaytime = 1200; |
| | | static uint16_t source_id; |
| | | uint8_t rec_index,rec_secdelay; |
| | | //uint16_t rec_value,rec_delaytime,rx_count; |
| | | //uint16_t rec_value,rec_delaytime,rx_count,datalen_offset; |
| | | |
| | | uint8_t shengji_flag,time=5; |
| | | extern uint32_t uwbled,gpsled,loraled,powerled; |
| | | extern struct RxDoneMsg RxDoneParams; |
| | | |
| | | //extern uint8_t Lora_tx_ancnum; |
| | | //extern uint8_t lora_seq_nb2; |
| | | extern uint16_t lora_yingda_num; |
| | | uint8_t lora_tx_flag=0; |
| | | uint8_t lora_txanchor_power_flag; |
| | | extern uint16_t Lora_tx_ancid[50]; |
| | | extern uint16_t Lora_tx_ancdist[50]; |
| | | extern uint8_t Lora_tx_anc_electricity[50]; |
| | | uint8_t lora_seq_nb1; |
| | | |
| | | extern uint8_t lora_sendbuffer[200]; |
| | | void LoraSendComMap(uint8_t cmd) |
| | | { |
| | | uint8_t data_length = 0x50; |
| | | uint16_t checksum = 0; |
| | | lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_READPARARESP; |
| | | lora_sendbuffer[MSG_LENGTH] = data_length+11; |
| | | memcpy(&lora_sendbuffer[SOURCE_ID_IDX],&g_com_map[DEV_ID],2); |
| | | memcpy(&lora_sendbuffer[DEST_ID_IDX],&wg_report_id,2); |
| | | lora_sendbuffer[RP_CMD_IDX] = cmd; |
| | | lora_sendbuffer[RP_INDEX_IDX] = 2; |
| | | lora_sendbuffer[RP_LEN_IDX] = data_length; |
| | | memcpy(&lora_sendbuffer[9], &g_com_map[1], data_length); |
| | | checksum = Checksum_u16(lora_sendbuffer,11+data_length); |
| | | memcpy(&lora_sendbuffer[11+data_length],&checksum,2); |
| | | // LORA_3029_SINGLE_SEND(lora_sendbuffer,data_length+13,0); |
| | | Radio.Send(lora_sendbuffer,data_length+13); |
| | | //++; |
| | | // Delay_Ms(100); |
| | | } |
| | | void LoraRspWriteCommap(uint8_t index) |
| | | { |
| | | uint8_t data_length = 2; |
| | | uint16_t checksum = 0; |
| | | lora_sendbuffer[MSG_TYPE_IDX] = LORA_MSGTYPE_READPARARESP; |
| | | lora_sendbuffer[MSG_LENGTH] = data_length+9; |
| | | memcpy(&lora_sendbuffer[SOURCE_ID_IDX],&g_com_map[DEV_ID],2); |
| | | memcpy(&lora_sendbuffer[DEST_ID_IDX],&wg_report_id,2); |
| | | lora_sendbuffer[RP_CMD_IDX] = WGRSP_RWTAG_WRITE; |
| | | lora_sendbuffer[RP_INDEX_IDX] = index; |
| | | lora_sendbuffer[RP_LEN_IDX] = data_length; |
| | | memcpy(&lora_sendbuffer[7], &g_com_map[index/2], data_length); |
| | | checksum = Checksum_u16(lora_sendbuffer,9+data_length); |
| | | memcpy(&lora_sendbuffer[9+data_length],&checksum,2); |
| | | Radio.Send(lora_sendbuffer,data_length+11); |
| | | |
| | | //LORA_3029_SINGLE_SEND(lora_sendbuffer,data_length+11,0); |
| | | // Delay_Ms(100); |
| | | } |
| | | uint8_t t22[20],ti; |
| | | uint8_t no_yingdaflag; |
| | | uint8_t aRxBuffer[1]; |
| | | |
| | | extern uint8_t group_id; |
| | | uint16_t lora_send_count; |
| | | uint8_t mode_flag=0; |
| | | uint32_t frqe,dangqian_frqe; |
| | | |
| | | uint8_t sum_count; |
| | | void Lora_Tx_Poll() |
| | | { |
| | | |
| | | // if(lora_tx_flag) |
| | | // { |
| | | // OnMaster(); |
| | | //// |
| | | // //rf_enter_continous_rx(); |
| | | // } |
| | | if(lora_tx_flag) |
| | | { |
| | | // gpio_pin_set(IO_PIN_5); |
| | | |
| | | |
| | | if(lora_send_count++%10==0||lora_jianting_flag) |
| | | { |
| | | sum_count++; |
| | | lora_tx_flag=0; |
| | | #ifdef GROUPID_SWITCH |
| | | if(rec_secdelay>0) |
| | | { |
| | | rec_secdelay--; |
| | | return; |
| | | } |
| | | #endif |
| | | |
| | | LoraReportPoll(); |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | ////States_t State = LOWPOWER; |
| | | |
| | | //////int8_t RssiValue = 0; |
| | | //////int8_t SnrValue = 0; |
| | | ////uint8_t lora_chongfuyingda_flag; |
| | | ////uint8_t Lora_rx_open_flag; |
| | | ////extern u32 Loratx_frequency; |
| | | uint8_t huifushengjibao_flag; |
| | | uint8_t LoraUp_flag; |
| | | //uint8_t lora_up_rec_flag; |
| | | uint8_t flag_writepara_needreset = 0; |
| | | //uint32_t wg_lost_count = 10; |
| | | //uint32_t lora_zhuangtai; |
| | | //uint16_t current_count; |
| | | //extern wg_state_enum wg_state; |
| | | uint8_t txdone=0; |
| | | void OnTxDone( void ) |
| | | { |
| | | txdone++; |
| | | if(flag_writepara_needreset) //é
ç½®åå
¥å®æè®¾å¤éè¦éå¯ |
| | | { |
| | | printf("ç½å
³ä¸åé
ç½®åå
¥å®æï¼éå¯"); |
| | | SCB->AIRCR = 0X05FA0000|(unsigned int)0x04; //软å¤ä½åå°bootloader |
| | | } |
| | | Radio.Standby(); |
| | | if(LoraUp_flag) |
| | | { |
| | | huifushengjibao_flag=1; |
| | | Radio.Rx( 500 ); |
| | | } |
| | | else |
| | | { |
| | | Radio.Rx( 50 ); |
| | | //LORA_LED_OFF; |
| | | } |
| | | } |
| | | #define BUFFER_SIZE 255 // Define the payload size here |
| | | |
| | | extern uint8_t imu_enable,motor_enable; |
| | | extern uint8_t lora_jianting_flag,report_ancnum; |
| | | extern uint16_t motor_keeptime; |
| | | extern uint32_t dev_id; |
| | | //extern wg_state_enum wg_state; |
| | | uint16_t rec_value,rec_delaytime,rx_count,datalen_offset; |
| | | uint16_t BufferSize = BUFFER_SIZE; |
| | | uint16_t CRC16=0; |
| | | uint16_t DEST_ID=0; |
| | | uint8_t shengji_flag; |
| | | int8_t RssiValue = 0; |
| | | int8_t SnrValue = 0; |
| | | uint8_t TX_Buffer[BUFFER_SIZE]; |
| | | uint8_t RX_Buffer[BUFFER_SIZE]; |
| | | static RadioEvents_t RadioEvents; |
| | | static uint16_t delaytime = 771; |
| | | static uint16_t source_id; |
| | | |
| | | |
| | | uint8_t rec_index,rec_secdelay; |
| | | uint16_t rec_value,rx_count,datalen_offset; |
| | | int32_t target_count; |
| | | uint32_t sleep_time_count=0; |
| | | uint32_t sleep_time_count_LAST=0; |
| | | uint16_t time_count; |
| | | uint8_t LoraUp_flag; |
| | | uint16_t REV_WG_pack=0; |
| | | uint8_t rxdone=0; |
| | | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) |
| | | { |
| | | uint16_t checksum1; |
| | | BufferSize = size; |
| | | memcpy( RX_Buffer, payload, BufferSize ); |
| | | RssiValue = rssi; |
| | | SnrValue = snr; |
| | | Radio.Standby(); |
| | | rxdone++; |
| | | no_rx_flag = 0; |
| | | lora_up_rec_flag=1; |
| | | if(RX_Buffer[MSG_TYPE_IDX]==LORA_MSGTYPE_WGRESPTAG) |
| | | { |
| | | checksum1=Checksum_u16(RX_Buffer,BufferSize-2); |
| | | |
| | | memcpy(&DEST_ID,&RX_Buffer[DEST_ID_IDX],2); |
| | | memcpy(&CRC16,&RX_Buffer[BufferSize-2],2); |
| | | if(!memcmp(&checksum1,&RX_Buffer[BufferSize-2],2)) |
| | | if(!memcmp(&dev_id,&RX_Buffer[DEST_ID_IDX],2)) |
| | | { |
| | | memcpy(&source_id,&RX_Buffer[SOURCE_ID_IDX],2); |
| | | if(wg_state==WG_Lost) |
| | | { |
| | | wg_state = WG_Connected; |
| | | wg_report_id = source_id; |
| | | } |
| | | if(!memcmp(&wg_report_id,&RX_Buffer[SOURCE_ID_IDX],2)) |
| | | { |
| | | wg_lost_count = 0; |
| | | switch(RX_Buffer[PWTAG_RW_FLAG_IDX]) |
| | | { |
| | | case WGRSP_RWTAG_NONE: |
| | | // REV_WG_pack++; |
| | | // wg_report_freq = RX_Buffer[POLL_FREQ_IDX]+400; |
| | | // memcpy(&rec_delaytime,&RX_Buffer[NEXTPOLL_TIME_IDX],2); |
| | | |
| | | // if(report_ancnum<2) |
| | | // { |
| | | // datalen_offset = report_ancnum*85; |
| | | // }else{ |
| | | // datalen_offset = (report_ancnum-1)*46+85; |
| | | // } |
| | | // rec_secdelay = RX_Buffer[PWTAG_SECDELAY_IDX]; |
| | | // if(BufferSize!=13||rec_secdelay>20) |
| | | // { |
| | | // rec_secdelay = 0; |
| | | // } |
| | | // if(rec_delaytime<500) |
| | | // { |
| | | // int t; |
| | | // t++; |
| | | // } |
| | | //// sleep_time_count =(__MS_TO_32K_CNT(rec_delaytime)/10)- delaytime-datalen_offset; |
| | | // sleep_time_count =(__MS_TO_32K_CNT(rec_delaytime)/10); |
| | | // while(sleep_time_count>=32768) |
| | | // { |
| | | // sleep_time_count-=32768; |
| | | // } |
| | | // while(sleep_time_count<2000) |
| | | // { |
| | | // sleep_time_count+=10000; |
| | | // } |
| | | // if(REV_WG_pack==1) |
| | | // { |
| | | // sleep_time_count_LAST=sleep_time_count; |
| | | // } |
| | | // if(abs(sleep_time_count_LAST-sleep_time_count)>2000||REV_WG_pack==1) |
| | | // { |
| | | // sleep_timer_start(sleep_time_count); |
| | | time_count++; |
| | | // } |
| | | break; |
| | | case WGRSP_RWTAG_READ: |
| | | no_rx_flag = 1; |
| | | LoraSendComMap(WGRSP_RWTAG_READ); |
| | | break; |
| | | case WGRSP_RWTAG_WRITE: |
| | | rec_index = RX_Buffer[PWTAG_WRITE_IDX_IDX]; |
| | | switch(rec_index) |
| | | { |
| | | case 0xdd: //è¯é³ä¸å |
| | | break; |
| | | // case 0x20: //è鸣 |
| | | // memcpy(&rec_value,&RX_Buffer[PWTAG_WRITE_VALUE_IDX],2); |
| | | // motor_keeptime = rec_value; |
| | | // break; |
| | | default : |
| | | memcpy(&rec_value,&RX_Buffer[PWTAG_WRITE_VALUE_IDX],2); |
| | | g_com_map[rec_index/2] = rec_value; |
| | | save_com_map_to_flash(); |
| | | LoraRspWriteCommap(SUBMSG_WRITE_ANCPARA); |
| | | //flag_writepara_needreset = 1; |
| | | no_rx_flag = 1; |
| | | } |
| | | |
| | | break; |
| | | case WGRSP_RWTAG_UPDATE: |
| | | rec_index = RX_Buffer[PWTAG_WRITE_IDX_IDX]; |
| | | // switch(rec_index) |
| | | // { |
| | | // case 0xaa: //å级ä¸å |
| | | // memcpy(&rec_wenjian_daxiao,&RX_Buffer[WRITEPARA_VALUE_IDX],2);//æä»¶å¤§å° |
| | | // if(rec_wenjian_daxiao>0XAC00||rec_wenjian_daxiao==0) |
| | | // {}//æä»¶è¿å¤§ï¼è¶
åºèå´ |
| | | // else |
| | | // { |
| | | // memcpy(&wangguan_up_id,&RX_Buffer[SOURCE_ID_IDX],2);//ç½å
³ID å ç¨2个åè |
| | | // shengji_flag=1; |
| | | // LoraUp_flag=1; |
| | | // imu_enable=0; |
| | | // } |
| | | //// LoraUp_Poll(); |
| | | // break; |
| | | // } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | if(!no_rx_flag) |
| | | { |
| | | if(lora_jianting_flag&&LoraUp_flag==0) |
| | | { |
| | | SwitchLoraSettings(UWB_CHANNEL_FRQ+group_id,UWB_CHANNEL_SF,0); |
| | | Radio.Rx(0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void OnTxTimeout( void ) |
| | | { |
| | | Radio.Standby(); |
| | | if(lora_jianting_flag) |
| | | { |
| | | SwitchLoraSettings(UWB_CHANNEL_FRQ+group_id,UWB_CHANNEL_SF,0); |
| | | Radio.Rx(0); |
| | | } |
| | | } |
| | | |
| | | void OnRxTimeout( void ) |
| | | { |
| | | Radio.Standby(); |
| | | if(lora_jianting_flag) |
| | | { |
| | | SwitchLoraSettings(UWB_CHANNEL_FRQ+group_id,UWB_CHANNEL_SF,0); |
| | | Radio.Rx(0); |
| | | } |
| | | } |
| | | |
| | | |
| | | void OnRxError( void ) |
| | | { |
| | | |
| | | Radio.Standby(); |
| | | if(lora_jianting_flag) |
| | | { |
| | | SwitchLoraSettings(UWB_CHANNEL_FRQ+group_id,UWB_CHANNEL_SF,0); |
| | | Radio.Rx(0); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | uint16_t freq_test; |
| | | void SwitchLoraSettings(uint32_t freq,uint8_t sf,uint8_t power) |
| | | { |
| | | Radio.Standby(); |
| | | Radio.SetChannel( freq*1000000 ); |
| | | freq_test = freq; |
| | | Radio.SetTxConfig( MODEM_LORA, power, 0, 2, |
| | | sf, LORA_CODINGRATE,LORA_PREAMBLE_LENGTH_T, LORA_FIX_LENGTH_PAYLOAD_ON, |
| | | false, 0, 0, LORA_IQ_INVERSION_ON_T, 3000 ); |
| | | |
| | | Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, |
| | | sf,LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH_R, |
| | | LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, |
| | | 0, false, 0, 0, LORA_IQ_INVERSION_ON_R, 0 ); |
| | | } |
| | | |
| | | |
| | | uint8_t active_flag; |
| | | void Lora_1268_Init(void) |
| | | { |
| | | RadioEvents.TxDone = OnTxDone; |
| | | RadioEvents.RxDone = OnRxDone; |
| | | RadioEvents.TxTimeout = OnTxTimeout; |
| | | RadioEvents.RxTimeout = OnRxTimeout; |
| | | RadioEvents.RxError = OnRxError; |
| | | |
| | | Radio.Init( &RadioEvents ); |
| | | // SwitchLoraSettings(UWB_CHANNEL_FRQ+group_id,UWB_CHANNEL_SF,0); //忢loraæ¥æ¶é¢ç¹ |
| | | if(active_flag) |
| | | { |
| | | Radio.Rx( 0 ); |
| | | } |
| | | // else{ |
| | | // Radio.Sleep(); |
| | | // } |
| | | // Radio.SetRxDutyCycle(RxDutyCycle_RX_time,RxDutyCycle_SLEEP_time); |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef __LORA_1268_H |
| | | #define __LORA_1268_H |
| | | #include "mk_io.h" |
| | | |
| | | //BTæ¿åæ´æ¹äºçéè§ |
| | | |
| | | //#define LORA_CS IO_PIN_14 |
| | | #define LORA_CS IO_PIN_8 |
| | | #define LORA_MOSI IO_PIN_11 |
| | | #define LORA_MISO IO_PIN_12 |
| | | #define LORA_CLK IO_PIN_13 |
| | | #define LORA_IRQ IO_PIN_7 |
| | | #define LORA_BUSY IO_PIN_2 |
| | | |
| | | #define LORA_NRST IO_PIN_4 |
| | | #define LORA_NRST_DOWN gpio_pin_clr(IO_PIN_4) |
| | | #define LORA_NRST_UP gpio_pin_set(IO_PIN_4) |
| | | |
| | | //#define BOXING_PIN IO_PIN_1 |
| | | //#define LORA_DIO IO_PIN_4 |
| | | #define ANC_MAX_NUM 50 |
| | | #define LORA_REPORT_MAXANC_NUM 10 |
| | | //#define TEST_FREQ |
| | | #ifdef TEST_FREQ |
| | | #define LORA_UPCHANNEL_FRQ 456 |
| | | #define LORA_UPCHANNEL_SF 9 |
| | | |
| | | #define TEST_FREQ_OFFSET 1 |
| | | #define UWB_CHANNEL_FRQ 450+TEST_FREQ_OFFSET |
| | | #define UWB_CHANNEL_SF 5 |
| | | |
| | | #define LR_DATA_CHANNEL_FRQ 457 |
| | | #define LR_DATA_CHANNEL_SF 9 |
| | | |
| | | #define REPORT_MANGE_CHANNEL_FRQ 458 +TEST_FREQ_OFFSET |
| | | #define REPORT_CHANNEL_SF 7 |
| | | #else |
| | | #define LORA_UPCHANNEL_FRQ 476 |
| | | #define LORA_UPCHANNEL_SF 8 |
| | | |
| | | #define UWB_CHANNEL_FRQ 470 |
| | | #define UWB_CHANNEL_SF 5 |
| | | |
| | | #define REPORT_MANGE_CHANNEL_FRQ 478 |
| | | #define REPORT_CHANNEL_SF 7 |
| | | |
| | | #define LR_DATA_CHANNEL_FRQ 475 |
| | | #define LR_DATA_CHANNEL_SF 9 |
| | | |
| | | //#define TEST_MANAGE_CHANNEL_FRQ 457 |
| | | //#define TEST_MANAGE_CHANNEL_SF 5 |
| | | |
| | | #endif |
| | | |
| | | //LORA æ°æ®æ ¼å¼ |
| | | |
| | | //å
å¸çº¿ç³»ç»ä¸ ææçLORAä¼ è¾ä¿¡æ¯é½å
å«å¨ä¸é¢çMSG TYPEï¼æ¶æ¯ç±»åï¼æ ¼å¼ä¸ï¼ä¸åçæ¶æ¯ç±»åï¼ä¼å¯¹åºä¸åçæææ ¼å¼ |
| | | //LORA MSG TYPEçå ç§ç±»å |
| | | #define LORA_MSGTYPE_SYNC 1//ç½å
³ä¸åç»åºç«çåæ¥ä¿¡æ¯ |
| | | #define LORA_MSGTYPE_CFGRSP 2//åºç«åå¤ç»ç½å
³é
置读åä¿¡æ¯ |
| | | #define LORA_MSGTYPE_UPDATE_CONFIRM 3//åºç«åå¤ç»ç½å
³åçº§ç¡®è®¤ä¿¡æ¯ |
| | | #define LORA_MSGTYPE_RANGEPOLL 4//åºç«åèµ·æµè·åæ¥ä¿¡å· |
| | | #define LORA_MSGTYPE_UPDATEFILE_REQUEST 5//åºç«åéç»ç½å
³å级æä»¶è¯·æ± |
| | | #define LORA_MSGTYPE_UPDATEFILE_RESP 6//ç½å
³åå¤åºç«å级æä»¶å
容 |
| | | #define LORA_MSGTYPE_ANCHEARTBEAT_POLL 7//ç½å
³åå¤åºç«å级æä»¶å
容 |
| | | #define LORA_MSGTYPE_TAGMSGTOWG 0x22//æ ç¾è·ç¦»ä¿¡æ¯åç»ç½å
³ |
| | | #define LORA_MSGTYPE_TAGMSGTOWG_GPS 0x23//æ ç¾è·ç¦»ä¿¡æ¯åç»ç½å
³ |
| | | |
| | | #define LORA_MSGTYPE_TAGMSGTOWG_BT 0x26//æ ç¾è·ç¦»ä¿¡æ¯èçè·ç¦»ä¿¡æ¯ï¼ä¿¡å·å¼ºåº¦ï¼åç»ç½å
³ |
| | | |
| | | #define LORA_MSGTYPE_WGRESPTAG 8//ç½å
³å夿 ç¾æµè·å®ä½æ¥æ |
| | | #define LORA_MSGTYPE_TAGHEARTBEAT 0x33//æ ç¾å¿è·³å
ä¸ä¼ |
| | | #define LORA_MSGTYPE_READPARARESP 0x39 //æ ç¾åºç«åå¤ç½å
³è¯»åé
ç½®æä»¤ |
| | | //SYNCæ¶æ¯ä¸ åæ¶æ¯ç±»åå®ä¹ |
| | | #define SUBMSG_NONE 0//æ å
¶ä»æ¶æ¯ åªæ¯åæ¥ä¿¡å· |
| | | #define SUBMSG_READ_ANCPARA 0x11//åæ¶æ¯ç±»åï¼è¯»ååºç«é
ç½® |
| | | #define SUBMSG_WRITE_ANCPARA 0x12//åæ¶æ¯ç±»åï¼ååºç«é
ç½® |
| | | #define SUBMSG_UPDATE_TAG 5//åæ¶æ¯ç±»åï¼å级æ ç¾ |
| | | #define SUBMSG_UPDATE_ANC 6//åæ¶æ¯ç±»åï¼å级åºç« |
| | | //SYNCæ¶æ¯ç±»åæ ¼å¼ |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define SYSTIME_IDX 6 //ç³»ç»æ¶é´ |
| | | #define RANGE_STATE_IDX 7 //该ç½å
³èå´æ¯å¦æµè·æ å¿ä½ï¼ä¸º1ååºåå
åºç«æµè·ï¼å¦ææ¯0ååºåå
åºç«ä¸æµè· |
| | | #define SUBMSGTYPE_IDX 9 //åæ¶æ¯ç±»åIDX |
| | | #define WRITEPARA_INDEX_IDX 10 //åå
¥åæ°çå°åIDX |
| | | #define WRITEPARA_VALUE_IDX 11 //åå
¥åæ°çå¼ï¼2个åè /*å¨åéå级åºç«è¯·æ±æ¶ï¼è¢«æ¿æ¢ä¸ºè¦åéçå级æä»¶çå¤§å° |
| | | #define WG_SYNC_RESERVE_IDX 13 //ä¿ç 4个åè |
| | | //LORA_MSGTYPE_TAGMSGTOWG æ ç¾ä¸æ¥ç½å
³å®ä½æ¥æä¿¡æ¯æ ¼å¼ |
| | | |
| | | #ifdef USE_GPS |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define SEQNUM_IDX 6 //æ ç¾æ¥æåºå· |
| | | #define BAT_IDX 7 //æ ç¾çµé |
| | | #define STATE_IDX 8 |
| | | #define GPS_JINGDU_IDX 9 |
| | | #define GPS_WEIDU_IDX 17 |
| | | #define GPS_HEIGHT_IDX 25 |
| | | #define GPS_STATE_IDX 29 |
| | | #define GPS_SATEL_NUM_IDX 30 |
| | | #define GPS_SPOWER_IDX 31 //ä¿¡å·å¼ºåº¦ |
| | | #define GPS_CHAFENLINGQI 32 //å·®å龿 |
| | | #define BAR_HEIGHT_IDX 33 //æ°åé«åº¦ |
| | | #define ANCNUM_IDX 35 |
| | | #define ANCID_IDX 36 //æ ¡éªå¨4*ancnum+ANCID_IDX ä½ç½® |
| | | #else |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define SEQNUM_IDX 6 //æ ç¾æ¥æåºå· |
| | | #define BAT_IDX 7 //æ ç¾çµé |
| | | #define STATE_IDX 8 |
| | | #define BAR_HEIGHT_IDX 9 //æ°åé«åº¦ |
| | | #define GATEWAY_CHANL 9 |
| | | #define CHANL_NUM 10 |
| | | #define ANCNUM_IDX 11 |
| | | #define ANCID_IDX 12 //æ ¡éªå¨4*ancnum+ANCID_IDX ä½ç½® |
| | | // #define LORA_RETRANSNUSSION_BT 13 //LORA转åèçåè®®æ è¯ç¬¦ |
| | | |
| | | |
| | | #endif |
| | | //#define LORA_MSGTYPE_WGRESPTAG 8//ç½å
³å夿 ç¾æµè·å®ä½æ¥æ æ ¼å¼ |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define NEXTPOLL_TIME_IDX 6 // |
| | | #define POLL_FREQ_IDX 8 //åé
çåéé¢çï¼éè¦+400çåç§»éã |
| | | #define PWTAG_RW_FLAG_IDX 9 //è¯»åæ å¿ 0æ 读å 1åå
¥ 2读å |
| | | #define PWTAG_WRITE_IDX_IDX 10 //åå
¥å°å |
| | | #define PWTAG_SECDELAY_IDX 10 //åå
¥æ ç¾ç§å»¶è¿ ä¸è¯»åå°åå
±ç¨ä¸ä¸ªä½ç½®ï¼å½æè¯»åå°åæ¶ï¼å°±æ²¡æè¿ä¸ªåæ°ã |
| | | #define PWTAG_WRITE_VALUE_IDX 11 //åå
¥å¼ |
| | | |
| | | #define WGRSP_RWTAG_NONE 0//ç½å
³å夿 ç¾ï¼æ 读å |
| | | #define WGRSP_RWTAG_READ 2//ç½å
³å夿 ç¾ï¼æ 读å |
| | | #define WGRSP_RWTAG_WRITE 1//ç½å
³å夿 ç¾ï¼æ 读å |
| | | #define WGRSP_RWTAG_UPDATE 0x06//ç½å
³å夿 ç¾ï¼æ 读å |
| | | //#define LORA_MSGTYPE_READPARARESP 0x39 //æ ç¾åºç«åå¤ç½å
³è¯»åé
ç½®æä»¤ |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define RP_CMD_IDX 6 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define RP_INDEX_IDX 7 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define RP_LEN_IDX 8 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | |
| | | //#define LORA_MSGTYPE_TAGHEARTBEAT 0x33//æ ç¾å¿è·³å
ä¸ä¼ æ ¼å¼ |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define HB_VERSION_IDX 6 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define HB_UWBPOWER_IDX 8 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define HB_LORAPOWER_IDX 9 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define HB_RESERVE_IDX 10//æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | |
| | | |
| | | //#define LORA_MSGTYPE_TAGBTMSGTOWG |
| | | #define MSG_TYPE_IDX 0 //LORA MSG TYPE å®ä¹ |
| | | #define MSG_LENGTH 1 //æ¥æé¿åº¦ |
| | | #define SOURCE_ID_IDX 2 //ç½å
³ID å ç¨2个åè |
| | | #define DEST_ID_IDX 4 //æ ç¾æè
åºç«ç设å¤ID 2个åè |
| | | #define SEQNUM_IDX 6 //æ ç¾æ¥æåºå· |
| | | #define BAT_IDX 7 //æ ç¾çµé |
| | | #define STATE_IDX 8 //æé®/鿢 |
| | | #define BAR_HEIGHT_IDX 9 //æ°åé«åº¦ |
| | | #define STEP_COUNT 15 |
| | | #define EXERCISE_STATE 16 |
| | | #define RESERVED_POSITION 17 |
| | | // #define GETWG_CHANL 11 //ç½å
³éé |
| | | // #define GETCHANL_NUM 12 //ééåºå· |
| | | // #define SIGNAL_STRENGTH 13 //ä¿¡å·å¼ºåº¦ |
| | | // #define ERROR_TIME 14 //误差æ¶é´ |
| | | #define STATION_NUM_UWB 16 //åºç«æ°é-èç |
| | | |
| | | // #define STATION_NUM_UWB |
| | | #define BT_ANCID_IDX 15 //æ ¡éªå¨4*ancnum+ANCID_IDX ä½ç½® |
| | | typedef enum{ WG_Lost, //䏿¥ä¸¢å¤± 失å»åç½å
³é讯 |
| | | WG_Connected,// 䏿¥ä¸ åç½å
³é讯æ£å¸¸ |
| | | }wg_state_enum; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | void Lora_1268_Init(void); |
| | | void OnTxDone( void ); |
| | | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); |
| | | void OnTxTimeout( void ); |
| | | void OnRxTimeout( void ); |
| | | void OnRxError( void ); |
| | | void SwitchLoraSettings(uint32_t freq,uint8_t sf,uint8_t power); |
| | | #endif |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /*! |
| | | * \file radio.c |
| | | * |
| | | * \brief Radio driver API definition |
| | | * |
| | | * \copyright Revised BSD License, see section \ref LICENSE. |
| | | * |
| | | * \code |
| | | * ______ _ |
| | | * / _____) _ | | |
| | | * ( (____ _____ ____ _| |_ _____ ____| |__ |
| | | * \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| | | * _____) ) ____| | | || |_| ____( (___| | | | |
| | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| | | * (C)2013-2017 Semtech |
| | | * |
| | | * \endcode |
| | | * |
| | | * \author Miguel Luis ( Semtech ) |
| | | * |
| | | * \author Gregory Cristian ( Semtech ) |
| | | */ |
| | | // #include "stm32l0xx_hal.h" |
| | | //#include "stm32l0xx_hal_conf.h" |
| | | //#include "main.h" |
| | | #include <math.h> |
| | | #include <string.h> |
| | | #include <stdbool.h> |
| | | //#include "stm32f0xx.h" |
| | | #include "delay.h" |
| | | //#include "dw_driver.h" |
| | | //#include "gpio.h" |
| | | //#include "spi.h" |
| | | #include "radio.h" |
| | | #include "sx126x.h" |
| | | #include "sx126x-board.h" |
| | | //#include "stm32l0xx_hal_gpio.h" |
| | | #include "lora_1268.h" |
| | | |
| | | /*! |
| | | * \brief Initializes the radio |
| | | * |
| | | * \param [IN] events Structure containing the driver callback functions |
| | | */ |
| | | void RadioInit( RadioEvents_t *events ); |
| | | |
| | | /*! |
| | | * Return current radio status |
| | | * |
| | | * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] |
| | | */ |
| | | RadioState_t RadioGetStatus( void ); |
| | | |
| | | /*! |
| | | * \brief Configures the radio with the given modem |
| | | * |
| | | * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] |
| | | */ |
| | | void RadioSetModem( RadioModems_t modem ); |
| | | |
| | | /*! |
| | | * \brief Sets the channel frequency |
| | | * |
| | | * \param [IN] freq Channel RF frequency |
| | | */ |
| | | void RadioSetChannel( uint32_t freq ); |
| | | |
| | | /*! |
| | | * \brief Checks if the channel is free for the given time |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] freq Channel RF frequency |
| | | * \param [IN] rssiThresh RSSI threshold |
| | | * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured |
| | | * |
| | | * \retval isFree [true: Channel is free, false: Channel is not free] |
| | | */ |
| | | bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); |
| | | |
| | | /*! |
| | | * \brief Generates a 32 bits random value based on the RSSI readings |
| | | * |
| | | * \remark This function sets the radio in LoRa modem mode and disables |
| | | * all interrupts. |
| | | * After calling this function either Radio.SetRxConfig or |
| | | * Radio.SetTxConfig functions must be called. |
| | | * |
| | | * \retval randomValue 32 bits random value |
| | | */ |
| | | uint32_t RadioRandom( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the reception parameters |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] bandwidth Sets the bandwidth |
| | | * FSK : >= 2600 and <= 250000 Hz |
| | | * LoRa: [0: 125 kHz, 1: 250 kHz, |
| | | * 2: 500 kHz, 3: Reserved] |
| | | * \param [IN] datarate Sets the Datarate |
| | | * FSK : 600..300000 bits/s |
| | | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
| | | * 10: 1024, 11: 2048, 12: 4096 chips] |
| | | * \param [IN] coderate Sets the coding rate (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
| | | * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) |
| | | * FSK : >= 2600 and <= 250000 Hz |
| | | * LoRa: N/A ( set to 0 ) |
| | | * \param [IN] preambleLen Sets the Preamble length |
| | | * FSK : Number of bytes |
| | | * LoRa: Length in symbols (the hardware adds 4 more symbols) |
| | | * \param [IN] symbTimeout Sets the RxSingle timeout value |
| | | * FSK : timeout in number of bytes |
| | | * LoRa: timeout in symbols |
| | | * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
| | | * \param [IN] payloadLen Sets payload length when fixed length is used |
| | | * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] |
| | | * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: OFF, 1: ON] |
| | | * \param [IN] HopPeriod Number of symbols between each hop |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: Number of symbols |
| | | * \param [IN] iqInverted Inverts IQ signals (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: not inverted, 1: inverted] |
| | | * \param [IN] rxContinuous Sets the reception in continuous mode |
| | | * [false: single mode, true: continuous mode] |
| | | */ |
| | | void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, |
| | | uint32_t datarate, uint8_t coderate, |
| | | uint32_t bandwidthAfc, uint16_t preambleLen, |
| | | uint16_t symbTimeout, bool fixLen, |
| | | uint8_t payloadLen, |
| | | bool crcOn, bool FreqHopOn, uint8_t HopPeriod, |
| | | bool iqInverted, bool rxContinuous ); |
| | | |
| | | /*! |
| | | * \brief Sets the transmission parameters |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] power Sets the output power [dBm] |
| | | * \param [IN] fdev Sets the frequency deviation (FSK only) |
| | | * FSK : [Hz] |
| | | * LoRa: 0 |
| | | * \param [IN] bandwidth Sets the bandwidth (LoRa only) |
| | | * FSK : 0 |
| | | * LoRa: [0: 125 kHz, 1: 250 kHz, |
| | | * 2: 500 kHz, 3: Reserved] |
| | | * \param [IN] datarate Sets the Datarate |
| | | * FSK : 600..300000 bits/s |
| | | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
| | | * 10: 1024, 11: 2048, 12: 4096 chips] |
| | | * \param [IN] coderate Sets the coding rate (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
| | | * \param [IN] preambleLen Sets the preamble length |
| | | * FSK : Number of bytes |
| | | * LoRa: Length in symbols (the hardware adds 4 more symbols) |
| | | * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
| | | * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] |
| | | * \param [IN] FreqHopOn Enables disables the intra-packet frequency hopping |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: OFF, 1: ON] |
| | | * \param [IN] HopPeriod Number of symbols between each hop |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: Number of symbols |
| | | * \param [IN] iqInverted Inverts IQ signals (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: not inverted, 1: inverted] |
| | | * \param [IN] timeout Transmission timeout [ms] |
| | | */ |
| | | void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, |
| | | uint32_t bandwidth, uint32_t datarate, |
| | | uint8_t coderate, uint16_t preambleLen, |
| | | bool fixLen, bool crcOn, bool FreqHopOn, |
| | | uint8_t HopPeriod, bool iqInverted, uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Checks if the given RF frequency is supported by the hardware |
| | | * |
| | | * \param [IN] frequency RF frequency to be checked |
| | | * \retval isSupported [true: supported, false: unsupported] |
| | | */ |
| | | bool RadioCheckRfFrequency( uint32_t frequency ); |
| | | |
| | | /*! |
| | | * \brief Computes the packet time on air in ms for the given payload |
| | | * |
| | | * \Remark Can only be called once SetRxConfig or SetTxConfig have been called |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] pktLen Packet payload length |
| | | * |
| | | * \retval airTime Computed airTime (ms) for the given packet payload length |
| | | */ |
| | | uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ); |
| | | |
| | | /*! |
| | | * \brief Sends the buffer of size. Prepares the packet to be sent and sets |
| | | * the radio in transmission |
| | | * |
| | | * \param [IN]: buffer Buffer pointer |
| | | * \param [IN]: size Buffer size |
| | | */ |
| | | void RadioSend( uint8_t *buffer, uint8_t size ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in sleep mode |
| | | */ |
| | | void RadioSleep( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in standby mode |
| | | */ |
| | | void RadioStandby( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in reception mode for the given time |
| | | * \param [IN] timeout Reception timeout [ms] |
| | | * [0: continuous, others timeout] |
| | | */ |
| | | void RadioRx( uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Start a Channel Activity Detection |
| | | */ |
| | | void RadioStartCad( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in continuous wave transmission mode |
| | | * |
| | | * \param [IN]: freq Channel RF frequency |
| | | * \param [IN]: power Sets the output power [dBm] |
| | | * \param [IN]: time Transmission mode timeout [s] |
| | | */ |
| | | void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ); |
| | | |
| | | /*! |
| | | * \brief Reads the current RSSI value |
| | | * |
| | | * \retval rssiValue Current RSSI value in [dBm] |
| | | */ |
| | | int16_t RadioRssi( RadioModems_t modem ); |
| | | |
| | | /*! |
| | | * \brief Writes the radio register at the specified address |
| | | * |
| | | * \param [IN]: addr Register address |
| | | * \param [IN]: data New register value |
| | | */ |
| | | void RadioWrite( uint16_t addr, uint8_t data ); |
| | | |
| | | /*! |
| | | * \brief Reads the radio register at the specified address |
| | | * |
| | | * \param [IN]: addr Register address |
| | | * \retval data Register value |
| | | */ |
| | | uint8_t RadioRead( uint16_t addr ); |
| | | |
| | | /*! |
| | | * \brief Writes multiple radio registers starting at address |
| | | * |
| | | * \param [IN] addr First Radio register address |
| | | * \param [IN] buffer Buffer containing the new register's values |
| | | * \param [IN] size Number of registers to be written |
| | | */ |
| | | void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); |
| | | |
| | | /*! |
| | | * \brief Reads multiple radio registers starting at address |
| | | * |
| | | * \param [IN] addr First Radio register address |
| | | * \param [OUT] buffer Buffer where to copy the registers data |
| | | * \param [IN] size Number of registers to be read |
| | | */ |
| | | void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ); |
| | | |
| | | /*! |
| | | * \brief Sets the maximum payload length. |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] max Maximum payload length in bytes |
| | | */ |
| | | void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ); |
| | | |
| | | /*! |
| | | * \brief Sets the network to public or private. Updates the sync byte. |
| | | * |
| | | * \remark Applies to LoRa modem only |
| | | * |
| | | * \param [IN] enable if true, it enables a public network |
| | | */ |
| | | void RadioSetPublicNetwork( bool enable ); |
| | | |
| | | /*! |
| | | * \brief Gets the time required for the board plus radio to get out of sleep.[ms] |
| | | * |
| | | * \retval time Radio plus board wakeup time in ms. |
| | | */ |
| | | uint32_t RadioGetWakeupTime( void ); |
| | | |
| | | /*! |
| | | * \brief Process radio irq |
| | | */ |
| | | void RadioIrqProcess( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in reception mode with Max LNA gain for the given time |
| | | * \param [IN] timeout Reception timeout [ms] |
| | | * [0: continuous, others timeout] |
| | | */ |
| | | void RadioRxBoosted( uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the Rx duty cycle management parameters |
| | | * |
| | | * \param [in] rxTime Structure describing reception timeout value |
| | | * \param [in] sleepTime Structure describing sleep timeout value |
| | | */ |
| | | void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); |
| | | |
| | | /*! |
| | | * Radio driver structure initialization |
| | | */ |
| | | const struct Radio_s Radio = |
| | | { |
| | | RadioInit, |
| | | RadioGetStatus, |
| | | RadioSetModem, |
| | | RadioSetChannel, |
| | | RadioIsChannelFree, |
| | | RadioRandom, |
| | | RadioSetRxConfig, |
| | | RadioSetTxConfig, |
| | | RadioCheckRfFrequency, |
| | | RadioTimeOnAir, |
| | | RadioSend, |
| | | RadioSleep, |
| | | RadioStandby, |
| | | RadioRx, |
| | | RadioStartCad, |
| | | RadioSetTxContinuousWave, |
| | | RadioRssi, |
| | | RadioWrite, |
| | | RadioRead, |
| | | RadioWriteBuffer, |
| | | RadioReadBuffer, |
| | | RadioSetMaxPayloadLength, |
| | | RadioSetPublicNetwork, |
| | | RadioGetWakeupTime, |
| | | RadioIrqProcess, |
| | | // Available on SX126x only |
| | | RadioRxBoosted, |
| | | RadioSetRxDutyCycle |
| | | }; |
| | | |
| | | /* |
| | | * Local types definition |
| | | */ |
| | | |
| | | |
| | | /*! |
| | | * FSK bandwidth definition |
| | | */ |
| | | typedef struct |
| | | { |
| | | uint32_t bandwidth; |
| | | uint8_t RegValue; |
| | | }FskBandwidth_t; |
| | | |
| | | /*! |
| | | * Precomputed FSK bandwidth registers values |
| | | */ |
| | | const FskBandwidth_t FskBandwidths[] = |
| | | { |
| | | { 4800 , 0x1F }, |
| | | { 5800 , 0x17 }, |
| | | { 7300 , 0x0F }, |
| | | { 9700 , 0x1E }, |
| | | { 11700 , 0x16 }, |
| | | { 14600 , 0x0E }, |
| | | { 19500 , 0x1D }, |
| | | { 23400 , 0x15 }, |
| | | { 29300 , 0x0D }, |
| | | { 39000 , 0x1C }, |
| | | { 46900 , 0x14 }, |
| | | { 58600 , 0x0C }, |
| | | { 78200 , 0x1B }, |
| | | { 93800 , 0x13 }, |
| | | { 117300, 0x0B }, |
| | | { 156200, 0x1A }, |
| | | { 187200, 0x12 }, |
| | | { 234300, 0x0A }, |
| | | { 312000, 0x19 }, |
| | | { 373600, 0x11 }, |
| | | { 467000, 0x09 }, |
| | | { 500000, 0x00 }, // Invalid Bandwidth |
| | | }; |
| | | |
| | | const RadioLoRaBandwidths_t Bandwidths[] = { LORA_BW_125, LORA_BW_250, LORA_BW_500 }; |
| | | |
| | | // SF12 SF11 SF10 SF9 SF8 SF7 |
| | | static double RadioLoRaSymbTime[3][6] = {{ 32.768, 16.384, 8.192, 4.096, 2.048, 1.024 }, // 125 KHz |
| | | { 16.384, 8.192, 4.096, 2.048, 1.024, 0.512 }, // 250 KHz |
| | | { 8.192, 4.096, 2.048, 1.024, 0.512, 0.256 }}; // 500 KHz |
| | | |
| | | uint8_t MaxPayloadLength = 0xFF; |
| | | |
| | | uint32_t TxTimeout = 0; |
| | | uint32_t RxTimeout = 0; |
| | | |
| | | bool RxContinuous = false; |
| | | |
| | | |
| | | PacketStatus_t RadioPktStatus; |
| | | uint8_t RadioRxPayload[255]; |
| | | |
| | | bool IrqFired = false; |
| | | |
| | | /* |
| | | * SX126x DIO IRQ callback functions prototype |
| | | */ |
| | | |
| | | /*! |
| | | * \brief DIO 0 IRQ callback |
| | | */ |
| | | void RadioOnDioIrq( void ); |
| | | |
| | | /*! |
| | | * \brief Tx timeout timer callback |
| | | */ |
| | | void RadioOnTxTimeoutIrq( void ); |
| | | |
| | | /*! |
| | | * \brief Rx timeout timer callback |
| | | */ |
| | | void RadioOnRxTimeoutIrq( void ); |
| | | |
| | | /* |
| | | * Private global variables |
| | | */ |
| | | |
| | | |
| | | /*! |
| | | * Holds the current network type for the radio |
| | | */ |
| | | typedef struct |
| | | { |
| | | bool Previous; |
| | | bool Current; |
| | | }RadioPublicNetwork_t; |
| | | |
| | | static RadioPublicNetwork_t RadioPublicNetwork = { false }; |
| | | |
| | | /*! |
| | | * Radio callbacks variable |
| | | */ |
| | | static RadioEvents_t* RadioEvents; |
| | | |
| | | /* |
| | | * Public global variables |
| | | */ |
| | | |
| | | /*! |
| | | * Radio hardware and global parameters |
| | | */ |
| | | SX126x_t SX126x; |
| | | |
| | | /*! |
| | | * Tx and Rx timers |
| | | */ |
| | | //TimerEvent_t TxTimeoutTimer; |
| | | //TimerEvent_t RxTimeoutTimer; |
| | | |
| | | /*! |
| | | * Returns the known FSK bandwidth registers value |
| | | * |
| | | * \param [IN] bandwidth Bandwidth value in Hz |
| | | * \retval regValue Bandwidth register value. |
| | | */ |
| | | static uint8_t RadioGetFskBandwidthRegValue( uint32_t bandwidth ) |
| | | { |
| | | uint8_t i; |
| | | |
| | | if( bandwidth == 0 ) |
| | | { |
| | | return( 0x1F ); |
| | | } |
| | | |
| | | for( i = 0; i < ( sizeof( FskBandwidths ) / sizeof( FskBandwidth_t ) ) - 1; i++ ) |
| | | { |
| | | if( ( bandwidth >= FskBandwidths[i].bandwidth ) && ( bandwidth < FskBandwidths[i + 1].bandwidth ) ) |
| | | { |
| | | return FskBandwidths[i+1].RegValue; |
| | | } |
| | | } |
| | | // ERROR: Value not found |
| | | while( 1 ); |
| | | } |
| | | uint8_t buf[2]; |
| | | void RadioInit( RadioEvents_t *events ) |
| | | { |
| | | RadioEvents = events; |
| | | |
| | | SX126xInit( RadioOnDioIrq ); |
| | | SX126xSetStandby( STDBY_RC ); |
| | | SX126xSetRegulatorMode( USE_DCDC ); |
| | | // printf("Lora_Init2\r\n"); |
| | | SX126xSetBufferBaseAddress( 0x00, 0x00 ); |
| | | |
| | | // SX126xReadCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 ); |
| | | SX126xSetTxParams( 0, RADIO_RAMP_200_US ); |
| | | SX126xSetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE ); |
| | | |
| | | //Initialize driver timeout timers |
| | | //TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq ); |
| | | //TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq ); |
| | | |
| | | IrqFired = false; |
| | | } |
| | | |
| | | RadioState_t RadioGetStatus( void ) |
| | | { |
| | | switch( SX126xGetOperatingMode( ) ) |
| | | { |
| | | case MODE_TX: |
| | | return RF_TX_RUNNING; |
| | | case MODE_RX: |
| | | return RF_RX_RUNNING; |
| | | case RF_CAD: |
| | | return RF_CAD; |
| | | default: |
| | | return RF_IDLE; |
| | | } |
| | | } |
| | | |
| | | void RadioSetModem( RadioModems_t modem ) |
| | | { |
| | | switch( modem ) |
| | | { |
| | | default: |
| | | case MODEM_FSK: |
| | | SX126xSetPacketType( PACKET_TYPE_GFSK ); |
| | | // When switching to GFSK mode the LoRa SyncWord register value is reset |
| | | // Thus, we also reset the RadioPublicNetwork variable |
| | | RadioPublicNetwork.Current = false; |
| | | break; |
| | | case MODEM_LORA: |
| | | SX126xSetPacketType( PACKET_TYPE_LORA ); |
| | | // Public/Private network register is reset when switching modems |
| | | if( RadioPublicNetwork.Current != RadioPublicNetwork.Previous ) |
| | | { |
| | | RadioPublicNetwork.Current = RadioPublicNetwork.Previous; |
| | | RadioSetPublicNetwork( RadioPublicNetwork.Current ); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | |
| | | void RadioSetChannel( uint32_t freq ) |
| | | { |
| | | SX126xSetRfFrequency( freq ); |
| | | } |
| | | |
| | | bool RadioIsChannelFree( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ) |
| | | { |
| | | bool status = true; |
| | | // int16_t rssi = 0; |
| | | // uint32_t carrierSenseTime = 0; |
| | | |
| | | RadioSetModem( modem ); |
| | | |
| | | RadioSetChannel( freq ); |
| | | |
| | | RadioRx( 0 ); |
| | | |
| | | HAL_Delay_nMS( 1 ); |
| | | |
| | | //carrierSenseTime = TimerGetCurrentTime( ); |
| | | |
| | | |
| | | //Perform carrier sense for maxCarrierSenseTime |
| | | // while( TimerGetElapsedTime( carrierSenseTime ) < maxCarrierSenseTime ) |
| | | // { |
| | | // rssi = RadioRssi( modem ); |
| | | // |
| | | // if( rssi > rssiThresh ) |
| | | // { |
| | | // status = false; |
| | | // break; |
| | | // } |
| | | // } |
| | | RadioSleep( ); |
| | | return status; |
| | | } |
| | | |
| | | uint32_t RadioRandom( void ) |
| | | { |
| | | uint8_t i; |
| | | uint32_t rnd = 0; |
| | | |
| | | /* |
| | | * Radio setup for random number generation |
| | | */ |
| | | // Set LoRa modem ON |
| | | RadioSetModem( MODEM_LORA ); |
| | | |
| | | // Set radio in continuous reception |
| | | SX126xSetRx( 0 ); |
| | | |
| | | for( i = 0; i < 32; i++ ) |
| | | { |
| | | HAL_Delay_nMS( 1 ); |
| | | // Unfiltered RSSI value reading. Only takes the LSB value |
| | | rnd |= ( ( uint32_t )SX126xGetRssiInst( ) & 0x01 ) << i; |
| | | } |
| | | |
| | | RadioSleep( ); |
| | | |
| | | return rnd; |
| | | } |
| | | |
| | | void RadioSetRxConfig( RadioModems_t modem, uint32_t bandwidth, |
| | | uint32_t datarate, uint8_t coderate, |
| | | uint32_t bandwidthAfc, uint16_t preambleLen, |
| | | uint16_t symbTimeout, bool fixLen, |
| | | uint8_t payloadLen, |
| | | bool crcOn, bool freqHopOn, uint8_t hopPeriod, |
| | | bool iqInverted, bool rxContinuous ) |
| | | { |
| | | |
| | | RxContinuous = rxContinuous; |
| | | |
| | | if( fixLen == true ) |
| | | { |
| | | MaxPayloadLength = payloadLen; |
| | | } |
| | | else |
| | | { |
| | | MaxPayloadLength = 0xFF; |
| | | } |
| | | |
| | | switch( modem ) |
| | | { |
| | | case MODEM_FSK: |
| | | SX126xSetStopRxTimerOnPreambleDetect( false ); |
| | | SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; |
| | | |
| | | SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; |
| | | SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; |
| | | SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); |
| | | |
| | | SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; |
| | | SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit |
| | | SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; |
| | | SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3; // convert byte into bit |
| | | SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; |
| | | SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; |
| | | SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength; |
| | | if( crcOn == true ) |
| | | { |
| | | SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; |
| | | } |
| | | SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREE_OFF; |
| | | |
| | | RadioStandby( ); |
| | | RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); |
| | | SX126xSetModulationParams( &SX126x.ModulationParams ); |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); |
| | | SX126xSetWhiteningSeed( 0x01FF ); |
| | | |
| | | RxTimeout = ( uint32_t )( symbTimeout * ( ( 1.0 / ( double )datarate ) * 8.0 ) * 1000 ); |
| | | break; |
| | | |
| | | case MODEM_LORA: |
| | | SX126xSetStopRxTimerOnPreambleDetect( false ); |
| | | SX126xSetLoRaSymbNumTimeout( symbTimeout ); |
| | | SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; |
| | | SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t )datarate; |
| | | SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; |
| | | SX126x.ModulationParams.Params.LoRa.CodingRate = ( RadioLoRaCodingRates_t )coderate; |
| | | |
| | | if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || |
| | | ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) |
| | | { |
| | | SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; |
| | | } |
| | | else |
| | | { |
| | | SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; |
| | | } |
| | | |
| | | SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; |
| | | |
| | | if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || |
| | | ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) |
| | | { |
| | | if( preambleLen < 12 ) |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PreambleLength = 12; |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; |
| | | } |
| | | |
| | | SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; |
| | | |
| | | SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; |
| | | SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; |
| | | SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; |
| | | |
| | | RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); |
| | | SX126xSetModulationParams( &SX126x.ModulationParams ); |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | |
| | | // Timeout Max, Timeout handled directly in SetRx function |
| | | RxTimeout = 0xFFFF; |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev, |
| | | uint32_t bandwidth, uint32_t datarate, |
| | | uint8_t coderate, uint16_t preambleLen, |
| | | bool fixLen, bool crcOn, bool freqHopOn, |
| | | uint8_t hopPeriod, bool iqInverted, uint32_t timeout ) |
| | | { |
| | | |
| | | switch( modem ) |
| | | { |
| | | case MODEM_FSK: |
| | | SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK; |
| | | SX126x.ModulationParams.Params.Gfsk.BitRate = datarate; |
| | | |
| | | SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1; |
| | | SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth ); |
| | | SX126x.ModulationParams.Params.Gfsk.Fdev = fdev; |
| | | |
| | | SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK; |
| | | SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit |
| | | SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS; |
| | | SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3 ; // convert byte into bit |
| | | SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF; |
| | | SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH; |
| | | |
| | | if( crcOn == true ) |
| | | { |
| | | SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT; |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF; |
| | | } |
| | | SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREEWHITENING; |
| | | |
| | | RadioStandby( ); |
| | | RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); |
| | | SX126xSetModulationParams( &SX126x.ModulationParams ); |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } ); |
| | | SX126xSetWhiteningSeed( 0x01FF ); |
| | | break; |
| | | |
| | | case MODEM_LORA: |
| | | SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA; |
| | | SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) datarate; |
| | | SX126x.ModulationParams.Params.LoRa.Bandwidth = Bandwidths[bandwidth]; |
| | | SX126x.ModulationParams.Params.LoRa.CodingRate= ( RadioLoRaCodingRates_t )coderate; |
| | | |
| | | if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) || |
| | | ( ( bandwidth == 1 ) && ( datarate == 12 ) ) ) |
| | | { |
| | | SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01; |
| | | } |
| | | else |
| | | { |
| | | SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00; |
| | | } |
| | | |
| | | SX126x.PacketParams.PacketType = PACKET_TYPE_LORA; |
| | | |
| | | if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) || |
| | | ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) ) |
| | | { |
| | | if( preambleLen < 12 ) |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PreambleLength = 12; |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen; |
| | | } |
| | | |
| | | SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen; |
| | | SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength; |
| | | SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn; |
| | | SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted; |
| | | |
| | | RadioStandby( ); |
| | | RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA ); |
| | | SX126xSetModulationParams( &SX126x.ModulationParams ); |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | break; |
| | | } |
| | | SX126xSetRfTxPower( power ); |
| | | TxTimeout = timeout; |
| | | } |
| | | |
| | | bool RadioCheckRfFrequency( uint32_t frequency ) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | uint32_t RadioTimeOnAir( RadioModems_t modem, uint8_t pktLen ) |
| | | { |
| | | uint32_t airTime = 0; |
| | | |
| | | switch( modem ) |
| | | { |
| | | case MODEM_FSK: |
| | | { |
| | | airTime = rint( ( 8 * ( SX126x.PacketParams.Params.Gfsk.PreambleLength + |
| | | ( SX126x.PacketParams.Params.Gfsk.SyncWordLength >> 3 ) + |
| | | ( ( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_FIXED_LENGTH ) ? 0.0 : 1.0 ) + |
| | | pktLen + |
| | | ( ( SX126x.PacketParams.Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES ) ? 2.0 : 0 ) ) / |
| | | SX126x.ModulationParams.Params.Gfsk.BitRate ) * 1e3 ); |
| | | } |
| | | break; |
| | | case MODEM_LORA: |
| | | { |
| | | double ts = RadioLoRaSymbTime[SX126x.ModulationParams.Params.LoRa.Bandwidth - 4][12 - SX126x.ModulationParams.Params.LoRa.SpreadingFactor]; |
| | | // time of preamble |
| | | double tPreamble = ( SX126x.PacketParams.Params.LoRa.PreambleLength + 4.25 ) * ts; |
| | | // Symbol length of payload and time |
| | | double tmp = ceil( ( 8 * pktLen - 4 * SX126x.ModulationParams.Params.LoRa.SpreadingFactor + |
| | | 28 + 16 * SX126x.PacketParams.Params.LoRa.CrcMode - |
| | | ( ( SX126x.PacketParams.Params.LoRa.HeaderType == LORA_PACKET_FIXED_LENGTH ) ? 20 : 0 ) ) / |
| | | ( double )( 4 * ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor - |
| | | ( ( SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize > 0 ) ? 2 : 0 ) ) ) ) * |
| | | ( ( SX126x.ModulationParams.Params.LoRa.CodingRate % 4 ) + 4 ); |
| | | double nPayload = 8 + ( ( tmp > 0 ) ? tmp : 0 ); |
| | | double tPayload = nPayload * ts; |
| | | // Time on air |
| | | double tOnAir = tPreamble + tPayload; |
| | | // return milli seconds |
| | | airTime = floor( tOnAir + 0.999 ); |
| | | } |
| | | break; |
| | | } |
| | | return airTime; |
| | | } |
| | | |
| | | void RadioSend( uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xSetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, |
| | | IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT, |
| | | IRQ_RADIO_NONE, |
| | | IRQ_RADIO_NONE ); |
| | | |
| | | if( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PayloadLength = size; |
| | | } |
| | | else |
| | | { |
| | | SX126x.PacketParams.Params.Gfsk.PayloadLength = size; |
| | | } |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | |
| | | SX126xSendPayload( buffer, size, 0 ); |
| | | // TimerSetValue( &TxTimeoutTimer, TxTimeout ); |
| | | // TimerStart( &TxTimeoutTimer ); |
| | | } |
| | | |
| | | void RadioSleep( void ) |
| | | { |
| | | SleepParams_t params = { 0 }; |
| | | |
| | | params.Fields.WarmStart = 1; |
| | | SX126xSetSleep( params ); |
| | | |
| | | HAL_Delay_nMS( 2 ); |
| | | } |
| | | |
| | | void RadioStandby( void ) |
| | | { |
| | | SX126xSetStandby( STDBY_RC ); |
| | | } |
| | | |
| | | void RadioRx( uint32_t timeout ) |
| | | { |
| | | SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, |
| | | // IRQ_RX_DONE|IRQ_RX_TX_TIMEOUT, |
| | | IRQ_RX_DONE| IRQ_RX_TX_TIMEOUT, |
| | | IRQ_RADIO_NONE, |
| | | IRQ_RADIO_NONE ); |
| | | |
| | | |
| | | if( RxContinuous == true ) |
| | | { |
| | | SX126xSetRx( 0xFFFFFF ); // Rx Continuous |
| | | } |
| | | else |
| | | { |
| | | SX126xSetRx( timeout << 6 ); |
| | | } |
| | | } |
| | | |
| | | void RadioRxBoosted( uint32_t timeout ) |
| | | { |
| | | SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, |
| | | IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT, |
| | | IRQ_RADIO_NONE, |
| | | IRQ_RADIO_NONE ); |
| | | |
| | | |
| | | if( RxContinuous == true ) |
| | | { |
| | | SX126xSetRxBoosted( 0xFFFFFF ); // Rx Continuous |
| | | } |
| | | else |
| | | { |
| | | SX126xSetRxBoosted( timeout << 6 ); |
| | | } |
| | | } |
| | | |
| | | void RadioSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) |
| | | { |
| | | SX126xSetRxDutyCycle( rxTime, sleepTime ); |
| | | } |
| | | |
| | | void RadioStartCad( void ) |
| | | { |
| | | SX126xSetCad( ); |
| | | } |
| | | |
| | | void RadioTx( uint32_t timeout ) |
| | | { |
| | | SX126xSetTx( timeout << 6 ); |
| | | } |
| | | |
| | | void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time ) |
| | | { |
| | | SX126xSetRfFrequency( freq ); |
| | | SX126xSetRfTxPower( power ); |
| | | SX126xSetTxContinuousWave( ); |
| | | |
| | | // TimerSetValue( &RxTimeoutTimer, time * 1e3 ); |
| | | // TimerStart( &RxTimeoutTimer ); |
| | | } |
| | | |
| | | int16_t RadioRssi( RadioModems_t modem ) |
| | | { |
| | | return SX126xGetRssiInst( ); |
| | | } |
| | | |
| | | void RadioWrite( uint16_t addr, uint8_t data ) |
| | | { |
| | | SX126xWriteRegister( addr, data ); |
| | | } |
| | | |
| | | uint8_t RadioRead( uint16_t addr ) |
| | | { |
| | | return SX126xReadRegister( addr ); |
| | | } |
| | | |
| | | void RadioWriteBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xWriteRegisters( addr, buffer, size ); |
| | | } |
| | | |
| | | void RadioReadBuffer( uint16_t addr, uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xReadRegisters( addr, buffer, size ); |
| | | } |
| | | |
| | | void RadioWriteFifo( uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xWriteBuffer( 0, buffer, size ); |
| | | } |
| | | |
| | | void RadioReadFifo( uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xReadBuffer( 0, buffer, size ); |
| | | } |
| | | |
| | | void RadioSetMaxPayloadLength( RadioModems_t modem, uint8_t max ) |
| | | { |
| | | if( modem == MODEM_LORA ) |
| | | { |
| | | SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength = max; |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | } |
| | | else |
| | | { |
| | | if( SX126x.PacketParams.Params.Gfsk.HeaderType == RADIO_PACKET_VARIABLE_LENGTH ) |
| | | { |
| | | SX126x.PacketParams.Params.Gfsk.PayloadLength = MaxPayloadLength = max; |
| | | SX126xSetPacketParams( &SX126x.PacketParams ); |
| | | } |
| | | } |
| | | } |
| | | |
| | | void RadioSetPublicNetwork( bool enable ) |
| | | { |
| | | RadioPublicNetwork.Current = RadioPublicNetwork.Previous = enable; |
| | | |
| | | RadioSetModem( MODEM_LORA ); |
| | | if( enable == true ) |
| | | { |
| | | // Change LoRa modem SyncWord |
| | | SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PUBLIC_SYNCWORD >> 8 ) & 0xFF ); |
| | | SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PUBLIC_SYNCWORD & 0xFF ); |
| | | } |
| | | else |
| | | { |
| | | // Change LoRa modem SyncWord |
| | | SX126xWriteRegister( REG_LR_SYNCWORD, ( LORA_MAC_PRIVATE_SYNCWORD >> 8 ) & 0xFF ); |
| | | SX126xWriteRegister( REG_LR_SYNCWORD + 1, LORA_MAC_PRIVATE_SYNCWORD & 0xFF ); |
| | | } |
| | | } |
| | | |
| | | uint32_t RadioGetWakeupTime( void ) |
| | | { |
| | | return( RADIO_TCXO_SETUP_TIME + RADIO_WAKEUP_TIME ); |
| | | } |
| | | |
| | | void RadioOnTxTimeoutIrq( void ) |
| | | { |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) |
| | | { |
| | | RadioEvents->TxTimeout( ); |
| | | } |
| | | } |
| | | |
| | | void RadioOnRxTimeoutIrq( void ) |
| | | { |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) |
| | | { |
| | | RadioEvents->RxTimeout( ); |
| | | } |
| | | } |
| | | |
| | | void RadioOnDioIrq( void ) |
| | | { |
| | | IrqFired = true; |
| | | } |
| | | |
| | | void RadioIrqProcess( void ) |
| | | { |
| | | // if( IrqFired == true ) |
| | | if(gpio_pin_get_val(LORA_IRQ)) |
| | | { |
| | | IrqFired = false; |
| | | |
| | | uint16_t irqRegs = SX126xGetIrqStatus( ); |
| | | SX126xClearIrqStatus( IRQ_RADIO_ALL ); |
| | | |
| | | if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE ) |
| | | { |
| | | |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) ) |
| | | { |
| | | RadioEvents->TxDone( ); |
| | | } |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE ) |
| | | { |
| | | uint8_t size; |
| | | |
| | | SX126xGetPayload( RadioRxPayload, &size , 255 ); |
| | | SX126xGetPacketStatus( &RadioPktStatus ); |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) ) |
| | | { |
| | | RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt ); |
| | | } |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR ) |
| | | { |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) ) |
| | | { |
| | | RadioEvents->RxError( ); |
| | | } |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE ) |
| | | { |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) ) |
| | | { |
| | | RadioEvents->CadDone( ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) ); |
| | | } |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT ) |
| | | { |
| | | if( SX126xGetOperatingMode( ) == MODE_TX ) |
| | | { |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) ) |
| | | { |
| | | RadioEvents->TxTimeout( ); |
| | | } |
| | | } |
| | | else if( SX126xGetOperatingMode( ) == MODE_RX ) |
| | | { |
| | | |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) |
| | | { |
| | | RadioEvents->RxTimeout( ); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_PREAMBLE_DETECTED ) == IRQ_PREAMBLE_DETECTED ) |
| | | { |
| | | //__NOP( ); |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID ) |
| | | { |
| | | //__NOP( ); |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID ) |
| | | { |
| | | //__NOP( ); |
| | | } |
| | | |
| | | if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR ) |
| | | { |
| | | if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) ) |
| | | { |
| | | RadioEvents->RxTimeout( ); |
| | | } |
| | | } |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /*! |
| | | * \file radio.h |
| | | * |
| | | * \brief Radio driver API definition |
| | | * |
| | | * \copyright Revised BSD License, see section \ref LICENSE. |
| | | * |
| | | * \code |
| | | * ______ _ |
| | | * / _____) _ | | |
| | | * ( (____ _____ ____ _| |_ _____ ____| |__ |
| | | * \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| | | * _____) ) ____| | | || |_| ____( (___| | | | |
| | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| | | * (C)2013-2017 Semtech |
| | | * |
| | | * \endcode |
| | | * |
| | | * \author Miguel Luis ( Semtech ) |
| | | * |
| | | * \author Gregory Cristian ( Semtech ) |
| | | */ |
| | | #ifndef __RADIO_H__ |
| | | #define __RADIO_H__ |
| | | |
| | | #include<stdint.h> |
| | | #include<stdbool.h> |
| | | |
| | | //#define USE_MODEM_LORA |
| | | |
| | | /*! |
| | | * Radio driver supported modems |
| | | */ |
| | | typedef enum |
| | | { |
| | | MODEM_FSK = 0, |
| | | MODEM_LORA, |
| | | }RadioModems_t; |
| | | |
| | | /*! |
| | | * Radio driver internal state machine states definition |
| | | */ |
| | | typedef enum |
| | | { |
| | | RF_IDLE = 0, //!< The radio is idle |
| | | RF_RX_RUNNING, //!< The radio is in reception state |
| | | RF_TX_RUNNING, //!< The radio is in transmission state |
| | | RF_CAD, //!< The radio is doing channel activity detection |
| | | }RadioState_t; |
| | | |
| | | /*! |
| | | * \brief Radio driver callback functions |
| | | */ |
| | | typedef struct |
| | | { |
| | | /*! |
| | | * \brief Tx Done callback prototype. |
| | | */ |
| | | void ( *TxDone )( void ); |
| | | /*! |
| | | * \brief Tx Timeout callback prototype. |
| | | */ |
| | | void ( *TxTimeout )( void ); |
| | | /*! |
| | | * \brief Rx Done callback prototype. |
| | | * |
| | | * \param [IN] payload Received buffer pointer |
| | | * \param [IN] size Received buffer size |
| | | * \param [IN] rssi RSSI value computed while receiving the frame [dBm] |
| | | * \param [IN] snr Raw SNR value given by the radio hardware |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: SNR value in dB |
| | | */ |
| | | void ( *RxDone )( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); |
| | | /*! |
| | | * \brief Rx Timeout callback prototype. |
| | | */ |
| | | void ( *RxTimeout )( void ); |
| | | /*! |
| | | * \brief Rx Error callback prototype. |
| | | */ |
| | | void ( *RxError )( void ); |
| | | /*! |
| | | * \brief FHSS Change Channel callback prototype. |
| | | * |
| | | * \param [IN] currentChannel Index number of the current channel |
| | | */ |
| | | void ( *FhssChangeChannel )( uint8_t currentChannel ); |
| | | |
| | | /*! |
| | | * \brief CAD Done callback prototype. |
| | | * |
| | | * \param [IN] channelDetected Channel Activity detected during the CAD |
| | | */ |
| | | void ( *CadDone ) ( bool channelActivityDetected ); |
| | | }RadioEvents_t; |
| | | |
| | | /*! |
| | | * \brief Radio driver definition |
| | | */ |
| | | struct Radio_s |
| | | { |
| | | /*! |
| | | * \brief Initializes the radio |
| | | * |
| | | * \param [IN] events Structure containing the driver callback functions |
| | | */ |
| | | void ( *Init )( RadioEvents_t *events ); |
| | | /*! |
| | | * Return current radio status |
| | | * |
| | | * \param status Radio status.[RF_IDLE, RF_RX_RUNNING, RF_TX_RUNNING] |
| | | */ |
| | | RadioState_t ( *GetStatus )( void ); |
| | | /*! |
| | | * \brief Configures the radio with the given modem |
| | | * |
| | | * \param [IN] modem Modem to be used [0: FSK, 1: LoRa] |
| | | */ |
| | | void ( *SetModem )( RadioModems_t modem ); |
| | | /*! |
| | | * \brief Sets the channel frequency |
| | | * |
| | | * \param [IN] freq Channel RF frequency |
| | | */ |
| | | void ( *SetChannel )( uint32_t freq ); |
| | | /*! |
| | | * \brief Checks if the channel is free for the given time |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] freq Channel RF frequency |
| | | * \param [IN] rssiThresh RSSI threshold |
| | | * \param [IN] maxCarrierSenseTime Max time while the RSSI is measured |
| | | * |
| | | * \retval isFree [true: Channel is free, false: Channel is not free] |
| | | */ |
| | | bool ( *IsChannelFree )( RadioModems_t modem, uint32_t freq, int16_t rssiThresh, uint32_t maxCarrierSenseTime ); |
| | | /*! |
| | | * \brief Generates a 32 bits random value based on the RSSI readings |
| | | * |
| | | * \remark This function sets the radio in LoRa modem mode and disables |
| | | * all interrupts. |
| | | * After calling this function either Radio.SetRxConfig or |
| | | * Radio.SetTxConfig functions must be called. |
| | | * |
| | | * \retval randomValue 32 bits random value |
| | | */ |
| | | uint32_t ( *Random )( void ); |
| | | /*! |
| | | * \brief Sets the reception parameters |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] bandwidth Sets the bandwidth |
| | | * FSK : >= 2600 and <= 250000 Hz |
| | | * LoRa: [0: 125 kHz, 1: 250 kHz, |
| | | * 2: 500 kHz, 3: Reserved] |
| | | * \param [IN] datarate Sets the Datarate |
| | | * FSK : 600..300000 bits/s |
| | | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
| | | * 10: 1024, 11: 2048, 12: 4096 chips] |
| | | * \param [IN] coderate Sets the coding rate (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
| | | * \param [IN] bandwidthAfc Sets the AFC Bandwidth (FSK only) |
| | | * FSK : >= 2600 and <= 250000 Hz |
| | | * LoRa: N/A ( set to 0 ) |
| | | * \param [IN] preambleLen Sets the Preamble length |
| | | * FSK : Number of bytes |
| | | * LoRa: Length in symbols (the hardware adds 4 more symbols) |
| | | * \param [IN] symbTimeout Sets the RxSingle timeout value |
| | | * FSK : timeout in number of bytes |
| | | * LoRa: timeout in symbols |
| | | * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
| | | * \param [IN] payloadLen Sets payload length when fixed length is used |
| | | * \param [IN] crcOn Enables/Disables the CRC [0: OFF, 1: ON] |
| | | * \param [IN] freqHopOn Enables disables the intra-packet frequency hopping |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: OFF, 1: ON] |
| | | * \param [IN] hopPeriod Number of symbols between each hop |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: Number of symbols |
| | | * \param [IN] iqInverted Inverts IQ signals (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: not inverted, 1: inverted] |
| | | * \param [IN] rxContinuous Sets the reception in continuous mode |
| | | * [false: single mode, true: continuous mode] |
| | | */ |
| | | void ( *SetRxConfig )( RadioModems_t modem, uint32_t bandwidth, |
| | | uint32_t datarate, uint8_t coderate, |
| | | uint32_t bandwidthAfc, uint16_t preambleLen, |
| | | uint16_t symbTimeout, bool fixLen, |
| | | uint8_t payloadLen, |
| | | bool crcOn, bool freqHopOn, uint8_t hopPeriod, |
| | | bool iqInverted, bool rxContinuous ); |
| | | /*! |
| | | * \brief Sets the transmission parameters |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] power Sets the output power [dBm] |
| | | * \param [IN] fdev Sets the frequency deviation (FSK only) |
| | | * FSK : [Hz] |
| | | * LoRa: 0 |
| | | * \param [IN] bandwidth Sets the bandwidth (LoRa only) |
| | | * FSK : 0 |
| | | * LoRa: [0: 125 kHz, 1: 250 kHz, |
| | | * 2: 500 kHz, 3: Reserved] |
| | | * \param [IN] datarate Sets the Datarate |
| | | * FSK : 600..300000 bits/s |
| | | * LoRa: [6: 64, 7: 128, 8: 256, 9: 512, |
| | | * 10: 1024, 11: 2048, 12: 4096 chips] |
| | | * \param [IN] coderate Sets the coding rate (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] |
| | | * \param [IN] preambleLen Sets the preamble length |
| | | * FSK : Number of bytes |
| | | * LoRa: Length in symbols (the hardware adds 4 more symbols) |
| | | * \param [IN] fixLen Fixed length packets [0: variable, 1: fixed] |
| | | * \param [IN] crcOn Enables disables the CRC [0: OFF, 1: ON] |
| | | * \param [IN] freqHopOn Enables disables the intra-packet frequency hopping |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: OFF, 1: ON] |
| | | * \param [IN] hopPeriod Number of symbols between each hop |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: Number of symbols |
| | | * \param [IN] iqInverted Inverts IQ signals (LoRa only) |
| | | * FSK : N/A ( set to 0 ) |
| | | * LoRa: [0: not inverted, 1: inverted] |
| | | * \param [IN] timeout Transmission timeout [ms] |
| | | */ |
| | | void ( *SetTxConfig )( RadioModems_t modem, int8_t power, uint32_t fdev, |
| | | uint32_t bandwidth, uint32_t datarate, |
| | | uint8_t coderate, uint16_t preambleLen, |
| | | bool fixLen, bool crcOn, bool freqHopOn, |
| | | uint8_t hopPeriod, bool iqInverted, uint32_t timeout ); |
| | | /*! |
| | | * \brief Checks if the given RF frequency is supported by the hardware |
| | | * |
| | | * \param [IN] frequency RF frequency to be checked |
| | | * \retval isSupported [true: supported, false: unsupported] |
| | | */ |
| | | bool ( *CheckRfFrequency )( uint32_t frequency ); |
| | | /*! |
| | | * \brief Computes the packet time on air in ms for the given payload |
| | | * |
| | | * \Remark Can only be called once SetRxConfig or SetTxConfig have been called |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] pktLen Packet payload length |
| | | * |
| | | * \retval airTime Computed airTime (ms) for the given packet payload length |
| | | */ |
| | | uint32_t ( *TimeOnAir )( RadioModems_t modem, uint8_t pktLen ); |
| | | /*! |
| | | * \brief Sends the buffer of size. Prepares the packet to be sent and sets |
| | | * the radio in transmission |
| | | * |
| | | * \param [IN]: buffer Buffer pointer |
| | | * \param [IN]: size Buffer size |
| | | */ |
| | | void ( *Send )( uint8_t *buffer, uint8_t size ); |
| | | /*! |
| | | * \brief Sets the radio in sleep mode |
| | | */ |
| | | void ( *Sleep )( void ); |
| | | /*! |
| | | * \brief Sets the radio in standby mode |
| | | */ |
| | | void ( *Standby )( void ); |
| | | /*! |
| | | * \brief Sets the radio in reception mode for the given time |
| | | * \param [IN] timeout Reception timeout [ms] |
| | | * [0: continuous, others timeout] |
| | | */ |
| | | void ( *Rx )( uint32_t timeout ); |
| | | /*! |
| | | * \brief Start a Channel Activity Detection |
| | | */ |
| | | void ( *StartCad )( void ); |
| | | /*! |
| | | * \brief Sets the radio in continuous wave transmission mode |
| | | * |
| | | * \param [IN]: freq Channel RF frequency |
| | | * \param [IN]: power Sets the output power [dBm] |
| | | * \param [IN]: time Transmission mode timeout [s] |
| | | */ |
| | | void ( *SetTxContinuousWave )( uint32_t freq, int8_t power, uint16_t time ); |
| | | /*! |
| | | * \brief Reads the current RSSI value |
| | | * |
| | | * \retval rssiValue Current RSSI value in [dBm] |
| | | */ |
| | | int16_t ( *Rssi )( RadioModems_t modem ); |
| | | /*! |
| | | * \brief Writes the radio register at the specified address |
| | | * |
| | | * \param [IN]: addr Register address |
| | | * \param [IN]: data New register value |
| | | */ |
| | | void ( *Write )( uint16_t addr, uint8_t data ); |
| | | /*! |
| | | * \brief Reads the radio register at the specified address |
| | | * |
| | | * \param [IN]: addr Register address |
| | | * \retval data Register value |
| | | */ |
| | | uint8_t ( *Read )( uint16_t addr ); |
| | | /*! |
| | | * \brief Writes multiple radio registers starting at address |
| | | * |
| | | * \param [IN] addr First Radio register address |
| | | * \param [IN] buffer Buffer containing the new register's values |
| | | * \param [IN] size Number of registers to be written |
| | | */ |
| | | void ( *WriteBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size ); |
| | | /*! |
| | | * \brief Reads multiple radio registers starting at address |
| | | * |
| | | * \param [IN] addr First Radio register address |
| | | * \param [OUT] buffer Buffer where to copy the registers data |
| | | * \param [IN] size Number of registers to be read |
| | | */ |
| | | void ( *ReadBuffer )( uint16_t addr, uint8_t *buffer, uint8_t size ); |
| | | /*! |
| | | * \brief Sets the maximum payload length. |
| | | * |
| | | * \param [IN] modem Radio modem to be used [0: FSK, 1: LoRa] |
| | | * \param [IN] max Maximum payload length in bytes |
| | | */ |
| | | void ( *SetMaxPayloadLength )( RadioModems_t modem, uint8_t max ); |
| | | /*! |
| | | * \brief Sets the network to public or private. Updates the sync byte. |
| | | * |
| | | * \remark Applies to LoRa modem only |
| | | * |
| | | * \param [IN] enable if true, it enables a public network |
| | | */ |
| | | void ( *SetPublicNetwork )( bool enable ); |
| | | /*! |
| | | * \brief Gets the time required for the board plus radio to get out of sleep.[ms] |
| | | * |
| | | * \retval time Radio plus board wakeup time in ms. |
| | | */ |
| | | uint32_t ( *GetWakeupTime )( void ); |
| | | /*! |
| | | * \brief Process radio irq |
| | | */ |
| | | void ( *IrqProcess )( void ); |
| | | /* |
| | | * The next functions are available only on SX126x radios. |
| | | */ |
| | | /*! |
| | | * \brief Sets the radio in reception mode with Max LNA gain for the given time |
| | | * |
| | | * \remark Available on SX126x radios only. |
| | | * |
| | | * \param [IN] timeout Reception timeout [ms] |
| | | * [0: continuous, others timeout] |
| | | */ |
| | | void ( *RxBoosted )( uint32_t timeout ); |
| | | /*! |
| | | * \brief Sets the Rx duty cycle management parameters |
| | | * |
| | | * \remark Available on SX126x radios only. |
| | | * |
| | | * \param [in] rxTime Structure describing reception timeout value |
| | | * \param [in] sleepTime Structure describing sleep timeout value |
| | | */ |
| | | void ( *SetRxDutyCycle ) ( uint32_t rxTime, uint32_t sleepTime ); |
| | | }; |
| | | |
| | | /*! |
| | | * \brief Radio driver |
| | | * |
| | | * \remark This variable is defined and initialized in the specific radio |
| | | * board implementation |
| | | */ |
| | | extern const struct Radio_s Radio; |
| | | |
| | | #endif // __RADIO_H__ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | ______ _ |
| | | / _____) _ | | |
| | | ( (____ _____ ____ _| |_ _____ ____| |__ |
| | | \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| | | _____) ) ____| | | || |_| ____( (___| | | | |
| | | (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| | | (C)2013 Semtech |
| | | |
| | | Description: SX126x driver specific target board functions implementation |
| | | |
| | | License: Revised BSD License, see LICENSE.TXT file include in the project |
| | | |
| | | Maintainer: Miguel Luis and Gregory Cristian |
| | | */ |
| | | //#include "stm32f0xx.h" |
| | | #include "delay.h" |
| | | //#include "gpio.h" |
| | | //#include "Spi.h" |
| | | //#include "spi.h" |
| | | #include "radio.h" |
| | | #include "sx126x.h" |
| | | #include "sx126x-board.h" |
| | | #include "lora_1268.h" |
| | | #include "PCA9555.h" |
| | | //#include "main.h" |
| | | //#include "stm32l0xx_hal_spi.h" |
| | | #include "mk_spi.h" |
| | | //extern SPI_HandleTypeDef hspi1; |
| | | |
| | | |
| | | //void HAL_Delay_nMS( uint32_t Delay ) |
| | | //{ |
| | | // uint32_t tickstart = 0; |
| | | // tickstart = HAL_GetTick( ); |
| | | // while( ( HAL_GetTick( ) - tickstart ) < Delay ); |
| | | //} |
| | | //void SX126x_CS_Di( ) |
| | | //{ |
| | | // if(!HAL_GPIO_ReadPin( SPIx_CS_GPIO, SPIx_CS)) |
| | | // { |
| | | // HAL_GPIO_WritePin( SPIx_CS_GPIO, SPIx_CS,GPIO_PIN_SET); |
| | | // printf("uwb_cs_error\r\n"); |
| | | // } |
| | | |
| | | //} |
| | | void spi_transfer_callback(void *dev, uint32_t err_code) |
| | | { |
| | | |
| | | } |
| | | static void spi_receive_callback(void *dev, uint32_t err_code) |
| | | { |
| | | |
| | | } |
| | | /*! |
| | | * @brief Sends txBuffer and receives rxBuffer |
| | | * |
| | | * @param [IN] txBuffer Byte to be sent |
| | | * @param [OUT] rxBuffer Byte to be sent |
| | | * @param [IN] size Byte to be sent |
| | | */ |
| | | uint8_t SpiInOut( uint8_t txBuffer) |
| | | { |
| | | uint8_t rxData = 0; |
| | | spi_transfer(SPI_ID0, &txBuffer,&rxData, 1, spi_transfer_callback); |
| | | return( rxData ); |
| | | } |
| | | |
| | | |
| | | |
| | | void SX126xReset( void ) |
| | | { |
| | | HAL_Delay_nMS( 10 ); |
| | | // HAL_GPIO_WritePin( RADIO_nRESET_GPIO_Port, RADIO_nRESET_Pin,GPIO_PIN_RESET); |
| | | // gpio_pin_clr(LORA_NRST); |
| | | LORA_NRST_DOWN; |
| | | delay_us( 2000 ); |
| | | // HAL_GPIO_WritePin( RADIO_nRESET_GPIO_Port, RADIO_nRESET_Pin,GPIO_PIN_SET); |
| | | // gpio_pin_set(LORA_NRST); |
| | | LORA_NRST_UP; |
| | | HAL_Delay_nMS( 10 ); |
| | | } |
| | | |
| | | void SX126xWaitOnBusy( void ) |
| | | { |
| | | // while(HAL_GPIO_ReadPin(RADIO_BUSY_GPIO_Port,RADIO_BUSY_Pin)==GPIO_PIN_SET); |
| | | while(gpio_pin_get_val(LORA_BUSY)==1); |
| | | } |
| | | |
| | | |
| | | void SX126xWakeup( void ) |
| | | { |
| | | |
| | | gpio_pin_clr(LORA_CS); |
| | | SpiInOut(RADIO_GET_STATUS); |
| | | SpiInOut(0); |
| | | |
| | | gpio_pin_set(LORA_CS); |
| | | // Wait for chip to be ready. |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | void SX126xWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) |
| | | { |
| | | |
| | | SX126xCheckDeviceReady( ); |
| | | gpio_pin_clr(LORA_CS); |
| | | SpiInOut(( uint8_t )command ); |
| | | |
| | | for( uint16_t i = 0; i < size; i++ ) |
| | | { |
| | | SpiInOut(buffer[i] ); |
| | | } |
| | | gpio_pin_set(LORA_CS); |
| | | |
| | | if( command != RADIO_SET_SLEEP ) |
| | | { |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | } |
| | | |
| | | void SX126xReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) |
| | | { |
| | | SX126xCheckDeviceReady( ); |
| | | gpio_pin_clr(LORA_CS); |
| | | // SX126x_CS_Di( ); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_RESET); |
| | | |
| | | SpiInOut(( uint8_t )command ); |
| | | SpiInOut(0x00 ); |
| | | for( uint16_t i = 0; i < size; i++ ) |
| | | { |
| | | buffer[i] = SpiInOut(0 ); |
| | | } |
| | | gpio_pin_set(LORA_CS); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_SET); |
| | | |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) |
| | | { |
| | | SX126xCheckDeviceReady( ); |
| | | // SX126x_CS_Di( ); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_RESET); |
| | | gpio_pin_clr(LORA_CS); |
| | | SpiInOut(RADIO_WRITE_REGISTER ); |
| | | SpiInOut(( address & 0xFF00 ) >> 8 ); |
| | | SpiInOut( address & 0x00FF ); |
| | | |
| | | for( uint16_t i = 0; i < size; i++ ) |
| | | { |
| | | SpiInOut(buffer[i] ); |
| | | } |
| | | |
| | | gpio_pin_set(LORA_CS); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_SET); |
| | | |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | void SX126xWriteRegister( uint16_t address, uint8_t value ) |
| | | { |
| | | SX126xWriteRegisters( address, &value, 1 ); |
| | | } |
| | | |
| | | void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) |
| | | { |
| | | SX126xCheckDeviceReady( ); |
| | | // SX126x_CS_Di( ); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_RESET); |
| | | gpio_pin_clr(LORA_CS); |
| | | SpiInOut(RADIO_READ_REGISTER ); |
| | | SpiInOut(( address & 0xFF00 ) >> 8 ); |
| | | SpiInOut( address & 0x00FF ); |
| | | SpiInOut( 0 ); |
| | | for( uint16_t i = 0; i < size; i++ ) |
| | | { |
| | | buffer[i] = SpiInOut(0 ); |
| | | } |
| | | gpio_pin_set(LORA_CS); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_SET); |
| | | |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | uint8_t SX126xReadRegister( uint16_t address ) |
| | | { |
| | | uint8_t data; |
| | | SX126xReadRegisters( address, &data, 1 ); |
| | | return data; |
| | | } |
| | | |
| | | void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xCheckDeviceReady( ); |
| | | // SX126x_CS_Di( ); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_RESET); |
| | | gpio_pin_clr(LORA_CS); |
| | | SpiInOut( RADIO_WRITE_BUFFER ); |
| | | SpiInOut( offset ); |
| | | for( uint16_t i = 0; i < size; i++ ) |
| | | { |
| | | SpiInOut( buffer[i] ); |
| | | } |
| | | gpio_pin_set(LORA_CS); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_SET); |
| | | |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) |
| | | { |
| | | SX126xCheckDeviceReady( ); |
| | | // SX126x_CS_Di( ); |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_RESET); |
| | | gpio_pin_clr(LORA_CS); |
| | | SpiInOut( RADIO_READ_BUFFER ); |
| | | SpiInOut( offset ); |
| | | SpiInOut( 0 ); |
| | | for( uint16_t i = 0; i < size; i++ ) |
| | | { |
| | | buffer[i] = SpiInOut( 0 ); |
| | | } |
| | | |
| | | // HAL_GPIO_WritePin( RADIO_NSS_GPIO_Port, RADIO_NSS_Pin,GPIO_PIN_SET); |
| | | gpio_pin_set(LORA_CS); |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | void SX126xSetRfTxPower( int8_t power ) |
| | | { |
| | | SX126xSetTxParams( power, RADIO_RAMP_40_US ); |
| | | } |
| | | |
| | | uint8_t SX126xGetPaSelect( uint32_t channel ) |
| | | { |
| | | // if( GpioRead( &DeviceSel ) == 1 ) |
| | | // { |
| | | // return SX1261; |
| | | // } |
| | | // else |
| | | // { |
| | | // return SX1262; |
| | | // } |
| | | |
| | | return SX1262; |
| | | } |
| | | |
| | | void SX126xAntSwOn( void ) |
| | | { |
| | | //GpioInit( &AntPow, ANT_SWITCH_POWER, PIN_OUTPUT, PIN_PUSH_PULL, PIN_PULL_UP, 1 ); |
| | | } |
| | | |
| | | void SX126xAntSwOff( void ) |
| | | { |
| | | // GpioInit( &AntPow, ANT_SWITCH_POWER, PIN_ANALOGIC, PIN_PUSH_PULL, PIN_NO_PULL, 0 ); |
| | | } |
| | | |
| | | bool SX126xCheckRfFrequency( uint32_t frequency ) |
| | | { |
| | | // Implement check. Currently all frequencies are supported |
| | | return true; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | ______ _ |
| | | / _____) _ | | |
| | | ( (____ _____ ____ _| |_ _____ ____| |__ |
| | | \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| | | _____) ) ____| | | || |_| ____( (___| | | | |
| | | (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| | | (C)2013 Semtech |
| | | |
| | | Description: SX126x driver specific target board functions implementation |
| | | |
| | | License: Revised BSD License, see LICENSE.TXT file include in the project |
| | | |
| | | Maintainer: Miguel Luis and Gregory Cristian |
| | | */ |
| | | #ifndef __SX126x_ARCH_H__ |
| | | #define __SX126x_ARCH_H__ |
| | | |
| | | #include "sx126x.h" |
| | | /*! |
| | | * \brief Initializes the radio I/Os pins interface |
| | | */ |
| | | //void SX126xIoInit( void ); |
| | | |
| | | /*! |
| | | * \brief Initializes DIO IRQ handlers |
| | | * |
| | | * \param [IN] irqHandlers Array containing the IRQ callback functions |
| | | */ |
| | | //void SX126xIoIrqInit( DioIrqHandler dioIrq ); |
| | | |
| | | /*! |
| | | * \brief De-initializes the radio I/Os pins interface. |
| | | * |
| | | * \remark Useful when going in MCU low power modes |
| | | */ |
| | | //void SX126xIoDeInit( void ); |
| | | |
| | | /*! |
| | | * \brief HW Reset of the radio |
| | | */ |
| | | void SX126xReset( void ); |
| | | |
| | | /*! |
| | | * \brief Blocking loop to wait while the Busy pin in high |
| | | */ |
| | | void SX126xWaitOnBusy( void ); |
| | | |
| | | /*! |
| | | * \brief Wakes up the radio |
| | | */ |
| | | void SX126xWakeup( void ); |
| | | |
| | | /*! |
| | | * \brief Send a command that write data to the radio |
| | | * |
| | | * \param [in] opcode Opcode of the command |
| | | * \param [in] buffer Buffer to be send to the radio |
| | | * \param [in] size Size of the buffer to send |
| | | */ |
| | | void SX126xWriteCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ); |
| | | |
| | | /*! |
| | | * \brief Send a command that read data from the radio |
| | | * |
| | | * \param [in] opcode Opcode of the command |
| | | * \param [out] buffer Buffer holding data from the radio |
| | | * \param [in] size Size of the buffer |
| | | */ |
| | | void SX126xReadCommand( RadioCommands_t opcode, uint8_t *buffer, uint16_t size ); |
| | | |
| | | /*! |
| | | * \brief Write a single byte of data to the radio memory |
| | | * |
| | | * \param [in] address The address of the first byte to write in the radio |
| | | * \param [in] value The data to be written in radio's memory |
| | | */ |
| | | void SX126xWriteRegister( uint16_t address, uint8_t value ); |
| | | |
| | | /*! |
| | | * \brief Read a single byte of data from the radio memory |
| | | * |
| | | * \param [in] address The address of the first byte to write in the radio |
| | | * |
| | | * \retval value The value of the byte at the given address in radio's memory |
| | | */ |
| | | uint8_t SX126xReadRegister( uint16_t address ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio output power. |
| | | * |
| | | * \param [IN] power Sets the RF output power |
| | | */ |
| | | void SX126xSetRfTxPower( int8_t power ); |
| | | |
| | | /*! |
| | | * \brief Gets the board PA selection configuration |
| | | * |
| | | * \param [IN] channel Channel frequency in Hz |
| | | * \retval PaSelect RegPaConfig PaSelect value |
| | | */ |
| | | uint8_t SX126xGetPaSelect( uint32_t channel ); |
| | | |
| | | /*! |
| | | * \brief Initializes the RF Switch I/Os pins interface |
| | | */ |
| | | void SX126xAntSwOn( void ); |
| | | |
| | | /*! |
| | | * \brief De-initializes the RF Switch I/Os pins interface |
| | | * |
| | | * \remark Needed to decrease the power consumption in MCU low power modes |
| | | */ |
| | | void SX126xAntSwOff( void ); |
| | | |
| | | /*! |
| | | * \brief Checks if the given RF frequency is supported by the hardware |
| | | * |
| | | * \param [IN] frequency RF frequency to be checked |
| | | * \retval isSupported [true: supported, false: unsupported] |
| | | */ |
| | | bool SX126xCheckRfFrequency( uint32_t frequency ); |
| | | |
| | | /*! |
| | | * Radio hardware and global parameters |
| | | */ |
| | | extern SX126x_t SX126x; |
| | | |
| | | |
| | | uint8_t SpiInOut( uint8_t txBuffer); |
| | | |
| | | #endif // __SX126x_ARCH_H__ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /*! |
| | | * \file sx126x.c |
| | | * |
| | | * \brief SX126x driver implementation |
| | | * |
| | | * \copyright Revised BSD License, see section \ref LICENSE. |
| | | * |
| | | * \code |
| | | * ______ _ |
| | | * / _____) _ | | |
| | | * ( (____ _____ ____ _| |_ _____ ____| |__ |
| | | * \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| | | * _____) ) ____| | | || |_| ____( (___| | | | |
| | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| | | * (C)2013-2017 Semtech |
| | | * |
| | | * \endcode |
| | | * |
| | | * \author Miguel Luis ( Semtech ) |
| | | * |
| | | * \author Gregory Cristian ( Semtech ) |
| | | */ |
| | | #include <math.h> |
| | | #include <string.h> |
| | | #include "sx126x.h" |
| | | #include "sx126x-board.h" |
| | | #include "delay.h" |
| | | |
| | | //#define USE_TCXO |
| | | /*! |
| | | * \brief Radio registers definition |
| | | */ |
| | | typedef struct |
| | | { |
| | | uint16_t Addr; //!< The address of the register |
| | | uint8_t Value; //!< The value of the register |
| | | }RadioRegisters_t; |
| | | |
| | | /*! |
| | | * \brief Holds the internal operating mode of the radio |
| | | */ |
| | | static RadioOperatingModes_t OperatingMode; |
| | | |
| | | /*! |
| | | * \brief Stores the current packet type set in the radio |
| | | */ |
| | | static RadioPacketTypes_t PacketType; |
| | | |
| | | /*! |
| | | * \brief Stores the last frequency error measured on LoRa received packet |
| | | */ |
| | | volatile uint32_t FrequencyError = 0; |
| | | |
| | | /*! |
| | | * \brief Hold the status of the Image calibration |
| | | */ |
| | | static bool ImageCalibrated = false; |
| | | |
| | | /* |
| | | * SX126x DIO IRQ callback functions prototype |
| | | */ |
| | | |
| | | /*! |
| | | * \brief DIO 0 IRQ callback |
| | | */ |
| | | void SX126xOnDioIrq( void ); |
| | | |
| | | /*! |
| | | * \brief DIO 0 IRQ callback |
| | | */ |
| | | void SX126xSetPollingMode( void ); |
| | | |
| | | /*! |
| | | * \brief DIO 0 IRQ callback |
| | | */ |
| | | void SX126xSetInterruptMode( void ); |
| | | |
| | | /* |
| | | * \brief Process the IRQ if handled by the driver |
| | | */ |
| | | void SX126xProcessIrqs( void ); |
| | | |
| | | |
| | | void SX126xInit( DioIrqHandler dioIrq ) |
| | | { |
| | | SX126xReset( ); |
| | | SX126xWakeup( ); |
| | | SX126xSetStandby( STDBY_RC ); |
| | | |
| | | #ifdef USE_TCXO |
| | | CalibrationParams_t calibParam; |
| | | |
| | | SX126xSetDio3AsTcxoCtrl( TCXO_CTRL_1_7V, RADIO_TCXO_SETUP_TIME << 6 ); // convert from ms to SX126x time base |
| | | calibParam.Value = 0x7F; |
| | | SX126xCalibrate( calibParam ); |
| | | |
| | | #endif |
| | | |
| | | SX126xSetDio2AsRfSwitchCtrl( true ); |
| | | OperatingMode = MODE_STDBY_RC; |
| | | } |
| | | |
| | | RadioOperatingModes_t SX126xGetOperatingMode( void ) |
| | | { |
| | | return OperatingMode; |
| | | } |
| | | |
| | | void SX126xCheckDeviceReady( void ) |
| | | { |
| | | if( ( SX126xGetOperatingMode( ) == MODE_SLEEP ) || ( SX126xGetOperatingMode( ) == MODE_RX_DC ) ) |
| | | { |
| | | SX126xWakeup( ); |
| | | // Switch is turned off when device is in sleep mode and turned on is all other modes |
| | | SX126xAntSwOn( ); |
| | | } |
| | | SX126xWaitOnBusy( ); |
| | | } |
| | | |
| | | void SX126xSetPayload( uint8_t *payload, uint8_t size ) |
| | | { |
| | | SX126xWriteBuffer( 0x00, payload, size ); |
| | | } |
| | | |
| | | uint8_t SX126xGetPayload( uint8_t *buffer, uint8_t *size, uint8_t maxSize ) |
| | | { |
| | | uint8_t offset = 0; |
| | | |
| | | SX126xGetRxBufferStatus( size, &offset ); |
| | | if( *size > maxSize ) |
| | | { |
| | | return 1; |
| | | } |
| | | SX126xReadBuffer( offset, buffer, *size ); |
| | | return 0; |
| | | } |
| | | |
| | | void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout ) |
| | | { |
| | | SX126xSetPayload( payload, size ); |
| | | SX126xSetTx( timeout ); |
| | | } |
| | | |
| | | uint8_t SX126xSetSyncWord( uint8_t *syncWord ) |
| | | { |
| | | SX126xWriteRegisters( REG_LR_SYNCWORDBASEADDRESS, syncWord, 8 ); |
| | | return 0; |
| | | } |
| | | |
| | | void SX126xSetCrcSeed( uint16_t seed ) |
| | | { |
| | | uint8_t buf[2]; |
| | | |
| | | buf[0] = ( uint8_t )( ( seed >> 8 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( seed & 0xFF ); |
| | | |
| | | switch( SX126xGetPacketType( ) ) |
| | | { |
| | | case PACKET_TYPE_GFSK: |
| | | SX126xWriteRegisters( REG_LR_CRCSEEDBASEADDR, buf, 2 ); |
| | | break; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | void SX126xSetCrcPolynomial( uint16_t polynomial ) |
| | | { |
| | | uint8_t buf[2]; |
| | | |
| | | buf[0] = ( uint8_t )( ( polynomial >> 8 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( polynomial & 0xFF ); |
| | | |
| | | switch( SX126xGetPacketType( ) ) |
| | | { |
| | | case PACKET_TYPE_GFSK: |
| | | SX126xWriteRegisters( REG_LR_CRCPOLYBASEADDR, buf, 2 ); |
| | | break; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | void SX126xSetWhiteningSeed( uint16_t seed ) |
| | | { |
| | | uint8_t regValue = 0; |
| | | |
| | | switch( SX126xGetPacketType( ) ) |
| | | { |
| | | case PACKET_TYPE_GFSK: |
| | | regValue = SX126xReadRegister( REG_LR_WHITSEEDBASEADDR_MSB ) & 0xFE; |
| | | regValue = ( ( seed >> 8 ) & 0x01 ) | regValue; |
| | | SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_MSB, regValue ); // only 1 bit. |
| | | SX126xWriteRegister( REG_LR_WHITSEEDBASEADDR_LSB, ( uint8_t )seed ); |
| | | break; |
| | | |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | |
| | | uint32_t SX126xGetRandom( void ) |
| | | { |
| | | uint8_t buf[] = { 0, 0, 0, 0 }; |
| | | |
| | | // Set radio in continuous reception |
| | | SX126xSetRx( 0 ); |
| | | |
| | | HAL_Delay_nMS( 1 ); |
| | | |
| | | SX126xReadRegisters( RANDOM_NUMBER_GENERATORBASEADDR, buf, 4 ); |
| | | |
| | | SX126xSetStandby( STDBY_RC ); |
| | | |
| | | return ( buf[0] << 24 ) | ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3]; |
| | | } |
| | | |
| | | void SX126xSetSleep( SleepParams_t sleepConfig ) |
| | | { |
| | | SX126xAntSwOff( ); |
| | | |
| | | SX126xWriteCommand( RADIO_SET_SLEEP, &sleepConfig.Value, 1 ); |
| | | OperatingMode = MODE_SLEEP; |
| | | } |
| | | |
| | | void SX126xSetStandby( RadioStandbyModes_t standbyConfig ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_STANDBY, ( uint8_t* )&standbyConfig, 1 ); |
| | | if( standbyConfig == STDBY_RC ) |
| | | { |
| | | OperatingMode = MODE_STDBY_RC; |
| | | } |
| | | else |
| | | { |
| | | OperatingMode = MODE_STDBY_XOSC; |
| | | } |
| | | } |
| | | |
| | | void SX126xSetFs( void ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_FS, 0, 0 ); |
| | | OperatingMode = MODE_FS; |
| | | } |
| | | |
| | | void SX126xSetTx( uint32_t timeout ) |
| | | { |
| | | uint8_t buf[3]; |
| | | |
| | | OperatingMode = MODE_TX; |
| | | |
| | | buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); |
| | | buf[2] = ( uint8_t )( timeout & 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_TX, buf, 3 ); |
| | | } |
| | | |
| | | void SX126xSetRx( uint32_t timeout ) |
| | | { |
| | | uint8_t buf[3]; |
| | | |
| | | OperatingMode = MODE_RX; |
| | | |
| | | buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); |
| | | buf[2] = ( uint8_t )( timeout & 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_RX, buf, 3 ); |
| | | } |
| | | |
| | | void SX126xSetRxBoosted( uint32_t timeout ) |
| | | { |
| | | uint8_t buf[3]; |
| | | |
| | | OperatingMode = MODE_RX; |
| | | |
| | | SX126xWriteRegister( REG_RX_GAIN, 0x96 ); // max LNA gain, increase current by ~2mA for around ~3dB in sensivity |
| | | |
| | | buf[0] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); |
| | | buf[2] = ( uint8_t )( timeout & 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_RX, buf, 3 ); |
| | | } |
| | | |
| | | void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ) |
| | | { |
| | | uint8_t buf[6]; |
| | | |
| | | buf[0] = ( uint8_t )( ( rxTime >> 16 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( ( rxTime >> 8 ) & 0xFF ); |
| | | buf[2] = ( uint8_t )( rxTime & 0xFF ); |
| | | buf[3] = ( uint8_t )( ( sleepTime >> 16 ) & 0xFF ); |
| | | buf[4] = ( uint8_t )( ( sleepTime >> 8 ) & 0xFF ); |
| | | buf[5] = ( uint8_t )( sleepTime & 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_RXDUTYCYCLE, buf, 6 ); |
| | | OperatingMode = MODE_RX_DC; |
| | | } |
| | | |
| | | void SX126xSetCad( void ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_CAD, 0, 0 ); |
| | | OperatingMode = MODE_CAD; |
| | | } |
| | | |
| | | void SX126xSetTxContinuousWave( void ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_TXCONTINUOUSWAVE, 0, 0 ); |
| | | } |
| | | |
| | | void SX126xSetTxInfinitePreamble( void ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_TXCONTINUOUSPREAMBLE, 0, 0 ); |
| | | } |
| | | |
| | | void SX126xSetStopRxTimerOnPreambleDetect( bool enable ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_STOPRXTIMERONPREAMBLE, ( uint8_t* )&enable, 1 ); |
| | | } |
| | | |
| | | void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_LORASYMBTIMEOUT, &SymbNum, 1 ); |
| | | } |
| | | |
| | | void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_REGULATORMODE, ( uint8_t* )&mode, 1 ); |
| | | } |
| | | |
| | | void SX126xCalibrate( CalibrationParams_t calibParam ) |
| | | { |
| | | SX126xWriteCommand( RADIO_CALIBRATE, ( uint8_t* )&calibParam, 1 ); |
| | | } |
| | | |
| | | void SX126xCalibrateImage( uint32_t freq ) |
| | | { |
| | | uint8_t calFreq[2]; |
| | | |
| | | if( freq > 900000000 ) |
| | | { |
| | | calFreq[0] = 0xE1; |
| | | calFreq[1] = 0xE9; |
| | | } |
| | | else if( freq > 850000000 ) |
| | | { |
| | | calFreq[0] = 0xD7; |
| | | calFreq[1] = 0xD8; |
| | | } |
| | | else if( freq > 770000000 ) |
| | | { |
| | | calFreq[0] = 0xC1; |
| | | calFreq[1] = 0xC5; |
| | | } |
| | | else if( freq > 460000000 ) |
| | | { |
| | | calFreq[0] = 0x75; |
| | | calFreq[1] = 0x81; |
| | | } |
| | | else if( freq > 425000000 ) |
| | | { |
| | | calFreq[0] = 0x6B; |
| | | calFreq[1] = 0x6F; |
| | | } |
| | | SX126xWriteCommand( RADIO_CALIBRATEIMAGE, calFreq, 2 ); |
| | | } |
| | | |
| | | void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut ) |
| | | { |
| | | uint8_t buf[4]; |
| | | |
| | | buf[0] = paDutyCycle; |
| | | buf[1] = hpMax; |
| | | buf[2] = deviceSel; |
| | | buf[3] = paLut; |
| | | SX126xWriteCommand( RADIO_SET_PACONFIG, buf, 4 ); |
| | | } |
| | | |
| | | void SX126xSetRxTxFallbackMode( uint8_t fallbackMode ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_TXFALLBACKMODE, &fallbackMode, 1 ); |
| | | } |
| | | |
| | | void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ) |
| | | { |
| | | uint8_t buf[8]; |
| | | |
| | | buf[0] = ( uint8_t )( ( irqMask >> 8 ) & 0x00FF ); |
| | | buf[1] = ( uint8_t )( irqMask & 0x00FF ); |
| | | buf[2] = ( uint8_t )( ( dio1Mask >> 8 ) & 0x00FF ); |
| | | buf[3] = ( uint8_t )( dio1Mask & 0x00FF ); |
| | | buf[4] = ( uint8_t )( ( dio2Mask >> 8 ) & 0x00FF ); |
| | | buf[5] = ( uint8_t )( dio2Mask & 0x00FF ); |
| | | buf[6] = ( uint8_t )( ( dio3Mask >> 8 ) & 0x00FF ); |
| | | buf[7] = ( uint8_t )( dio3Mask & 0x00FF ); |
| | | SX126xWriteCommand( RADIO_CFG_DIOIRQ, buf, 8 ); |
| | | } |
| | | |
| | | uint16_t SX126xGetIrqStatus( void ) |
| | | { |
| | | uint8_t irqStatus[2]; |
| | | |
| | | SX126xReadCommand( RADIO_GET_IRQSTATUS, irqStatus, 2 ); |
| | | return ( irqStatus[0] << 8 ) | irqStatus[1]; |
| | | } |
| | | |
| | | void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable ) |
| | | { |
| | | SX126xWriteCommand( RADIO_SET_RFSWITCHMODE, &enable, 1 ); |
| | | } |
| | | |
| | | void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout ) |
| | | { |
| | | uint8_t buf[4]; |
| | | |
| | | buf[0] = tcxoVoltage & 0x07; |
| | | buf[1] = ( uint8_t )( ( timeout >> 16 ) & 0xFF ); |
| | | buf[2] = ( uint8_t )( ( timeout >> 8 ) & 0xFF ); |
| | | buf[3] = ( uint8_t )( timeout & 0xFF ); |
| | | |
| | | SX126xWriteCommand( RADIO_SET_TCXOMODE, buf, 4 ); |
| | | } |
| | | |
| | | void SX126xSetRfFrequency( uint32_t frequency ) |
| | | { |
| | | uint8_t buf[4]; |
| | | uint32_t freq = 0; |
| | | |
| | | if( ImageCalibrated == false ) |
| | | { |
| | | SX126xCalibrateImage( frequency ); |
| | | ImageCalibrated = true; |
| | | } |
| | | |
| | | freq = ( uint32_t )( ( double )frequency / ( double )FREQ_STEP ); |
| | | buf[0] = ( uint8_t )( ( freq >> 24 ) & 0xFF ); |
| | | buf[1] = ( uint8_t )( ( freq >> 16 ) & 0xFF ); |
| | | buf[2] = ( uint8_t )( ( freq >> 8 ) & 0xFF ); |
| | | buf[3] = ( uint8_t )( freq & 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_RFFREQUENCY, buf, 4 ); |
| | | } |
| | | |
| | | void SX126xSetPacketType( RadioPacketTypes_t packetType ) |
| | | { |
| | | // Save packet type internally to avoid questioning the radio |
| | | PacketType = packetType; |
| | | SX126xWriteCommand( RADIO_SET_PACKETTYPE, ( uint8_t* )&packetType, 1 ); |
| | | } |
| | | |
| | | RadioPacketTypes_t SX126xGetPacketType( void ) |
| | | { |
| | | return PacketType; |
| | | } |
| | | |
| | | void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime ) |
| | | { |
| | | uint8_t buf[2]; |
| | | |
| | | if( SX126xGetPaSelect( 0 ) == SX1261 ) |
| | | { |
| | | if( power == 15 ) |
| | | { |
| | | SX126xSetPaConfig( 0x06, 0x00, 0x01, 0x01 ); |
| | | } |
| | | else |
| | | { |
| | | SX126xSetPaConfig( 0x04, 0x00, 0x01, 0x01 ); |
| | | } |
| | | if( power >= 14 ) |
| | | { |
| | | power = 14; |
| | | } |
| | | else if( power < -3 ) |
| | | { |
| | | power = -3; |
| | | } |
| | | SX126xWriteRegister( REG_OCP, 0x18 ); // current max is 80 mA for the whole device |
| | | } |
| | | else // sx1262 |
| | | { |
| | | SX126xSetPaConfig( 0x04, 0x07, 0x00, 0x01 ); |
| | | if( power > 22 ) |
| | | { |
| | | power = 22; |
| | | } |
| | | else if( power < -3 ) |
| | | { |
| | | power = -3; |
| | | } |
| | | SX126xWriteRegister( REG_OCP, 0x38 ); // current max 160mA for the whole device |
| | | } |
| | | buf[0] = power; |
| | | buf[1] = ( uint8_t )rampTime; |
| | | SX126xWriteCommand( RADIO_SET_TXPARAMS, buf, 2 ); |
| | | } |
| | | |
| | | void SX126xSetModulationParams( ModulationParams_t *modulationParams ) |
| | | { |
| | | uint8_t n; |
| | | uint32_t tempVal = 0; |
| | | uint8_t buf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
| | | |
| | | // Check if required configuration corresponds to the stored packet type |
| | | // If not, silently update radio packet type |
| | | if( PacketType != modulationParams->PacketType ) |
| | | { |
| | | SX126xSetPacketType( modulationParams->PacketType ); |
| | | } |
| | | |
| | | switch( modulationParams->PacketType ) |
| | | { |
| | | case PACKET_TYPE_GFSK: |
| | | n = 8; |
| | | tempVal = ( uint32_t )( 32 * ( ( double )XTAL_FREQ / ( double )modulationParams->Params.Gfsk.BitRate ) ); |
| | | buf[0] = ( tempVal >> 16 ) & 0xFF; |
| | | buf[1] = ( tempVal >> 8 ) & 0xFF; |
| | | buf[2] = tempVal & 0xFF; |
| | | buf[3] = modulationParams->Params.Gfsk.ModulationShaping; |
| | | buf[4] = modulationParams->Params.Gfsk.Bandwidth; |
| | | tempVal = ( uint32_t )( ( double )modulationParams->Params.Gfsk.Fdev / ( double )FREQ_STEP ); |
| | | buf[5] = ( tempVal >> 16 ) & 0xFF; |
| | | buf[6] = ( tempVal >> 8 ) & 0xFF; |
| | | buf[7] = ( tempVal& 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n ); |
| | | break; |
| | | case PACKET_TYPE_LORA: |
| | | n = 4; |
| | | buf[0] = modulationParams->Params.LoRa.SpreadingFactor; |
| | | buf[1] = modulationParams->Params.LoRa.Bandwidth; |
| | | buf[2] = modulationParams->Params.LoRa.CodingRate; |
| | | buf[3] = modulationParams->Params.LoRa.LowDatarateOptimize; |
| | | |
| | | SX126xWriteCommand( RADIO_SET_MODULATIONPARAMS, buf, n ); |
| | | |
| | | break; |
| | | default: |
| | | case PACKET_TYPE_NONE: |
| | | return; |
| | | } |
| | | } |
| | | |
| | | void SX126xSetPacketParams( PacketParams_t *packetParams ) |
| | | { |
| | | uint8_t n; |
| | | uint8_t crcVal = 0; |
| | | uint8_t buf[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
| | | |
| | | // Check if required configuration corresponds to the stored packet type |
| | | // If not, silently update radio packet type |
| | | if( PacketType != packetParams->PacketType ) |
| | | { |
| | | SX126xSetPacketType( packetParams->PacketType ); |
| | | } |
| | | |
| | | switch( packetParams->PacketType ) |
| | | { |
| | | case PACKET_TYPE_GFSK: |
| | | if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_IBM ) |
| | | { |
| | | SX126xSetCrcSeed( CRC_IBM_SEED ); |
| | | SX126xSetCrcPolynomial( CRC_POLYNOMIAL_IBM ); |
| | | crcVal = RADIO_CRC_2_BYTES; |
| | | } |
| | | else if( packetParams->Params.Gfsk.CrcLength == RADIO_CRC_2_BYTES_CCIT ) |
| | | { |
| | | SX126xSetCrcSeed( CRC_CCITT_SEED ); |
| | | SX126xSetCrcPolynomial( CRC_POLYNOMIAL_CCITT ); |
| | | crcVal = RADIO_CRC_2_BYTES_INV; |
| | | } |
| | | else |
| | | { |
| | | crcVal = packetParams->Params.Gfsk.CrcLength; |
| | | } |
| | | n = 9; |
| | | buf[0] = ( packetParams->Params.Gfsk.PreambleLength >> 8 ) & 0xFF; |
| | | buf[1] = packetParams->Params.Gfsk.PreambleLength; |
| | | buf[2] = packetParams->Params.Gfsk.PreambleMinDetect; |
| | | buf[3] = ( packetParams->Params.Gfsk.SyncWordLength /*<< 3*/ ); // convert from byte to bit |
| | | buf[4] = packetParams->Params.Gfsk.AddrComp; |
| | | buf[5] = packetParams->Params.Gfsk.HeaderType; |
| | | buf[6] = packetParams->Params.Gfsk.PayloadLength; |
| | | buf[7] = crcVal; |
| | | buf[8] = packetParams->Params.Gfsk.DcFree; |
| | | break; |
| | | case PACKET_TYPE_LORA: |
| | | n = 6; |
| | | buf[0] = ( packetParams->Params.LoRa.PreambleLength >> 8 ) & 0xFF; |
| | | buf[1] = packetParams->Params.LoRa.PreambleLength; |
| | | buf[2] = packetParams->Params.LoRa.HeaderType; |
| | | buf[3] = packetParams->Params.LoRa.PayloadLength; |
| | | buf[4] = packetParams->Params.LoRa.CrcMode; |
| | | buf[5] = packetParams->Params.LoRa.InvertIQ; |
| | | break; |
| | | default: |
| | | case PACKET_TYPE_NONE: |
| | | return; |
| | | } |
| | | SX126xWriteCommand( RADIO_SET_PACKETPARAMS, buf, n ); |
| | | } |
| | | |
| | | void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout ) |
| | | { |
| | | uint8_t buf[7]; |
| | | |
| | | buf[0] = ( uint8_t )cadSymbolNum; |
| | | buf[1] = cadDetPeak; |
| | | buf[2] = cadDetMin; |
| | | buf[3] = ( uint8_t )cadExitMode; |
| | | buf[4] = ( uint8_t )( ( cadTimeout >> 16 ) & 0xFF ); |
| | | buf[5] = ( uint8_t )( ( cadTimeout >> 8 ) & 0xFF ); |
| | | buf[6] = ( uint8_t )( cadTimeout & 0xFF ); |
| | | SX126xWriteCommand( RADIO_SET_CADPARAMS, buf, 5 ); |
| | | OperatingMode = MODE_CAD; |
| | | } |
| | | |
| | | void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress ) |
| | | { |
| | | uint8_t buf[2]; |
| | | |
| | | buf[0] = txBaseAddress; |
| | | buf[1] = rxBaseAddress; |
| | | SX126xWriteCommand( RADIO_SET_BUFFERBASEADDRESS, buf, 2 ); |
| | | } |
| | | |
| | | RadioStatus_t SX126xGetStatus( void ) |
| | | { |
| | | uint8_t stat = 0; |
| | | RadioStatus_t status; |
| | | |
| | | SX126xReadCommand( RADIO_GET_STATUS, ( uint8_t * )&stat, 1 ); |
| | | status.Value = stat; |
| | | return status; |
| | | } |
| | | |
| | | int8_t SX126xGetRssiInst( void ) |
| | | { |
| | | uint8_t buf[1]; |
| | | int8_t rssi = 0; |
| | | |
| | | SX126xReadCommand( RADIO_GET_RSSIINST, buf, 1 ); |
| | | rssi = -buf[0] >> 1; |
| | | return rssi; |
| | | } |
| | | |
| | | void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBufferPointer ) |
| | | { |
| | | uint8_t status[2]; |
| | | |
| | | SX126xReadCommand( RADIO_GET_RXBUFFERSTATUS, status, 2 ); |
| | | |
| | | // In case of LORA fixed header, the payloadLength is obtained by reading |
| | | // the register REG_LR_PAYLOADLENGTH |
| | | if( ( SX126xGetPacketType( ) == PACKET_TYPE_LORA ) && ( SX126xReadRegister( REG_LR_PACKETPARAMS ) >> 7 == 1 ) ) |
| | | { |
| | | *payloadLength = SX126xReadRegister( REG_LR_PAYLOADLENGTH ); |
| | | } |
| | | else |
| | | { |
| | | *payloadLength = status[0]; |
| | | } |
| | | *rxStartBufferPointer = status[1]; |
| | | } |
| | | |
| | | void SX126xGetPacketStatus( PacketStatus_t *pktStatus ) |
| | | { |
| | | uint8_t status[3]; |
| | | |
| | | SX126xReadCommand( RADIO_GET_PACKETSTATUS, status, 3 ); |
| | | |
| | | pktStatus->packetType = SX126xGetPacketType( ); |
| | | switch( pktStatus->packetType ) |
| | | { |
| | | case PACKET_TYPE_GFSK: |
| | | pktStatus->Params.Gfsk.RxStatus = status[0]; |
| | | pktStatus->Params.Gfsk.RssiSync = -status[1] >> 1; |
| | | pktStatus->Params.Gfsk.RssiAvg = -status[2] >> 1; |
| | | pktStatus->Params.Gfsk.FreqError = 0; |
| | | break; |
| | | |
| | | case PACKET_TYPE_LORA: |
| | | pktStatus->Params.LoRa.RssiPkt = -status[0] >> 1; |
| | | ( status[1] < 128 ) ? ( pktStatus->Params.LoRa.SnrPkt = status[1] >> 2 ) : ( pktStatus->Params.LoRa.SnrPkt = ( ( status[1] - 256 ) >> 2 ) ); |
| | | pktStatus->Params.LoRa.SignalRssiPkt = -status[2] >> 1; |
| | | pktStatus->Params.LoRa.FreqError = FrequencyError; |
| | | break; |
| | | |
| | | default: |
| | | case PACKET_TYPE_NONE: |
| | | // In that specific case, we set everything in the pktStatus to zeros |
| | | // and reset the packet type accordingly |
| | | memset( pktStatus, 0, sizeof( PacketStatus_t ) ); |
| | | pktStatus->packetType = PACKET_TYPE_NONE; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | RadioError_t SX126xGetDeviceErrors( void ) |
| | | { |
| | | RadioError_t error; |
| | | |
| | | SX126xReadCommand( RADIO_GET_ERROR, ( uint8_t * )&error, 2 ); |
| | | return error; |
| | | } |
| | | |
| | | void SX126xClearDeviceErrors( void ) |
| | | { |
| | | uint8_t buf[2] = { 0x00, 0x00 }; |
| | | SX126xWriteCommand( RADIO_CLR_ERROR, buf, 2 ); |
| | | } |
| | | |
| | | void SX126xClearIrqStatus( uint16_t irq ) |
| | | { |
| | | uint8_t buf[2]; |
| | | |
| | | buf[0] = ( uint8_t )( ( ( uint16_t )irq >> 8 ) & 0x00FF ); |
| | | buf[1] = ( uint8_t )( ( uint16_t )irq & 0x00FF ); |
| | | SX126xWriteCommand( RADIO_CLR_IRQSTATUS, buf, 2 ); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /*! |
| | | * \file sx126x.h |
| | | * |
| | | * \brief SX126x driver implementation |
| | | * |
| | | * \copyright Revised BSD License, see section \ref LICENSE. |
| | | * |
| | | * \code |
| | | * ______ _ |
| | | * / _____) _ | | |
| | | * ( (____ _____ ____ _| |_ _____ ____| |__ |
| | | * \____ \| ___ | (_ _) ___ |/ ___) _ \ |
| | | * _____) ) ____| | | || |_| ____( (___| | | | |
| | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| |
| | | * (C)2013-2017 Semtech |
| | | * |
| | | * \endcode |
| | | * |
| | | * \author Miguel Luis ( Semtech ) |
| | | * |
| | | * \author Gregory Cristian ( Semtech ) |
| | | */ |
| | | #ifndef __SX126x_H__ |
| | | #define __SX126x_H__ |
| | | |
| | | #include <stdint.h> |
| | | #include <stdbool.h> |
| | | |
| | | |
| | | #define SX1261 1 |
| | | #define SX1262 2 |
| | | |
| | | #ifdef USE_TCXO |
| | | /*! |
| | | * Radio complete Wake-up Time with TCXO stabilisation time |
| | | */ |
| | | #define RADIO_TCXO_SETUP_TIME 5 // [ms] |
| | | #else |
| | | /*! |
| | | * Radio complete Wake-up Time with TCXO stabilisation time |
| | | */ |
| | | #define RADIO_TCXO_SETUP_TIME 0 // No Used |
| | | #endif |
| | | |
| | | /*! |
| | | * Radio complete Wake-up Time with margin for temperature compensation |
| | | */ |
| | | #define RADIO_WAKEUP_TIME 3 // [ms] |
| | | |
| | | /*! |
| | | * \brief Compensation delay for SetAutoTx/Rx functions in 15.625 microseconds |
| | | */ |
| | | #define AUTO_RX_TX_OFFSET 2 |
| | | |
| | | /*! |
| | | * \brief LFSR initial value to compute IBM type CRC |
| | | */ |
| | | #define CRC_IBM_SEED 0xFFFF |
| | | |
| | | /*! |
| | | * \brief LFSR initial value to compute CCIT type CRC |
| | | */ |
| | | #define CRC_CCITT_SEED 0x1D0F |
| | | |
| | | /*! |
| | | * \brief Polynomial used to compute IBM CRC |
| | | */ |
| | | #define CRC_POLYNOMIAL_IBM 0x8005 |
| | | |
| | | /*! |
| | | * \brief Polynomial used to compute CCIT CRC |
| | | */ |
| | | #define CRC_POLYNOMIAL_CCITT 0x1021 |
| | | |
| | | /*! |
| | | * \brief The address of the register holding the first byte defining the CRC seed |
| | | * |
| | | */ |
| | | #define REG_LR_CRCSEEDBASEADDR 0x06BC |
| | | |
| | | /*! |
| | | * \brief The address of the register holding the first byte defining the CRC polynomial |
| | | */ |
| | | #define REG_LR_CRCPOLYBASEADDR 0x06BE |
| | | |
| | | /*! |
| | | * \brief The address of the register holding the first byte defining the whitening seed |
| | | */ |
| | | #define REG_LR_WHITSEEDBASEADDR_MSB 0x06B8 |
| | | #define REG_LR_WHITSEEDBASEADDR_LSB 0x06B9 |
| | | |
| | | /*! |
| | | * \brief The address of the register holding the packet configuration |
| | | */ |
| | | #define REG_LR_PACKETPARAMS 0x0704 |
| | | |
| | | /*! |
| | | * \brief The address of the register holding the payload size |
| | | */ |
| | | #define REG_LR_PAYLOADLENGTH 0x0702 |
| | | |
| | | /*! |
| | | * \brief The addresses of the registers holding SyncWords values |
| | | */ |
| | | #define REG_LR_SYNCWORDBASEADDRESS 0x06C0 |
| | | |
| | | /*! |
| | | * \brief The addresses of the register holding LoRa Modem SyncWord value |
| | | */ |
| | | #define REG_LR_SYNCWORD 0x0740 |
| | | |
| | | /*! |
| | | * Syncword for Private LoRa networks |
| | | */ |
| | | #define LORA_MAC_PRIVATE_SYNCWORD 0x1424 |
| | | |
| | | /*! |
| | | * Syncword for Public LoRa networks |
| | | */ |
| | | #define LORA_MAC_PUBLIC_SYNCWORD 0x3444 |
| | | |
| | | /*! |
| | | * The address of the register giving a 4 bytes random number |
| | | */ |
| | | #define RANDOM_NUMBER_GENERATORBASEADDR 0x0819 |
| | | |
| | | /*! |
| | | * The address of the register holding RX Gain value (0x94: power saving, 0x96: rx boosted) |
| | | */ |
| | | #define REG_RX_GAIN 0x08AC |
| | | |
| | | /*! |
| | | * Change the value on the device internal trimming capacitor |
| | | */ |
| | | #define REG_XTA_TRIM 0x0911 |
| | | |
| | | /*! |
| | | * Set the current max value in the over current protection |
| | | */ |
| | | #define REG_OCP 0x08E7 |
| | | |
| | | /*! |
| | | * \brief Structure describing the radio status |
| | | */ |
| | | typedef union RadioStatus_u |
| | | { |
| | | uint8_t Value; |
| | | struct |
| | | { //bit order is lsb -> msb |
| | | uint8_t Reserved : 1; //!< Reserved |
| | | uint8_t CmdStatus : 3; //!< Command status |
| | | uint8_t ChipMode : 3; //!< Chip mode |
| | | uint8_t CpuBusy : 1; //!< Flag for CPU radio busy |
| | | }Fields; |
| | | }RadioStatus_t; |
| | | |
| | | /*! |
| | | * \brief Structure describing the error codes for callback functions |
| | | */ |
| | | typedef enum |
| | | { |
| | | IRQ_HEADER_ERROR_CODE = 0x01, |
| | | IRQ_SYNCWORD_ERROR_CODE = 0x02, |
| | | IRQ_CRC_ERROR_CODE = 0x04, |
| | | }IrqErrorCode_t; |
| | | |
| | | enum IrqPblSyncHeaderCode_t |
| | | { |
| | | IRQ_PBL_DETECT_CODE = 0x01, |
| | | IRQ_SYNCWORD_VALID_CODE = 0x02, |
| | | IRQ_HEADER_VALID_CODE = 0x04, |
| | | }; |
| | | |
| | | /*! |
| | | * \brief Represents the operating mode the radio is actually running |
| | | */ |
| | | typedef enum |
| | | { |
| | | MODE_SLEEP = 0x00, //! The radio is in sleep mode |
| | | MODE_STDBY_RC, //! The radio is in standby mode with RC oscillator |
| | | MODE_STDBY_XOSC, //! The radio is in standby mode with XOSC oscillator |
| | | MODE_FS, //! The radio is in frequency synthesis mode |
| | | MODE_TX, //! The radio is in transmit mode |
| | | MODE_RX, //! The radio is in receive mode |
| | | MODE_RX_DC, //! The radio is in receive duty cycle mode |
| | | MODE_CAD //! The radio is in channel activity detection mode |
| | | }RadioOperatingModes_t; |
| | | |
| | | /*! |
| | | * \brief Declares the oscillator in use while in standby mode |
| | | * |
| | | * Using the STDBY_RC standby mode allow to reduce the energy consumption |
| | | * STDBY_XOSC should be used for time critical applications |
| | | */ |
| | | typedef enum |
| | | { |
| | | STDBY_RC = 0x00, |
| | | STDBY_XOSC = 0x01, |
| | | }RadioStandbyModes_t; |
| | | |
| | | /*! |
| | | * \brief Declares the power regulation used to power the device |
| | | * |
| | | * This command allows the user to specify if DC-DC or LDO is used for power regulation. |
| | | * Using only LDO implies that the Rx or Tx current is doubled |
| | | */ |
| | | typedef enum |
| | | { |
| | | USE_LDO = 0x00, // default |
| | | USE_DCDC = 0x01, |
| | | }RadioRegulatorMode_t; |
| | | |
| | | /*! |
| | | * \brief Represents the possible packet type (i.e. modem) used |
| | | */ |
| | | typedef enum |
| | | { |
| | | PACKET_TYPE_GFSK = 0x00, |
| | | PACKET_TYPE_LORA = 0x01, |
| | | PACKET_TYPE_NONE = 0x0F, |
| | | }RadioPacketTypes_t; |
| | | |
| | | /*! |
| | | * \brief Represents the ramping time for power amplifier |
| | | */ |
| | | typedef enum |
| | | { |
| | | RADIO_RAMP_10_US = 0x00, |
| | | RADIO_RAMP_20_US = 0x01, |
| | | RADIO_RAMP_40_US = 0x02, |
| | | RADIO_RAMP_80_US = 0x03, |
| | | RADIO_RAMP_200_US = 0x04, |
| | | RADIO_RAMP_800_US = 0x05, |
| | | RADIO_RAMP_1700_US = 0x06, |
| | | RADIO_RAMP_3400_US = 0x07, |
| | | }RadioRampTimes_t; |
| | | |
| | | /*! |
| | | * \brief Represents the number of symbols to be used for channel activity detection operation |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_CAD_01_SYMBOL = 0x00, |
| | | LORA_CAD_02_SYMBOL = 0x01, |
| | | LORA_CAD_04_SYMBOL = 0x02, |
| | | LORA_CAD_08_SYMBOL = 0x03, |
| | | LORA_CAD_16_SYMBOL = 0x04, |
| | | }RadioLoRaCadSymbols_t; |
| | | |
| | | /*! |
| | | * \brief Represents the Channel Activity Detection actions after the CAD operation is finished |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_CAD_ONLY = 0x00, |
| | | LORA_CAD_RX = 0x01, |
| | | LORA_CAD_LBT = 0x10, |
| | | }RadioCadExitModes_t; |
| | | |
| | | /*! |
| | | * \brief Represents the modulation shaping parameter |
| | | */ |
| | | typedef enum |
| | | { |
| | | MOD_SHAPING_OFF = 0x00, |
| | | MOD_SHAPING_G_BT_03 = 0x08, |
| | | MOD_SHAPING_G_BT_05 = 0x09, |
| | | MOD_SHAPING_G_BT_07 = 0x0A, |
| | | MOD_SHAPING_G_BT_1 = 0x0B, |
| | | }RadioModShapings_t; |
| | | |
| | | /*! |
| | | * \brief Represents the modulation shaping parameter |
| | | */ |
| | | typedef enum |
| | | { |
| | | RX_BW_4800 = 0x1F, |
| | | RX_BW_5800 = 0x17, |
| | | RX_BW_7300 = 0x0F, |
| | | RX_BW_9700 = 0x1E, |
| | | RX_BW_11700 = 0x16, |
| | | RX_BW_14600 = 0x0E, |
| | | RX_BW_19500 = 0x1D, |
| | | RX_BW_23400 = 0x15, |
| | | RX_BW_29300 = 0x0D, |
| | | RX_BW_39000 = 0x1C, |
| | | RX_BW_46900 = 0x14, |
| | | RX_BW_58600 = 0x0C, |
| | | RX_BW_78200 = 0x1B, |
| | | RX_BW_93800 = 0x13, |
| | | RX_BW_117300 = 0x0B, |
| | | RX_BW_156200 = 0x1A, |
| | | RX_BW_187200 = 0x12, |
| | | RX_BW_234300 = 0x0A, |
| | | RX_BW_312000 = 0x19, |
| | | RX_BW_373600 = 0x11, |
| | | RX_BW_467000 = 0x09, |
| | | }RadioRxBandwidth_t; |
| | | |
| | | /*! |
| | | * \brief Represents the possible spreading factor values in LoRa packet types |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_SF5 = 0x05, |
| | | LORA_SF6 = 0x06, |
| | | LORA_SF7 = 0x07, |
| | | LORA_SF8 = 0x08, |
| | | LORA_SF9 = 0x09, |
| | | LORA_SF10 = 0x0A, |
| | | LORA_SF11 = 0x0B, |
| | | LORA_SF12 = 0x0C, |
| | | }RadioLoRaSpreadingFactors_t; |
| | | |
| | | /*! |
| | | * \brief Represents the bandwidth values for LoRa packet type |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_BW_500 = 6, |
| | | LORA_BW_250 = 5, |
| | | LORA_BW_125 = 4, |
| | | LORA_BW_062 = 3, |
| | | LORA_BW_041 = 10, |
| | | LORA_BW_031 = 2, |
| | | LORA_BW_020 = 9, |
| | | LORA_BW_015 = 1, |
| | | LORA_BW_010 = 8, |
| | | LORA_BW_007 = 0, |
| | | }RadioLoRaBandwidths_t; |
| | | |
| | | /*! |
| | | * \brief Represents the coding rate values for LoRa packet type |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_CR_4_5 = 0x01, |
| | | LORA_CR_4_6 = 0x02, |
| | | LORA_CR_4_7 = 0x03, |
| | | LORA_CR_4_8 = 0x04, |
| | | }RadioLoRaCodingRates_t; |
| | | |
| | | /*! |
| | | * \brief Represents the preamble length used to detect the packet on Rx side |
| | | */ |
| | | typedef enum |
| | | { |
| | | RADIO_PREAMBLE_DETECTOR_OFF = 0x00, //!< Preamble detection length off |
| | | RADIO_PREAMBLE_DETECTOR_08_BITS = 0x04, //!< Preamble detection length 8 bits |
| | | RADIO_PREAMBLE_DETECTOR_16_BITS = 0x05, //!< Preamble detection length 16 bits |
| | | RADIO_PREAMBLE_DETECTOR_24_BITS = 0x06, //!< Preamble detection length 24 bits |
| | | RADIO_PREAMBLE_DETECTOR_32_BITS = 0x07, //!< Preamble detection length 32 bit |
| | | }RadioPreambleDetection_t; |
| | | |
| | | /*! |
| | | * \brief Represents the possible combinations of SyncWord correlators activated |
| | | */ |
| | | typedef enum |
| | | { |
| | | RADIO_ADDRESSCOMP_FILT_OFF = 0x00, //!< No correlator turned on, i.e. do not search for SyncWord |
| | | RADIO_ADDRESSCOMP_FILT_NODE = 0x01, |
| | | RADIO_ADDRESSCOMP_FILT_NODE_BROAD = 0x02, |
| | | }RadioAddressComp_t; |
| | | |
| | | /*! |
| | | * \brief Radio GFSK packet length mode |
| | | */ |
| | | typedef enum |
| | | { |
| | | RADIO_PACKET_FIXED_LENGTH = 0x00, //!< The packet is known on both sides, no header included in the packet |
| | | RADIO_PACKET_VARIABLE_LENGTH = 0x01, //!< The packet is on variable size, header included |
| | | }RadioPacketLengthModes_t; |
| | | |
| | | /*! |
| | | * \brief Represents the CRC length |
| | | */ |
| | | typedef enum |
| | | { |
| | | RADIO_CRC_OFF = 0x01, //!< No CRC in use |
| | | RADIO_CRC_1_BYTES = 0x00, |
| | | RADIO_CRC_2_BYTES = 0x02, |
| | | RADIO_CRC_1_BYTES_INV = 0x04, |
| | | RADIO_CRC_2_BYTES_INV = 0x06, |
| | | RADIO_CRC_2_BYTES_IBM = 0xF1, |
| | | RADIO_CRC_2_BYTES_CCIT = 0xF2, |
| | | }RadioCrcTypes_t; |
| | | |
| | | /*! |
| | | * \brief Radio whitening mode activated or deactivated |
| | | */ |
| | | typedef enum |
| | | { |
| | | RADIO_DC_FREE_OFF = 0x00, |
| | | RADIO_DC_FREEWHITENING = 0x01, |
| | | }RadioDcFree_t; |
| | | |
| | | /*! |
| | | * \brief Holds the Radio lengths mode for the LoRa packet type |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_PACKET_VARIABLE_LENGTH = 0x00, //!< The packet is on variable size, header included |
| | | LORA_PACKET_FIXED_LENGTH = 0x01, //!< The packet is known on both sides, no header included in the packet |
| | | LORA_PACKET_EXPLICIT = LORA_PACKET_VARIABLE_LENGTH, |
| | | LORA_PACKET_IMPLICIT = LORA_PACKET_FIXED_LENGTH, |
| | | }RadioLoRaPacketLengthsMode_t; |
| | | |
| | | /*! |
| | | * \brief Represents the CRC mode for LoRa packet type |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_CRC_ON = 0x01, //!< CRC activated |
| | | LORA_CRC_OFF = 0x00, //!< CRC not used |
| | | }RadioLoRaCrcModes_t; |
| | | |
| | | /*! |
| | | * \brief Represents the IQ mode for LoRa packet type |
| | | */ |
| | | typedef enum |
| | | { |
| | | LORA_IQ_NORMAL = 0x00, |
| | | LORA_IQ_INVERTED = 0x01, |
| | | }RadioLoRaIQModes_t; |
| | | |
| | | /*! |
| | | * \brief Represents the voltage used to control the TCXO on/off from DIO3 |
| | | */ |
| | | typedef enum |
| | | { |
| | | TCXO_CTRL_1_6V = 0x00, |
| | | TCXO_CTRL_1_7V = 0x01, |
| | | TCXO_CTRL_1_8V = 0x02, |
| | | TCXO_CTRL_2_2V = 0x03, |
| | | TCXO_CTRL_2_4V = 0x04, |
| | | TCXO_CTRL_2_7V = 0x05, |
| | | TCXO_CTRL_3_0V = 0x06, |
| | | TCXO_CTRL_3_3V = 0x07, |
| | | }RadioTcxoCtrlVoltage_t; |
| | | |
| | | /*! |
| | | * \brief Represents the interruption masks available for the radio |
| | | * |
| | | * \remark Note that not all these interruptions are available for all packet types |
| | | */ |
| | | typedef enum |
| | | { |
| | | IRQ_RADIO_NONE = 0x0000, |
| | | IRQ_TX_DONE = 0x0001, |
| | | IRQ_RX_DONE = 0x0002, |
| | | IRQ_PREAMBLE_DETECTED = 0x0004, |
| | | IRQ_SYNCWORD_VALID = 0x0008, |
| | | IRQ_HEADER_VALID = 0x0010, |
| | | IRQ_HEADER_ERROR = 0x0020, |
| | | IRQ_CRC_ERROR = 0x0040, |
| | | IRQ_CAD_DONE = 0x0080, |
| | | IRQ_CAD_ACTIVITY_DETECTED = 0x0100, |
| | | IRQ_RX_TX_TIMEOUT = 0x0200, |
| | | IRQ_RADIO_ALL = 0xFFFF, |
| | | }RadioIrqMasks_t; |
| | | |
| | | /*! |
| | | * \brief Represents all possible opcode understood by the radio |
| | | */ |
| | | typedef enum RadioCommands_e |
| | | { |
| | | RADIO_GET_STATUS = 0xC0, |
| | | RADIO_WRITE_REGISTER = 0x0D, |
| | | RADIO_READ_REGISTER = 0x1D, |
| | | RADIO_WRITE_BUFFER = 0x0E, |
| | | RADIO_READ_BUFFER = 0x1E, |
| | | RADIO_SET_SLEEP = 0x84, |
| | | RADIO_SET_STANDBY = 0x80, |
| | | RADIO_SET_FS = 0xC1, |
| | | RADIO_SET_TX = 0x83, |
| | | RADIO_SET_RX = 0x82, |
| | | RADIO_SET_RXDUTYCYCLE = 0x94, |
| | | RADIO_SET_CAD = 0xC5, |
| | | RADIO_SET_TXCONTINUOUSWAVE = 0xD1, |
| | | RADIO_SET_TXCONTINUOUSPREAMBLE = 0xD2, |
| | | RADIO_SET_PACKETTYPE = 0x8A, |
| | | RADIO_GET_PACKETTYPE = 0x11, |
| | | RADIO_SET_RFFREQUENCY = 0x86, |
| | | RADIO_SET_TXPARAMS = 0x8E, |
| | | RADIO_SET_PACONFIG = 0x95, |
| | | RADIO_SET_CADPARAMS = 0x88, |
| | | RADIO_SET_BUFFERBASEADDRESS = 0x8F, |
| | | RADIO_SET_MODULATIONPARAMS = 0x8B, |
| | | RADIO_SET_PACKETPARAMS = 0x8C, |
| | | RADIO_GET_RXBUFFERSTATUS = 0x13, |
| | | RADIO_GET_PACKETSTATUS = 0x14, |
| | | RADIO_GET_RSSIINST = 0x15, |
| | | RADIO_GET_STATS = 0x10, |
| | | RADIO_RESET_STATS = 0x00, |
| | | RADIO_CFG_DIOIRQ = 0x08, |
| | | RADIO_GET_IRQSTATUS = 0x12, |
| | | RADIO_CLR_IRQSTATUS = 0x02, |
| | | RADIO_CALIBRATE = 0x89, |
| | | RADIO_CALIBRATEIMAGE = 0x98, |
| | | RADIO_SET_REGULATORMODE = 0x96, |
| | | RADIO_GET_ERROR = 0x17, |
| | | RADIO_CLR_ERROR = 0x07, |
| | | RADIO_SET_TCXOMODE = 0x97, |
| | | RADIO_SET_TXFALLBACKMODE = 0x93, |
| | | RADIO_SET_RFSWITCHMODE = 0x9D, |
| | | RADIO_SET_STOPRXTIMERONPREAMBLE = 0x9F, |
| | | RADIO_SET_LORASYMBTIMEOUT = 0xA0, |
| | | }RadioCommands_t; |
| | | |
| | | /*! |
| | | * \brief The type describing the modulation parameters for every packet types |
| | | */ |
| | | typedef struct |
| | | { |
| | | RadioPacketTypes_t PacketType; //!< Packet to which the modulation parameters are referring to. |
| | | struct |
| | | { |
| | | struct |
| | | { |
| | | uint32_t BitRate; |
| | | uint32_t Fdev; |
| | | RadioModShapings_t ModulationShaping; |
| | | uint8_t Bandwidth; |
| | | }Gfsk; |
| | | struct |
| | | { |
| | | RadioLoRaSpreadingFactors_t SpreadingFactor; //!< Spreading Factor for the LoRa modulation |
| | | RadioLoRaBandwidths_t Bandwidth; //!< Bandwidth for the LoRa modulation |
| | | RadioLoRaCodingRates_t CodingRate; //!< Coding rate for the LoRa modulation |
| | | uint8_t LowDatarateOptimize; //!< Indicates if the modem uses the low datarate optimization |
| | | }LoRa; |
| | | }Params; //!< Holds the modulation parameters structure |
| | | }ModulationParams_t; |
| | | |
| | | /*! |
| | | * \brief The type describing the packet parameters for every packet types |
| | | */ |
| | | typedef struct |
| | | { |
| | | RadioPacketTypes_t PacketType; //!< Packet to which the packet parameters are referring to. |
| | | struct |
| | | { |
| | | /*! |
| | | * \brief Holds the GFSK packet parameters |
| | | */ |
| | | struct |
| | | { |
| | | uint16_t PreambleLength; //!< The preamble Tx length for GFSK packet type in bit |
| | | RadioPreambleDetection_t PreambleMinDetect; //!< The preamble Rx length minimal for GFSK packet type |
| | | uint8_t SyncWordLength; //!< The synchronization word length for GFSK packet type |
| | | RadioAddressComp_t AddrComp; //!< Activated SyncWord correlators |
| | | RadioPacketLengthModes_t HeaderType; //!< If the header is explicit, it will be transmitted in the GFSK packet. If the header is implicit, it will not be transmitted |
| | | uint8_t PayloadLength; //!< Size of the payload in the GFSK packet |
| | | RadioCrcTypes_t CrcLength; //!< Size of the CRC block in the GFSK packet |
| | | RadioDcFree_t DcFree; |
| | | }Gfsk; |
| | | /*! |
| | | * \brief Holds the LoRa packet parameters |
| | | */ |
| | | struct |
| | | { |
| | | uint16_t PreambleLength; //!< The preamble length is the number of LoRa symbols in the preamble |
| | | RadioLoRaPacketLengthsMode_t HeaderType; //!< If the header is explicit, it will be transmitted in the LoRa packet. If the header is implicit, it will not be transmitted |
| | | uint8_t PayloadLength; //!< Size of the payload in the LoRa packet |
| | | RadioLoRaCrcModes_t CrcMode; //!< Size of CRC block in LoRa packet |
| | | RadioLoRaIQModes_t InvertIQ; //!< Allows to swap IQ for LoRa packet |
| | | }LoRa; |
| | | }Params; //!< Holds the packet parameters structure |
| | | }PacketParams_t; |
| | | |
| | | /*! |
| | | * \brief Represents the packet status for every packet type |
| | | */ |
| | | typedef struct |
| | | { |
| | | RadioPacketTypes_t packetType; //!< Packet to which the packet status are referring to. |
| | | struct |
| | | { |
| | | struct |
| | | { |
| | | uint8_t RxStatus; |
| | | int8_t RssiAvg; //!< The averaged RSSI |
| | | int8_t RssiSync; //!< The RSSI measured on last packet |
| | | uint32_t FreqError; |
| | | }Gfsk; |
| | | struct |
| | | { |
| | | int8_t RssiPkt; //!< The RSSI of the last packet |
| | | int8_t SnrPkt; //!< The SNR of the last packet |
| | | int8_t SignalRssiPkt; |
| | | uint32_t FreqError; |
| | | }LoRa; |
| | | }Params; |
| | | }PacketStatus_t; |
| | | |
| | | /*! |
| | | * \brief Represents the Rx internal counters values when GFSK or LoRa packet type is used |
| | | */ |
| | | typedef struct |
| | | { |
| | | RadioPacketTypes_t packetType; //!< Packet to which the packet status are referring to. |
| | | uint16_t PacketReceived; |
| | | uint16_t CrcOk; |
| | | uint16_t LengthError; |
| | | }RxCounter_t; |
| | | |
| | | /*! |
| | | * \brief Represents a calibration configuration |
| | | */ |
| | | typedef union |
| | | { |
| | | struct |
| | | { |
| | | uint8_t RC64KEnable : 1; //!< Calibrate RC64K clock |
| | | uint8_t RC13MEnable : 1; //!< Calibrate RC13M clock |
| | | uint8_t PLLEnable : 1; //!< Calibrate PLL |
| | | uint8_t ADCPulseEnable : 1; //!< Calibrate ADC Pulse |
| | | uint8_t ADCBulkNEnable : 1; //!< Calibrate ADC bulkN |
| | | uint8_t ADCBulkPEnable : 1; //!< Calibrate ADC bulkP |
| | | uint8_t ImgEnable : 1; |
| | | uint8_t : 1; |
| | | }Fields; |
| | | uint8_t Value; |
| | | }CalibrationParams_t; |
| | | |
| | | /*! |
| | | * \brief Represents a sleep mode configuration |
| | | */ |
| | | typedef union |
| | | { |
| | | struct |
| | | { |
| | | uint8_t WakeUpRTC : 1; //!< Get out of sleep mode if wakeup signal received from RTC |
| | | uint8_t Reset : 1; |
| | | uint8_t WarmStart : 1; |
| | | uint8_t Reserved : 5; |
| | | }Fields; |
| | | uint8_t Value; |
| | | }SleepParams_t; |
| | | |
| | | /*! |
| | | * \brief Represents the possible radio system error states |
| | | */ |
| | | typedef union |
| | | { |
| | | struct |
| | | { |
| | | uint8_t Rc64kCalib : 1; //!< RC 64kHz oscillator calibration failed |
| | | uint8_t Rc13mCalib : 1; //!< RC 13MHz oscillator calibration failed |
| | | uint8_t PllCalib : 1; //!< PLL calibration failed |
| | | uint8_t AdcCalib : 1; //!< ADC calibration failed |
| | | uint8_t ImgCalib : 1; //!< Image calibration failed |
| | | uint8_t XoscStart : 1; //!< XOSC oscillator failed to start |
| | | uint8_t PllLock : 1; //!< PLL lock failed |
| | | uint8_t BuckStart : 1; //!< Buck converter failed to start |
| | | uint8_t PaRamp : 1; //!< PA ramp failed |
| | | uint8_t : 7; //!< Reserved |
| | | }Fields; |
| | | uint16_t Value; |
| | | }RadioError_t; |
| | | |
| | | /*! |
| | | * Radio hardware and global parameters |
| | | */ |
| | | typedef struct SX126x_s |
| | | { |
| | | // Gpio_t Reset; |
| | | // Gpio_t BUSY; |
| | | // Gpio_t DIO1; |
| | | // Gpio_t DIO2; |
| | | // Gpio_t DIO3; |
| | | // Spi_t Spi; |
| | | PacketParams_t PacketParams; |
| | | PacketStatus_t PacketStatus; |
| | | ModulationParams_t ModulationParams; |
| | | }SX126x_t; |
| | | |
| | | /*! |
| | | * Hardware IO IRQ callback function definition |
| | | */ |
| | | typedef void ( DioIrqHandler )( void ); |
| | | |
| | | /*! |
| | | * SX126x definitions |
| | | */ |
| | | |
| | | /*! |
| | | * \brief Provides the frequency of the chip running on the radio and the frequency step |
| | | * |
| | | * \remark These defines are used for computing the frequency divider to set the RF frequency |
| | | */ |
| | | #define XTAL_FREQ ( double )32000000 |
| | | #define FREQ_DIV ( double )pow( 2.0, 25.0 ) |
| | | #define FREQ_STEP ( double )( XTAL_FREQ / FREQ_DIV ) |
| | | |
| | | #define RX_BUFFER_SIZE 256 |
| | | |
| | | /*! |
| | | * \brief The radio callbacks structure |
| | | * Holds function pointers to be called on radio interrupts |
| | | */ |
| | | typedef struct |
| | | { |
| | | void ( *txDone )( void ); //!< Pointer to a function run on successful transmission |
| | | void ( *rxDone )( void ); //!< Pointer to a function run on successful reception |
| | | void ( *rxPreambleDetect )( void ); //!< Pointer to a function run on successful Preamble detection |
| | | void ( *rxSyncWordDone )( void ); //!< Pointer to a function run on successful SyncWord reception |
| | | void ( *rxHeaderDone )( bool isOk ); //!< Pointer to a function run on successful Header reception |
| | | void ( *txTimeout )( void ); //!< Pointer to a function run on transmission timeout |
| | | void ( *rxTimeout )( void ); //!< Pointer to a function run on reception timeout |
| | | void ( *rxError )( IrqErrorCode_t errCode ); //!< Pointer to a function run on reception error |
| | | void ( *cadDone )( bool cadFlag ); //!< Pointer to a function run on channel activity detected |
| | | }SX126xCallbacks_t; |
| | | |
| | | /*! |
| | | * ============================================================================ |
| | | * Public functions prototypes |
| | | * ============================================================================ |
| | | */ |
| | | |
| | | /*! |
| | | * \brief Initializes the radio driver |
| | | */ |
| | | void SX126xInit( DioIrqHandler dioIrq ); |
| | | |
| | | /*! |
| | | * \brief Gets the current Operation Mode of the Radio |
| | | * |
| | | * \retval RadioOperatingModes_t last operating mode |
| | | */ |
| | | RadioOperatingModes_t SX126xGetOperatingMode( void ); |
| | | |
| | | /*! |
| | | * \brief Wakeup the radio if it is in Sleep mode and check that Busy is low |
| | | */ |
| | | void SX126xCheckDeviceReady( void ); |
| | | |
| | | /*! |
| | | * \brief Saves the payload to be send in the radio buffer |
| | | * |
| | | * \param [in] payload A pointer to the payload |
| | | * \param [in] size The size of the payload |
| | | */ |
| | | void SX126xSetPayload( uint8_t *payload, uint8_t size ); |
| | | |
| | | /*! |
| | | * \brief Reads the payload received. If the received payload is longer |
| | | * than maxSize, then the method returns 1 and do not set size and payload. |
| | | * |
| | | * \param [out] payload A pointer to a buffer into which the payload will be copied |
| | | * \param [out] size A pointer to the size of the payload received |
| | | * \param [in] maxSize The maximal size allowed to copy into the buffer |
| | | */ |
| | | uint8_t SX126xGetPayload( uint8_t *payload, uint8_t *size, uint8_t maxSize ); |
| | | |
| | | /*! |
| | | * \brief Sends a payload |
| | | * |
| | | * \param [in] payload A pointer to the payload to send |
| | | * \param [in] size The size of the payload to send |
| | | * \param [in] timeout The timeout for Tx operation |
| | | */ |
| | | void SX126xSendPayload( uint8_t *payload, uint8_t size, uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the Sync Word given by index used in GFSK |
| | | * |
| | | * \param [in] syncWord SyncWord bytes ( 8 bytes ) |
| | | * |
| | | * \retval status [0: OK, 1: NOK] |
| | | */ |
| | | uint8_t SX126xSetSyncWord( uint8_t *syncWord ); |
| | | |
| | | /*! |
| | | * \brief Sets the Initial value for the LFSR used for the CRC calculation |
| | | * |
| | | * \param [in] seed Initial LFSR value ( 2 bytes ) |
| | | * |
| | | */ |
| | | void SX126xSetCrcSeed( uint16_t seed ); |
| | | |
| | | /*! |
| | | * \brief Sets the seed used for the CRC calculation |
| | | * |
| | | * \param [in] seed The seed value |
| | | * |
| | | */ |
| | | void SX126xSetCrcPolynomial( uint16_t polynomial ); |
| | | |
| | | /*! |
| | | * \brief Sets the Initial value of the LFSR used for the whitening in GFSK protocols |
| | | * |
| | | * \param [in] seed Initial LFSR value |
| | | */ |
| | | void SX126xSetWhiteningSeed( uint16_t seed ); |
| | | |
| | | /*! |
| | | * \brief Gets a 32 bits random value generated by the radio |
| | | * |
| | | * \remark The radio must be in reception mode before executing this function |
| | | * |
| | | * \retval randomValue 32 bits random value |
| | | */ |
| | | uint32_t SX126xGetRandom( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in sleep mode |
| | | * |
| | | * \param [in] sleepConfig The sleep configuration describing data |
| | | * retention and RTC wake-up |
| | | */ |
| | | void SX126xSetSleep( SleepParams_t sleepConfig ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in configuration mode |
| | | * |
| | | * \param [in] mode The standby mode to put the radio into |
| | | */ |
| | | void SX126xSetStandby( RadioStandbyModes_t mode ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in FS mode |
| | | */ |
| | | void SX126xSetFs( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in transmission mode |
| | | * |
| | | * \param [in] timeout Structure describing the transmission timeout value |
| | | */ |
| | | void SX126xSetTx( uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in reception mode |
| | | * |
| | | * \param [in] timeout Structure describing the reception timeout value |
| | | */ |
| | | void SX126xSetRx( uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in reception mode with Boosted LNA gain |
| | | * |
| | | * \param [in] timeout Structure describing the reception timeout value |
| | | */ |
| | | void SX126xSetRxBoosted( uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the Rx duty cycle management parameters |
| | | * |
| | | * \param [in] rxTime Structure describing reception timeout value |
| | | * \param [in] sleepTime Structure describing sleep timeout value |
| | | */ |
| | | void SX126xSetRxDutyCycle( uint32_t rxTime, uint32_t sleepTime ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in CAD mode |
| | | */ |
| | | void SX126xSetCad( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in continuous wave transmission mode |
| | | */ |
| | | void SX126xSetTxContinuousWave( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio in continuous preamble transmission mode |
| | | */ |
| | | void SX126xSetTxInfinitePreamble( void ); |
| | | |
| | | /*! |
| | | * \brief Decide which interrupt will stop the internal radio rx timer. |
| | | * |
| | | * \param [in] enable [0: Timer stop after header/syncword detection |
| | | * 1: Timer stop after preamble detection] |
| | | */ |
| | | void SX126xSetStopRxTimerOnPreambleDetect( bool enable ); |
| | | |
| | | /*! |
| | | * \brief Set the number of symbol the radio will wait to validate a reception |
| | | * |
| | | * \param [in] SymbNum number of LoRa symbols |
| | | */ |
| | | void SX126xSetLoRaSymbNumTimeout( uint8_t SymbNum ); |
| | | |
| | | /*! |
| | | * \brief Sets the power regulators operating mode |
| | | * |
| | | * \param [in] mode [0: LDO, 1:DC_DC] |
| | | */ |
| | | void SX126xSetRegulatorMode( RadioRegulatorMode_t mode ); |
| | | |
| | | /*! |
| | | * \brief Calibrates the given radio block |
| | | * |
| | | * \param [in] calibParam The description of blocks to be calibrated |
| | | */ |
| | | void SX126xCalibrate( CalibrationParams_t calibParam ); |
| | | |
| | | /*! |
| | | * \brief Calibrates the Image rejection depending of the frequency |
| | | * |
| | | * \param [in] freq The operating frequency |
| | | */ |
| | | void SX126xCalibrateImage( uint32_t freq ); |
| | | |
| | | /*! |
| | | * \brief Activate the extention of the timeout when long preamble is used |
| | | * |
| | | * \param [in] enable The radio will extend the timeout to cope with long preamble |
| | | */ |
| | | void SX126xSetLongPreamble( uint8_t enable ); |
| | | |
| | | /*! |
| | | * \brief Sets the transmission parameters |
| | | * |
| | | * \param [in] paDutyCycle Duty Cycle for the PA |
| | | * \param [in] hpMax 0 for sx1261, 7 for sx1262 |
| | | * \param [in] deviceSel 1 for sx1261, 0 for sx1262 |
| | | * \param [in] paLut 0 for 14dBm LUT, 1 for 22dBm LUT |
| | | */ |
| | | void SX126xSetPaConfig( uint8_t paDutyCycle, uint8_t hpMax, uint8_t deviceSel, uint8_t paLut ); |
| | | |
| | | /*! |
| | | * \brief Defines into which mode the chip goes after a TX / RX done |
| | | * |
| | | * \param [in] fallbackMode The mode in which the radio goes |
| | | */ |
| | | void SX126xSetRxTxFallbackMode( uint8_t fallbackMode ); |
| | | |
| | | /*! |
| | | * \brief Write data to the radio memory |
| | | * |
| | | * \param [in] address The address of the first byte to write in the radio |
| | | * \param [in] buffer The data to be written in radio's memory |
| | | * \param [in] size The number of bytes to write in radio's memory |
| | | */ |
| | | void SX126xWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ); |
| | | |
| | | /*! |
| | | * \brief Read data from the radio memory |
| | | * |
| | | * \param [in] address The address of the first byte to read from the radio |
| | | * \param [out] buffer The buffer that holds data read from radio |
| | | * \param [in] size The number of bytes to read from radio's memory |
| | | */ |
| | | void SX126xReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ); |
| | | |
| | | /*! |
| | | * \brief Write data to the buffer holding the payload in the radio |
| | | * |
| | | * \param [in] offset The offset to start writing the payload |
| | | * \param [in] buffer The data to be written (the payload) |
| | | * \param [in] size The number of byte to be written |
| | | */ |
| | | void SX126xWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ); |
| | | |
| | | /*! |
| | | * \brief Read data from the buffer holding the payload in the radio |
| | | * |
| | | * \param [in] offset The offset to start reading the payload |
| | | * \param [out] buffer A pointer to a buffer holding the data from the radio |
| | | * \param [in] size The number of byte to be read |
| | | */ |
| | | void SX126xReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ); |
| | | |
| | | /*! |
| | | * \brief Sets the IRQ mask and DIO masks |
| | | * |
| | | * \param [in] irqMask General IRQ mask |
| | | * \param [in] dio1Mask DIO1 mask |
| | | * \param [in] dio2Mask DIO2 mask |
| | | * \param [in] dio3Mask DIO3 mask |
| | | */ |
| | | void SX126xSetDioIrqParams( uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask, uint16_t dio3Mask ); |
| | | |
| | | /*! |
| | | * \brief Returns the current IRQ status |
| | | * |
| | | * \retval irqStatus IRQ status |
| | | */ |
| | | uint16_t SX126xGetIrqStatus( void ); |
| | | |
| | | /*! |
| | | * \brief Indicates if DIO2 is used to control an RF Switch |
| | | * |
| | | * \param [in] enable true of false |
| | | */ |
| | | void SX126xSetDio2AsRfSwitchCtrl( uint8_t enable ); |
| | | |
| | | /*! |
| | | * \brief Indicates if the Radio main clock is supplied from a tcxo |
| | | * |
| | | * \param [in] tcxoVoltage voltage used to control the TCXO |
| | | * \param [in] timeout time given to the TCXO to go to 32MHz |
| | | */ |
| | | void SX126xSetDio3AsTcxoCtrl( RadioTcxoCtrlVoltage_t tcxoVoltage, uint32_t timeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the RF frequency |
| | | * |
| | | * \param [in] frequency RF frequency [Hz] |
| | | */ |
| | | void SX126xSetRfFrequency( uint32_t frequency ); |
| | | |
| | | /*! |
| | | * \brief Sets the radio for the given protocol |
| | | * |
| | | * \param [in] packetType [PACKET_TYPE_GFSK, PACKET_TYPE_LORA] |
| | | * |
| | | * \remark This method has to be called before SetRfFrequency, |
| | | * SetModulationParams and SetPacketParams |
| | | */ |
| | | void SX126xSetPacketType( RadioPacketTypes_t packetType ); |
| | | |
| | | /*! |
| | | * \brief Gets the current radio protocol |
| | | * |
| | | * \retval packetType [PACKET_TYPE_GFSK, PACKET_TYPE_LORA] |
| | | */ |
| | | RadioPacketTypes_t SX126xGetPacketType( void ); |
| | | |
| | | /*! |
| | | * \brief Sets the transmission parameters |
| | | * |
| | | * \param [in] power RF output power [-18..13] dBm |
| | | * \param [in] rampTime Transmission ramp up time |
| | | */ |
| | | void SX126xSetTxParams( int8_t power, RadioRampTimes_t rampTime ); |
| | | |
| | | /*! |
| | | * \brief Set the modulation parameters |
| | | * |
| | | * \param [in] modParams A structure describing the modulation parameters |
| | | */ |
| | | void SX126xSetModulationParams( ModulationParams_t *modParams ); |
| | | |
| | | /*! |
| | | * \brief Sets the packet parameters |
| | | * |
| | | * \param [in] packetParams A structure describing the packet parameters |
| | | */ |
| | | void SX126xSetPacketParams( PacketParams_t *packetParams ); |
| | | |
| | | /*! |
| | | * \brief Sets the Channel Activity Detection (CAD) parameters |
| | | * |
| | | * \param [in] cadSymbolNum The number of symbol to use for CAD operations |
| | | * [LORA_CAD_01_SYMBOL, LORA_CAD_02_SYMBOL, |
| | | * LORA_CAD_04_SYMBOL, LORA_CAD_08_SYMBOL, |
| | | * LORA_CAD_16_SYMBOL] |
| | | * \param [in] cadDetPeak Limit for detection of SNR peak used in the CAD |
| | | * \param [in] cadDetMin Set the minimum symbol recognition for CAD |
| | | * \param [in] cadExitMode Operation to be done at the end of CAD action |
| | | * [LORA_CAD_ONLY, LORA_CAD_RX, LORA_CAD_LBT] |
| | | * \param [in] cadTimeout Defines the timeout value to abort the CAD activity |
| | | */ |
| | | void SX126xSetCadParams( RadioLoRaCadSymbols_t cadSymbolNum, uint8_t cadDetPeak, uint8_t cadDetMin, RadioCadExitModes_t cadExitMode, uint32_t cadTimeout ); |
| | | |
| | | /*! |
| | | * \brief Sets the data buffer base address for transmission and reception |
| | | * |
| | | * \param [in] txBaseAddress Transmission base address |
| | | * \param [in] rxBaseAddress Reception base address |
| | | */ |
| | | void SX126xSetBufferBaseAddress( uint8_t txBaseAddress, uint8_t rxBaseAddress ); |
| | | |
| | | /*! |
| | | * \brief Gets the current radio status |
| | | * |
| | | * \retval status Radio status |
| | | */ |
| | | RadioStatus_t SX126xGetStatus( void ); |
| | | |
| | | /*! |
| | | * \brief Returns the instantaneous RSSI value for the last packet received |
| | | * |
| | | * \retval rssiInst Instantaneous RSSI |
| | | */ |
| | | int8_t SX126xGetRssiInst( void ); |
| | | |
| | | /*! |
| | | * \brief Gets the last received packet buffer status |
| | | * |
| | | * \param [out] payloadLength Last received packet payload length |
| | | * \param [out] rxStartBuffer Last received packet buffer address pointer |
| | | */ |
| | | void SX126xGetRxBufferStatus( uint8_t *payloadLength, uint8_t *rxStartBuffer ); |
| | | |
| | | /*! |
| | | * \brief Gets the last received packet payload length |
| | | * |
| | | * \param [out] pktStatus A structure of packet status |
| | | */ |
| | | void SX126xGetPacketStatus( PacketStatus_t *pktStatus ); |
| | | |
| | | /*! |
| | | * \brief Returns the possible system errors |
| | | * |
| | | * \retval sysErrors Value representing the possible sys failures |
| | | */ |
| | | RadioError_t SX126xGetDeviceErrors( void ); |
| | | |
| | | /*! |
| | | * \brief Clear all the errors in the device |
| | | */ |
| | | void SX126xClearDeviceErrors( void ); |
| | | |
| | | /*! |
| | | * \brief Clears the IRQs |
| | | * |
| | | * \param [in] irq IRQ(s) to be cleared |
| | | */ |
| | | void SX126xClearIrqStatus( uint16_t irq ); |
| | | |
| | | #endif // __SX126x_H__ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | #ifndef _USER_H_ |
| | | #define _USER_H_ |
| | | |
| | | //#include "stm32f0xx.h" |
| | | //#include "stm32l0xx_hal.h" |
| | | |
| | | #include <stdint.h> |
| | | #include <stdbool.h> |
| | | #include <string.h> |
| | | |
| | | //#include "gpio.h" |
| | | #include "delay.h" |
| | | //#include "spi.h" |
| | | |
| | | #include "radio.h" |
| | | #include "sx126x.h" |
| | | #include "sx126x-board.h" |
| | | #include "crc.h" |
| | | |
| | | |
| | | #endif |
| | | |