#include "lora.h" #include "includes.h" #include "radio.h" #include "project_config.h" #include "stdio.h" #include "stm32f10x_it.h" #include "delay.h" #include "string.h" #include "lora.h" #include "bsp.h" #include "cad.h" #include "gw_ctrl.h" #define RADIO_RX_TIMEOUT_VALUE 0 uint8_t cmpBuf[256] ; uint8_t lora_state = lora_state_idle; uint8_t lora_state_tmp = lora_state_idle; OS_Q lora_q; //system_lora_t sys_lora; system_lora_t sys_lora_rx; system_lora_t sys_lora_tx; uint8_t lora_send_buf[256],lora_send_size; uint8_t lora_cad_num = 0,lora_cad_start = 0,lora_send_start = 0; uint16_t delay_time = 0; lora_para_t lora_para; uint8_t lora_para_choice; uint32_t LORA_FRE = 486300000; uint8_t LORA_TX_OUTPUT_POWER = 20; uint8_t LORA_BANDWIDTH = 1; uint8_t LORA_SPREADING_FACTOR = 7; uint8_t LORA_CODINGRATE = 2; uint8_t LORA_PREAMBLE_LENGTH = 8; //lora参数 lora_para_single_t lora_para_fixed[]= { 486300000,20,1,7,2,8, 489300000,20,1,7,2,8, 509700000,20,2,8,3,8, 470300000,20,2,8,3,8, }; //lora中断定时器 timeout_t tt_lora_irq={ 0xff, 0, 60*1000, }; //lora接收定时器 //lora一小时未接收到数据,设备复位 timeout_t tt_lora_rcv_state={ 0xff, 0, 60*60*1000, //1小时 }; //lora一小时复位后 timeout_t tt_lora_rst_rcv_state={ 0,0,5*60*1000,//5分钟 }; /*信道空闲的标志*/ bool channel_free = false; /** * @brief lora状态机,死机定时器 */ timeout_t tt_lora_state={ 0xFF, 0, 1*60*1000 //1分钟 }; /** * @brief 从cad切换至rx后,停留在rx状态的定时器 */ timeout_t tt_fromCadtoRx={ 1, 0, 200 //200ms }; /*! * Radio events function pointer * 这个是传参进入其他函数中了,所以用全局变量(局部变量使用完了内存释放可能导致异常) */ static RadioEvents_t RadioEventsObj; static void SX126xOnTxDone( void ); static void SX126xOnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); static void SX126xOnCadDone( bool channelActivityDetected ); static void SX126xOnTxTimeout( void ); static void SX126xOnRxTimeout( void ); static void SX126xOnRxError( void ); ///////////////////////////////////////////////////////////////// //lora初始超时定时 void lora_timeout_start(void) { //收到升级相关指令时,重新打开Lora超时定时器 //打开Lora接收或发送超时定时器(用于判断Lora模块是否正常工作) timeout_start(&tt_lora_rcv_state,0xff); timeout_stop(&tt_lora_rst_rcv_state); device_fixed_info.reset_flag = 0; } ///////////////////////////////////////////////////////////////////// //申请Lora消息队列 void* lora_queue_mem_calloc_must(uint8_t state) { OS_ERR err; void * p_msg = NULL; if(state == SYS_LORA_RX) { OSSemPend(&sys_lora_rx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); p_msg = OSMemGet(&sys_lora_rx.lora_m, &err); OSSemPost(&sys_lora_rx.sem, OS_OPT_POST_ALL, &err); } else if(state == SYS_LORA_TX) { OSSemPend(&sys_lora_tx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); p_msg = OSMemGet(&sys_lora_tx.lora_m, &err); OSSemPost(&sys_lora_tx.sem, OS_OPT_POST_ALL, &err); } return p_msg; } //释放Lora消息队列 int lora_queue_mem_free(uint8_t state,void * p_msg) { OS_ERR err; if(state == SYS_LORA_RX) { OSSemPend(&sys_lora_rx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); OSMemPut(&sys_lora_rx.lora_m, p_msg, &err); OSSemPost(&sys_lora_rx.sem, OS_OPT_POST_ALL, &err); } else if(state == SYS_LORA_TX) { OSSemPend(&sys_lora_tx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); OSMemPut(&sys_lora_tx.lora_m, p_msg, &err); OSSemPost(&sys_lora_tx.sem, OS_OPT_POST_ALL, &err); } return err; } //往消息队列内插入数据 void lora_queue_insert(uint8_t state,char *p_msg, uint32_t msg_len) { OS_ERR err; if(state == SYS_LORA_RX) { OSSemPend(&sys_lora_rx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); OS_QPost(&sys_lora_rx.lora_q, p_msg, msg_len, OS_OPT_POST_FIFO, 0, &err); OSSemPost(&sys_lora_rx.sem, OS_OPT_POST_ALL, &err); } else if(state == SYS_LORA_TX) { OSSemPend(&sys_lora_tx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); OS_QPost(&sys_lora_tx.lora_q, p_msg, msg_len, OS_OPT_POST_FIFO, 0, &err); OSSemPost(&sys_lora_tx.sem, OS_OPT_POST_ALL, &err); } } static void SX126xOnTxDone( void ) { //printf("TxDone\r\n"); Radio.Standby(); lora_state = lora_state_idle; lora_send_start = 0; //Radio.Rx( RADIO_RX_TIMEOUT_VALUE ); } static void SX126xOnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { char *p_msg = NULL; printf_debug(LORA_RCV_DEBUG, "RxDone size:%d \r\n",size, rssi, snr); Radio.Standby(); data_dump_debug(LORA_RCV_DATA_DEBUG, "lora rcv", (uint8_t *)payload, size); p_msg = lora_queue_mem_calloc_must(SYS_LORA_RX); if(p_msg) { if(size) //和上次数据不同,数据有效 { memcpy(p_msg, payload, size); lora_queue_insert(SYS_LORA_RX,(char *)p_msg, size); } else { lora_queue_mem_free(SYS_LORA_RX,p_msg); } } else { lora_queue_mem_free(SYS_LORA_RX,p_msg); } lora_state = lora_state_idle; } static void SX126xOnCadDone( bool channelActivityDetected ) { lora_cad_start = 0; Radio.Standby(); printf("cadDone %d\r\n", channelActivityDetected); if(channelActivityDetected) { channel_free = false; LORA_DEBUG_F("SX126xOnCadDone CAD占用\r\n"); if(device_fixed_info.Work_State==DEV_WORK_STATE_UPDATING)//升级模式 { if(ota_state.update_mode == OTA_WORK_STATE_SLAVE && ota_state.update_state_slave == OTA_WORK_STATE_RETRANSMIT) { //升级重传时,cad占用延时700ms ota_timer_retransmit_require_slave_set(OPEN,RETRANSMIT_DELAY_TIMEOUT_MAX);//打开重传延时定时器 lora_queue_delete(SYS_LORA_TX);//清空发送消息队列 } if(ota_state.update_mode == OTA_WORK_STATE_UPLOAD)//上报升级状态 { ota_timer_upload_cad_slave_set(OPEN,SLAVE_CAD_TIME_MAX); lora_queue_delete(SYS_LORA_TX);//清空发送消息队列 } } // lora_state = lora_state_cadDone; } else { channel_free = true; LORA_DEBUG_F("SX126xOnCadDone CAD空闲\r\n"); } lora_state = lora_state_cadDone; return ; } //static void SX126xOnCadTimeout( void ) //{ // Radio.Standby(); // //Radio.Rx(LORA_RX_TIMEOUT_VALUE); // channel_free = false; // LORA_DEBUG_F("SX126xOnCadTimeout CAD超时\r\n"); // lora_state = lora_state_cadTimeout; //} static void SX126xOnTxTimeout( void ) { printf("TxTimeout\r\n"); Radio.Standby(); lora_state = lora_state_idle; } static void SX126xOnRxTimeout( void ) { printf("RxTimeout retry recive\r\n"); Radio.Standby(); //Radio.Rx( LORA_RX_TIMEOUT_VALUE ); lora_state = lora_state_idle; } static void SX126xOnRxError( void ) { printf("RxError retry recive\r\n"); Radio.Standby(); //Radio.Rx(LORA_RX_TIMEOUT_VALUE); lora_state = lora_state_idle; } //lora发送函数 void lora_send(char *tx_data, uint32_t tx_len) { char *p_msg = NULL; p_msg = (char *)lora_queue_mem_calloc_must(SYS_LORA_TX); if(p_msg) { memcpy(p_msg, tx_data, tx_len); lora_queue_insert(SYS_LORA_TX,(char *)p_msg, tx_len); } else { lora_queue_mem_free(SYS_LORA_TX,p_msg); } } //Lora接收队列处理 void lora_queue_proc_rx(void) { OS_ERR err; OS_MSG_SIZE msg_len; collect_gateway_msg_format_t *p_msg = NULL; uint16_t p_crc, crc; transparent_info_t *p_tax = NULL; OSSemPend(&sys_lora_rx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); p_msg = (collect_gateway_msg_format_t *)OSQPend(&sys_lora_rx.lora_q, 0, OS_OPT_PEND_NON_BLOCKING, &msg_len, NULL, &err); /* blocking. */ OSSemPost(&sys_lora_rx.sem, OS_OPT_POST_ALL, &err); if(p_msg&&msg_len) { if(p_msg->frame_header!=0xfefe)//帧头错误 { // printf("p_msg->header:%04x\n",p_msg->frame_header); printf("header error\n"); lora_queue_mem_free(SYS_LORA_RX,p_msg); return; } if(p_msg->msg_len+FRAME_HEADER_LEN > msg_len)//命令的数据长度大于实际长度 { printf("datalen err\n"); lora_queue_mem_free(SYS_LORA_RX,p_msg); return; } //crc 校验 p_crc = *(uint16_t*)&p_msg->info[p_msg->msg_len-2]; crc = CRC16_get((uint8_t *)p_msg,p_msg->msg_len+FRAME_HEADER_LEN-2); if(device_fixed_info.Work_State != DEV_WORK_STATE_PT) { if(p_msg->proto_Ver == PROTOCOL_VERSION)//协议1 { if((p_msg->first_type&0xF0) == 0x50) //业务数据命令 { if(p_crc != crc) { printf("crc err\n"); lora_queue_mem_free(SYS_LORA_RX,p_msg); return; } if(device_fixed_info.Work_State == DEV_WORK_STATE_NORMAL) { gateway_coll_ctrl_comm(p_msg); } } else if((p_msg->first_type&0xF0) == 0x10) //升级下发命令 { lora_timeout_start();//Lora初始超时定时时间 if((ota_state.update_mode != OTA_WORK_STATE_MASTER) && (device_fixed_info.Work_State != DEV_WORK_STATE_XSP_UPDATING)) //从设备处理升级下发指令,主设备不处理 gateway_lora_ota_proc(p_msg); } else if((p_msg->first_type&0xf0) == 0x20)//升级时的主设备 { lora_timeout_start();//Lora初始超时定时时间 if(device_fixed_info.Work_State == DEV_WORK_STATE_UPDATING && (ota_state.update_mode == OTA_WORK_STATE_MASTER || ota_state.update_mode == OTA_WORK_STATE_ONLOOKER)) { lora_master_ota_proc(p_msg); } } else if(p_msg->first_type == FIRST_TYPE_SYSTEM)//系统类,透传指令 { p_tax = (transparent_info_t *)p_msg->info; if(p_tax->coll_sn == device_info.device_sn) { if(p_msg->second_type == SYSTEM_SECOND_TRANS_DOWN)//透传指令 { printf_debug(MSG_HEARTBEAT_DOWN_TYPE1, "device_sn=%010u<0x%08x>\n",p_tax->coll_sn,p_tax->coll_sn); printf("first type:%x, second type:%x\n",p_msg->first_type,p_msg->second_type); //lora接收指示灯 led_start(LORA_RCV_LED); gateway_coll_transparent_proc(p_msg); } } } } else if(p_msg->proto_Ver == PROTOCOL_VERSION_3)//版本3.0 { if(device_fixed_info.Work_State == DEV_WORK_STATE_NORMAL) { coll_rcv_lora_ver3_handle((uint8_t *)p_msg,msg_len); } } else if(p_msg->proto_Ver == PROTOCOL_VERSION_FF)//版本FF { if(device_fixed_info.Work_State == DEV_WORK_STATE_NORMAL) { coll_rcv_lora_verff_handle((uint8_t *)p_msg,msg_len); } } } lora_queue_mem_free(SYS_LORA_RX,p_msg); } } //Lora发送队列处理 void lora_queue_proc_tx(void) { OS_ERR err; uint8_t *p_msg; OS_MSG_SIZE msg_len; OSSemPend(&sys_lora_tx.sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err); p_msg = (uint8_t *)OSQPend(&sys_lora_tx.lora_q, 0, OS_OPT_PEND_NON_BLOCKING, &msg_len, NULL, &err); /* blocking. */ // OSSemPost(&sys_lora_tx.sem, OS_OPT_POST_ALL, &err); if(p_msg&&msg_len) { Radio.Send((uint8_t *)p_msg,msg_len); data_dump_debug(LORA_SEND_DATA_DEBUG, "LORA Tx", (uint8_t *)p_msg, msg_len); //lora发送指示灯 led_start(LORA_SEND_LED); lora_timeout_start();//Lora初始超时定时时间 if(device_fixed_info.Work_State==DEV_WORK_STATE_UPDATING)//升级模式 { if(ota_state.update_mode == OTA_WORK_STATE_SLAVE && ota_state.update_state_slave == OTA_WORK_STATE_RETRANSMIT) { //升级重传时 ota_timer_retransmit_require_slave_set(OPEN,RETRANSMIT_DELAY_TIMEOUT_MIN);//打开重传延时定时器 } if(ota_state.update_mode == OTA_WORK_STATE_UPLOAD)//上报升级状态 { slave_upload_info.num++; printf("slave send %d ",slave_upload_info.num); data_dump("times",(uint8_t *)p_msg,msg_len); if(slave_upload_info.num