/* * Copyright (c) 2021 HPMicro * * SPDX-License-Identifier: BSD-3-Clause * */ #ifndef HPM_MBX_DRV_H #define HPM_MBX_DRV_H #include "hpm_common.h" #include "hpm_mbx_regs.h" /** * @brief MBX driver APIs * @defgroup mbx_interface MBX driver APIs * @ingroup io_interfaces * @{ */ /* * @brief Bus access responses */ typedef enum { no_bus_error_no_wait = 0, generate_bus_error = 1, } mbx_bus_access_resp_t; /* * @brief MBX specific status */ enum { status_mbx_not_available = MAKE_STATUS(status_group_mbx, 2), }; #define MBX_CR_ALL_INTERRUPTS_MASK (MBX_CR_TFMAIE_MASK | MBX_CR_RFMAIE_MASK \ | MBX_CR_RFMFIE_MASK | MBX_CR_TWMEIE_MASK) #ifdef __cplusplus extern "C" { #endif /** * @brief Set bus access response * * @param[in] ptr MBX base address * @param[in] resp response value type */ static inline void mbx_set_bus_access_response(MBX_Type *ptr, mbx_bus_access_resp_t resp) { ptr->CR = (ptr->CR & ~(MBX_CR_BARCTL_MASK)) | MBX_CR_BARCTL_SET(resp); } /** * @brief Enable interrupt with mask * * @param[in] ptr MBX base address * @param[in] mask Mask of interrupts to be enabled */ static inline void mbx_enable_intr(MBX_Type *ptr, uint32_t mask) { ptr->CR |= mask; } /** * @brief Disable interrupt with mask * * @param[in] ptr MBX base address * @param[in] mask Mask of interrupts to be disabled */ static inline void mbx_disable_intr(MBX_Type *ptr, uint32_t mask) { ptr->CR &= ~mask; } /** * @brief Empty fifo * * @param[in] ptr MBX base address */ static inline void mbx_empty_txfifo(MBX_Type *ptr) { ptr->CR |= MBX_CR_TXRESET_MASK; } /** * @brief Initialization * * @param[in] ptr MBX base address */ static inline void mbx_init(MBX_Type *ptr) { mbx_empty_txfifo(ptr); mbx_disable_intr(ptr, MBX_CR_ALL_INTERRUPTS_MASK); } /** * @brief Send message * * @param[in] ptr MBX base address * @param[in] msg Message data in 32 bits * * @return status_success if everything is okay */ static inline hpm_stat_t mbx_send_message(MBX_Type *ptr, uint32_t msg) { if (ptr->SR & MBX_SR_TWME_MASK) { ptr->TXREG = msg; return status_success; } return status_mbx_not_available; } /** * @brief Retrieve message * * @param[in] ptr MBX base address * @param[out] msg Pointer to buffer to save message data * * @return status_success if everything is okay */ static inline hpm_stat_t mbx_retrieve_message(MBX_Type *ptr, uint32_t *msg) { if (ptr->SR & MBX_SR_RWMV_MASK) { *msg = ptr->RXREG; return status_success; } return status_mbx_not_available; } /** * @brief Send message to fifo * * @param[in] ptr MBX base address * @param[in] msg Pointer to message array to be sent * @param[in] count Number of 32-bit data to be sent * * @return status_success if everything is okay * @return status_not_available if fifo is full */ static inline hpm_stat_t mbx_send_fifo(MBX_Type *ptr, uint32_t *msg, uint32_t count) { uint32_t i; hpm_stat_t status = status_success; for (i = 0; i < 4; i++) { if (ptr->SR & MBX_SR_TFMA_MASK) { ptr->TXWRD[0] = MBX_TXWRD_TXFIFO_SET(*(msg + i)); count--; if (!count) { break; } } else { status = status_mbx_not_available; break; } } return status; } /** * @brief Retrieve data from fifo * * @param[in] ptr MBX base address * @param[out] msg Pointer of buffer to receive data * @param[in] count Number of 32-bit data to be retrieved * * @return status_success if everything is okay * @return status_mbx_not_available if fifo is empty */ static inline hpm_stat_t mbx_retrieve_fifo(MBX_Type *ptr, uint32_t *msg, uint32_t count) { uint32_t i; hpm_stat_t status = status_success; for (i = 0; i < 4; i++) { if (ptr->SR & MBX_SR_RFMA_MASK) { *(msg + i) = (ptr->RXWRD[0] & MBX_RXWRD_RXFIFO_MASK) >> MBX_RXWRD_RXFIFO_SHIFT; count--; if (!count) { break; } } else { status = status_mbx_not_available; break; } } return status; } #ifdef __cplusplus } #endif /** * @} */ #endif /* HPM_MBX_DRV_H */