1.5wuling_zhuanjietou/HARDWARE/CAN/porting.c
2024-10-17 09:06:51 +08:00

540 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**********************************************************
** porting.c *
** 2022-11-15 *
** V1.0 *
**********************************************************/
#include "porting.h"
/**
* @brief: ³õʼ»¯Ò»¸ö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;
}
/*********************************************ÐźÅÏà¹ØµÄ²Ù×÷*******************************************************/
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]; /* ´æ´¢my_kill ×¢²áµÄÐźźͻص÷ */
signal_cell_t signal[40];
st_fifo_t queue;
} signal_queue_t;
static signal_queue_t can_signal_queue = {0};
/*
* \brief: ·¢ËÍÒ»¸öÏûÏ¢¸ø½ø³ÌPID
* \para:
* signal: my_signal_e ÀàÐ͵ÄÐźÅÖµ
* para1,para2: ²ÎÊý£¬my_kill Óë¶ÔÓ¦ÏûÏ¢»Øµ÷Ö®¼ä´«µÝ²ÎÊýÓÃ
*
* ÕâÀï³ýÁ˽«ÏûÏ¢´æ·Åµ½¶ÓÁÐÍ⣬»¹»á¼ì²éµ±Ç°¶ÓÁÐÖеÄÏûÏ¢
* ¸öÊý£¬µ±³¬¹ýÒ»¶¨ÖµÊ±¸øÓ뾯¸æÌáʾ
*/
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: ÉêÃ÷²¶»ñ½ø³ÌPID µÄÏûÏ¢signal
* \para:
* signal: Òª²¶»ñµÄÏûÏ¢
* cb: ²¶»ñº¯Êý
* \return:
* 0-³É¹¦ <0 ʧ°Ü
*
*¼ì²éÒª²¶»ñµÄÏûÏ¢ÊÇ·ñÒÑÔÚpSQueue->mass Öб»ÉêÃ÷£¬ÒÑÉêÃ÷Ôò·µ»Øʧ°Ü
*½«ÆäÌí¼Óµ½pSQueue->signal_map ÖÐ
*/
int can_signal(unsigned int signal, signal_callback cb)
{
unsigned int i;
if (signal == E_CAN_SIGNAL_NULL) return -1;
/*Èç¹ûÒѾ­ÉêÃ÷ÔòÓÃеĻص÷º¯ÊýÌ滻֮ǰµÄ»Øµ÷º¯Êý*/
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)
{
/* ɾ³ý»Øµ÷ */
can_signal_queue.signal_map[i].signal = E_CAN_SIGNAL_NULL;
}
return 0;
}
}
/*Èç¹ûûÓÐÉêÃ÷ÔòÌí¼Ó*/
if (cb == NULL)
{
/* Ìí¼ÓÐÂÐźţ¬ÔòÆä´¦Àíº¯Êý±ØÐ벻Ϊ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;
}
/* ÐźŹ¦Äܵijõʼ»¯ */
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: ´¦ÀíCANµÄÐźŵ÷¶È
*/
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;
}
/******************************************¶¨Ê±Æ÷********************************************************************/
typedef struct tmr_st {
unsigned int holdtime; //¶¨Ê±Ê±¼ä£¬Îª0±íʾֹͣ£»
unsigned int optime;
can_tmr_func tmrfunc; //¶¨Ê±Ö´ÐÐÈÎÎñµÄÖ¸Õë
} 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;
}
}
/* ¶¨Ê±Æ÷¹¦Äܵijõʼ»¯ */
int can_timer_init(void)
{
memset(can_timer, 0x00, sizeof(can_timer));
return 0;
}
/* ¶¨Ê±Æ÷¹¦Äܵijõʼ»¯ */
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: ³õʼ»¯can ЭÒéµÄ»ù´¡¹¦ÄÜ
*/
void can_porting_init(void)
{
can_timer_init();
can_signal_queue_init();
}
/**
* @brief: ³õʼ»¯can ЭÒéµÄ»ù´¡¹¦Äܵĵ÷¶È
*/
void can_porting_schedule(void)
{
can_signal_schedule();
can_timer_schedule();
}