287 lines
5.7 KiB
C
287 lines
5.7 KiB
C
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <rtthread.h>
|
|
|
|
#include "chrg_gpio.h"
|
|
#include "chrg_thread.h"
|
|
#include "chrg_north_pkg.h"
|
|
#include "chrg_north.h"
|
|
#include "chrg_roll_nor.h"
|
|
#include "chrg_switch.h"
|
|
#include "chrg_utils.h"
|
|
|
|
#define LOG_TAG "chrg.nor"
|
|
#define DBG_LEVEL DBG_LOG
|
|
#include <rtdbg.h>
|
|
|
|
|
|
struct chrg_north_t chrgnorth = {
|
|
.devname = DEV_NAME_NORTH,
|
|
.tty = RT_NULL,
|
|
.enable = {1, 1, 1, 1},
|
|
.sw[IDX_NOR_CH1] = {
|
|
.id = ID_SINK,
|
|
},
|
|
.sw[IDX_NOR_CH2] = {
|
|
.id = ID_SINK,
|
|
},
|
|
.sw[IDX_NOR_CH3] = {
|
|
.id = ID_SINK,
|
|
},
|
|
.sw[IDX_NOR_CH4] = {
|
|
.id = ID_SINK,
|
|
},
|
|
.manual = 0,
|
|
};
|
|
|
|
// 北向通道选择
|
|
int chrg_north_switch (eIDX_NOR_CH ch)
|
|
{
|
|
if (ch >= TOTAL_NOR_CHS) {
|
|
return -1;
|
|
}
|
|
|
|
return chrg_switch_ch(chrgios[IDX_GPO_NOR_SW_A].base,
|
|
chrgios[IDX_GPO_NOR_SW_B].base, (eIDX_CH)ch);
|
|
}
|
|
|
|
int chrg_north_send (rt_uint8_t *data, rt_size_t length)
|
|
{
|
|
rt_ssize_t ret = -1;
|
|
struct chrg_tty_t *pTTY = chrgnorth.tty;
|
|
|
|
if (RT_NULL != pTTY) {
|
|
ret = chrg_tty_send(pTTY, data, length);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// 提取3字节帧头
|
|
static int chrg_north_frame_head (struct rt_ringbuffer *rb, rt_uint8_t *head, eIDX_ID id)
|
|
{
|
|
int i = 0;
|
|
rt_uint8_t data = 0, stage = 0;
|
|
rt_size_t ret = 0;
|
|
rt_size_t len_rb = 0; // ring数据长度
|
|
rt_uint8_t len_frame = 0; // 帧长度
|
|
|
|
if (RT_NULL == rb) {
|
|
return -1;
|
|
}
|
|
|
|
len_rb = rt_ringbuffer_data_len(rb);
|
|
if (len_rb < LEN_FRAME_HEAD + 2) { // 最短5字节
|
|
return -1;
|
|
}
|
|
|
|
for (i = 0; i < len_rb - 2; i++) { // 找头三个字节 [帧长, 0x00, id]
|
|
ret = rt_ringbuffer_getchar(rb, &data);
|
|
if (0 == ret) {
|
|
continue;
|
|
}
|
|
|
|
switch (stage) {
|
|
case 0:
|
|
head[0] = data;
|
|
len_frame = data;
|
|
if (data < MIN_FRAME_LENGTH) { // 长度不符
|
|
stage = 0;
|
|
continue;
|
|
}
|
|
|
|
stage = 1;
|
|
break;
|
|
|
|
case 1:
|
|
head[1] = data;
|
|
if (0x00 != data) {
|
|
stage = 0;
|
|
} else {
|
|
stage = 2;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
head[2] = data;
|
|
if ((rt_uint8_t)id != data) {
|
|
stage = 0;
|
|
} else {
|
|
return len_frame;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int chrg_north_pickup_frame (struct rt_ringbuffer *rb,
|
|
struct pickup_info_t *pFrame, eIDX_NOR_CH idx)
|
|
{
|
|
int cnt = 0;
|
|
rt_size_t len_rb = 0;
|
|
|
|
if ((RT_NULL == rb)||(RT_NULL == pFrame)) {
|
|
return -1;
|
|
}
|
|
|
|
struct chrg_switch_t *pSW = &chrgnorth.sw[idx];
|
|
|
|
do {
|
|
if (0 == pFrame->findhead) {
|
|
pFrame->len_msg = chrg_north_frame_head(rb, pFrame->head, pSW->id);
|
|
if (pFrame->len_msg > 0) {
|
|
pFrame->pMB = (struct mb_msg_t *)rt_malloc(sizeof(struct mb_msg_t));
|
|
if (RT_NULL == pFrame->pMB) {
|
|
LOG_E("malloc mb failed.");
|
|
return -2;
|
|
}
|
|
|
|
pFrame->pMB->length = pFrame->len_msg;
|
|
if (pFrame->pMB->length >= SIZE_BUF_TTY) {
|
|
rt_free(pFrame->pMB);
|
|
pFrame->pMB = RT_NULL;
|
|
LOG_E("too long msg.");
|
|
return -3;
|
|
}
|
|
|
|
pFrame->pMB->payload = (rt_uint8_t *)rt_malloc(pFrame->len_msg);
|
|
if (RT_NULL == pFrame->pMB->payload) {
|
|
LOG_E("malloc buf failed.");
|
|
return -4;
|
|
}
|
|
|
|
rt_memcpy(pFrame->pMB->payload, pFrame->head, LEN_FRAME_HEAD);
|
|
|
|
len_rb = rt_ringbuffer_data_len(rb);
|
|
if (len_rb >= pFrame->len_msg - LEN_FRAME_HEAD) {
|
|
rt_ringbuffer_get(rb, &pFrame->pMB->payload[LEN_FRAME_HEAD],
|
|
pFrame->len_msg - LEN_FRAME_HEAD);
|
|
|
|
chrg_thread_mb_send(IDX_THR_NORTH, pFrame->pMB);
|
|
//chrg_north_pkg_decode(pFrame->pMB->payload, pFrame->len_msg, pSW);
|
|
|
|
pFrame->length = 0;
|
|
pFrame->len_msg = 0;
|
|
cnt++;
|
|
} else {
|
|
rt_ringbuffer_get(rb, &pFrame->pMB->payload[LEN_FRAME_HEAD], len_rb);
|
|
pFrame->length = LEN_FRAME_HEAD + len_rb;
|
|
pFrame->findhead = 1;
|
|
pFrame->last_tick = rt_tick_get();
|
|
break;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
len_rb = rt_ringbuffer_data_len(rb);
|
|
int len_need = pFrame->len_msg - LEN_FRAME_HEAD;
|
|
if (len_rb >= len_need) {
|
|
rt_ringbuffer_get(rb, &pFrame->pMB->payload[pFrame->length], len_need);
|
|
|
|
chrg_thread_mb_send(IDX_THR_NORTH, pFrame->pMB);
|
|
//chrg_north_pkg_decode(pFrame->pMB->payload, pFrame->len_msg, pSW);
|
|
|
|
pFrame->length = 0;
|
|
pFrame->findhead = 0;
|
|
pFrame->len_msg = 0;
|
|
cnt++;
|
|
} else {
|
|
rt_ringbuffer_get(rb, &pFrame->pMB->payload[pFrame->length], len_rb);
|
|
pFrame->length += len_rb;
|
|
pFrame->last_tick = rt_tick_get();
|
|
break;
|
|
}
|
|
}
|
|
|
|
len_rb = rt_ringbuffer_data_len(rb);
|
|
} while (len_rb >= LEN_FRAME_HEAD);
|
|
|
|
return cnt;
|
|
}
|
|
|
|
void chrg_north_thread_entry (void *data)
|
|
{
|
|
struct chrg_thread_t *pTHR = (struct chrg_thread_t *)data;
|
|
|
|
if (RT_NULL == pTHR) {
|
|
return ;
|
|
}
|
|
|
|
int len = 0;
|
|
struct chrg_tty_t *pTTY = RT_NULL;
|
|
struct chrg_north_t *pNOR = &chrgnorth;
|
|
|
|
chrg_north_switch(IDX_NOR_CH1);
|
|
|
|
pTTY = chrg_tty_create(pNOR->devname, BAUD_RATE_2000000, 0, -1, 1);
|
|
if (RT_NULL == pTTY) {
|
|
LOG_E("tty can't create.");
|
|
return ;
|
|
}
|
|
|
|
chrg_tty_set_recv_tmo(pTTY, 100);
|
|
if (chrg_tty_connect(pTTY) != RT_EOK) {
|
|
chrg_tty_destory(pTTY);
|
|
return ;
|
|
}
|
|
|
|
pNOR->tty = pTTY;
|
|
|
|
pNOR->rb = rt_ringbuffer_create(SIZE_BUF_TTY*2);
|
|
if (RT_NULL == pNOR->rb) {
|
|
LOG_E("create rb '%s' failed.", pNOR->devname);
|
|
return ;
|
|
}
|
|
|
|
while (1) {
|
|
rt_memset(pNOR->rx_buf, 0, sizeof(pNOR->rx_buf));
|
|
len = chrg_tty_recv(pTTY, pNOR->rx_buf, sizeof(pNOR->rx_buf));
|
|
if (len <= 0) {
|
|
rt_thread_mdelay(1);
|
|
continue;
|
|
}
|
|
|
|
rt_ringbuffer_put(pNOR->rb, pNOR->rx_buf, len);
|
|
|
|
if (1 == pNOR->frame.findhead) {
|
|
if (rt_tick_get() >= pNOR->frame.last_tick + 100) { // 100ms
|
|
pNOR->frame.findhead = 0; // reset
|
|
//LOG_E("timeo\r\n");
|
|
}
|
|
}
|
|
|
|
chrg_north_pickup_frame(pNOR->rb, &pNOR->frame, pNOR->idx);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
#if 1
|
|
static int north_ch(rt_uint8_t argc, char **argv)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (2 != argc) {
|
|
rt_kprintf("help : %s [0-3]\r\n", argv[0]);
|
|
return -1;
|
|
}
|
|
|
|
ret = chrg_north_switch((eIDX_NOR_CH)atoi(argv[1]));
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
MSH_CMD_EXPORT(north_ch, north channel select);
|
|
|
|
#endif
|
|
|
|
|