X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fssi_lm3s.h;h=d8ab39ea10b58d3f2192decba62a9c40229622a3;hb=563795df4180aaceb7d69306551230c98fbca879;hp=69b88ac2abe540a73c36657fc2d9ef7cc561de6b;hpb=dc8158b1e365c04ab3cbb198cbcac6cc5bdedb87;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/ssi_lm3s.h b/bertos/cpu/cortex-m3/drv/ssi_lm3s.h index 69b88ac2..d8ab39ea 100644 --- a/bertos/cpu/cortex-m3/drv/ssi_lm3s.h +++ b/bertos/cpu/cortex-m3/drv/ssi_lm3s.h @@ -31,12 +31,15 @@ * --> * * \brief LM3S1968 Synchronous Serial Interface (SSI) driver. + * */ #ifndef SSI_LM3S_H #define SSI_LM3S_H #include /* cpu_relax() */ +#include /* KFile */ +#include /** * LM3S1968 SSI frame format @@ -59,20 +62,130 @@ #define SSI_MODE_SLAVE_OD 0x00000002 //< SSI slave with output disabled /*\}*/ -int lm3s_ssi_init(uint32_t base, uint32_t frame, int mode, - unsigned int bitrate, unsigned int data_width); -void lm3s_ssi_enable(uint32_t base); -void lm3s_ssi_disable(uint32_t base); -void lm3s_ssi_write_frame(uint32_t base, uint32_t val); -int lm3s_ssi_write_frame_nonblocking(uint32_t base, uint32_t val); -void lm3s_ssi_read_frame(uint32_t base, uint32_t *val); -int lm3s_ssi_read_frame_nonblocking(uint32_t base, uint32_t *val); -bool lm3s_ssi_txdone(uint32_t base); - -INLINE void lm3s_ssi_wait_txdone(uint32_t base) +/* LM3S SSI handle properties */ +enum +{ + /* Non-blocking I/O */ + LM3S_SSI_NONBLOCK = 1, +}; + +/** LM3S1968 SSI handle structure */ +typedef struct LM3SSSI +{ + /* SSI Kfile structure */ + KFile fd; + + /* Handle properties */ + uint32_t flags; + + /* SSI port address */ + uint32_t addr; +} LM3SSSI; + +/** + * ID for LM3S SSI. + */ +#define KFT_LM3SSSI MAKE_ID('L', 'S', 'S', 'I') + +INLINE LM3SSSI *LM3SSSI_CAST(KFile *fd) +{ + ASSERT(fd->_type == KFT_LM3SSSI); + return (LM3SSSI *)fd; +} + +/* KFile interface to LM3S SSI */ +void lm3s_ssiInit(struct LM3SSSI *fds, uint32_t addr, uint32_t frame, int mode, + int bitrate, uint32_t data_width); + +/* Raw interface to LM3S SSI */ +int lm3s_ssiOpen(uint32_t addr, uint32_t frame, int mode, + int bitrate, uint32_t data_width); + +/* + * Check if the SSI transmitter is busy or not + * + * This allows to determine whether the TX FIFO have been cleared by the + * hardware, so the transmission can be safely considered completed. + */ +INLINE bool lm3s_ssiTxDone(uint32_t base) +{ + return (HWREG(base + SSI_O_SR) & SSI_SR_BSY) ? true : false; +} + +/* + * Check if the SSI TX FIFO is full + */ +INLINE bool lm3s_ssiTxReady(uint32_t base) +{ + return (HWREG(base + SSI_O_SR) & SSI_SR_TNF) ? true : false; +} + +/* + * Check for data available in the RX FIFO + */ +INLINE bool lm3s_ssiRxReady(uint32_t base) +{ + return (HWREG(base + SSI_O_SR) & SSI_SR_RNE) ? true : false; +} + +/* + * Get a frame into the SSI receive FIFO without blocking. + * + * Return the number of frames read from the RX FIFO. + */ +INLINE int lm3s_ssiReadFrameNonBlocking(uint32_t base, uint32_t *val) +{ + /* Check for data available in the RX FIFO */ + if (!lm3s_ssiRxReady(base)) + return 0; + /* Read data from SSI RX FIFO */ + *val = HWREG(base + SSI_O_DR); + return 1; +} + +/* + * Get a frame from the SSI receive FIFO. + */ +INLINE void lm3s_ssiReadFrame(uint32_t base, uint32_t *val) +{ + /* Wait for data available in the RX FIFO */ + while (!lm3s_ssiRxReady(base)) + cpu_relax(); + /* Read data from SSI RX FIFO */ + *val = HWREG(base + SSI_O_DR); +} + +/* + * Put a frame into the SSI transmit FIFO without blocking. + * + * NOTE: the upper bits of the frame will be automatically discarded by the + * hardware according to the frame data width. + * + * Return the number of frames written to the TX FIFO. + */ +INLINE int lm3s_ssiWriteFrameNonBlocking(uint32_t base, uint32_t val) +{ + /* Check for available space in the TX FIFO */ + if (!lm3s_ssiTxReady(base)) + return 0; + /* Enqueue data to the TX FIFO */ + HWREG(base + SSI_O_DR) = val; + return 1; +} + +/* + * Put a frame into the SSI transmit FIFO. + * + * NOTE: the upper bits of the frame will be automatically discarded by the + * hardware according to the frame data width. + */ +INLINE void lm3s_ssiWriteFrame(uint32_t base, uint32_t val) { - while (!lm3s_ssi_txdone(base)) + /* Wait for available space in the TX FIFO */ + while (!lm3s_ssiTxReady(base)) cpu_relax(); + /* Enqueue data to the TX FIFO */ + HWREG(base + SSI_O_DR) = val; } -#endif /* LM3S_SSI_H */ +#endif /* SSI_LM3S_H */