mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-13 17:00:19 +00:00
448 lines
16 KiB
C
448 lines
16 KiB
C
/*
|
|
* Copyright 2020-2022 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
#ifndef FSL_IMU_H_
|
|
#define FSL_IMU_H_
|
|
|
|
#include "fsl_common.h"
|
|
|
|
/*!
|
|
* @addtogroup imu
|
|
* @{
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* Definitions
|
|
*****************************************************************************/
|
|
|
|
/*! @name Driver version */
|
|
/*! @{ */
|
|
/*! @brief IMU driver version. */
|
|
#define FSL_IMU_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
|
|
/*! @} */
|
|
|
|
#define IMU_MSG_FIFO_STATUS_MSG_FIFO_LOCKED_MASK (1UL)
|
|
#define IMU_MSG_FIFO_STATUS_MSG_FIFO_ALMOST_FULL_MASK (1UL << 1U)
|
|
#define IMU_MSG_FIFO_STATUS_MSG_FIFO_FULL_MASK (1UL << 2U)
|
|
#define IMU_MSG_FIFO_STATUS_MSG_FIFO_EMPTY_MASK (1UL << 3U)
|
|
#define IMU_MSG_FIFO_STATUS_MSG_COUNT_MASK (0x1FUL << 4U)
|
|
#define IMU_MSG_FIFO_STATUS_MSG_COUNT_SHIFT (4U)
|
|
#define IMU_MSG_FIFO_STATUS_WR_PTR_MASK (0xFUL << 16U)
|
|
#define IMU_MSG_FIFO_STATUS_WR_PTR_SHIFT (16U)
|
|
#define IMU_MSG_FIFO_STATUS_RD_PTR_MASK (0xFUL << 20U)
|
|
#define IMU_MSG_FIFO_STATUS_RD_PTR_SHIFT (20U)
|
|
|
|
#define IMU_MSG_FIFO_CNTL_MSG_RDY_INT_CLR_MASK (1UL << 0U)
|
|
#define IMU_MSG_FIFO_CNTL_SP_AV_INT_CLR_MASK (1UL << 1U)
|
|
#define IMU_MSG_FIFO_CNTL_FIFO_FLUSH_MASK (1UL << 16U)
|
|
#define IMU_MSG_FIFO_CNTL_WAIT_FOR_ACK_MASK (1UL << 17U)
|
|
#define IMU_MSG_FIFO_CNTL_FIFO_FULL_WATERMARK_MASK (0x0FUL << 20U)
|
|
#define IMU_MSG_FIFO_CNTL_FIFO_FULL_WATERMARK_SHIFT (20U)
|
|
#define IMU_MSG_FIFO_CNTL_FIFO_FULL_WATERMARK(x) (((uint32_t)(x)) << 20U)
|
|
|
|
/* Write message directly. */
|
|
#define IMU_WR_MSG(link, msg) (((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->WR_MSG = (msg))
|
|
|
|
/* Read message directly. */
|
|
#define IMU_RD_MSG(link) (((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->RD_MSG)
|
|
|
|
/* Check whether RX FIFO is locked. */
|
|
#define IMU_RX_FIFO_LOCKED(link) \
|
|
(0UL != \
|
|
(((IMU_Type *)(uintptr_t)IMU_PEER_CPU_BASE(link))->MSG_FIFO_STATUS & IMU_MSG_FIFO_STATUS_MSG_FIFO_LOCKED_MASK))
|
|
|
|
/* Check whether TX FIFO is locked. */
|
|
#define IMU_TX_FIFO_LOCKED(link) \
|
|
(0UL != \
|
|
(((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_STATUS & IMU_MSG_FIFO_STATUS_MSG_FIFO_LOCKED_MASK))
|
|
|
|
/* Check whether TX FIFO is almost full. */
|
|
#define IMU_TX_FIFO_ALMOST_FULL(link) \
|
|
(0UL != (((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_STATUS & \
|
|
IMU_MSG_FIFO_STATUS_MSG_FIFO_ALMOST_FULL_MASK))
|
|
|
|
/*! @brief Get Rx FIFO empty status. */
|
|
#define IMU_RX_FIFO_EMPTY(link) \
|
|
(0UL != \
|
|
(((IMU_Type *)(uintptr_t)IMU_PEER_CPU_BASE(link))->MSG_FIFO_STATUS & IMU_MSG_FIFO_STATUS_MSG_FIFO_EMPTY_MASK))
|
|
|
|
/* Lock the TX FIFO. */
|
|
#define IMU_LOCK_TX_FIFO(link) \
|
|
(((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL |= IMU_MSG_FIFO_CNTL_WAIT_FOR_ACK_MASK)
|
|
|
|
/* Unlock the TX FIFO. */
|
|
#define IMU_UNLOCK_TX_FIFO(link) \
|
|
(((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL &= ~IMU_MSG_FIFO_CNTL_WAIT_FOR_ACK_MASK)
|
|
|
|
/* Get message count in RX FIFO. */
|
|
#define IMU_RX_FIFO_MSG_COUNT(link) \
|
|
((((IMU_Type *)(uintptr_t)IMU_PEER_CPU_BASE(link))->MSG_FIFO_STATUS & IMU_MSG_FIFO_STATUS_MSG_COUNT_MASK) >> \
|
|
IMU_MSG_FIFO_STATUS_MSG_COUNT_SHIFT)
|
|
|
|
/* Get message count in TX FIFO. */
|
|
#define IMU_TX_FIFO_MSG_COUNT(link) \
|
|
((((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_STATUS & IMU_MSG_FIFO_STATUS_MSG_COUNT_MASK) >> \
|
|
IMU_MSG_FIFO_STATUS_MSG_COUNT_SHIFT)
|
|
|
|
/* Get message count from RX FIFO status register value. */
|
|
#define IMU_RX_FIFO_MSG_COUNT_FROM_STATUS(rxFifoStatus) \
|
|
(((rxFifoStatus)&IMU_MSG_FIFO_STATUS_MSG_COUNT_MASK) >> IMU_MSG_FIFO_STATUS_MSG_COUNT_SHIFT)
|
|
|
|
/* Get RX FIFO lock status from RX FIFO status register value. */
|
|
#define IMU_RX_FIFO_LOCKED_FROM_STATUS(rxFifoStatus) (0UL != ((rxFifoStatus)&IMU_MSG_FIFO_STATUS_MSG_FIFO_LOCKED_MASK))
|
|
|
|
/* TX FIFO status register. */
|
|
#define IMU_TX_FIFO_STATUS(link) (((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_STATUS)
|
|
|
|
/* RX FIFO status register. */
|
|
#define IMU_RX_FIFO_STATUS(link) (((IMU_Type *)(uintptr_t)IMU_PEER_CPU_BASE(link))->MSG_FIFO_STATUS)
|
|
|
|
/* RX FIFO control register. */
|
|
#define IMU_TX_FIFO_CNTL(link) (((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL)
|
|
|
|
/*! @brief IMU driver returned error value. */
|
|
#define IMU_ERR_TX_FIFO_LOCKED (-1L)
|
|
|
|
/*! @brief Maximum message numbers in FIFO. */
|
|
#define IMU_MSG_FIFO_MAX_COUNT 16U
|
|
|
|
/*! @brief Maximum message FIFO warter mark. */
|
|
#define IMU_MAX_MSG_FIFO_WATER_MARK (IMU_MSG_FIFO_MAX_COUNT - 1U)
|
|
|
|
/* IMP: ICC_MAX_MSG_CNT should be power of 2 */
|
|
#define IMU_FIFO_SW_WRAPAROUND(ptr) ((ptr) & (IMU_MSG_FIFO_MAX_COUNT - 1U))
|
|
|
|
#define IMU_WR_PTR(link) \
|
|
IMU_FIFO_SW_WRAPAROUND((IMU_TX_FIFO_STATUS(link) & IMU_MSG_FIFO_STATUS_WR_PTR_MASK) >> \
|
|
IMU_MSG_FIFO_STATUS_WR_PTR_SHIFT)
|
|
|
|
#define IMU_RD_PTR(link) \
|
|
IMU_FIFO_SW_WRAPAROUND((IMU_RX_FIFO_STATUS(link) & IMU_MSG_FIFO_STATUS_RD_PTR_MASK) >> \
|
|
IMU_MSG_FIFO_STATUS_RD_PTR_SHIFT)
|
|
|
|
/*!
|
|
* @brief IMU status flags.
|
|
* @anchor _imu_status_flags
|
|
*/
|
|
enum _imu_status_flags
|
|
{
|
|
kIMU_TxFifoEmpty = IMU_MSG_FIFO_STATUS_MSG_FIFO_EMPTY_MASK,
|
|
kIMU_TxFifoFull = IMU_MSG_FIFO_STATUS_MSG_FIFO_FULL_MASK,
|
|
kIMU_TxFifoAlmostFull = IMU_MSG_FIFO_STATUS_MSG_FIFO_ALMOST_FULL_MASK,
|
|
kIMU_TxFifoLocked = IMU_MSG_FIFO_STATUS_MSG_FIFO_LOCKED_MASK,
|
|
kIMU_RxFifoEmpty = IMU_MSG_FIFO_STATUS_MSG_FIFO_EMPTY_MASK << 8U,
|
|
kIMU_RxFifoFull = IMU_MSG_FIFO_STATUS_MSG_FIFO_FULL_MASK << 8U,
|
|
kIMU_RxFifoAlmostFull = IMU_MSG_FIFO_STATUS_MSG_FIFO_ALMOST_FULL_MASK << 8U,
|
|
kIMU_RxFifoLocked = IMU_MSG_FIFO_STATUS_MSG_FIFO_LOCKED_MASK << 8U,
|
|
};
|
|
|
|
/*!
|
|
* @brief IMU interrupt.
|
|
* @anchor _imu_interrupts
|
|
*/
|
|
enum _imu_interrupts
|
|
{
|
|
kIMU_RxMsgReadyInterrupt = IMU_MSG_FIFO_CNTL_MSG_RDY_INT_CLR_MASK,
|
|
kIMU_TxFifoSpaceAvailableInterrupt = IMU_MSG_FIFO_CNTL_SP_AV_INT_CLR_MASK,
|
|
};
|
|
|
|
/*! @brief IMU register structure. */
|
|
typedef struct
|
|
{
|
|
volatile uint32_t WR_MSG;
|
|
const volatile uint32_t RD_MSG;
|
|
const volatile uint32_t MSG_FIFO_STATUS;
|
|
volatile uint32_t MSG_FIFO_CNTL;
|
|
const volatile uint32_t RD_MSG_DBG;
|
|
} IMU_Type;
|
|
|
|
/*******************************************************************************
|
|
* API
|
|
******************************************************************************/
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*!
|
|
* @name IMU initialization.
|
|
* @{
|
|
*/
|
|
|
|
/*!
|
|
* @brief Initializes the IMU module.
|
|
*
|
|
* This function sets IMU to initialized state, including:
|
|
*
|
|
* - Flush the send FIFO.
|
|
* - Unlock the send FIFO.
|
|
* - Set the water mark to (IMU_MAX_MSG_FIFO_WATER_MARK)
|
|
* - Flush the read FIFO.
|
|
*
|
|
* @param link IMU link.
|
|
* @retval kStatus_InvalidArgument The link is invalid.
|
|
* @retval kStatus_Success Initialized successfully.
|
|
*/
|
|
status_t IMU_Init(imu_link_t link);
|
|
|
|
/*!
|
|
* @brief De-initializes the IMU module.
|
|
*
|
|
* @param link IMU link.
|
|
*/
|
|
void IMU_Deinit(imu_link_t link);
|
|
|
|
/*! @} */
|
|
|
|
/*!
|
|
* @name IMU Message
|
|
* @{
|
|
*/
|
|
|
|
/*!
|
|
* @brief Write one message to TX FIFO.
|
|
*
|
|
* This function writes message to the TX FIFO, user need to make sure
|
|
* there is empty space in the TX FIFO, and TX FIFO not locked before
|
|
* calling this function.
|
|
*
|
|
* @param link IMU link.
|
|
* @param msg The message to send.
|
|
*/
|
|
static inline void IMU_WriteMsg(imu_link_t link, uint32_t msg)
|
|
{
|
|
IMU_WR_MSG(link, msg);
|
|
}
|
|
|
|
/*!
|
|
* @brief Read one message from RX FIFO.
|
|
*
|
|
* User need to make sure there is available message in the RX FIFO.
|
|
*
|
|
* @param link IMU link.
|
|
* @return The message.
|
|
*/
|
|
static inline uint32_t IMU_ReadMsg(imu_link_t link)
|
|
{
|
|
return IMU_RD_MSG(link);
|
|
}
|
|
|
|
/*!
|
|
* @brief Blocking to send messages.
|
|
*
|
|
* This function blocks until all messages have been filled to TX FIFO.
|
|
*
|
|
* - If the TX FIFO is locked, this function returns IMU_ERR_TX_FIFO_LOCKED.
|
|
* - If TX FIFO not locked, this function waits the available empty slot in TX FIFO,
|
|
* and fills the message to TX FIFO.
|
|
* - To lock TX FIFO after filling all messages, set @p lockSendFifo to true.
|
|
*
|
|
* @param link IMU link.
|
|
* @param msgs The messages to send.
|
|
* @param msgCount Message count, one message is a 32-bit word.
|
|
* @param lockSendFifo If set to true, the TX FIFO is locked after all messages filled to TX FIFO.
|
|
* @return If TX FIFO is locked, this function returns IMU_ERR_TX_FIFO_LOCKED,
|
|
* otherwise, this function returns the actual message count sent out, it equals @p msgCount
|
|
* because this function is blocking function, it returns until all messages have been
|
|
* filled into TX FIFO.
|
|
*/
|
|
int32_t IMU_SendMsgsBlocking(imu_link_t link, const uint32_t *msgs, int32_t msgCount, bool lockSendFifo);
|
|
|
|
/*!
|
|
* @brief Try to send messages.
|
|
*
|
|
* This function is similar with @ref IMU_SendMsgsBlocking, the difference is,
|
|
* this function tries to send as many as possible, if there is not enough
|
|
* empty slot in TX FIFO, this function fills messages to available empty slots
|
|
* and returns how many messages have been filled.
|
|
*
|
|
* - If the TX FIFO is locked, this function returns IMU_ERR_TX_FIFO_LOCKED.
|
|
* - If TX FIFO not locked, this function fills messages to TX FIFO empty slot,
|
|
* and returns how many messages have been filled.
|
|
* - If @p lockSendFifo is set to true, TX FIFO is locked after all messages have
|
|
* been filled to TX FIFO. In other word, TX FIFO is locked if the function
|
|
* return value equals @p msgCount, when @p lockSendFifo set to true.
|
|
*
|
|
* @param link IMU link.
|
|
* @param msgs The messages to send.
|
|
* @param msgCount Message count, one message is a 32-bit word.
|
|
* @param lockSendFifo If set to true, the TX FIFO is locked after all messages filled to TX FIFO.
|
|
* @return If TX FIFO is locked, this function returns IMU_ERR_TX_FIFO_LOCKED,
|
|
* otherwise, this function returns the actual message count sent out.
|
|
*/
|
|
int32_t IMU_TrySendMsgs(imu_link_t link, const uint32_t *msgs, int32_t msgCount, bool lockSendFifo);
|
|
|
|
/*!
|
|
* @brief Try to receive messages.
|
|
*
|
|
* This function tries to read messages from RX FIFO. It reads the messages already
|
|
* exists in RX FIFO and returns the actual read count.
|
|
*
|
|
* - If the RX FIFO has enough messages, this function reads the messages and returns.
|
|
* - If the RX FIFO does not have enough messages, this function the messages in RX FIFO
|
|
* and returns the actual read count.
|
|
* - During message reading, if RX FIFO is empty and locked, in this case peer CPU will not
|
|
* send message until current CPU send lock ack message. Then this function
|
|
* returns the message count actually received, and sets @p needAckLock to true
|
|
* to inform upper layer.
|
|
*
|
|
* @param link IMU link.
|
|
* @param msgs The buffer to read messages.
|
|
* @param desiredMsgCount Desired read count, one message is a 32-bit word.
|
|
* @param needAckLock Upper layer should always check this value. When this is
|
|
* set to true by this function, upper layer should send lock ack message to peer CPU.
|
|
* @return Count of messages actually received.
|
|
*/
|
|
int32_t IMU_TryReceiveMsgs(imu_link_t link, uint32_t *msgs, int32_t desiredMsgCount, bool *needAckLock);
|
|
|
|
/*!
|
|
* @brief Blocking to receive messages.
|
|
*
|
|
* This function blocks until all desired messages have been received or the RX FIFO
|
|
* is locked.
|
|
*
|
|
* - If the RX FIFO has enough messages, this function reads the messages and returns.
|
|
* - If the RX FIFO does not have enough messages, this function waits for the new
|
|
* messages.
|
|
* - During message reading, if RX FIFO is empty and locked, in this case peer CPU will not
|
|
* send message until current CPU send lock ack message. Then this function
|
|
* returns the message count actually received, and sets @p needAckLock to true
|
|
* to inform upper layer.
|
|
*
|
|
* @param link IMU link.
|
|
* @param msgs The buffer to read messages.
|
|
* @param desiredMsgCount Desired read count, one message is a 32-bit word.
|
|
* @param needAckLock Upper layer should always check this value. When this is
|
|
* set to true by this function, upper layer should send lock ack message to peer CPU.
|
|
* @return Count of messages actually received.
|
|
*/
|
|
int32_t IMU_ReceiveMsgsBlocking(imu_link_t link, uint32_t *msgs, int32_t desiredMsgCount, bool *needAckLock);
|
|
|
|
/*!
|
|
* @brief Blocking to send messages pointer.
|
|
*
|
|
* Compared with @ref IMU_SendMsgsBlocking, this function fills message pointer
|
|
* to TX FIFO, but not the message content.
|
|
*
|
|
* This function blocks until the message pointer is filled to TX FIFO.
|
|
*
|
|
* - If the TX FIFO is locked, this function returns IMU_ERR_TX_FIFO_LOCKED.
|
|
* - If TX FIFO not locked, this function waits the available empty slot in TX FIFO,
|
|
* and fills the message pointer to TX FIFO.
|
|
* - To lock TX FIFO after filling the message pointer, set @p lockSendFifo to true.
|
|
*
|
|
* @param link IMU link.
|
|
* @param msgPtr The buffer pointer to message to send.
|
|
* @param needAckLock Upper layer should always check this value. When this is
|
|
* set to true by this function, upper layer should send lock ack message to peer CPU.
|
|
* @retval 0 The message pointer set successfully.
|
|
* @retval IMU_ERR_TX_FIFO_LOCKED The TX FIFO is locked, send failed.
|
|
*/
|
|
int32_t IMU_SendMsgPtrBlocking(imu_link_t link, uint32_t msgPtr, bool lockSendFifo);
|
|
|
|
/*!
|
|
* @brief Lock or unlock the TX FIFO.
|
|
*
|
|
* @param link IMU link.
|
|
* @param lock Use true to lock the FIFO, use false to unlock.
|
|
*/
|
|
static inline void IMU_LockSendFifo(imu_link_t link, bool lock)
|
|
{
|
|
if (lock)
|
|
{
|
|
((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL |= IMU_MSG_FIFO_CNTL_WAIT_FOR_ACK_MASK;
|
|
}
|
|
else
|
|
{
|
|
((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL &= ~IMU_MSG_FIFO_CNTL_WAIT_FOR_ACK_MASK;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* @brief Flush the send FIFO.
|
|
*
|
|
* Flush all messages in send FIFO.
|
|
*
|
|
* @param link IMU link.
|
|
*/
|
|
void IMU_FlushSendFifo(imu_link_t link);
|
|
|
|
/*!
|
|
* @brief Set send FIFO warter mark.
|
|
*
|
|
* The warter mark must be less than IMU_MAX_MSG_FIFO_WATER_MARK,
|
|
* i.e. 0 < waterMark <= IMU_MAX_MSG_FIFO_WATER_MARK.
|
|
*
|
|
* @param link IMU link.
|
|
* @param waterMark Send FIFO warter mark.
|
|
*/
|
|
static inline void IMU_SetSendFifoWaterMark(imu_link_t link, uint8_t waterMark)
|
|
{
|
|
uint32_t reg = ((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL;
|
|
|
|
reg &= ~IMU_MSG_FIFO_CNTL_FIFO_FULL_WATERMARK_MASK;
|
|
reg |= IMU_MSG_FIFO_CNTL_FIFO_FULL_WATERMARK(waterMark);
|
|
|
|
((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL = reg;
|
|
}
|
|
|
|
/*!
|
|
* @brief Get the message count in receive FIFO.
|
|
*
|
|
* @param link IMU link.
|
|
* @return The message count in receive FIFO.
|
|
*/
|
|
static inline uint32_t IMU_GetReceivedMsgCount(imu_link_t link)
|
|
{
|
|
return IMU_RX_FIFO_MSG_COUNT(link);
|
|
}
|
|
|
|
/*!
|
|
* @brief Get the empty slot in send FIFO.
|
|
*
|
|
* @param link IMU link.
|
|
* @return The empty slot count in send FIFO.
|
|
*/
|
|
static inline uint32_t IMU_GetSendFifoEmptySpace(imu_link_t link)
|
|
{
|
|
return IMU_MSG_FIFO_MAX_COUNT - IMU_TX_FIFO_MSG_COUNT(link) - 1U;
|
|
}
|
|
|
|
/*! @} */
|
|
|
|
/*!
|
|
* @name Status and Interrupt.
|
|
* @{
|
|
*/
|
|
|
|
/*!
|
|
* @brief Gets the IMU status flags.
|
|
*
|
|
* @param link IMU link.
|
|
* @return Bit mask of the IMU status flags, see @ref _imu_status_flags.
|
|
*/
|
|
uint32_t IMU_GetStatusFlags(imu_link_t link);
|
|
|
|
/*!
|
|
* @brief Clear the IMU IRQ
|
|
*
|
|
* @param link IMU link.
|
|
* @param mask Bit mask of the interrupts to clear, see @ref _imu_interrupts.
|
|
*/
|
|
static inline void IMU_ClearPendingInterrupts(imu_link_t link, uint32_t mask)
|
|
{
|
|
((IMU_Type *)(uintptr_t)IMU_CUR_CPU_BASE(link))->MSG_FIFO_CNTL |= mask;
|
|
}
|
|
|
|
/*! @} */
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif /*_cplusplus*/
|
|
/*! @} */
|
|
|
|
#endif /* FSL_IMU_H_*/
|