747 lines
18 KiB
C
747 lines
18 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* 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_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};
|
||
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串口接收的消息通知
|
||
volatile uint8_t RF_semAck = 0;
|
||
volatile uint8_t RF_semGateway = 0;
|
||
volatile uint8_t RF_semResp = 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};
|
||
|
||
#define RF_MOD_MD0 (PA13)
|
||
#define RF_MOD_MD1 (PA12)
|
||
#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);
|
||
}
|
||
|
||
// 设置网关
|
||
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 - 2] = crc >> 8;
|
||
((uint8_t *) frame)[frame->len - 1] = crc & 0xFF;
|
||
|
||
// 计算目的地址
|
||
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;
|
||
|
||
// while(!RF_READY());
|
||
|
||
// 随机延时
|
||
delay_ms((rand() % 10) * (70 + rand() % 20));
|
||
|
||
printf("\nRF send to Gateway (%02X %02X %02X, %d bytes):\n",
|
||
phy_header[0], phy_header[1], phy_header[2], frame->len);
|
||
for(i = 0; i < frame->len; i++)
|
||
printf(" %02X", ((uint8_t *) frame)[i]);
|
||
printf("\n");
|
||
|
||
// 因为射频模块接收数据不能中断超过3个字节的时间,故不允许打断。
|
||
__disable_irq();
|
||
SCUART_Write(SC2, phy_header, 3);
|
||
SCUART_Write(SC2, (uint8_t *) frame, frame->len);
|
||
__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)
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
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_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层发送
|
||
if(rf_net_send_data(&RF_Send_Frame, RF_DIR_UP, RF_GatewayPSN) == 0)
|
||
return 0;
|
||
|
||
// 等待服务器返回:15秒
|
||
stop_seconds = rf_get_seconds() + 15;
|
||
while(rf_get_seconds() < stop_seconds)
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
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个网关
|
||
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();
|
||
// 4秒内没有收到网关回应,则停止等待
|
||
stop_seconds = rf_get_seconds() + 4;
|
||
while(rf_get_seconds() <= stop_seconds)
|
||
{
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
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();
|
||
return 0;
|
||
}
|
||
|
||
rf_set_gateway(PSN_List[k]);
|
||
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;
|
||
}
|
||
|
||
// 模块上电,设置硬件参数
|
||
void RF_PowerOn()
|
||
{
|
||
uint32_t stop_seconds;
|
||
char last_c = 0, c;
|
||
uint8_t cfg[6];
|
||
uint16_t addr = rf_get_addr(RF_SelfPSN);
|
||
|
||
if(RF_hasPowered)
|
||
return;
|
||
|
||
printf("\nRF power on ...\n");
|
||
// 将串口更改为9600bps
|
||
SCUART_Open(SC2, 9600);
|
||
NVIC_DisableIRQ(SC2_IRQn);
|
||
|
||
VCC_RF_ON();
|
||
delay_ms(500);
|
||
|
||
// while(!RF_READY());
|
||
|
||
RF_initStatus = 0;
|
||
|
||
// 进入休眠模式:模式3
|
||
RF_MOD_MD1 = 1;
|
||
RF_MOD_MD0 = 1;
|
||
delay_ms(50);
|
||
|
||
cfg[0] = 0xC2; // 设置的参数掉电不保存,每次上电都重新设置
|
||
cfg[1] = addr >> 8;
|
||
cfg[2] = addr & 0xFF;
|
||
cfg[3] = 0x3C; // 【00 111 100】: UART 8N1, 115200bps, 空中速率9.6k
|
||
cfg[4] = RF_DOWN_CHANNEL;
|
||
cfg[5] = 0xC0; // 【1 1 000 0 00】:定点-ON,推挽输出,唤醒,FEC-OFF,20dbm(100mW)
|
||
|
||
printf("\nInitialize RF Module: %02X %02X %02X %02X %02X %02X\n",
|
||
cfg[0], cfg[1], cfg[2], cfg[3], cfg[4], cfg[5]);
|
||
|
||
// 喂狗
|
||
if(!Wakeup_Sleeping)
|
||
WDT_RESET_COUNTER();
|
||
|
||
SCUART_Write(SC2, cfg, 6);
|
||
stop_seconds = rf_get_seconds() + 2;
|
||
while(rf_get_seconds() < stop_seconds)
|
||
{
|
||
if(SCUART_IS_RX_READY(SC2))
|
||
{
|
||
c = SC2->RBR;
|
||
printf("%c", c);
|
||
if(last_c == 'O' && c == 'K')
|
||
{
|
||
// 设置状态
|
||
RF_initStatus = 1;
|
||
break;
|
||
}
|
||
last_c = c;
|
||
}
|
||
}
|
||
|
||
// 进入工作模式:模式0
|
||
RF_MOD_MD1 = 0;
|
||
RF_MOD_MD0 = 0;
|
||
delay_ms(50);
|
||
|
||
// while(!RF_READY());
|
||
|
||
// 将串口更改为115200bps
|
||
SCUART_Open(SC2, 115200ul);
|
||
NVIC_EnableIRQ(SC2_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);
|
||
}
|
||
|
||
// 重新寻找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);
|
||
}
|
||
|
||
// 模块任务主体:处理射频接收数据
|
||
void RF_ParseFrame(uint8_t c)
|
||
{
|
||
static uint16_t RdIdx = 0;
|
||
uint8_t *RF_ModuleData = (uint8_t *) &RF_RecvFrame;
|
||
rf_ack_t ack;
|
||
rf_resp_t resp;
|
||
uint16_t i;
|
||
uint8_t frameOk, frameErr;
|
||
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 继续寻找下一帧
|
||
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 SC2_IRQHandler(void)
|
||
{
|
||
uint8_t c;
|
||
|
||
if(SCUART_GET_INT_FLAG(SC2, SC_ISR_RDA_IS_Msk) || SCUART_GET_INT_FLAG(SC2, SC_ISR_RTMR_IS_Msk)) /* Rx Ready or Time-out INT*/
|
||
{
|
||
SCUART_CLR_INT_FLAG(SC2, SC_ISR_RDA_IS_Msk | SC_ISR_RTMR_IS_Msk);
|
||
// do
|
||
{
|
||
c = SC2->RBR;
|
||
// printf("%02X ", c);
|
||
// 直接解析帧
|
||
RF_ParseFrame(c);
|
||
} //while(SCUART_IS_RX_READY(SC2));
|
||
}
|
||
if(SCUART_GET_INT_FLAG(SC2, SC_ISR_TERR_IS_Msk))
|
||
{
|
||
SCUART_CLR_INT_FLAG(SC2, SC_ISR_TERR_IS_Msk);
|
||
}
|
||
}
|
||
|
||
// 初始化
|
||
void RF_Init()
|
||
{
|
||
// RF MD0, MD1
|
||
SYS->PA_H_MFP &= ~(SYS_PA_H_MFP_PA13_MFP_Msk | SYS_PA_H_MFP_PA12_MFP_Msk);
|
||
SYS->PA_H_MFP |= (SYS_PA_H_MFP_PA13_MFP_GPA13 | SYS_PA_H_MFP_PA12_MFP_GPA12);
|
||
GPIO_SetMode(PA, 1 << 13, GPIO_PMD_OUTPUT);
|
||
GPIO_SetMode(PA, 1 << 12, GPIO_PMD_OUTPUT);
|
||
|
||
/* Select SC UART module clock source as HXT and UART module clock divider as 1 */
|
||
CLK_SetModuleClock(SC2_MODULE, CLK_CLKSEL2_SC_S_HXT, CLK_SC2_CLK_DIVIDER(1));
|
||
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
/* Init I/O Multi-function */
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
|
||
/* Set PB.10 and PB.11 pin for SC UART mode */
|
||
SYS->PB_H_MFP &= ~(SYS_PB_H_MFP_PB10_MFP_Msk | SYS_PB_H_MFP_PB11_MFP_Msk);
|
||
SYS->PB_H_MFP |= (SYS_PB_H_MFP_PB10_MFP_SC2_CLK | SYS_PB_H_MFP_PB11_MFP_SC2_DAT);
|
||
|
||
/* Enable SC UART module clock */
|
||
CLK_EnableModuleClock(SC2_MODULE);
|
||
}
|
||
|
||
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);
|
||
|
||
// 创建信号量
|
||
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
/* Init UART */
|
||
/*---------------------------------------------------------------------------------------------------------*/
|
||
/* Reset SC2 module */
|
||
// SYS_ResetModule(SC2_RST);
|
||
|
||
/* Configure SC2 and set SC2 Baudrate */
|
||
SCUART_Open(SC2, 9600);
|
||
|
||
/* Enable RDA\RLS\Time-out Interrupt */
|
||
SCUART_ENABLE_INT(SC2, (SC_IER_RDA_IE_Msk)); // | SC_IER_RTMR_IE_Msk));// | SC_IER_TERR_IE_Msk));
|
||
/* Enable SC1 interrupt */
|
||
NVIC_SetPriority(SC2_IRQn, 1);
|
||
NVIC_EnableIRQ(SC2_IRQn);
|
||
}
|