Systick works now, better SPC560P ME support.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4707 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
gdisirio 2012-09-21 10:39:16 +00:00
parent 7a68e17dd0
commit 442fea6ed3
7 changed files with 768 additions and 10 deletions

View File

@ -45,6 +45,25 @@
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief PIT channel 3 interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(vector127) {
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
chSysTimerHandlerI();
chSysUnlockFromIsr();
/* Resets the PIT channel 3 IRQ flag.*/
PIT.CH[3].TFLG.R = 1;
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@ -55,11 +74,31 @@
* @notapi
*/
void hal_lld_init(void) {
extern void _vectors(void);
uint32_t reg;
/* The system is switched to the RUN0 mode, the default for normal
operations.*/
if (halSPC560PSetRunMode(SPC560P_RUNMODE_RUN0) == CH_FAILED)
chSysHalt();
/* INTC initialization, software vector mode, 4 bytes vectors, starting
at priority 0.*/
INTC.MCR.R = 0;
INTC.CPR.R = 0;
INTC.IACKR.R = (uint32_t)_vectors;
/* PIT channel 3 initialization for Kernel ticks, the PIT is configured
to run in DRUN,RUN0...RUN3 and HALT0 modes, the clock is gated in other
modes.*/
INTC.PSR[127].R = SPC560P_PIT3_IRQ_PRIORITY;
ME.PCTL[92].R = SPC560P_ME_PCTL_RUN(2) | SPC560P_ME_PCTL_LP(2);
reg = halSPC560PGetSystemClock() / CH_FREQUENCY - 1;
PIT.PITMCR.R = 1; /* PIT clock enabled, stop while debugging. */
PIT.CH[3].LDVAL.R = reg;
PIT.CH[3].CVAL.R = reg;
PIT.CH[3].TFLG.R = 1; /* Interrupt flag cleared. */
PIT.CH[3].TCTRL.R = 3; /* Timer active, interrupt enabled. */
}
/**
@ -100,12 +139,30 @@ void spc560p_clock_init(void) {
ME.SAFE.R = SPC560P_ME_SAFE_MC_BITS; /* SAFE run mode. */
ME.DRUN.R = SPC560P_ME_DRUN_MC_BITS; /* DRUN run mode. */
ME.RUN[0].R = SPC560P_ME_RUN0_MC_BITS; /* RUN0 run mode. */
ME.RUN[1].R = SPC560P_ME_RUN1_MC_BITS; /* RUN0 run mode. */
ME.RUN[2].R = SPC560P_ME_RUN2_MC_BITS; /* RUN0 run mode. */
ME.RUN[1].R = SPC560P_ME_RUN1_MC_BITS; /* RUN1 run mode. */
ME.RUN[2].R = SPC560P_ME_RUN2_MC_BITS; /* RUN2 run mode. */
ME.RUN[3].R = SPC560P_ME_RUN3_MC_BITS; /* RUN0 run mode. */
ME.HALT0.R = SPC560P_ME_HALT0_MC_BITS; /* HALT0 run mode. */
ME.STOP0.R = SPC560P_ME_STOP0_MC_BITS; /* STOP0 run mode. */
/* Peripherals run and low power modes initialization.*/
ME.RUNPC[0].R = SPC560P_ME_RUN_PC0_BITS;
ME.RUNPC[1].R = SPC560P_ME_RUN_PC1_BITS;
ME.RUNPC[2].R = SPC560P_ME_RUN_PC2_BITS;
ME.RUNPC[3].R = SPC560P_ME_RUN_PC3_BITS;
ME.RUNPC[4].R = SPC560P_ME_RUN_PC4_BITS;
ME.RUNPC[5].R = SPC560P_ME_RUN_PC5_BITS;
ME.RUNPC[6].R = SPC560P_ME_RUN_PC6_BITS;
ME.RUNPC[7].R = SPC560P_ME_RUN_PC7_BITS;
ME.LPPC[0].R = SPC560P_ME_LP_PC0_BITS;
ME.LPPC[1].R = SPC560P_ME_LP_PC1_BITS;
ME.LPPC[2].R = SPC560P_ME_LP_PC2_BITS;
ME.LPPC[3].R = SPC560P_ME_LP_PC3_BITS;
ME.LPPC[4].R = SPC560P_ME_LP_PC4_BITS;
ME.LPPC[5].R = SPC560P_ME_LP_PC5_BITS;
ME.LPPC[6].R = SPC560P_ME_LP_PC6_BITS;
ME.LPPC[7].R = SPC560P_ME_LP_PC7_BITS;
/* Switches again to DRUN mode (current mode) in order to update the
settings.*/
if (halSPC560PSetRunMode(SPC560P_RUNMODE_DRUN) == CH_FAILED)
@ -116,8 +173,14 @@ void spc560p_clock_init(void) {
/**
* @brief Switches the system to the specified run mode.
*
* @param[in] mode one of the possible run modes
*
* @return The operation status.
* @retval CH_SUCCESS if the switch operation has been completed.
* @retval CH_FAILED if the switch operation failed.
*/
bool_t halSPC560PSetRunMode(spc560prunmode_t mode) {
bool_t halSPC560PSetRunMode(spc560prunmode_t mode) {
/* Starts a transition process.*/
ME.MCTL.R = SPC560P_ME_MCTL_MODE(mode) | SPC560P_ME_MCTL_KEY;
@ -133,9 +196,34 @@ bool_t halSPC560PSetRunMode(spc560prunmode_t mode) {
/* Verifies that the mode has been effectively switched.*/
if (ME.GS.B.S_CURRENTMODE != mode)
return TRUE;
return CH_FAILED;
return FALSE;
return CH_SUCCESS;
}
#if !SPC560P_NO_INIT || defined(__DOXYGEN__)
/**
* @brief Returns the system clock under the current run mode.
*
* @return The system clock in Hertz.
*/
uint32_t halSPC560PGetSystemClock(void) {
uint32_t sysclk;
sysclk = ME.GS.B.S_SYSCLK;
switch (sysclk) {
case SPC560P_ME_GS_SYSCLK_IRC:
return SPC560P_IRC_CLK;
case SPC560P_ME_GS_SYSCLK_XOSC:
return SPC560P_XOSC_CLK;
case SPC560P_ME_GS_SYSCLK_FMPLL0:
return SPC560P_FMPLL0_CLK;
case SPC560P_ME_GS_SYSCLK_FMPLL1:
return SPC560P_FMPLL1_CLK;
default:
return 0;
}
}
#endif /* !SPC560P_NO_INIT */
/** @} */

View File

@ -119,6 +119,17 @@
#define SPC560P_FMPLL_ODF_DIV16 (3U << 24)
/** @} */
/**
* @name ME_GS register bits definitions
* @{
*/
#define SPC560P_ME_GS_SYSCLK_MASK (15U << 0)
#define SPC560P_ME_GS_SYSCLK_IRC (0U << 0)
#define SPC560P_ME_GS_SYSCLK_XOSC (2U << 0)
#define SPC560P_ME_GS_SYSCLK_FMPLL0 (4U << 0)
#define SPC560P_ME_GS_SYSCLK_FMPLL1 (5U << 0)
/** @} */
/**
* @name ME_ME register bits definitions
* @{
@ -174,6 +185,38 @@
#define SPC560P_ME_MCTL_MODE(n) ((n) << 28)
/** @} */
/**
* @name ME_RUN_PCx registers bits definitions
* @{
*/
#define SPC560P_ME_RUN_PC_TEST (1U << 1)
#define SPC560P_ME_RUN_PC_SAFE (1U << 2)
#define SPC560P_ME_RUN_PC_DRUN (1U << 3)
#define SPC560P_ME_RUN_PC_RUN0 (1U << 4)
#define SPC560P_ME_RUN_PC_RUN1 (1U << 5)
#define SPC560P_ME_RUN_PC_RUN2 (1U << 6)
#define SPC560P_ME_RUN_PC_RUN3 (1U << 7)
/** @} */
/**
* @name ME_LP_PCx registers bits definitions
* @{
*/
#define SPC560P_ME_LP_PC_HALT0 (1U << 8)
#define SPC560P_ME_LP_PC_STOP0 (1U << 10)
/** @} */
/**
* @name ME_PCTL registers bits definitions
* @{
*/
#define SPC560P_ME_PCTL_RUN_MASK (7U << 0)
#define SPC560P_ME_PCTL_RUN(n) ((n) << 0)
#define SPC560P_ME_PCTL_LP_MASK (7U << 3)
#define SPC560P_ME_PCTL_LP(n) ((n) << 3)
#define SPC560P_ME_PCTL_DBG (1U << 6)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@ -369,6 +412,180 @@
SPC560P_ME_MC_MVRON)
#endif
/**
* @brief Peripheral mode 0 (run mode).
* @note Do not change this setting, it is expected to be the "always run"
* mode.
*/
#if !defined(SPC560P_ME_RUN_PC0_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC0_BITS (SPC560P_ME_RUN_PC_TEST | \
SPC560P_ME_RUN_PC_SAFE | \
SPC560P_ME_RUN_PC_DRUN | \
SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 1 (run mode).
* @note Do not change this setting, it is expected to be the "never run"
* mode.
*/
#if !defined(SPC560P_ME_RUN_PC1_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC1_BITS 0
#endif
/**
* @brief Peripheral mode 2 (run mode).
* @note Do not change this setting, it is expected to be the "only during
* normal run" mode.
*/
#if !defined(SPC560P_ME_RUN_PC2_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC2_BITS (SPC560P_ME_RUN_PC_DRUN | \
SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 3 (run mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_RUN_PC3_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC3_BITS (SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 4 (run mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_RUN_PC4_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC4_BITS (SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 5 (run mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_RUN_PC5_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC5_BITS (SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 6 (run mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_RUN_PC6_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC6_BITS (SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 7 (run mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_RUN_PC7_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_RUN_PC7_BITS (SPC560P_ME_RUN_PC_RUN0 | \
SPC560P_ME_RUN_PC_RUN1 | \
SPC560P_ME_RUN_PC_RUN2 | \
SPC560P_ME_RUN_PC_RUN3)
#endif
/**
* @brief Peripheral mode 0 (low power mode).
* @note Do not change this setting, it is expected to be the "always run"
* mode.
*/
#if !defined(SPC560P_ME_LP_PC0_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC0_BITS (SPC560P_ME_LP_PC_HALT0 | \
SPC560P_ME_LP_PC_STOP0)
#endif
/**
* @brief Peripheral mode 1 (low power mode).
* @note Do not change this setting, it is expected to be the "never run"
* mode.
*/
#if !defined(SPC560P_ME_LP_PC1_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC1_BITS 0
#endif
/**
* @brief Peripheral mode 2 (low power mode).
* @note Do not change this setting, it is expected to be the "halt only"
* mode.
*/
#if !defined(SPC560P_ME_LP_PC2_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC2_BITS (SPC560P_ME_LP_PC_HALT0)
#endif
/**
* @brief Peripheral mode 3 (low power mode).
* @note Do not change this setting, it is expected to be the "stop only"
* mode.
*/
#if !defined(SPC560P_ME_LP_PC3_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC3_BITS (SPC560P_ME_LP_PC_STOP0)
#endif
/**
* @brief Peripheral mode 4 (low power mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_LP_PC4_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC4_BITS (SPC560P_ME_LP_PC_HALT0 | \
SPC560P_ME_LP_PC_STOP0)
#endif
/**
* @brief Peripheral mode 5 (low power mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_LP_PC5_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC5_BITS (SPC560P_ME_LP_PC_HALT0 | \
SPC560P_ME_LP_PC_STOP0)
#endif
/**
* @brief Peripheral mode 6 (low power mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_LP_PC6_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC6_BITS (SPC560P_ME_LP_PC_HALT0 | \
SPC560P_ME_LP_PC_STOP0)
#endif
/**
* @brief Peripheral mode 7 (low power mode).
* @note Not defined, available to application-specific modes.
*/
#if !defined(SPC560P_ME_LP_PC7_BITS) || defined(__DOXYGEN__)
#define SPC560P_ME_LP_PC7_BITS (SPC560P_ME_LP_PC_HALT0 | \
SPC560P_ME_LP_PC_STOP0)
#endif
/**
* @brief PIT channel 3 IRQ priority.
* @note This PIT channel is allocated permanently for system tick
* generation.
*/
#if !defined(SPC560P_PIT3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SPC560P_PIT3_IRQ_PRIORITY 4
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
@ -501,6 +718,9 @@ extern "C" {
void hal_lld_init(void);
void spc560p_clock_init(void);
bool_t halSPC560PSetRunMode(spc560prunmode_t mode);
#if !SPC560P_NO_INIT
uint32_t halSPC560PGetSystemClock(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,7 @@
# List of all the SPC560Pxx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/SPC560Pxx/hal_lld.c
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/SPC560Pxx/hal_lld.c \
${CHIBIOS}/os/hal/platforms/SPC5xx/LINFlex_v1/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/SPC560Pxx
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/SPC560Pxx \
${CHIBIOS}/os/hal/platforms/SPC5xx/LINFlex_v1

View File

@ -0,0 +1,294 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file SPC56x/serial_lld.c
* @brief SPC563 low level serial driver code.
*
* @addtogroup SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief eSCI-A serial driver identifier.
*/
#if USE_SPC563_ESCIA || defined(__DOXYGEN__)
SerialDriver SD1;
#endif
/**
* @brief eSCI-B serial driver identifier.
*/
#if USE_SPC563_ESCIB || defined(__DOXYGEN__)
SerialDriver SD2;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief Driver default configuration.
*/
static const SerialConfig default_config = {
SERIAL_DEFAULT_BITRATE,
SD_MODE_NORMAL | SD_MODE_PARITY_NONE
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief eSCI initialization.
* @details This function must be invoked with interrupts disabled.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration
*/
static void esci_init(SerialDriver *sdp, const SerialConfig *config) {
volatile struct ESCI_tag *escip = sdp->escip;
uint8_t mode = config->sc_mode;
escip->CR2.R = 0; /* MDIS off. */
escip->CR1.R = 0;
escip->LCR.R = 0;
escip->CR1.B.SBR = SPC563_SYSCLK / (16 * config->sc_speed);
if (mode & SD_MODE_LOOPBACK)
escip->CR1.B.LOOPS = 1;
switch (mode & SD_MODE_PARITY) {
case SD_MODE_PARITY_ODD:
escip->CR1.B.PT = 1;
case SD_MODE_PARITY_EVEN:
escip->CR1.B.PE = 1;
escip->CR1.B.M = 1; /* Makes it 8 bits data + 1 bit parity. */
default:
;
}
escip->LPR.R = 0;
escip->CR1.R |= 0x0000002C; /* RIE, TE, RE to 1. */
escip->CR2.R |= 0x000F; /* ORIE, NFIE, FEIE, PFIE to 1. */
}
/**
* @brief eSCI de-initialization.
* @details This function must be invoked with interrupts disabled.
*
* @param[in] escip pointer to an eSCI I/O block
*/
static void esci_deinit(volatile struct ESCI_tag *escip) {
escip->LPR.R = 0;
escip->SR.R = 0xFFFFFFFF;
escip->CR1.R = 0;
escip->CR2.R = 0x8000; /* MDIS on. */
}
/**
* @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;
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;*/
chSysLockFromIsr();
chnAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
/**
* @brief Common IRQ handler.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
static void serve_interrupt(SerialDriver *sdp) {
volatile struct ESCI_tag *escip = sdp->escip;
uint32_t sr = escip->SR.R;
escip->SR.R = 0x3FFFFFFF; /* Does not clear TDRE | TC.*/
if (sr & 0x0F000000) /* OR | NF | FE | PF. */
set_error(sdp, sr);
if (sr & 0x20000000) { /* RDRF. */
chSysLockFromIsr();
sdIncomingDataI(sdp, escip->DR.B.D);
chSysUnlockFromIsr();
}
if (escip->CR1.B.TIE && (sr & 0x80000000)) { /* TDRE. */
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
escip->CR1.B.TIE = 0;
}
else {
ESCI_A.SR.B.TDRE = 1;
escip->DR.R = (uint16_t)b;
}
chSysUnlockFromIsr();
}
}
#if USE_SPC563_ESCIA || defined(__DOXYGEN__)
static void notify1(GenericQueue *qp) {
(void)qp;
if (ESCI_A.SR.B.TDRE) {
msg_t b = sdRequestDataI(&SD1);
if (b != Q_EMPTY) {
ESCI_A.SR.B.TDRE = 1;
ESCI_A.CR1.B.TIE = 1;
ESCI_A.DR.R = (uint16_t)b;
}
}
}
#endif
#if USE_SPC563_ESCIB || defined(__DOXYGEN__)
static void notify2(GenericQueue *qp) {
(void)qp;
if (ESCI_B.SR.B.TDRE) {
msg_t b = sdRequestDataI(&SD2);
if (b != Q_EMPTY) {
ESCI_B.SR.B.TDRE = 1;
ESCI_B.CR1.B.TIE = 1;
ESCI_B.DR.R = (uint16_t)b;
}
}
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if USE_SPC563_ESCIA || defined(__DOXYGEN__)
/**
* @brief eSCI-A interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(vector146) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD1);
CH_IRQ_EPILOGUE();
}
#endif
#if USE_SPC563_ESCIB || defined(__DOXYGEN__)
/**
* @brief eSCI-B interrupt handler.
*
* @isr
*/
CH_IRQ_HANDLER(vector149) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD2);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*
* @notapi
*/
void sd_lld_init(void) {
#if USE_SPC563_ESCIA
sdObjectInit(&SD1, NULL, notify1);
SD1.escip = &ESCI_A;
ESCI_A.CR2.R = 0x8000; /* MDIS ON. */
INTC.PSR[146].R = SPC563_ESCIA_PRIORITY;
#endif
#if USE_SPC563_ESCIB
sdObjectInit(&SD2, NULL, notify2);
SD2.escip = &ESCI_B;
ESCI_B.CR2.R = 0x8000; /* MDIS ON. */
INTC.PSR[149].R = SPC563_ESCIB_PRIORITY;
#endif
}
/**
* @brief Low level serial driver configuration and (re)start.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
*
* @notapi
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
esci_init(sdp, config);
}
/**
* @brief Low level serial driver stop.
*
* @param[in] sdp pointer to a @p SerialDriver object
*
* @notapi
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY)
esci_deinit(sdp->escip);
}
#endif /* HAL_USE_SERIAL */
/** @} */

View File

@ -0,0 +1,149 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file SPC5xx/serial_lld.h
* @brief SPC5xx low level serial driver header.
*
* @addtogroup SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief eSCI-A driver enable switch.
* @details If set to @p TRUE the support for eSCI-A is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SPC563_ESCIA) || defined(__DOXYGEN__)
#define USE_SPC563_ESCIA FALSE
#endif
/**
* @brief eSCI-B driver enable switch.
* @details If set to @p TRUE the support for eSCI-B is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SPC563_ESCIB) || defined(__DOXYGEN__)
#define USE_SPC563_ESCIB FALSE
#endif
/**
* @brief eSCI-A interrupt priority level setting.
*/
#if !defined(SPC563_ESCIA_PRIORITY) || defined(__DOXYGEN__)
#define SPC563_ESCIA_PRIORITY 8
#endif
/**
* @brief eSCI-B interrupt priority level setting.
*/
#if !defined(SPC563_ESCIB_PRIORITY) || defined(__DOXYGEN__)
#define SPC563_ESCIB_PRIORITY 8
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Generic Serial Driver configuration structure.
* @details An instance of this structure must be passed to @p sdStart()
* in order to configure and start a serial driver operations.
* @note This structure content is architecture dependent, each driver
* implementation defines its own version and the custom static
* initializers.
*/
typedef struct {
/**
* @brief Bit rate.
*/
uint32_t sc_speed;
/**
* @brief Mode flags.
*/
uint8_t sc_mode;
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Pointer to the volatile eSCI registers block.*/ \
volatile struct ESCI_tag *escip;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_SPC563_ESCIA && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_SPC563_ESCIB && !defined(__DOXYGEN__)
extern SerialDriver SD2;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void sd_lld_init(void);
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
void sd_lld_stop(SerialDriver *sdp);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@ -47,13 +47,17 @@ SECTIONS
. = ORIGIN(flash);
.boot : ALIGN(16) SUBALIGN(16)
{
__ivpr_base__ = .;
KEEP(*(.bam))
KEEP(*(.crt0))
. = ALIGN(0x00000800);
KEEP(*(.handlers))
. = ALIGN(0x00001000);
KEEP(*(.vectors))
/* Note, have to waste the first 64KB because the IVPR register
requires an alignment of 64KB and the first 64KB cannot be used,
IVOR0 would conflict with the BAM word. Applications could
allocate code or data in the first 64KB by using special sections.*/
. = ALIGN(0x00010000);
__ivpr_base__ = .;
KEEP(*(.handlers))
} > flash
constructors : ALIGN(4) SUBALIGN(4)

View File

@ -44,6 +44,7 @@ _boot_address:
* IVPR initialization.
*/
lis %r4, __ivpr_base__@h
ori %r4, %r4, __ivpr_base__@l
mtIVPR %r4
/*
* Small sections registers initialization.