#include "chip.h" #include "board.h" typedef union { struct { uint8_t type; uint8_t dl; uint8_t data[MB_FRAME_DSIZE]; }frame_data; uint32_t raw_data[MAILBOX_DR_SUM]; }mb_frame_fmt_t; #ifdef MAILBOX_SUPPORT static SemaphoreHandle_t msg_tx_mutex[MB_MSG_T_MAX]; static QueueHandle_t msg_rx_queue[MB_MSG_T_MAX]; static reply_t mb_rx_cb(mail_t mail, void *param) { int i; reply_t reply = {0}; mb_frame_fmt_t fr_data; mb_rxmsg_t msg; for (i = 0; i < MAILBOX_DR_SUM; i++) { fr_data.raw_data[i] = mail.data[i]; } msg.dl = fr_data.frame_data.dl; memcpy(msg.data, fr_data.frame_data.data, msg.dl); xQueueSendFromISR(msg_rx_queue[fr_data.frame_data.type], &msg, 0); return reply; } int mailbox_msg_send(mb_msg_type_t type, const uint8_t *data, uint32_t dl, TickType_t xTicksToWait) { uint32_t i, j; mail_t mail; mb_frame_fmt_t fr_data; int id; int ret = 0; TickType_t stick, tick, ptick, rtick; stick = xTaskGetTickCount(); if (xSemaphoreTake(msg_tx_mutex[type], xTicksToWait) != pdTRUE) { printf("%s time out!\n", __func__); return -1; } tick = xTaskGetTickCount(); if (tick >= stick) { ptick = tick - stick; } else { ptick = (portMAX_DELAY - stick) + tick; } if (ptick < xTicksToWait) { rtick = xTicksToWait - ptick; } else { rtick = 1; } while (rtick) { id = mailbox_request(-1); if (id >= 0) break; vTaskDelay(1); rtick--; } if (id >= 0) { fr_data.frame_data.type = type; if (!data) { fr_data.frame_data.dl = 0; for (j = 0; j < MAILBOX_DR_SUM; j++) mail.data[j] = fr_data.raw_data[j]; mail.auto_acknowledge = 0; mail.auto_link = 0; mail.sender = MAILBOX_MY_CORE_ID; mail.recipients = MAILBOX_MCU_CORE_ID; mail.mailbox_id = id; mail.tx_tout_tick = rtick; mailbox_send_mail(&mail, 1); if (mail.tx_status != mail_s_done) ret = -1; } else { for (i = 0; i < dl;) { if ((dl - i) >= MB_FRAME_DSIZE) { fr_data.frame_data.dl = MB_FRAME_DSIZE; for (j = 0; j < fr_data.frame_data.dl; j++, i++) fr_data.frame_data.data[j] = data[i]; for (j = 0; j < MAILBOX_DR_SUM; j++) mail.data[j] = fr_data.raw_data[j]; } else { fr_data.frame_data.dl = dl - i; for (j = 0; j < fr_data.frame_data.dl; j++, i++) fr_data.frame_data.data[j] = data[i]; for (j = 0; j < MAILBOX_DR_SUM; j++) mail.data[j] = fr_data.raw_data[j]; } mail.auto_acknowledge = 0; mail.auto_link = 0; mail.sender = MAILBOX_MY_CORE_ID; mail.recipients = MAILBOX_MCU_CORE_ID; mail.mailbox_id = id; mail.tx_tout_tick = rtick; mailbox_send_mail(&mail, 1); if (mail.tx_status != mail_s_done) ret = -1; } } mailbox_release(id); } else { ret = -1; } xSemaphoreGive(msg_tx_mutex[type]); return ret; } BaseType_t mailbox_msg_receive(mb_msg_type_t type, mb_rxmsg_t *msg, TickType_t xTicksToWait) { int ret = 0; mb_rxmsg_t rx_msg; ret = xQueueReceive(msg_rx_queue[type], &rx_msg, xTicksToWait); if (msg) *msg = rx_msg; return ret; } void mailbox_msg_init(void) { int i; mailbox_init(); for (i = 0; i < MB_MSG_T_MAX; i++) { msg_tx_mutex[i] = xSemaphoreCreateMutex(); msg_rx_queue[i] = xQueueCreate(MB_RX_QUEUE_LEN, sizeof(mb_rxmsg_t)); } for (i = RX_MAILBOX_START_ID; i < RX_MAILBOX_MAX_ID; i++) { mailbox_register_rx_cb(i, mb_rx_cb, NULL); } } #endif