/* ********************************************************************************************************* * IAR Development Kits * on the * * Nano100 * * Filename : uart_BDModule.h * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #include "includes.h" const uint8_t BD_APP = RF_APP_AJH; const uint8_t BD_PROTOCOL_VER = RF_PROTOCOL_VER_2; loopbuff_t CC200A_TaskM; uint8_t CC200A_TaskM_Data[sizeof(uint8_t) * (4 + 1)] = {0}; #define RF_SelfPSN (dcBuff.configBottle.PSN) uint8_t BD_RF_MAC_FN = 0; uint8_t BD_RF_APP_PN = 0; uint8_t BD_RF_APP_IDX = 0; // 发送、接收帧 bd_frame_t BD_Send_Frame, BD_RecvFrame; // 接收自检信息和反馈信息 volatile uint8_t BD_semZjxx = 0, BD_semFkxx = 0; bd_zjxx_t BD_Zjxx; bd_fkxx_t BD_Fkxx; // 北斗初始化状态 uint8_t BD_initStatus = 0; volatile uint8_t BD_hasPowered = 0; // 计算校验和(异或) uint8_t bd_cs_nor(uint8_t *message, int16_t len) { int16_t i; uint8_t cs = 0; for(i = 0; i < len; i++) cs ^= message[i]; return cs; } // 初始化帧 void bd_initial_frame(bd_frame_t *frame, char *cmd) { memset((uint8_t *) frame, 0, sizeof(bd_frame_t)); frame->sof = BD_FRAME_SOF; memmove(frame->cmd, cmd, 4); frame->len = BD_MIN_FRAME_LEN; // 小端模式,发送时再转换成大端模式 } // 追加负载数据 uint8_t bd_append_payload(bd_frame_t *frame, uint8_t payload_len, uint8_t *payload) { if(frame->len < BD_MIN_FRAME_LEN || frame->len + payload_len > BD_MAX_FRAME_LEN) return 0; if(payload_len > 0) memmove(frame->bd_payload + (frame->len - BD_MIN_FRAME_LEN), payload, payload_len); frame->len += payload_len; return 1; } void bd_prepare_send(bd_frame_t *frame) { uint8_t *buf = (uint8_t *) frame; uint16_t len = frame->len; frame->len = htons(len); // 转换成大端模式 buf[len - 1] = bd_cs_nor(buf, len - 1); // 填写校验码 } // 北斗物理层校验 uint8_t bd_phy_valid(bd_frame_t *frame) { // 通信信息帧 if(strncmp(frame->cmd, BD_TXXX, 4) == 0) { // 通信01、代码1、不回执0、通信0、无密钥0、保留00 if(frame->txxx.xxlb != 0x60 || ntohs(frame->txxx.bitLen) > 624) return 0; } // 北斗帧校验成功 return 1; } // 物理层校验 uint8_t bd_rf_phy_valid(bd_rf_frame_t *frame) { if(frame->sof != RF_FRAME_SOF || frame->len < BD_RF_MIN_FRAME_LEN || frame->len > BD_RF_MAX_FRAME_LEN) return 0; if(frame->vendor_id != RF_MARK_LS || frame->app_id != BD_APP || frame->protocol_ver != BD_PROTOCOL_VER) return 0; if(rf_crc_16((uint8_t *) frame, frame->len) != 0) return 0; // 物理层校验成功 return 1; } // mac层校验 uint8_t bd_rf_mac_valid(bd_rf_frame_t *frame, uint8_t dir) { if(frame->dir != dir) return 0; // mac层校验成功 return 1; } // 重新寻找SOF void BD_SearchSOF(uint8_t *buf, uint16_t fromPos, uint16_t *len) { uint16_t i; for(i = fromPos; i < *len && buf[i] != BD_FRAME_SOF; i++) { } *len -= i; memmove(buf, buf + i, *len); } // 分析串口数据,组帧 char CC200A_recvBuff[100] = {0}; // 扩展内存 uint16_t CC200A_Idx = 0; void CC200A_ParseFrame(uint8_t c) { if((CC200A_Idx==0)&&(c!='\n')) return; if(CC200A_Idx < 100) CC200A_recvBuff[CC200A_Idx++] = c; // 换行符 if((c == '\n')&&(CC200A_Idx>2)) { // 丢掉\n前面的\r if(CC200A_Idx > 0 && CC200A_recvBuff[CC200A_Idx - 1] == '\r') CC200A_recvBuff[--CC200A_Idx] = 0; // 先检查字符串(电话号码没有特征字符串) if(strstr(CC200A_recvBuff, "RDY")) { //DTU_recvBuff[idx] = 0; printf("CC200A RDY"); } // 检查返回错误的字符串 if(strstr(CC200A_recvBuff,"ERROR")) { printf("CC200A ERROR"); } // 没有所要的字符串,清空 memset(CC200A_recvBuff, 0, DTU_RECVBUFF_SIZE); CC200A_Idx = 0; } } // 等待DTU命令的返回,检查期待的结果字符串 uint32_t CC200A_ParseResult(char *checkPattern, char *checkErrPattern, char *resultBuff, uint16_t waitSeconds) { uint8_t done = 0, timeOut; uint32_t timeOutTick; uint8_t u8DTU; uint16_t count, idx = 0; uint32_t ret = FALSE; uint8_t strLen = strlen(checkPattern); uint8_t errLen = strlen(checkErrPattern); memset(DTU_recvBuff, 0, DTU_RECVBUFF_SIZE); // 检测返回信息 do { timeOut = 1; timeOutTick = GetDelayTick(waitSeconds * 1000); while(!IsTickOut(timeOutTick)) { if(LoopBuff_GetCount(&CC200A_TaskM)) { timeOut = 0; break; } } if(!timeOut) { count = LoopBuff_GetCount(&DTU_TaskM); while(count--) { // 取数据 memmove(&u8DTU, LoopBuff_GetDataPtr(&DTU_TaskM, DTU_TaskM.info.rdPtr), 1); LoopBuff_RemoveItems(&DTU_TaskM, 1); // if(u8DTU == '\n') // printf("\\n"); // else if(u8DTU == '\r') // printf("\\r"); // else // printf("%c", u8DTU); // 如果是检测发送的提示符(>),直接返回成功 if(strcmp(checkPattern, ">") == 0 && u8DTU == '>') { strcpy(resultBuff, ">"); ret = TRUE; done = 1; break; } // 换行符 if(u8DTU == '\n') { // 丢掉\n前面的\r if(idx > 0 && DTU_recvBuff[idx - 1] == '\r') DTU_recvBuff[--idx] = 0; // 先检查字符串(电话号码没有特征字符串) if((strLen > 0 && strstr(DTU_recvBuff, checkPattern)) || (strLen == 0 && idx > 0)) { DTU_recvBuff[idx] = 0; strcpy(resultBuff, DTU_recvBuff); ret = TRUE; done = 1; break; } // 检查返回错误的字符串 if(errLen > 0 && strstr(DTU_recvBuff, checkErrPattern)) { DTU_recvBuff[idx] = 0; strcpy(resultBuff, DTU_recvBuff); ret = FALSE; done = 1; break; } // 没有所要的字符串,清空 memset(DTU_recvBuff, 0, DTU_RECVBUFF_SIZE); idx = 0; continue; } if(idx < DTU_RECVBUFF_SIZE) DTU_recvBuff[idx++] = u8DTU; } } } while(!done && !timeOut); return ret; } // 自检 uint8_t BD_Xtzj() { // uint8_t try_cnt; // uint32_t stop_seconds; // bd_initial_frame(&BD_Send_Frame, BD_XTZJ); // bd_append_payload(&BD_Send_Frame, sizeof(bd_xtzj_t), BD_Send_Frame.bd_payload); // bd_prepare_send(&BD_Send_Frame); // for(try_cnt = 0; try_cnt < 1; try_cnt++) // { // // 清除返回标志 // BD_semZjxx = 0; // // 发送命令 // UART_Transmit(&huart1, (uint8_t *) &BD_Send_Frame, ntohs(BD_Send_Frame.len)); // // 等待返回数据 // stop_seconds = rf_get_seconds() + 2; // while(rf_get_seconds() < stop_seconds) // { // if(BD_semZjxx) // { // printf("\nBD Module self check returned.\n"); // if(BD_Zjxx.antennaErr) // printf("\nThe antenna has error!\n"); // if(BD_Zjxx.boardErr) // printf("\nThe board has error!\n"); // if(BD_Zjxx.cardErr) // printf("\nThe card has error!\n"); // if(BD_Zjxx.channelErr) // printf("\nThe channel has error!\n"); // if(BD_Zjxx.snErr) // printf("\nThe serial no has error!\n"); // if(BD_Zjxx.dataErr) // printf("\nThe data has error!\n"); // if(BD_Zjxx.chkErr) // printf("\nThe check has error!\n"); // if(BD_Zjxx.idErr) // printf("\nThe id has error!\n"); // if(BD_Zjxx.phyErr) // printf("\nThe physical has error!\n"); // if(!BD_Zjxx.antennaErr && !BD_Zjxx.boardErr && !BD_Zjxx.cardErr && !BD_Zjxx.channelErr // && !BD_Zjxx.snErr && !BD_Zjxx.dataErr && !BD_Zjxx.chkErr && !BD_Zjxx.idErr && !BD_Zjxx.phyErr) // { // return 1; // } // break; // } // delay_ms(200); // } // delay_ms(500); // } // return 0; } void CC200A_IRQHandler(USART_Handle *huart) { // uint8_t c = (uint8_t) huart->Instance->RDR; // printf("%c", c); // // 直接处理,分析并组帧 // CC200A_ParseFrame(c); uint8_t u8DTU = (uint8_t) huart->Instance->RDR; //if(DTU_uartPrint) { if(u8DTU == '\n') printf("\\n\n"); else if(u8DTU == '\r') printf("\\r"); else printf("%c", u8DTU); } // 加入缓冲 // // LoopBuff_PutItem(&CC200A_TaskM, &u8DTU); if(u8DTU == 'Y') printf("%c", u8DTU); } // 初始化 void CC200A_Init() { LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); /**USART3 GPIO Configuration PB6 ------> USART1_TX PB7 ------> USART1_RX */ GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7; 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(GPIOB, &GPIO_InitStruct); } void CC200A_Open() { LL_USART_InitTypeDef USART_InitStruct = {0}; // 用PSN的CRC校验值作为伪随机数的种子 //srand(rf_crc_16(dcBuff.configBottle.PSN, 6)); // BD_RF_MAC_FN = rand() % 256; // BD_RF_APP_PN = rand() % 256; // 分配循环缓冲 LoopBuff_Create(&CC200A_TaskM, sizeof(uint8_t), 4, 0, (uint32_t) CC200A_TaskM_Data); //LL_USART_Disable(huart1.Instance); huart1.RxISR = CC200A_IRQHandler; // /* Peripheral clock enable */ // LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); // /* USART3 interrupt Init */ // NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0)); // NVIC_EnableIRQ(USART1_IRQn); // USART_InitStruct.BaudRate = 115200; // 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(USART1, &USART_InitStruct); // LL_USART_ConfigAsyncMode(USART1); // SET_BIT(USART1->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); // LL_USART_Enable(USART1); } // 初始化帧 void bd_rf_initial_frame(bd_rf_frame_t *frame) { memset((uint8_t *) frame, 0, sizeof(bd_rf_frame_t)); frame->len = BD_RF_MIN_FRAME_LEN; } // 追加负载数据 uint8_t bd_rf_append_payload(bd_rf_frame_t *frame, uint8_t payload_len, uint8_t *payload) { if(frame->len < BD_RF_MIN_FRAME_LEN || frame->len + payload_len > BD_RF_MAX_FRAME_LEN) return 0; if(payload_len > 0) memmove(frame->app_payload + (frame->len - BD_RF_MIN_FRAME_LEN), payload, payload_len); frame->len += payload_len; return 1; } // 模块上电,设置硬件参数 void CC200A_PowerOn() { uint8_t i, count = 0; char buff[40]; static uint8_t first = 1; if(BD_hasPowered) return; printf("\nCC200A power on ...\n"); VCC_CC200A_ON(); VCC_CC200A_BCK_ON(); //delay_ms(2700); if(CC200A_ParseResult("RDY", "", buff, 60)) { printf("r RDY"); } // if(DTU_ParseResult("+QURC: 5", "", buff, 30)) // { // printf("r +QURC: 5"); // } // if(DTU_ParseResult("+QURC: 0", "", buff, 30)) // { // printf("r +QURC: 0"); // } // if(DTU_ParseResult("+QURC: 3", "", buff, 30)) // { // printf("r +QURC: 3"); // } } void CC200A_PowerOff() { // if(!BD_hasPowered) // return; BD_hasPowered = 0; printf("\nCC200A_PowerOff ...\n"); VCC_CC200A_OFF(); VCC_CC200A_BCK_OFF(); delay_ms(200); } // 串口超时定时器 extern uint16_t DTU_tmrQPendLong; // 120s //extern uint16_t DTU_tmrQPendShort; // 5s extern uint16_t DTU_tmrQPendSpec; // 40s // 应用层发送:数据 uint8_t CC200A_rf_app_send_data(uint8_t payload_len, uint8_t *payload) { // uint16_t i; char cmd[80], buff[40]; //AT+QSMGT="TEST7",1,128,1,1,"TEST003" sprintf(cmd, "AT+QSMGT=1,128,1,1,\"%s\"",payload); if(!DTU_ExecuteCmd(cmd, "+QURC: 2", "ERROR", buff, DTU_tmrQPendSpec)) { printf("\nsend err ...\n"); } // break; // if(strstr(buff, "+QIOPEN: 0,0")) // { // ret = TRUE; // break; // } // uint8_t try_cnt; // uint32_t stop_seconds; // uint16_t crc; // bd_rf_frame_t *rf = (bd_rf_frame_t *) BD_Send_Frame.txsq.bytes; // S_RTC_TIME_DATA_T sRTC; // // 初始化BD帧 // bd_initial_frame(&BD_Send_Frame, BD_TXSQ); // // 初始化RF帧 // bd_rf_initial_frame(rf); // // 应用层 // bd_rf_append_payload(rf, payload_len, payload); // rf->app_pn = BD_RF_APP_PN; // rf->app_idx = 0; // 暂不实现分包组包 // rf->app_tbc = 0; // // net层 // rf->net_type = RF_NET_TYPE_DATA; // // mac层 // rf->dir = RF_DIR_UP; // rf->mac_type = RF_MAC_TYPE_DATA; // rf->mac_ack_req = 0; // rf->mac_fn = BD_RF_MAC_FN; // // 物理层 // rf->sof = RF_FRAME_SOF; // rf->vendor_id = RF_MARK_LS; // rf->app_id = BD_APP; // rf->protocol_ver = BD_PROTOCOL_VER; // memmove(rf->srcPSN, RF_SelfPSN, 6); // crc = rf_crc_16((uint8_t *) rf, rf->len - 2); // ((uint8_t *) rf)[rf->len - 2] = crc >> 8; // ((uint8_t *) rf)[rf->len - 1] = crc & 0xFF; // // 通讯申请 // BD_Send_Frame.txsq.xxlb = 0x46; // 普通报文代码 // BD_Send_Frame.txsq.dstAddr[0] = (dcBuff.configDisplay.bdCommander >> 16) & 0xFF; // 指挥机卡号 // BD_Send_Frame.txsq.dstAddr[1] = (dcBuff.configDisplay.bdCommander >> 8) & 0xFF; // BD_Send_Frame.txsq.dstAddr[2] = (dcBuff.configDisplay.bdCommander & 0xFF); // BD_Send_Frame.txsq.bitLen = htons(rf->len * 8); // // 追加通讯申请内容 // bd_append_payload(&BD_Send_Frame, // sizeof(BD_Send_Frame.txsq) - sizeof(BD_Send_Frame.txsq.bytes) + payload_len + BD_RF_MIN_FRAME_LEN, // (uint8_t *) &BD_Send_Frame.txsq); // // 修改数据格式,计算cs // bd_prepare_send(&BD_Send_Frame); // for(try_cnt = 0; try_cnt < 3; try_cnt++) // { // // 清除返回标志 // BD_semFkxx = 0; // // 发送命令 // UART_Transmit(&huart1, (uint8_t *) &BD_Send_Frame, ntohs(BD_Send_Frame.len)); //// for(i = 0; i < ntohs(BD_Send_Frame.len); i++) //// printf("%02X ", ((uint8_t *) &BD_Send_Frame)[i]); //// printf("\n"); // // 等待返回数据s // stop_seconds = rf_get_seconds() + 2; // while(rf_get_seconds() < stop_seconds) // { // if(BD_semFkxx) // { // printf("\nBD Module feedback returned.\n"); // if(BD_Fkxx.fkbz == 0 && strncmp(BD_Fkxx.fjxx, BD_TXSQ, 4) == 0) // { // printf("\nThe message has send.\n"); // BD_RF_MAC_FN++; // BD_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; // } // printf("\nThe message has not send.\n"); // break; // } // delay_ms(200); // } // delay_ms(500); // } return 0; }