1.5wuling_zhuanjietou/HARDWARE/CAN/porting.c

540 lines
12 KiB
C
Raw Normal View History

2024-10-17 01:06:51 +00:00
/**********************************************************
** porting.c *
** 2022-11-15 *
** V1.0 *
**********************************************************/
#include "porting.h"
/**
* @brief: <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>FIFO
*
*
*/
void sfifo_init(st_fifo_t *stfifo, void *array, unsigned short stsize, unsigned short deepth)
{
stfifo->deepth = deepth;
stfifo->occupy = 0;
stfifo->array = array;
stfifo->stsize = stsize;
stfifo->limit = (void*)((unsigned int)array + stsize*deepth);
stfifo->wp = stfifo->array;
stfifo->rp = stfifo->array;
}
void sfifo_reset(st_fifo_t *stfifo)
{
stfifo->occupy = 0;
stfifo->rp = stfifo->array;
stfifo->wp = stfifo->array;
}
bool sfifo_write(st_fifo_t *stfifo, const void *stunit)
{
if (stfifo->occupy >= stfifo->deepth || stfifo->array == NULL) return false;
memcpy((unsigned char*)stfifo->wp,(unsigned char*)stunit,stfifo->stsize);
stfifo->wp = (void*)((unsigned int)stfifo->wp + stfifo->stsize);
if (stfifo->wp >= stfifo->limit) stfifo->wp = stfifo->array;
stfifo->occupy++;
return true;
}
bool sfifo_empty(st_fifo_t *stfifo)
{
if (stfifo->occupy == 0 || stfifo->array == NULL) return true;
else return false;
}
bool sfifo_full(st_fifo_t *stfifo)
{
if (stfifo->occupy >= stfifo->deepth) return true;
else return false;
}
unsigned int sfifo_read(st_fifo_t *stfifo,void *stunit)
{
if (stfifo->occupy == 0 || stfifo->array == NULL) return 0x0;
memcpy((unsigned char*)stunit,(unsigned char*)stfifo->rp,stfifo->stsize);
stfifo->rp = (void*)((unsigned int)stfifo->rp + stfifo->stsize);
if (stfifo->rp >= stfifo->limit) stfifo->rp = stfifo->array;
stfifo->occupy--;
return stfifo->stsize;
}
unsigned int sfifo_occupy_get(st_fifo_t *stfifo)
{
return stfifo->occupy;
}
/******************************************************************
QUEUE
******************************************************************/
bool CreateQueue(QUEUE *que)
{
if (que == 0) return FALSE;
que->head = 0;
que->tail = 0;
que->item = 0;
return TRUE;
}
unsigned short QueueItem(QUEUE *que)
{
if (que == 0) return 0;
else return (que->item);
}
QUEUEMEM *QueueHead(QUEUE *que)
{
if (que == 0 || que->item == 0) return 0;
else return ((QUEUEMEM *)que->head);// + sizeof(NODE));
}
QUEUEMEM *QueueTail(QUEUE *que)
{
if (que == 0 || que->item == 0) return 0;
else return ((QUEUEMEM *)que->tail);// + sizeof(NODE));
}
QUEUEMEM *QueueNext(QUEUEMEM *element)
{
QUEUENODE *curnode;
if (element == 0) return 0;
curnode = (QUEUENODE *)(element);// - sizeof(NODE));
if ((curnode = curnode->next) == 0) return 0;
else return ((QUEUEMEM *)curnode);// + sizeof(NODE));
}
QUEUEMEM *DelQueueElement(QUEUE *que, QUEUEMEM *element)
{
QUEUENODE *curnode, *prenode, *nextnode;
if (que == 0 || element == 0) return 0;
if (que->item == 0) return 0;
que->item--;
curnode = (QUEUENODE *)(element);// - sizeof(NODE));
if (curnode == que->head) {
que->head = curnode->next;
if (que->item == 0) {
que->tail = 0;
return 0;
} else {
return (QUEUEMEM *)(que->head);// + sizeof(NODE);
}
}
nextnode = curnode->next;
prenode = que->head;
while (prenode != 0) {
if (prenode->next == curnode) {
break;
} else {
prenode = prenode->next;
}
}
if (prenode == 0) return 0;
prenode->next = nextnode;
if (curnode == que->tail) {
que->tail = prenode;
return 0;
} else {
return ((QUEUEMEM *)nextnode);// + sizeof(NODE));
}
}
// Return: Queue head
QUEUEMEM *DelQueueHead(QUEUE *que)
{
QUEUEMEM *element;
if (que == 0 || que->item == 0) return 0;
element = (QUEUEMEM *)que->head;//+ sizeof(NODE);
DelQueueElement(que, element);
return element;
}
// Return: Queue tail
QUEUEMEM *DelQueueTail(QUEUE *que)
{
QUEUEMEM *element;
if (que == 0 || que->item == 0) return 0;
element = (QUEUEMEM *)que->tail;// + sizeof(NODE);
DelQueueElement(que, element);
return element;
}
bool AppendQueue(QUEUE *que, QUEUEMEM *element)
{
QUEUENODE *curnode;
if (que == 0 || element == 0) return FALSE;
curnode = (QUEUENODE *)(element);// - sizeof(NODE));
if (que->item == 0) {
que->head = curnode;
} else {
que->tail->next = curnode;
}
curnode->next = 0;
que->tail = curnode;
que->item++;
return TRUE;
}
//intsert element before curelement
bool InsertBeforeQueue(QUEUE *que, QUEUEMEM *element,QUEUEMEM *curelement)
{
QUEUENODE *curnode, *prenode, *node;
if (que == 0 || element == 0 || curelement == 0) return FALSE;
node = (QUEUENODE*)element;
curnode = (QUEUENODE*)curelement;
if (que->head == curnode) {
que->head = node;
node->next = curnode;
} else {
prenode = que->head;
while (prenode != 0) {
if (prenode->next == curnode) {
break;
} else {
prenode = prenode->next;
}
}
if (prenode == 0) return false;
prenode->next = node;
node->next = curnode;
}
que->item++;
return true;
}
/*********************************************<2A>ź<EFBFBD><C5BA><EFBFBD><EFBFBD>صIJ<D8B5><C4B2><EFBFBD>*******************************************************/
typedef struct {
unsigned int signal_id;
unsigned int para1;
unsigned int para2;
} signal_cell_t;
typedef struct {
unsigned int signal;
signal_callback cb;
}signal_callback_t;
typedef struct {
signal_callback_t signal_map[20]; /* <20>洢my_kill ע<><D7A2><EFBFBD><EFBFBD><EFBFBD>źźͻص<CDBB> */
signal_cell_t signal[40];
st_fifo_t queue;
} signal_queue_t;
static signal_queue_t can_signal_queue = {0};
/*
* \brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PID
* \para:
* signal: my_signal_e <EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD>ź<EFBFBD>ֵ
* para1,para2: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>my_kill <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>Ϣ<EFBFBD>ص<EFBFBD>֮<EFBFBD><EFBFBD>ݲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˽<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD>Ϣ
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ֵʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
*/
int can_kill(unsigned int signal, unsigned int para1, unsigned int para2)
{
signal_cell_t signal_cell;
signal_cell.signal_id = signal;
signal_cell.para1 = para1;
signal_cell.para2 = para2;
return sfifo_write(&can_signal_queue.queue, (void *)&signal_cell);
}
/*
* \brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PID <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣsignal
* \para:
* signal: Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
* cb: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return:
* 0-<EFBFBD>ɹ<EFBFBD> <0 ʧ<EFBFBD><EFBFBD>
*
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pSQueue->mass <EFBFBD>б<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD>ʧ<EFBFBD><EFBFBD>
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>pSQueue->signal_map <EFBFBD><EFBFBD>
*/
int can_signal(unsigned int signal, signal_callback cb)
{
unsigned int i;
if (signal == E_CAN_SIGNAL_NULL) return -1;
/*<2A><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µĻص<C4BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻֮ǰ<D6AE>Ļص<C4BB><D8B5><EFBFBD><EFBFBD><EFBFBD>*/
for (i=0; i<NELEMENTS(can_signal_queue.signal_map); i++)
{
if (can_signal_queue.signal_map[i].signal == signal)
{
can_signal_queue.signal_map[i].cb = cb;
if (can_signal_queue.signal_map[i].cb == NULL)
{
/* ɾ<><C9BE><EFBFBD>ص<EFBFBD> */
can_signal_queue.signal_map[i].signal = E_CAN_SIGNAL_NULL;
}
return 0;
}
}
/*<2A><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
if (cb == NULL)
{
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źţ<C5BA><C5A3><EFBFBD><EFBFBD><EFBFBD><E4B4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>벻ΪNULL */
return -1;
}
for (i=0; i<NELEMENTS(can_signal_queue.signal_map); i++)
{
if (can_signal_queue.signal_map[i].signal == E_CAN_SIGNAL_NULL || can_signal_queue.signal_map[i].cb == NULL)
{
can_signal_queue.signal_map[i].signal = signal;
can_signal_queue.signal_map[i].cb = cb;
return 0;
}
}
return -1;
}
/* <20>źŹ<C5BA><C5B9>ܵij<DCB5>ʼ<EFBFBD><CABC> */
int can_signal_queue_init(void)
{
memset(&can_signal_queue, 0x00, sizeof(can_signal_queue));
sfifo_init(&can_signal_queue.queue, &can_signal_queue.signal[0], sizeof(can_signal_queue.signal[0]), NELEMENTS(can_signal_queue.signal));
return 0;
}
/**
* @brief: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN<EFBFBD><EFBFBD><EFBFBD>źŵ<EFBFBD><EFBFBD><EFBFBD>
*/
int can_signal_schedule(void)
{
signal_callback cb;
signal_cell_t signal_cell;
unsigned int i;
while(sfifo_empty(&can_signal_queue.queue) == false)
{
sfifo_read(&can_signal_queue.queue, (void *)&signal_cell);
for (i=0; i<NELEMENTS(can_signal_queue.signal_map); i++)
{
if (can_signal_queue.signal_map[i].signal == signal_cell.signal_id)
{
cb = can_signal_queue.signal_map[i].cb;
if (cb != NULL) cb(signal_cell.signal_id, signal_cell.para1, signal_cell.para2);
break;
}
}
}
return 0;
}
/******************************************<2A><>ʱ<EFBFBD><CAB1>********************************************************************/
typedef struct tmr_st {
unsigned int holdtime; //<2F><>ʱʱ<CAB1>䣬Ϊ0<CEAA><30>ʾֹͣ<CDA3><D6B9>
unsigned int optime;
can_tmr_func tmrfunc; //<2F><>ʱִ<CAB1><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
} timer_cell_t;;
static timer_cell_t can_timer[20];
TIMER can_timer_create(can_tmr_func cb)
{
unsigned short i;
if (cb == NULL)
{
return 0;
}
for (i = 0; i < NELEMENTS(can_timer); i++)
{
if (can_timer[i].tmrfunc == NULL)
{
can_timer[i].tmrfunc = cb;
can_timer[i].holdtime = 0;
return (TIMER)&can_timer[i];
}
}
return 0;
}
void can_timer_remove(TIMER tmr)
{
timer_cell_t *pCur = (timer_cell_t *)tmr;
if ((NULL == pCur))
{
return;
}
pCur->holdtime = 0;
pCur->optime = 0;
pCur->tmrfunc = NULL;
return;
}
void can_timer_start(TIMER tmr,unsigned int ms)
{
timer_cell_t *pCur = (timer_cell_t *)tmr;
if (pCur == NULL) return;
pCur->holdtime = ms;
TickOut(&(pCur->optime), 0);
}
void can_timer_stop(TIMER tmr)
{
timer_cell_t *pCur = (timer_cell_t *)tmr;
if (pCur == NULL) return;
pCur->holdtime = 0;
}
bool can_timer_switch(TIMER tmr)
{
timer_cell_t *pCur = (timer_cell_t *)tmr;
if (pCur == NULL) return false;
if (pCur->holdtime > 0) {
return true;
} else {
return false;
}
}
/* <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ܵij<DCB5>ʼ<EFBFBD><CABC> */
int can_timer_init(void)
{
memset(can_timer, 0x00, sizeof(can_timer));
return 0;
}
/* <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ܵij<DCB5>ʼ<EFBFBD><CABC> */
int can_timer_schedule(void)
{
unsigned int tick, i, holdtime, last_tick = 0;
can_tmr_func cb;
TickOut(&tick, 0);
if (tick == last_tick || tick == (last_tick+1))
{
return 0;
}
last_tick = tick;
for (i = 0; i < NELEMENTS(can_timer); i++)
{
cb = can_timer[i].tmrfunc;
holdtime = can_timer[i].holdtime;
if (holdtime > 0 && cb != NULL)
{
if (TickOut(&can_timer[i].optime,holdtime) == TRUE)
{
if (can_timer[i].tmrfunc != NULL)
{
can_timer[i].optime += ((tick - can_timer[i].optime)/holdtime*holdtime);
}
if (cb != NULL)
{
cb((TIMER)&can_timer[i]);
}
}
}
}
return 0;
}
/**
* @brief: <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>can Э<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void can_porting_init(void)
{
can_timer_init();
can_signal_queue_init();
}
/**
* @brief: <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>can Э<EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵĵ<EFBFBD><EFBFBD><EFBFBD>
*/
void can_porting_schedule(void)
{
can_signal_schedule();
can_timer_schedule();
}