/* ********************************************************************************************************* * IAR Development Kits * on the * * M451 * * Filename : uart_RFModule.h * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #include "includes.h" const uint8_t RF_APP = RF_APP_AJH; const uint8_t RF_PROTOCOL_VER = RF_PROTOCOL_VER_1; const uint8_t RF_LNG_LORA_CHANNEL = 1; // 通信信道: 471M const uint8_t RF_UP_CHANNEL = 28; // 上行信道: 438M const uint8_t RF_DOWN_CHANNEL = 29; // 下行信道: 439M const uint8_t RF_BROADCAST_PSN[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; const uint8_t RF_EMPTYPSN[6] = {0, 0, 0, 0, 0, 0}; const uint8_t RF_LNG_LORA_EMPTYPSN[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t RF_GatewayPSN[6] = {0, 0, 0, 0, 0, 0}; #define RF_SelfPSN (dcBuff.configBottle.PSN) uint8_t RF_MAC_FN = 0; uint8_t RF_APP_PN = 0; uint8_t RF_APP_IDX = 0; // 发送、接收帧 rf_frame_t RF_Send_Frame, RF_RecvFrame; rf_lng_lora_t RF_LNG_LORA_Send_Frame, RF_LNG_LORA_Recv_Frame; // LNG-LORA发送状态 volatile uint8_t RF_LNG_LORA_State = 0; // 0-不发送,1-随机延时15秒内应答一次,2-每隔5秒发送一次 // RF串口接收的消息通知 volatile uint8_t RF_semAck = 0; volatile uint8_t RF_semGateway = 0; volatile uint8_t RF_semResp = 0; volatile uint8_t RF_semMatch = 0; loopbuff_t RF_GatewayBuff; uint8_t RF_GatewayBuff_Data[6 * (4 + 1)] = {0}; loopbuff_t RF_AckBuff; uint8_t RF_AckBuff_Data[sizeof(rf_ack_t) * (2 + 1)] = {0}; loopbuff_t RF_RespBuff; uint8_t RF_RespBuff_Data[sizeof(rf_resp_t) * (2 + 1)] = {0}; loopbuff_t RF_MatchBuff; uint8_t RF_MatchBuff_Data[sizeof(rf_charge_match_t) * (2 + 1)] = {0}; #define RF_MOD_MD0_1() LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_13) #define RF_MOD_MD0_0() LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_13) #define RF_MOD_MD1_1() LL_GPIO_SetOutputPin(GPIOD, LL_GPIO_PIN_12) #define RF_MOD_MD1_0() LL_GPIO_ResetOutputPin(GPIOD, LL_GPIO_PIN_12) #define RF_READY() (1) // 射频初始化状态 uint8_t RF_initStatus = 0; volatile uint8_t RF_hasPowered = 0; // 多项式为x16+x15+x2+1,LSB顺序 // 同ibutton的crc算法,不同于modbus的crc算法 uint16_t rf_crc_16(uint8_t *message, int16_t len) { #if 0 int16_t i, j; uint16_t crc_reg = 0; uint16_t current; for (i = 0; i < len; i++) { current = message[i]; for (j = 0; j < 8; j++) { if ((crc_reg ^ current) & 0x0001) crc_reg = (crc_reg >> 1) ^ 0xA001; else crc_reg >>= 1; current >>= 1; } } // 交换高低字节顺序 return ((crc_reg & 0xFF) << 8) | ((crc_reg >> 8) & 0xFF); #else return MODBUS_RTU_CRC16(message, len); #endif } // 计算自启动以来经过的秒数 uint32_t rf_get_seconds() { S_RTC_TIME_DATA_T sRTC; RTC_GetDateAndTime(&sRTC); return Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); } // 判断存了网关么 uint8_t is_gateway(void) { if(RF_GatewayPSN[0]==0xff) return 1; else return 0; } // 设置网关 void rf_set_gateway(uint8_t PSN[6]) { memmove(RF_GatewayPSN, PSN, 6); } // 清除网关 void rf_clear_gateway() { memmove(RF_GatewayPSN, RF_EMPTYPSN, 6); } // 计算通信地址,用于定点传输 uint16_t rf_get_addr(uint8_t PSN[6]) { // uint16_t addr = rf_crc_16(PSN, 6); // if(addr == 0xFFFF) // 不能为广播地址 // return 0; // return addr; } // 物理层校验 uint8_t rf_phy_valid(rf_frame_t *frame) { // if(frame->vendor_id != RF_MARK_LS)// || frame->app_id != RF_APP || frame->protocol_ver != RF_PROTOCOL_VER) // { // // 物理层校验失败 // return 0; // } // return 1; } // mac层校验 uint8_t rf_mac_valid(rf_frame_t *frame, uint8_t dir) { // if(frame->dir != dir // || (memcmp(frame->destPSN, RF_SelfPSN, 6) != 0 && (dir == RF_DIR_DOWN || memcmp(frame->destPSN, RF_BROADCAST_PSN, 6) != 0)) // ) // { // // mac层校验失败 // return 0; // } // return 1; } // 初始化帧 void rf_initial_frame(rf_frame_t *frame) { memset((uint8_t *) frame, 0, sizeof(rf_frame_t)); frame->len = RF_MIN_FRAME_LEN; } // 追加负载数据 uint8_t rf_append_payload(rf_frame_t *frame, uint8_t payload_len, uint8_t *payload) { if(frame->len < RF_MIN_FRAME_LEN || frame->len + payload_len > RF_MAX_FRAME_LEN) return 0; if(payload_len > 0) memmove(frame->app_payload + (frame->len - RF_MIN_FRAME_LEN), payload, payload_len); frame->len += payload_len; return 1; } // 物理层发送 uint8_t rf_uart_send(rf_frame_t *frame) { uint8_t phy_header[3]; uint16_t crc; // uint16_t dst; uint8_t i; // 填写固定字段 //frame->sof = RF_FRAME_SOF; frame->vendor_id = RF_MARK_LS; //frame->app_id = RF_APP; //frame->protocol_ver = RF_PROTOCOL_VER; memmove(frame->srcPSN, RF_SelfPSN, 6); crc = rf_crc_16((uint8_t *) frame, frame->len - 2); ((uint8_t *) frame)[frame->len - 1] = crc >> 8; ((uint8_t *) frame)[frame->len - 2] = crc & 0xFF; //// // 计算目的地址 //// if(dcBuff.configDisplay.op_BOX_VER) // 泽耀 //// { //// if(frame->dir == RF_DIR_UP) //// dst = rf_get_addr((uint8_t *) RF_BROADCAST_PSN); //// else //// dst = rf_get_addr(frame->destPSN); //// phy_header[0] = dst >> 8; //// phy_header[1] = dst & 0xFF; //// // 信道 //// if(frame->dir == RF_DIR_UP) //// phy_header[2] = RF_UP_CHANNEL; //// else //// phy_header[2] = RF_DOWN_CHANNEL; //// } //// else // LORA { // 信道 if(frame->dir == RF_DIR_UP) phy_header[0] = RF_UP_CHANNEL; else phy_header[0] = RF_DOWN_CHANNEL; } // while(!RF_READY()); // 随机延时 delay_ms((rand() % 10) * (70 + rand() % 20)); //// if(dcBuff.configDisplay.op_BOX_VER) // 泽耀 //// { //// printf("\nRF send to Gateway (%02X %02X %02X, %d bytes):\n", //// phy_header[0], phy_header[1], phy_header[2], frame->len); //// } //// else // LORA { printf("\nRF send to Gateway (%02X, %d bytes):\n", phy_header[0], frame->len); } for(i = 0; i < frame->len; i++) printf(" %02X", ((uint8_t *) frame)[i]); printf("\n"); //SX127X_TxPacket(testbuffer,frame->len); SX127X_TxPacket((uint8_t *)frame,frame->len); // 因为射频模块接收数据不能中断超过3个字节的时间,故不允许打断。 // __disable_irq(); //////// if(dcBuff.configDisplay.op_BOX_VER) // 泽耀 //////// UART_Transmit(&huart3, phy_header, 3); //////// else // LORA //// UART_Transmit(&huart3, phy_header, 1); //// UART_Transmit(&huart3, (uint8_t *) frame, frame->len); // __enable_irq(); // return 1; } // 物理层发送 uint8_t rf_uart_send_lng_lora(rf_lng_lora_t *frame) { uint16_t crc; uint8_t i; // 填写固定字段 memmove(frame->frame_header, "TANK", 4); crc = rf_crc_16((uint8_t *) frame, sizeof(rf_lng_lora_t) - 2); ((uint8_t *) frame)[sizeof(rf_lng_lora_t) - 2] = crc >> 8; ((uint8_t *) frame)[sizeof(rf_lng_lora_t) - 1] = crc & 0xFF; // while(!RF_READY()); // 随机延时0.8~1s delay_ms(800 + (rand() % 11) * (10 + rand() % 11)); printf("\nRF send2 to Gateway:\n"); for(i = 0; i < sizeof(rf_lng_lora_t); i++) printf(" %02X", ((uint8_t *) frame)[i]); printf("\n"); SX127X_TxPacket((uint8_t *) frame,sizeof(rf_lng_lora_t)); // 因为射频模块接收数据不能中断超过3个字节的时间,故不允许打断。 // __disable_irq(); // UART_Transmit(&huart3, (uint8_t *) frame, sizeof(rf_lng_lora_t)); // __enable_irq(); return 1; } // mac层发送: ACK uint8_t rf_mac_send_ack(uint8_t oriDir, uint8_t oriMac_fn, uint8_t oriPSN[6]) { // rf_initial_frame(&RF_Send_Frame); // if(oriDir == RF_DIR_UP) // RF_Send_Frame.dir = RF_DIR_DOWN; // else // RF_Send_Frame.dir = RF_DIR_UP; // RF_Send_Frame.mac_type = RF_MAC_TYPE_ACK; // RF_Send_Frame.mac_ack_req = 0; // RF_Send_Frame.mac_fn = oriMac_fn; // memmove(RF_Send_Frame.destPSN, oriPSN, 6); // // 调用物理层发送 // return rf_uart_send(&RF_Send_Frame); } // mac层发送: 数据 uint8_t rf_mac_send_data(rf_frame_t *frame, uint8_t dir, uint8_t fn, uint8_t destPSN[6]) { uint32_t tick; rf_ack_t ack; uint32_t stop_seconds; uint8_t count; // 清除回应 RF_semAck = 0; LoopBuff_Clear(&RF_AckBuff); // 数据来自上层 frame->dir = dir; frame->mac_type = RF_MAC_TYPE_DATA; //// if(frame->dir == RF_DIR_UP && frame->net_type == RF_NET_TYPE_DATA) //// frame->mac_ack_req = 1; //// else frame->mac_ack_req = 0; frame->mac_fn = RF_MAC_FN; //memmove(frame->destPSN, destPSN, 6); // 调用物理层发送 if(!rf_uart_send(frame)) return 0; // 无须ACK确认 if(!frame->mac_ack_req) { RF_MAC_FN++; return 1; } // 等待ACK确认 stop_seconds = rf_get_seconds() + 3; while(rf_get_seconds() < stop_seconds) { tick = GetDelayTick(500); while(!IsTickOut(tick)) { if(RF_semAck) break; } count = LoopBuff_GetCount(&RF_AckBuff); while(count--) { memmove(&ack, LoopBuff_GetDataPtr(&RF_AckBuff, RF_AckBuff.info.rdPtr), sizeof(ack)); LoopBuff_RemoveItems(&RF_AckBuff, 1); if(ack.mac_fn == RF_MAC_FN && memcmp(ack.srcPSN, destPSN, 6) == 0) { RF_MAC_FN++; return 1; } } } return 0; } // net层发送:寻找中继器 uint8_t rf_net_send_find_relay() { // // 清除回应 // RF_semGateway = 0; // LoopBuff_Clear(&RF_GatewayBuff); // rf_initial_frame(&RF_Send_Frame); // RF_Send_Frame.net_type = RF_NET_TYPE_FIND_RELAY; // // 调用mac层发送 // return rf_mac_send_data(&RF_Send_Frame, RF_DIR_UP, RF_MAC_TYPE_DATA, (uint8_t *) RF_BROADCAST_PSN); } // net层发送:回应中继器 uint8_t rf_net_send_resp_relay(uint8_t oriPSN[6]) { // rf_initial_frame(&RF_Send_Frame); // RF_Send_Frame.net_type = RF_NET_TYPE_RESP_RELAY; // // 调用mac层发送 // return rf_mac_send_data(&RF_Send_Frame, RF_DIR_DOWN, RF_MAC_TYPE_DATA, oriPSN); } // net层发送:充装匹配 uint8_t rf_net_send_charge_match(uint8_t charging) { // rf_charge_match_t *pMatch = (rf_charge_match_t *) RF_Send_Frame.app_payload; // // 清除回应 // RF_semMatch = 0; // LoopBuff_Clear(&RF_MatchBuff); // rf_initial_frame(&RF_Send_Frame); // RF_Send_Frame.net_type = RF_NET_TYPE_CHARGE_MATCH; // // pMatch->posState = dcBuff.dtuData.posState; // pMatch->longitude = dcBuff.dtuData.longitude; // pMatch->latitude = dcBuff.dtuData.latitude; // pMatch->source = dcBuff.configBottle.source; // pMatch->charging = charging; //// rf_append_payload(&RF_Send_Frame, sizeof(rf_charge_match_t), (uint8_t *) pMatch); // // 调用mac层发送 // return rf_mac_send_data(&RF_Send_Frame, RF_DIR_UP, RF_MAC_TYPE_DATA, (uint8_t *) RF_BROADCAST_PSN); } // net层发送:回应充装匹配 uint8_t rf_net_send_resp_charge_match(uint8_t oriPSN[6], uint8_t charging) { // rf_charge_match_t *pMatch = (rf_charge_match_t *) RF_Send_Frame.app_payload; // // rf_initial_frame(&RF_Send_Frame); // RF_Send_Frame.net_type = RF_NET_TYPE_CHARGE_MATCH; // pMatch->posState = dcBuff.dtuData.posState; // pMatch->longitude = dcBuff.dtuData.longitude; // pMatch->latitude = dcBuff.dtuData.latitude; // pMatch->source = dcBuff.configBottle.source; // pMatch->charging = charging; // rf_append_payload(&RF_Send_Frame, sizeof(rf_charge_match_t), (uint8_t *) pMatch); // // // 调用mac层发送 // return rf_mac_send_data(&RF_Send_Frame, RF_DIR_DOWN, RF_MAC_TYPE_DATA, oriPSN); } // net层发送:回应遥控命令 uint8_t rf_net_send_resp_remote_ctrl(uint8_t oriPSN[6], uint8_t func) { // rf_initial_frame(&RF_Send_Frame); // RF_Send_Frame.net_type = RF_NET_TYPE_REMOTE_CTRL; // rf_append_payload(&RF_Send_Frame, 1, &func); // // // 调用mac层发送 // return rf_mac_send_data(&RF_Send_Frame, RF_DIR_DOWN, RF_MAC_TYPE_DATA, oriPSN); } // net层发送:数据 uint8_t rf_net_send_data(rf_frame_t *frame, uint8_t dir, uint8_t destPSN[6]) { // 数据来自应用层 frame->net_type = RF_NET_TYPE_DATA; // 调用mac层发送 return rf_mac_send_data(frame, dir, RF_MAC_TYPE_DATA, destPSN); } // 应用层发送:回应 uint8_t rf_app_send_resp(uint8_t oriPSN[6], uint8_t oriApp_pn, uint8_t payload_len, uint8_t *payload) { // rf_initial_frame(&RF_Send_Frame); // rf_append_payload(&RF_Send_Frame, payload_len, payload); // // RF_Send_Frame.app_pn = oriApp_pn; // RF_Send_Frame.app_idx = 0; // 暂不实现分包组包 // RF_Send_Frame.app_tbc = 0; // // 调用net层发送 // return rf_net_send_data(&RF_Send_Frame, RF_DIR_DOWN, oriPSN); } // 应用层发送:数据 uint8_t rf_app_send_data(uint8_t payload_len, uint8_t *payload)// { // uint32_t tick; // rf_resp_t resp; // uint32_t stop_seconds; // uint8_t count; // S_RTC_TIME_DATA_T sRTC; // 清除回应 RF_semResp = 0; LoopBuff_Clear(&RF_RespBuff); rf_initial_frame(&RF_Send_Frame); rf_append_payload(&RF_Send_Frame, payload_len, payload); // RF_Send_Frame.app_pn = RF_APP_PN; // RF_Send_Frame.app_idx = 0; // 暂不实现分包组包 // RF_Send_Frame.app_tbc = 0; // 调用net层发送 printf("lora send data start !"); //if( rf_net_send_data(&RF_Send_Frame, RF_DIR_UP, RF_GatewayPSN); printf("lora send data over !"); //== 0) // return 0; // // // 等待服务器返回:15秒 // stop_seconds = rf_get_seconds() + 15; // while(rf_get_seconds() < stop_seconds) // { // tick = GetDelayTick(500); // while(!IsTickOut(tick)) // { // if(RF_semResp) // break; // } // count = LoopBuff_GetCount(&RF_RespBuff); // while(count--) // { // memmove(&resp, LoopBuff_GetDataPtr(&RF_RespBuff, RF_RespBuff.info.rdPtr), sizeof(resp)); // LoopBuff_RemoveItems(&RF_RespBuff, 1); // if(resp.app_pn == RF_APP_PN && memcmp(resp.srcPSN, RF_GatewayPSN, 6) == 0) // { // // print app_payload // RF_APP_PN++; // // 记录发送成功的时间 // RTC_GetDateAndTime(&sRTC); //// DTU_succTime = Calc_SecondsFromYear(INITIAL_YEAR, sRTC.u32Year, sRTC.u32Month, sRTC.u32Day, //// sRTC.u32Hour, sRTC.u32Minute, sRTC.u32Second); // return 1; // } // } // } return 0; } // 检查当前是否已经设置了网关 uint8_t rf_has_gateway() { // return (memcmp(RF_GatewayPSN, RF_EMPTYPSN, 6) != 0); } // 终端模块搜寻网关:发送搜寻命令,等待回应。 // 搜寻5次,取回应次数最多的作为通信网关。 // 最多接收10个网关 extern rf_frame_t revframe; uint8_t rf_check_gateway() { uint32_t tick; uint8_t PSN_List[10][6]; // 接收到的网关PSN列表 uint8_t CNT_List[10]; // 接收到网关应答的次数 // uint8_t PSN[6]; uint32_t stop_seconds; // uint8_t i, j, k; // uint8_t count; // uint8_t done = 0; // 重新搜索网关 memset(PSN_List, 0, sizeof(PSN_List)); memset(CNT_List, 0, sizeof(CNT_List)); // 搜寻3次(如果和原来的中继相同,则只搜寻1次) // for(i = 0; i < 3 && !done; i++) // { // 发送搜寻命令 rf_net_send_find_relay(); //get_sys_tick_sec_value(); // 4秒内没有收到网关回应,则停止等待 //stop_seconds = rf_get_seconds() + 4; // stop_seconds = get_sys_tick_sec_value() + 4; // while(rf_get_seconds() <= stop_seconds) // { // tick = GetDelayTick(500); // while(!IsTickOut(tick)) // { // if(RF_semGateway) // break; // } // count = LoopBuff_GetCount(&RF_GatewayBuff); // while(count--) // { // memmove(PSN, LoopBuff_GetDataPtr(&RF_GatewayBuff, RF_GatewayBuff.info.rdPtr), 6); // LoopBuff_RemoveItems(&RF_GatewayBuff, 1); // // // 如果和原来的中继相同,则只搜寻1次 // if(memcmp(RF_GatewayPSN, PSN, 6) == 0) // done = 1; // // for(j = 0; j < 10; j++) // { // // 找到该PSN所在位置,或者第一个空位置 // if(memcmp(PSN_List[j], PSN, 6) == 0 || CNT_List[j] == 0) // { // memmove(PSN_List[j], PSN, 6); // CNT_List[j]++; // break; // } // // 没有位置则丢弃 // } // // 延迟等待3秒 // stop_seconds = rf_get_seconds() + 3; // } // } //} // 使用收到次数最多的一个 // k = 0; // i = CNT_List[0]; // for(j = 1; j < 10; j++) // { // if(CNT_List[j] > i) // { // k = j; // i = CNT_List[j]; // } // } // if(i == 0) // { // rf_clear_gateway(); // printf("NO RF_Gateway!\n"); // return 0; // } // rf_set_gateway(revframe.destPSN); // printf("RF_GatewayPSN: 20%02d%02d%02d%02d%03d\n", RF_GatewayPSN[0], RF_GatewayPSN[1], // RF_GatewayPSN[2], RF_GatewayPSN[3], (RF_GatewayPSN[4] << 8) | RF_GatewayPSN[5]); return 1; } // 判断储罐和槽车是否匹配 uint32_t rf_is_charge_match(rf_charge_match_t *pMatch) { // // 判断介质 // if(pMatch->source != dcBuff.configBottle.source) // return 0; // // 判断槽车处于静止状态 // if(dcBuff.configDisplay.op_SEND_GPS_DATA && Motion_Status && dcBuff.dtuData.posState && dcBuff.dtuData.speed >= 5) // return 0; // // // 无法判断距离 // if(pMatch->posState == 0 || dcBuff.dtuData.posState == 0) // return 1; // // // 判断储罐和槽车之间的距离 // if(GetDistance(pMatch->latitude, pMatch->longitude, dcBuff.dtuData.latitude, dcBuff.dtuData.longitude) > 500) // return 0; return 1; } // 判断槽车是否离开原地 uint32_t rf_is_truck_leave() { // // 无法判断距离 // if(Pump_Stop_posState == 0 || dcBuff.dtuData.posState == 0) // return 0; // // // 判断槽车处于运动状态 // if(!Motion_Status || dcBuff.dtuData.speed < 5) // return 0; // // // 判断槽车离原点之间的距离 // if(GetDistance(Pump_Stop_Latitude, Pump_Stop_Longitude, dcBuff.dtuData.latitude, dcBuff.dtuData.longitude) < 2000) // return 0; return 1; } // 储罐发送充装匹配命令,并等待应答 uint8_t rf_charge_match(uint8_t charging) { // uint32_t tick; // uint32_t stop_tick; // rf_charge_match_t match; // uint8_t count; // uint8_t try_count = 2; // // 发送2次 // while(try_count--) // { // // 发送匹配命令 // rf_net_send_charge_match(charging); // // // 等待3秒内的有效应答 // stop_tick = GetDelayTick(3000); // while(!IsTickOut(stop_tick)) // { // tick = GetDelayTick(500); // while(!IsTickOut(tick)) // { // if(RF_semMatch) // break; // } // count = LoopBuff_GetCount(&RF_MatchBuff); // while(count--) // { // memmove(&match, LoopBuff_GetDataPtr(&RF_MatchBuff, RF_MatchBuff.info.rdPtr), sizeof(match)); // LoopBuff_RemoveItems(&RF_MatchBuff, 1); // // // 判断匹配是否合法 // if(rf_is_charge_match(&match) && match.charging == charging) // return 1; // } // } // } // return 0; } // 重新寻找SOF void RF_SearchSOF(uint8_t *buf, uint16_t fromPos, uint16_t *len) { // uint16_t i; // // for(i = fromPos; i < *len && buf[i] != RF_FRAME_SOF; i++) // { // } // // *len -= i; // memmove(buf, buf + i, *len); } // 重新寻找HEADER void RF_SearchHeader(uint8_t *buf, uint16_t fromPos, uint16_t *len) { // uint16_t i; // // for(i = fromPos; i < *len && buf[i] != 'L'; i++) // { // } // // *len -= i; // memmove(buf, buf + i, *len); } // 模块任务主体:处理射频接收数据 void RF_ParseFrame(uint8_t c) { // static uint16_t RdIdx = 0; // static uint32_t outTick = 0; // uint8_t *RF_ModuleData = (uint8_t *) &RF_RecvFrame; // rf_ack_t ack; // rf_resp_t resp; // rf_charge_match_t match; // uint16_t i; // uint8_t frameOk, frameErr; // if(IsTickOut(outTick)) // RdIdx = 0; // outTick = GetDelayTick(50); // if(RdIdx == 0 && c != RF_FRAME_SOF) // return; // // RF_ModuleData[RdIdx++] = c; // do // { // frameErr = (RdIdx >= 2 && // (RF_ModuleData[1] < RF_MIN_FRAME_LEN || RF_ModuleData[1] > RF_MAX_FRAME_LEN)); // if(frameErr) // { // // 从1开始寻找SOF // RF_SearchSOF(RF_ModuleData, 1, &RdIdx); // } // frameOk = (RdIdx >= 2 && RF_ModuleData[1] >= RF_MIN_FRAME_LEN && RF_ModuleData[1] <= RF_MAX_FRAME_LEN // && RdIdx >= RF_ModuleData[1]); // if(frameOk) // { // if(rf_crc_16(RF_ModuleData, RF_ModuleData[1]) == 0) // { // if(rf_phy_valid(&RF_RecvFrame) && rf_mac_valid(&RF_RecvFrame, RF_DIR_DOWN)) // { // // 收到一帧 // printf("\nRF recv from Gateway (%d bytes):\n", RF_ModuleData[1]); // for(i = 0; i < RF_ModuleData[1]; i++) // printf(" %02X", RF_ModuleData[i]); // printf("\n"); // // // 判断帧类型 // if(RF_RecvFrame.mac_type == RF_MAC_TYPE_ACK) // { // // Ack确认帧 // memmove(ack.srcPSN, RF_RecvFrame.srcPSN, 6); // ack.mac_fn = RF_RecvFrame.mac_fn; // LoopBuff_PutItem(&RF_AckBuff, (uint8_t *) &ack); // // 发消息给任务 // RF_semAck = 1; // } // else if(RF_RecvFrame.net_type == RF_NET_TYPE_RESP_RELAY) // { // // 中继应答帧 // LoopBuff_PutItem(&RF_GatewayBuff, RF_RecvFrame.srcPSN); // // 发消息给任务 // RF_semGateway = 1; // } // else if(RF_RecvFrame.net_type == RF_NET_TYPE_DATA) // { // // 服务器应答帧 // memmove(resp.srcPSN, RF_RecvFrame.srcPSN, 6); // resp.app_pn = RF_RecvFrame.app_pn; // resp.payload_len = RF_RecvFrame.len - RF_MIN_FRAME_LEN; // memmove(resp.payload, RF_RecvFrame.app_payload, resp.payload_len); // LoopBuff_PutItem(&RF_RespBuff, (uint8_t *) &resp); // // 发消息给任务 // RF_semResp = 1; // } // else if(RF_RecvFrame.net_type == RF_NET_TYPE_CHARGE_MATCH) // { // if(!dcBuff.configDisplay.op_SEND_GPS_DATA) // { // // 储罐收到来自槽车的匹配帧 // memmove(&match, RF_RecvFrame.app_payload, sizeof(match)); // LoopBuff_PutItem(&RF_MatchBuff, (uint8_t *) &match); // // 发消息给任务 // RF_semMatch = 1; // } // } // } // else if(dcBuff.configDisplay.op_SEND_GPS_DATA // && rf_phy_valid(&RF_RecvFrame) && rf_mac_valid(&RF_RecvFrame, RF_DIR_UP)) // { // // 收到一帧 // printf("\nRF recv from remote (%d bytes):\n", RF_ModuleData[1]); // for(i = 0; i < RF_ModuleData[1]; i++) // printf(" %02X", RF_ModuleData[i]); // printf("\n"); // // // 判断帧类型 // if(RF_RecvFrame.net_type == RF_NET_TYPE_CHARGE_MATCH) // { // // 槽车收到来自储罐的匹配帧 // // // 判断是否匹配,如匹配则应答 // // memmove(&match, RF_RecvFrame.app_payload, sizeof(match)); // if(rf_is_charge_match(&match)) // { // if(!match.charging) // { // // 记录关泵的时间和GPS地址 //// Pump_Stop_Time = rf_get_seconds(); //// Pump_Stop_posState = dcBuff.dtuData.posState; //// Pump_Stop_Longitude = dcBuff.dtuData.longitude; //// Pump_Stop_Latitude = dcBuff.dtuData.latitude; // // 断开充液泵 //// KZ_PUMP_OFF(); // } // rf_net_send_resp_charge_match(RF_RecvFrame.srcPSN, match.charging); // } // } // else if(RF_RecvFrame.net_type == RF_NET_TYPE_REMOTE_CTRL) // { // // 槽车收到遥控器命令 // if(RF_RecvFrame.app_payload[0] == 3) // 配对 // { //// if(MeterInSamplePage()) // 标定页面:允许遥控配对 //// rf_net_send_resp_remote_ctrl(RF_RecvFrame.srcPSN, 3); // } // else if(RF_RecvFrame.app_payload[0] == 1 || RF_RecvFrame.app_payload[0] == 2) // 遥控泵 // { // if(memcmp(RF_RecvFrame.destPSN, dcBuff.configBottle.PSN, 6) == 0) // { //// if(RF_RecvFrame.app_payload[0] == 1) // 开泵 //// { //// KZ_VALUE_ENABLE(); //// rf_net_send_resp_remote_ctrl(RF_RecvFrame.srcPSN, 1); //// } //// else // 关泵 //// { //// KZ_VALUE_DISABLE(); //// rf_net_send_resp_remote_ctrl(RF_RecvFrame.srcPSN, 2); //// } // } // } // } // } // // // 继续寻找下一帧 // RdIdx -= RF_ModuleData[1]; // memmove(RF_ModuleData, RF_ModuleData + RF_ModuleData[1], RdIdx); // // 从0开始寻找SOF // RF_SearchSOF(RF_ModuleData, 0, &RdIdx); // } // else // { // // 从1开始寻找SOF // RF_SearchSOF(RF_ModuleData, 1, &RdIdx); // } // } // } while(frameOk || frameErr); } // 模块任务主体:处理射频接收数据 void RF_ParseLNGLora(uint8_t c) { // static uint16_t RdIdx = 0; // static uint32_t outTick = 0; // uint8_t *RF_ModuleData = (uint8_t *) &RF_LNG_LORA_Recv_Frame; // uint16_t i; // uint8_t frameOk, frameErr; // char psn[14]; // if(IsTickOut(outTick)) // RdIdx = 0; // outTick = GetDelayTick(50); // if(RdIdx == 0 && c != 'L') // return; // // RF_ModuleData[RdIdx++] = c; // do // { // frameErr = ((RdIdx >= 2 && RF_ModuleData[1] != 'N') // || (RdIdx >= 3 && RF_ModuleData[2] != 'G') // || (RdIdx >= 4 && RF_ModuleData[3] != 'C')); // if(frameErr) // { // // 从1开始寻找SOF // RF_SearchHeader(RF_ModuleData, 1, &RdIdx); // } // frameOk = (RdIdx >= sizeof(rf_lng_lora_t) && memcmp(RF_ModuleData, "LNGC", 4) == 0); // if(frameOk) // { // if(rf_crc_16(RF_ModuleData, sizeof(rf_lng_lora_t)) == 0) // { // // 收到一帧 // printf("\nRF recv from Gateway (%d bytes):\n", sizeof(rf_lng_lora_t)); // for(i = 0; i < sizeof(rf_lng_lora_t); i++) // printf(" %02X", RF_ModuleData[i]); // printf("\n"); // // sprintf(psn, "20%02d%02d%02d%02d%03d", // dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], // dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); // if(memcmp(RF_LNG_LORA_Recv_Frame.tank_psn, RF_LNG_LORA_EMPTYPSN, 13) == 0) // { // if(RF_LNG_LORA_State == 0) // RF_LNG_LORA_State = 1; // } // else if(memcmp(RF_LNG_LORA_Recv_Frame.tank_psn, psn, 13) == 0) // { // if(RF_LNG_LORA_Recv_Frame.send_mod == 0) // RF_LNG_LORA_State = 0; // else // RF_LNG_LORA_State = 2; // } // // 继续寻找下一帧 // RdIdx -= sizeof(rf_lng_lora_t); // memmove(RF_ModuleData, RF_ModuleData + sizeof(rf_lng_lora_t), RdIdx); // // 从0开始寻找SOF // RF_SearchHeader(RF_ModuleData, 0, &RdIdx); // } // else // { // // 从1开始寻找SOF // RF_SearchHeader(RF_ModuleData, 1, &RdIdx); // } // } // } while(frameOk || frameErr); } //void RF_IRQHandler(USART_Handle *huart) //{ // uint8_t c = (uint8_t) huart->Instance->RDR; // // //printf("RF rec:%02X ", c); // // 直接解析帧 // if(dcBuff.configDisplay.op_LNG_LORA) // RF_ParseLNGLora(c); // else // RF_ParseFrame(c); //} void RF_Uart_Open(u32 baudrate) { // LL_USART_InitTypeDef USART_InitStruct = {0}; // huart3.RxISR = RF_IRQHandler; // /* Peripheral clock enable */ // LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3); // /* USART3 interrupt Init */ // NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); // NVIC_EnableIRQ(USART3_IRQn); // USART_InitStruct.BaudRate = baudrate; // USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; // USART_InitStruct.StopBits = LL_USART_STOPBITS_1; // USART_InitStruct.Parity = LL_USART_PARITY_NONE; // USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; // USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; // USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; // LL_USART_Init(USART3, &USART_InitStruct); // LL_USART_ConfigAsyncMode(USART3); // SET_BIT(USART3->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); // LL_USART_Enable(USART3); } // 模块上电,设置硬件参数 void RF_PowerOn() { //// uint32_t stop_seconds; //// char last_c = 0, c; //// uint8_t cfg[6]; //// static uint8_t first = 1; // // uint16_t addr = rf_get_addr(RF_SelfPSN); // // 槽车版本,类似中继器的角色 // if(dcBuff.configDisplay.op_SEND_GPS_DATA) // addr = rf_get_addr((uint8_t *) RF_BROADCAST_PSN); // if(RF_hasPowered) // return; // // printf("\nRF power on ...\n"); //// VCC_RF_ON(); // delay_ms(500); // // 将串口更改为9600bps //// LL_USART_Disable(huart3.Instance); //// RF_Uart_Open(9600); //// NVIC_DisableIRQ(USART3_IRQn); //// while(!RF_READY()); // // 进入休眠模式:模式3 //// RF_MOD_MD1_1(); //// RF_MOD_MD0_1(); // delay_ms(50); // //// cfg[0] = 0xC2; // 设置的参数掉电不保存,每次上电都重新设置 //// cfg[1] = addr >> 8; //// cfg[2] = addr & 0xFF; //// if(dcBuff.configDisplay.op_LNG_LORA) //// cfg[3] = 2 | (7 << 3) | (3 << 6); // sf=8, 115200bps, cr=4/8 //////// else if(dcBuff.configDisplay.op_BOX_VER) //////// cfg[3] = 0x3C; // 泽耀模块:【00 111 100】: UART 8N1, 115200bps, 空中速率9.6k //// else //// cfg[3] = 6 | (7 << 3) | (0 << 6); // sf=12, 115200bps, cr=4/5 //// cfg[4] = RF_DOWN_CHANNEL; //// // LNG-LORA版本 //// if(dcBuff.configDisplay.op_LNG_LORA) //// cfg[4] = RF_LNG_LORA_CHANNEL; //// // 槽车版本,类似中继器的角色 //// else if(dcBuff.configDisplay.op_SEND_GPS_DATA) //// cfg[4] = RF_UP_CHANNEL; //// //// if(dcBuff.configDisplay.op_LNG_LORA) //// cfg[5] = 1 | (0 << 2) | (9 << 3) | (0 << 7); // freqcast=0, bw=500kHz, unicast=0 //////// else if(dcBuff.configDisplay.op_BOX_VER) //////// cfg[5] = 0xC0; // 泽耀模块:【1 1 000 0 00】:定点-ON,推挽输出,唤醒,FEC-OFF,20dbm(100mW) //// else //// cfg[5] = 1 | (1 << 2) | (9 << 3) | (0 << 7); // freqcast=1, bw=500kHz, unicast=0 //// //// printf("\nInitialize RF Module: %02X %02X %02X %02X %02X %02X\n", //// cfg[0], cfg[1], cfg[2], cfg[3], cfg[4], cfg[5]); // //// UART_Transmit(&huart3, cfg, 6); //// stop_seconds = rf_get_seconds() + 2; //// while(rf_get_seconds() < stop_seconds) //// { //// if(huart3.Instance->ISR & USART_ISR_RXNE) //// { //// c = huart3.Instance->RDR; //// printf("%c", c); //// if(last_c == 'O' && c == 'K') //// { //// // 设置状态:以第一次检测的结果为准 //// if(first) //// RF_initStatus = 1; //// break; //// } //// last_c = c; //// } //// } // //// first = 0; // // 进入工作模式:模式0 //// RF_MOD_MD1_0(); //// RF_MOD_MD0_0(); // delay_ms(50); //// while(!RF_READY()); // // 将串口更改为115200bps ////// LL_USART_Disable(huart3.Instance); //// RF_Uart_Open(115200ul); //// NVIC_EnableIRQ(USART3_IRQn); // // RF_hasPowered = 1; } void RF_PowerOff() { // if(!RF_hasPowered) // return; // // RF_hasPowered = 0; // printf("\nRF power off ...\n"); //// VCC_RF_OFF(); // delay_ms(200); } // 初始化 void RF_Init() { // LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; // // RF MD0, MD1 // LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); // GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; // GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; // GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; // GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; // GPIO_InitStruct.Pin = LL_GPIO_PIN_12|LL_GPIO_PIN_13; // LL_GPIO_Init(GPIOD, &GPIO_InitStruct); // LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); // /**USART3 GPIO Configuration // PD8 ------> USART3_TX // PD9 ------> USART3_RX // */ // GPIO_InitStruct.Pin = LL_GPIO_PIN_8|LL_GPIO_PIN_9; // GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; // GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM; // GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; // GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; // GPIO_InitStruct.Alternate = LL_GPIO_AF_7; // LL_GPIO_Init(GPIOD, &GPIO_InitStruct); } void RF_UnInit() { // LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; // // 反初始化串口 // LL_USART_DeInit(USART3); // // 恢复引脚 // GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; // GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; // LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); // GPIO_InitStruct.Pin = LL_GPIO_PIN_8|LL_GPIO_PIN_9|LL_GPIO_PIN_12|LL_GPIO_PIN_13; // LL_GPIO_Init(GPIOD, &GPIO_InitStruct); } void RF_Open() { // 用PSN的CRC校验值作为伪随机数的种子 srand(rf_crc_16(dcBuff.configBottle.PSN, 6)); RF_MAC_FN = rand() % 256; RF_APP_PN = rand() % 256; // 创建消息队列 LoopBuff_Create(&RF_GatewayBuff, 6, 4, 0, (uint32_t) RF_GatewayBuff_Data); LoopBuff_Create(&RF_AckBuff, sizeof(rf_ack_t), 2, 0, (uint32_t) RF_AckBuff_Data); LoopBuff_Create(&RF_RespBuff, sizeof(rf_resp_t), 2, 0, (uint32_t) RF_RespBuff_Data); LoopBuff_Create(&RF_MatchBuff, sizeof(rf_charge_match_t), 2, 0, (uint32_t) RF_MatchBuff_Data); RF_Uart_Open(9600); } void rf_pack_lng_lora_data() { // memset(&RF_LNG_LORA_Send_Frame, 0, sizeof(RF_LNG_LORA_Send_Frame)); // // // psn // sprintf(RF_LNG_LORA_Send_Frame.tank_psn, "20%02d%02d%02d%02d%03d", // dcBuff.configBottle.PSN[0], dcBuff.configBottle.PSN[1], dcBuff.configBottle.PSN[2], // dcBuff.configBottle.PSN[3], (dcBuff.configBottle.PSN[4] << 8) | dcBuff.configBottle.PSN[5]); // // send_mod // RF_LNG_LORA_Send_Frame.send_mod = (RF_LNG_LORA_State == 2 ? 0x5A : 0); // // status // if(dcBuff.sampleData.staDPress.notConnect) // RF_LNG_LORA_Send_Frame.level_conn = 1; // if(dcBuff.sampleData.staExtTempr[0].notConnect) // RF_LNG_LORA_Send_Frame.tempr_conn = 1; // if(dcBuff.sampleData.staPress.notConnect) // RF_LNG_LORA_Send_Frame.press_conn = 1; // if(dcBuff.sampleData.vacuum[0].staVacuum == VACUUM_STATUS_COMM_FAULT) // RF_LNG_LORA_Send_Frame.vacuu_conn = 1; // if(dcBuff.sampleData.staDPress.underFlow || dcBuff.sampleData.staDPress.overFlow) // RF_LNG_LORA_Send_Frame.level_fault = 1; // if(dcBuff.sampleData.staExtTempr[0].underFlow || dcBuff.sampleData.staExtTempr[0].overFlow) // RF_LNG_LORA_Send_Frame.tempr_fault = 1; // if(dcBuff.sampleData.staPress.underFlow || dcBuff.sampleData.staPress.overFlow) // RF_LNG_LORA_Send_Frame.press_fault = 1; // if(dcBuff.sampleData.vacuum[0].staVacuum != VACUUM_STATUS_COMM_FAULT && (dcBuff.sampleData.vacuum[0].vacuum <= 0.00999999 || dcBuff.sampleData.vacuum[0].vacuum > 99.99999999)) // RF_LNG_LORA_Send_Frame.vacuu_fault = 1; // // liquid_level、volume、volumePct // if(RF_LNG_LORA_Send_Frame.level_conn || RF_LNG_LORA_Send_Frame.level_fault) // { // RF_LNG_LORA_Send_Frame.liquid_level = 0; // RF_LNG_LORA_Send_Frame.volume = 0; // RF_LNG_LORA_Send_Frame.volumePct = 0; // } // else // { //// RF_LNG_LORA_Send_Frame.liquid_level = KPa2mmH2O(dcBuff.sampleData.diff); // RF_LNG_LORA_Send_Frame.volume = dcBuff.sampleData.volume; // RF_LNG_LORA_Send_Frame.volumePct = dcBuff.sampleData.volumePct; // } // // temperature // if(RF_LNG_LORA_Send_Frame.tempr_conn || RF_LNG_LORA_Send_Frame.tempr_fault) // RF_LNG_LORA_Send_Frame.temp = 0; // else // RF_LNG_LORA_Send_Frame.temp = dcBuff.sampleData.extTempr[0]; // // press // if(RF_LNG_LORA_Send_Frame.press_conn || RF_LNG_LORA_Send_Frame.press_fault) // RF_LNG_LORA_Send_Frame.pressure = 0; // else // RF_LNG_LORA_Send_Frame.pressure = dcBuff.sampleData.pressure * 0.001; // // vacuum // if(RF_LNG_LORA_Send_Frame.vacuu_conn || RF_LNG_LORA_Send_Frame.vacuu_fault) // RF_LNG_LORA_Send_Frame.vacuum = 0; // else // RF_LNG_LORA_Send_Frame.vacuum = dcBuff.sampleData.vacuum[0].vacuum; } void LNG_LORA_Task(void *p_arg) { // uint32_t seconds = 0; // uint32_t sendSeconds = 0; // uint8_t last_state = 0; // uint32_t resetSeconds = rf_get_seconds() + 300; // while(1) // { // osDelay(500); // // 获取当前时间 // seconds = rf_get_seconds(); // // if(RF_LNG_LORA_State == 1) // { // // 只应答一次 // RF_LNG_LORA_State = 0; // // 随机延时14秒以内(升级发送的时候还要随机延时0.8~1s,总共在15秒以内) // osDelay((rand() % 29) * (250 + rand() % 251)); // rf_pack_lng_lora_data(); // // //rf_uart_send(&RF_Send_Frame); // rf_uart_send_lng_lora(&RF_LNG_LORA_Send_Frame); // } // else if(RF_LNG_LORA_State == 2) // { // if(RF_LNG_LORA_State != last_state) // sendSeconds = seconds; // if(seconds >= sendSeconds) // { // // 下次发送的时间 // sendSeconds = seconds + 5; // // rf_pack_lng_lora_data(); // rf_uart_send_lng_lora(&RF_LNG_LORA_Send_Frame); // } // } // else // 如果LORA处于不发送状态,且持续5分钟,则重启LORA模块 // { // if(RF_LNG_LORA_State != last_state) // resetSeconds = seconds + 300; // if(seconds >= resetSeconds) // { // // 下次重启的时间 // resetSeconds = seconds + 300; // // RF_PowerOff(); // RF_PowerOn(); // } // } // // last_state = RF_LNG_LORA_State; // } }