From ee48ed8aa675e9ed3adec18969675441e2d8b998 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 28 Sep 2012 16:01:31 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4718 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/SPC56x/serial_lld.h | 2 +- os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c | 119 +++++++++++++++++------- os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.h | 64 +++++++++++++ 3 files changed, 149 insertions(+), 36 deletions(-) (limited to 'os/hal') diff --git a/os/hal/platforms/SPC56x/serial_lld.h b/os/hal/platforms/SPC56x/serial_lld.h index 93ccb8365..b02b160b1 100644 --- a/os/hal/platforms/SPC56x/serial_lld.h +++ b/os/hal/platforms/SPC56x/serial_lld.h @@ -35,7 +35,7 @@ /* Driver constants. */ /*===========================================================================*/ -#define SD_MODE_PARITY 0x03 /**< @brief Parity field mask. */ +#define SD_MODE_PARITY_MASK 0x03 /**< @brief Parity field mask. */ #define SD_MODE_PARITY_NONE 0x00 /**< @brief No parity. */ #define SD_MODE_PARITY_EVEN 0x01 /**< @brief Even parity. */ #define SD_MODE_PARITY_ODD 0x02 /**< @brief Odd parity. */ diff --git a/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c b/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c index 077d61b06..8e392fce6 100644 --- a/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c +++ b/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c @@ -87,13 +87,26 @@ static const SerialConfig default_config = { * @param[in] config the architecture-dependent serial driver configuration */ static void spc5_linflex_init(SerialDriver *sdp, const SerialConfig *config) { + uint32_t div; volatile struct LINFLEX_tag *linflexp = sdp->linflexp; - linflexp->LINFBRR.R = 0; /* Fractional divider. */ - linflexp->LINIBRR.R = 0; /* Integer divider. */ - linflexp->UARTSR.R = 0xFFFF; /* Clearing UART status register. */ - linflexp->UARTCR.R = config->mode | 1;/* Enforced UART mode. */ - linflexp->LINIER.R = 0; /* Interrupts enabled. */ + /* Enters the configuration mode.*/ + linflexp->LINCR1.R = 1; /* INIT bit. */ + + /* Configures the LINFlex in UART mode with all the required + parameters.*/ + div = halSPC560PGetSystemClock() / (16 * config->speed); + linflexp->LINFBRR.R = (uint16_t)(div & 15); /* Fractional divider. */ + linflexp->LINIBRR.R = (uint16_t)(div >> 4); /* Integer divider. */ + linflexp->UARTSR.R = 0xFFFF; /* Clearing UARTSR register.*/ + linflexp->UARTCR.R = config->mode | + SPC5_UARTCR_RXEN | SPC5_UARTCR_UART; + linflexp->LINIER.R = SPC5_LINIER_DTIE | SPC5_LINIER_DRIE | + SPC5_LINIER_BOIE | SPC5_LINIER_FEIE | + SPC5_LINIER_SZIE; /* Interrupts enabled. */ + + /* Leaves the configuration mode.*/ + linflexp->LINCR1.R = 0; } /** @@ -104,38 +117,18 @@ static void spc5_linflex_init(SerialDriver *sdp, const SerialConfig *config) { */ static void spc5_linflex_deinit(volatile struct LINFLEX_tag *linflexp) { -#if 0 - escip->LPR.R = 0; - escip->SR.R = 0xFFFFFFFF; - escip->CR1.R = 0; - escip->CR2.R = 0x8000; /* MDIS on. */ -#endif -} + /* Enters the configuration mode.*/ + linflexp->LINCR1.R = 1; /* INIT bit. */ -/** - * @brief Error handling routine. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] sr eSCI SR register value - */ -static void set_error(SerialDriver *sdp, uint32_t sr) { - flagsmask_t sts = 0; + /* Resets the LINFlex registers.*/ + linflexp->LINFBRR.R = 0; /* Fractional divider. */ + linflexp->LINIBRR.R = 0; /* Integer divider. */ + linflexp->UARTSR.R = 0xFFFF; /* Clearing UARTSR register.*/ + linflexp->UARTCR.R = SPC5_UARTCR_UART; + linflexp->LINIER.R = 0; /* Interrupts disabled. */ -#if 0 - if (sr & 0x08000000) - sts |= SD_OVERRUN_ERROR; - if (sr & 0x04000000) - sts |= SD_NOISE_ERROR; - if (sr & 0x02000000) - sts |= SD_FRAMING_ERROR; - if (sr & 0x01000000) - sts |= SD_PARITY_ERROR; -/* if (sr & 0x00000000) - sts |= SD_BREAK_DETECTED;*/ -#endif - chSysLockFromIsr(); - chnAddFlagsI(sdp, sts); - chSysUnlockFromIsr(); + /* Leaves the configuration mode.*/ + linflexp->LINCR1.R = 0; } /** @@ -144,6 +137,24 @@ static void set_error(SerialDriver *sdp, uint32_t sr) { * @param[in] sdp pointer to a @p SerialDriver object */ static void spc5xx_serve_rxi_interrupt(SerialDriver *sdp) { + flagsmask_t sts = 0; + uint16_t sr = sdp->linflexp->UARTSR.R; + + sdp->linflexp->UARTSR.R = SPC5_UARTSR_NF | SPC5_UARTSR_DRF | + SPC5_UARTSR_PE0; + if (sr & SPC5_UARTSR_NF) + sts |= SD_NOISE_ERROR; + if (sr & SPC5_UARTSR_PE0) + sts |= SD_PARITY_ERROR; + if (sts) { + chSysLockFromIsr(); + chnAddFlagsI(sdp, sts); + chSysUnlockFromIsr(); + } + if (sr & SPC5_UARTSR_DRF) { + sdIncomingDataI(sdp, sdp->linflexp->BDRL.B.DATA0); + sdp->linflexp->UARTSR.R = SPC5_UARTSR_RMB; + } } /** @@ -152,6 +163,16 @@ static void spc5xx_serve_rxi_interrupt(SerialDriver *sdp) { * @param[in] sdp pointer to a @p SerialDriver object */ static void spc5xx_serve_txi_interrupt(SerialDriver *sdp) { + msg_t b; + + sdp->linflexp->UARTSR.R = SPC5_UARTSR_DTF; + b = chOQGetI(&sdp->oqueue); + if (b < Q_OK) { + chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); + sdp->linflexp->UARTCR.B.TXEN = 0; + } + else + sdp->linflexp->BDRL.B.DATA0 = b; } /** @@ -160,12 +181,33 @@ static void spc5xx_serve_txi_interrupt(SerialDriver *sdp) { * @param[in] sdp pointer to a @p SerialDriver object */ static void spc5xx_serve_err_interrupt(SerialDriver *sdp) { + flagsmask_t sts = 0; + uint16_t sr = sdp->linflexp->UARTSR.R; + + sdp->linflexp->UARTSR.R = SPC5_UARTSR_BOF | SPC5_UARTSR_FEF | + SPC5_UARTSR_SZF; + if (sr & SPC5_UARTSR_BOF) + sts |= SD_OVERRUN_ERROR; + if (sr & SPC5_UARTSR_FEF) + sts |= SD_FRAMING_ERROR; + if (sr & SPC5_UARTSR_SZF) + sts |= SD_BREAK_DETECTED; + chSysLockFromIsr(); + chnAddFlagsI(sdp, sts); + chSysUnlockFromIsr(); } #if SPC5_SERIAL_USE_LINFLEX0 || defined(__DOXYGEN__) static void notify1(GenericQueue *qp) { (void)qp; + if (!SD1.linflexp->UARTCR.B.TXEN) { + msg_t b = sdRequestDataI(&SD1); + if (b != Q_EMPTY) { + SD1.linflexp->UARTCR.B.TXEN = 1; + SD1.linflexp->BDRL.B.DATA0 = b; + } + } } #endif @@ -173,6 +215,13 @@ static void notify1(GenericQueue *qp) { static void notify2(GenericQueue *qp) { (void)qp; + if (!SD2.linflexp->UARTCR.B.TXEN) { + msg_t b = sdRequestDataI(&SD2); + if (b != Q_EMPTY) { + SD2.linflexp->UARTCR.B.TXEN = 1; + SD2.linflexp->BDRL.B.DATA0 = b; + } + } } #endif diff --git a/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.h b/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.h index 0568310a3..12ab8cbcc 100644 --- a/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.h +++ b/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.h @@ -35,6 +35,70 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @name LINIER register bits definitions + * @{ + */ +#define SPC5_LINIER_HRIE (1U << 0) +#define SPC5_LINIER_DTIE (1U << 1) +#define SPC5_LINIER_DRIE (1U << 2) +#define SPC5_LINIER_DBEIE (1U << 3) +#define SPC5_LINIER_DBFIE (1U << 4) +#define SPC5_LINIER_WUIE (1U << 5) +#define SPC5_LINIER_LSIE (1U << 6) +#define SPC5_LINIER_BOIE (1U << 7) +#define SPC5_LINIER_FEIE (1U << 8) +#define SPC5_LINIER_HEIE (1U << 11) +#define SPC5_LINIER_CEIE (1U << 12) +#define SPC5_LINIER_BEIE (1U << 13) +#define SPC5_LINIER_OCIE (1U << 14) +#define SPC5_LINIER_SZIE (1U << 15) +/** @} */ + +/** + * @name UARTSR register bits definitions + * @{ + */ +#define SPC5_UARTSR_NF (1U << 0) +#define SPC5_UARTSR_DTF (1U << 1) +#define SPC5_UARTSR_DRF (1U << 2) +#define SPC5_UARTSR_WUF (1U << 5) +#define SPC5_UARTSR_RPS (1U << 6) +#define SPC5_UARTSR_BOF (1U << 7) +#define SPC5_UARTSR_FEF (1U << 8) +#define SPC5_UARTSR_RMB (1U << 9) +#define SPC5_UARTSR_PE0 (1U << 10) +#define SPC5_UARTSR_PE1 (1U << 11) +#define SPC5_UARTSR_PE2 (1U << 12) +#define SPC5_UARTSR_PE3 (1U << 13) +#define SPC5_UARTSR_OCF (1U << 14) +#define SPC5_UARTSR_SZF (1U << 15) +/** @} */ + +/** + * @name UARTCR register bits definitions + * @{ + */ +#define SPC5_UARTCR_UART (1U << 0) +#define SPC5_UARTCR_WL (1U << 1) +#define SPC5_UARTCR_PCE (1U << 2) +#define SPC5_UARTCR_OP (1U << 3) +#define SPC5_UARTCR_TXEN (1U << 4) +#define SPC5_UARTCR_RXEN (1U << 5) +/** @} */ + +/** + * @name Serial driver allowable modes + * @{ + */ +#define SD_MODE_8BITS_PARITY_NONE 0 +#define SD_MODE_8BITS_PARITY_EVEN (SPC5_UARTCR_WL | \ + SPC5_UARTCR_PCE) +#define SD_MODE_8BITS_PARITY_ODD (SPC5_UARTCR_WL | \ + SPC5_UARTCR_PCE | \ + SPC5_UARTCR_OP) +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ -- cgit v1.2.3