aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-09-28 16:01:31 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-09-28 16:01:31 +0000
commitee48ed8aa675e9ed3adec18969675441e2d8b998 (patch)
treec65b96bf243aba978d1ce0245ea20143dbd1692a /os/hal/platforms
parent798f17d3f274dcc7a7a165db05556eac6da48bb3 (diff)
downloadChibiOS-ee48ed8aa675e9ed3adec18969675441e2d8b998.tar.gz
ChibiOS-ee48ed8aa675e9ed3adec18969675441e2d8b998.tar.bz2
ChibiOS-ee48ed8aa675e9ed3adec18969675441e2d8b998.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4718 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms')
-rw-r--r--os/hal/platforms/SPC56x/serial_lld.h2
-rw-r--r--os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c119
-rw-r--r--os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.h64
3 files changed, 149 insertions, 36 deletions
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. */
/*===========================================================================*/