| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- #include "chip.h"
- #include "board.h"
- #define MAILBOX_BASE REGS_MAILBOX_BASE
- #define MBDBUG(fmt, args...) printf("[MBDBUG]: "fmt , ##args)
- #define MBERR(fmt, args...) printf("[MBERR]: "fmt , ##args)
- #define MODE_AUTO_LINK (1<<1)
- #define MODE_AUTO_ACKNOWLEDGE (1<<0)
- #define SEND_MSG_TO_DEST (1<<0)
- #define SEND_MSG_TO_SRC (1<<1)
- #define MAILBOX_MIS0_REG_OFFSET 0X800
- #define MAILBOX_RIS0_REG_OFFSET 0X804
- #define READ_MIS(COREx) *((volatile uint32_t *)(COREx * 0x08 + MAILBOX_MIS0_REG_OFFSET + MAILBOX_BASE))
- #define READ_RIS(COREx) *((volatile uint32_t *)(COREx * 0x08 + MAILBOX_RIS0_REG_OFFSET + MAILBOX_BASE))
- typedef struct {
- mb_rx_cb_func_t cb;
- void *param;
- }mb_rx_cb_inf_t;
- #ifdef MAILBOX_SUPPORT
- static QueueHandle_t mailbox_tx_flg[TX_MAILBOX_NUM] = {0};
- static mb_rx_cb_inf_t mailbox_rx_cb_inf_tab[RX_MAILBOX_NUM] = {0};
- static void mailbox_int_handler(void *param)
- {
- int i,j;
- mail_t mail;
- uint32_t RIS = 0;
- mailbox_t *p_mailbox = NULL;
- reply_t reply_dat;
- uint32_t mstatus;
- RIS = READ_RIS(MAILBOX_MY_CORE_NUM);
- for (i=0; i<MAILBOX_SUM; i++) {
- if (RIS & (1 << i)) {
- //MBDBUG("mb int%d!\n",i);
- p_mailbox = (mailbox_t *)(i*0X40 + MAILBOX_BASE);
- if (p_mailbox->SRC == MAILBOX_MY_CORE_ID) {
- p_mailbox->MCLR = 0xffffffff;
- p_mailbox->SEND = 0x0;
- if (((i - TX_MAILBOX_START_ID) >= 0) && ((i - TX_MAILBOX_START_ID) < TX_MAILBOX_NUM)) {
- xQueueSendFromISR(mailbox_tx_flg[i - TX_MAILBOX_START_ID], NULL, 0);
- }
- } else {
- mail.sender = p_mailbox->SRC;
- mail.recipients = p_mailbox->DSTA;
- mail.mailbox_id = i;
- for (j=0; j<MAILBOX_DR_SUM; j++) {
- mail.data[j] = p_mailbox->DR[j];
- }
- if (p_mailbox->MODE & MODE_AUTO_LINK) {
- mail.auto_link = 1;
- } else {
- mail.auto_link = 0;
- }
- if (p_mailbox->MODE & MODE_AUTO_ACKNOWLEDGE) {
- mail.auto_acknowledge = 1;
- } else {
- mail.auto_acknowledge = 0;
- }
- if (((mail.mailbox_id - RX_MAILBOX_START_ID) >= 0) && \
- ((mail.mailbox_id - RX_MAILBOX_START_ID) < RX_MAILBOX_NUM))
- {
- if (mailbox_rx_cb_inf_tab[mail.mailbox_id - RX_MAILBOX_START_ID].cb) {
- reply_dat = mailbox_rx_cb_inf_tab[mail.mailbox_id - RX_MAILBOX_START_ID].cb(mail, \
- mailbox_rx_cb_inf_tab[mail.mailbox_id - RX_MAILBOX_START_ID].param);
- }
- }
- if (mail.auto_acknowledge) {
- p_mailbox->DCLR = MAILBOX_MY_CORE_ID;
- } else {
- if (((mail.mailbox_id - RX_MAILBOX_START_ID) >= 0) && \
- ((mail.mailbox_id - RX_MAILBOX_START_ID) < RX_MAILBOX_NUM))
- {
- if (mailbox_rx_cb_inf_tab[mail.mailbox_id - RX_MAILBOX_START_ID].cb) {
- for (j=0; j<MAILBOX_DR_SUM; j++) {
- p_mailbox->DR[j] = reply_dat.data[j];
- }
- }
- }
- mstatus = p_mailbox->MSTA;
- p_mailbox->MCLR = 0xffffffff;
- p_mailbox->SEND = 0;
- p_mailbox->MSET = (mstatus | p_mailbox->SRC) & (~p_mailbox->DSTA);
- p_mailbox->SEND = SEND_MSG_TO_SRC;
- }
- }
- }
- }
- }
- /**
- *@note:
- * 1.自动确认模式下,接收方返回确认信息时不会修改原邮件内容。
- * 2.自动连接的邮箱号必须按递增顺序,连接的最后一个邮箱需auto_link设为0。
- */
- int mailbox_send_mail(mail_t *mail, uint32_t mail_num)
- {
- int ret = 0;
- int i,j;
- uint32_t val;
- int dest_cnt = 0;
- mailbox_t *p_mailbox = NULL;
- int mail_last_num;
- int mail_cnt;
- int mailbox_cnt;
- int link_start;
- mail_status status;
- mail_t *pmail = NULL;
- if ((!mail) || (mail_num == 0)) {
- ret = -1;
- goto exit;
- }
- for (mail_cnt=0; mail_cnt<mail_num; mail_cnt++) {
- mailbox_cnt = 0;
- status = mail_s_done;
- link_start = -1;
- while (1) {
- pmail = &mail[mail_cnt];
- if (status == mail_s_done) {
- if ((link_start > 0) && (pmail->mailbox_id != (mail[link_start].mailbox_id + mailbox_cnt))) {
- status = mail_s_link_discontinuous;
- }
- if ((pmail->mailbox_id >= TX_MAILBOX_MAX_ID) || (pmail->mailbox_id < TX_MAILBOX_START_ID)) {
- status = mail_s_mb_num_err;
- }
- }
- if (status == mail_s_done) {
- p_mailbox = (mailbox_t *)(pmail->mailbox_id*0X40 + MAILBOX_BASE);
- if (p_mailbox->SRC != pmail->sender) {
- status = mail_s_occ;
- } else {
- p_mailbox->MCLR = 0xffffffff;
- p_mailbox->DCLR = 0xffffffff;
- p_mailbox->DEST = pmail->recipients;
- dest_cnt = 0;
- for (i=0; i<32; i++) {
- if ((pmail->recipients >> i) & 0x01) {
- dest_cnt++;
- }
- }
- val = 0;
- if (dest_cnt > 1) // 多个目标核心必须开启自动确认
- val |= MODE_AUTO_ACKNOWLEDGE;
- if (pmail->auto_acknowledge)
- val |= MODE_AUTO_ACKNOWLEDGE;
- if (pmail->auto_link && (mail_cnt < (mail_num-1)))
- val |= MODE_AUTO_LINK;
- p_mailbox->MODE = val;
- for (i=0; i<MAILBOX_DR_SUM; i++) {
- p_mailbox->DR[i] = pmail->data[i];
- }
- p_mailbox->MSET = pmail->recipients;
- }
- }
- if (link_start < 0) {
- link_start = mail_cnt;
- }
- if (status == mail_s_done) {
- mailbox_cnt++;
- }
- if (pmail->auto_link) {
- if (mail_cnt < (mail_num -1)) {
- mail_cnt++;
- } else {
- break;
- }
- } else {
- break;
- }
- }
- if (status == mail_s_done) {
- p_mailbox = (mailbox_t *)(mail[link_start].mailbox_id*0X40 + MAILBOX_BASE);
- xQueueReset(mailbox_tx_flg[mail[mail_cnt].mailbox_id - TX_MAILBOX_START_ID]);
- p_mailbox->SEND = SEND_MSG_TO_DEST;
- if (xQueueReceive(mailbox_tx_flg[mail[mail_cnt].mailbox_id - TX_MAILBOX_START_ID], NULL, \
- mail[mail_cnt].tx_tout_tick) != pdTRUE) {
- status = mail_s_tx_tout;
- MBERR("mailbox wait acknowledge time out!\n");
- }
- }
- for (i=0; i<mailbox_cnt; i++) {
- p_mailbox = (mailbox_t *)(mail[link_start + i].mailbox_id*0X40 + MAILBOX_BASE);
- pmail = &mail[link_start + i];
- if (i == 0) {
- pmail->tx_status = status;
- }
- for (j=0; j<MAILBOX_DR_SUM; j++) {
- pmail->data[j] = p_mailbox->DR[j];
- }
- }
- }
- exit:
- return ret;
- }
- /**
- *@berief:
- * 注册接收回调函数。
- * 使用回调方式接收数据可带答复数据(仅当接收的邮件类型为非自动答复类型)。
- *
- *@note:
- * 回调函数将在中断被调用。
- */
- int mailbox_register_rx_cb(int id, mb_rx_cb_func_t cb, void *param)
- {
- if ((id >= RX_MAILBOX_MAX_ID) || (id < RX_MAILBOX_START_ID)){
- printf("%s id error!\n", __func__);
- return -1;
- }
- portENTER_CRITICAL();
- mailbox_rx_cb_inf_tab[id - RX_MAILBOX_START_ID].cb = cb;
- mailbox_rx_cb_inf_tab[id - RX_MAILBOX_START_ID].param = param;
- portEXIT_CRITICAL();
- return 0;
- }
- /*
- *@param:
- * id: 指定邮箱号(TX_MAILBOX_START_ID : (TX_MAILBOX_MAX_ID - 1)),小于0时,则自动找一个空闲邮箱。
- *
- *@return:
- * 返回值小于0时,表示分配失败。
- */
- int mailbox_request(int id)
- {
- int ret = -1;
- int i;
- mailbox_t *p_mailbox = NULL;
- int retry;
- if (id >= 0) {
- if ((id < TX_MAILBOX_START_ID) || (id >= TX_MAILBOX_MAX_ID)) {
- printf("%s id error!\n", __func__);
- return -1;
- }
- }
- portENTER_CRITICAL();
- if (id >= 0) {
- p_mailbox = (mailbox_t *)(id*0X40 + MAILBOX_BASE);
- if (p_mailbox->SRC == 0) {
- retry = 10;
- do {
- p_mailbox->SRC = 0;
- p_mailbox->SRC = MAILBOX_MY_CORE_ID;
- } while ((p_mailbox->SRC != MAILBOX_MY_CORE_ID) && (--retry));
- if (p_mailbox->SRC == MAILBOX_MY_CORE_ID)
- ret = id;
- else
- p_mailbox->SRC = 0;
- }
- } else {
- for (i = TX_MAILBOX_START_ID; i < TX_MAILBOX_MAX_ID; i++) {
- p_mailbox = (mailbox_t *)(i*0X40 + MAILBOX_BASE);
- if (p_mailbox->SRC == 0) {
- retry = 10;
- do {
- p_mailbox->SRC = 0;
- p_mailbox->SRC = MAILBOX_MY_CORE_ID;
- } while ((p_mailbox->SRC != MAILBOX_MY_CORE_ID) && (--retry));
- if (p_mailbox->SRC == MAILBOX_MY_CORE_ID) {
- ret = i;
- break;
- } else {
- p_mailbox->SRC = 0;
- }
- }
- }
- }
- portEXIT_CRITICAL();
- return ret;
- }
- int mailbox_release(int id)
- {
- mailbox_t *p_mailbox = NULL;
- if ((id >= TX_MAILBOX_MAX_ID) || (id < TX_MAILBOX_START_ID)){
- printf("%s id error!\n", __func__);
- return -1;
- }
- p_mailbox = (mailbox_t *)(id*0X40 + MAILBOX_BASE);
- if (p_mailbox->SRC == MAILBOX_MY_CORE_ID) {
- p_mailbox->SRC = 0;
- }
- return 0;
- }
- int mailbox_init(void)
- {
- int i;
- for (i = 0; i < TX_MAILBOX_NUM; i++) {
- mailbox_tx_flg[i] = xQueueCreate(1, 0);
- }
- request_irq(MAILBOX_IRQn + MAILBOX_MY_CORE_NUM, 0, mailbox_int_handler, NULL);
- return 0;
- }
- void mailbox_reset(void)
- {
- int i;
- mailbox_t *p_mailbox = NULL;
- for (i = TX_MAILBOX_START_ID; i < TX_MAILBOX_MAX_ID; i++) {
- p_mailbox = (mailbox_t *)(i*0X40 + MAILBOX_BASE);
- p_mailbox->SRC = 0x0;
- }
- }
- #endif
|