Added uart and serial FLEXCOM

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10736 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
edolomb 2017-10-01 16:04:25 +00:00
parent c711d410d7
commit bac29fef11
4 changed files with 1112 additions and 130 deletions

View File

@ -67,7 +67,7 @@
* @notapi
*/
#define sdFlexEnableWP(sdp) { \
sdp->usart->US_WPMR = US_WPMR_WPKEY_PASSWD | US_WPMR_WPEN; \
sdp->US_WPMR = US_WPMR_WPKEY_PASSWD | US_WPMR_WPEN; \
}
/**
@ -78,7 +78,7 @@
* @notapi
*/
#define sdFlexDisableWP(sdp) { \
sdp->usart->US_WPMR = US_WPMR_WPKEY_PASSWD; \
sdp->US_WPMR = US_WPMR_WPKEY_PASSWD; \
}
#endif
@ -113,27 +113,27 @@ SerialDriver SD4;
/** @brief FLEXCOM0 serial driver identifier.*/
#if SAMA_SERIAL_USE_FLEXCOM0 || defined(__DOXYGEN__)
SerialDriver SDFLEX0;
SerialDriver SFLEXD0;
#endif
/** @brief FLEXCOM1 serial driver identifier.*/
#if SAMA_SERIAL_USE_FLEXCOM1 || defined(__DOXYGEN__)
SerialDriver SDFLEX1;
SerialDriver SFLEXD1;
#endif
/** @brief FLEXCOM2 serial driver identifier.*/
#if SAMA_SERIAL_USE_FLEXCOM2 || defined(__DOXYGEN__)
SerialDriver SDFLEX2;
SerialDriver SFLEXD2;
#endif
/** @brief FLEXCOM3 serial driver identifier.*/
#if SAMA_SERIAL_USE_FLEXCOM3 || defined(__DOXYGEN__)
SerialDriver SDFLEX3;
SerialDriver SFLEXD3;
#endif
/** @brief FLEXCOM0 serial driver identifier.*/
#if SAMA_SERIAL_USE_FLEXCOM4 || defined(__DOXYGEN__)
SerialDriver SDFLEX4;
SerialDriver SFLEXD4;
#endif
/*===========================================================================*/
@ -193,42 +193,42 @@ static uint8_t sd_out_buf4[SAMA_SERIAL_UART4_IN_BUF_SIZE];
#endif
#if SAMA_SERIAL_USE_FLEXCOM0 || defined(__DOXYGEN__)
/** @brief Input buffer for SDFLEX0.*/
/** @brief Input buffer for SFLEXD0.*/
static uint8_t sdFlex_in_buf0[SAMA_SERIAL_FLEXCOM0_IN_BUF_SIZE];
/** @brief Output buffer for SDFLEX0.*/
/** @brief Output buffer for SFLEXD0.*/
static uint8_t sdFlex_out_buf0[SAMA_SERIAL_FLEXCOM0_OUT_BUF_SIZE];
#endif
#if SAMA_SERIAL_USE_FLEXCOM1 || defined(__DOXYGEN__)
/** @brief Input buffer for SDFLEX1.*/
/** @brief Input buffer for SFLEXD1.*/
static uint8_t sdFlex_in_buf1[SAMA_SERIAL_FLEXCOM1_IN_BUF_SIZE];
/** @brief Output buffer for SDFLEX1.*/
/** @brief Output buffer for SFLEXD1.*/
static uint8_t sdFlex_out_buf1[SAMA_SERIAL_FLEXCOM1_OUT_BUF_SIZE];
#endif
#if SAMA_SERIAL_USE_FLEXCOM2 || defined(__DOXYGEN__)
/** @brief Input buffer for SDFLEX2.*/
/** @brief Input buffer for SFLEXD2.*/
static uint8_t sdFlex_in_buf2[SAMA_SERIAL_FLEXCOM2_IN_BUF_SIZE];
/** @brief Output buffer for SDFLEX2.*/
/** @brief Output buffer for SFLEXD2.*/
static uint8_t sdFlex_out_buf2[SAMA_SERIAL_FLEXCOM2_OUT_BUF_SIZE];
#endif
#if SAMA_SERIAL_USE_FLEXCOM3 || defined(__DOXYGEN__)
/** @brief Input buffer for SDFLEX3.*/
/** @brief Input buffer for SFLEXD3.*/
static uint8_t sdFlex_in_buf3[SAMA_SERIAL_FLEXCOM3_IN_BUF_SIZE];
/** @brief Output buffer for SDFLEX3.*/
/** @brief Output buffer for SFLEXD3.*/
static uint8_t sdFlex_out_buf3[SAMA_SERIAL_FLEXCOM3_OUT_BUF_SIZE];
#endif
#if SAMA_SERIAL_USE_FLEXCOM4 || defined(__DOXYGEN__)
/** @brief Input buffer for SDFLEX4.*/
/** @brief Input buffer for SFLEXD4.*/
static uint8_t sdFlex_in_buf4[SAMA_SERIAL_FLEXCOM4_IN_BUF_SIZE];
/** @brief Output buffer for SDFLEX4.*/
/** @brief Output buffer for SFLEXD4.*/
static uint8_t sdFlex_out_buf4[SAMA_SERIAL_FLEXCOM4_OUT_BUF_SIZE];
#endif
@ -277,7 +277,7 @@ static void uart_init(SerialDriver *sdp, const SerialConfig *config) {
Usart *us = sdp->usart;
/* Disabling write protection */
sdFlexDisableWP(sdp)
sdFlexDisableWP(us)
/* Enabling USART on FLEXCOM */
fl->FLEX_MR = FLEX_MR_OPMODE_USART;
/* Baud rate setting (OVER = 0 and SYNC = 0)*/
@ -292,7 +292,7 @@ static void uart_init(SerialDriver *sdp, const SerialConfig *config) {
/* Enabling Tx and Rx */
us->US_CR |= US_CR_RXEN | US_CR_TXEN;
/* Enabling write protection */
sdFlexEnableWP(sdp)
sdFlexEnableWP(us)
}
#endif /* SAMA_SERIAL_USE_FLEXCOM */
#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM
@ -331,12 +331,12 @@ static void uart_deinit(SerialDriver *sdp) {
Usart *us = sdp->usart;
/* Disabling write protection */
sdFlexDisableWP(sdp)
sdFlexDisableWP(us)
us->US_CR = 0;
us->US_MR = 0;
/* Enabling write protection */
sdFlexEnableWP(sdp)
sdFlexEnableWP(us)
}
#endif /* SAMA_SERIAL_USE_FLEXCOM */
#if SAMA_SERIAL_USE_UART && SAMA_SERIAL_USE_FLEXCOM
@ -642,11 +642,11 @@ OSAL_IRQ_HANDLER(SAMA_UART4_HANDLER) {
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM0_HANDLER) {
OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM0_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_interrupt(&SDFLEX0);
serve_uartFlex_interrupt(&SFLEXD0);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
@ -658,11 +658,11 @@ OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM0_HANDLER) {
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM1_HANDLER) {
OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM1_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_interrupt(&SDFLEX1);
serve_uartFlex_interrupt(&SFLEXD1);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
@ -674,11 +674,11 @@ OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM1_HANDLER) {
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM2_HANDLER) {
OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM2_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_interrupt(&SDFLEX2);
serve_uartFlex_interrupt(&SFLEXD2);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
@ -690,11 +690,11 @@ OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM2_HANDLER) {
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM3_HANDLER) {
OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM3_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_interrupt(&SDFLEX3);
serve_uartFlex_interrupt(&SFLEXD3);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
@ -706,11 +706,11 @@ OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM3_HANDLER) {
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM4_HANDLER) {
OSAL_IRQ_HANDLER(SAMA_SERIAL_FLEXCOM4_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_interrupt(&SDFLEX4);
serve_uartFlex_interrupt(&SFLEXD4);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
@ -788,70 +788,70 @@ void sd_lld_init(void) {
#endif
#if SAMA_SERIAL_USE_FLEXCOM0
sdObjectInit(&SDFLEX0);
iqObjectInit(&SDFLEX0.iqueue, sdFlex_in_buf0, sizeof sdFlex_in_buf0, NULL, &SDFLEX0);
oqObjectInit(&SDFLEX0.oqueue, sdFlex_out_buf0, sizeof sdFlex_out_buf0, notifyFlex0, &SDFLEX0);
SDFLEX0.flexcom = FLEXCOM0;
SDFLEX0.usart = USART0;
SDFLEX0.clock = SAMA_FLEXCOM0CLK;
sdObjectInit(&SFLEXD0);
iqObjectInit(&SFLEXD0.iqueue, sdFlex_in_buf0, sizeof sdFlex_in_buf0, NULL, &SFLEXD0);
oqObjectInit(&SFLEXD0.oqueue, sdFlex_out_buf0, sizeof sdFlex_out_buf0, notifyFlex0, &SFLEXD0);
SFLEXD0.flexcom = FLEXCOM0;
SFLEXD0.usart = USART0;
SFLEXD0.clock = SAMA_FLEXCOM0CLK;
aicSetSourcePriority(ID_USART0, SAMA_SERIAL_FLEXCOM0_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART0, SAMA_UART_FLEXCOM0_HANDLER);
aicSetSourceHandler(ID_USART0, SAMA_SERIAL_FLEXCOM0_HANDLER);
aicEnableInt(ID_USART0);
#endif
#if SAMA_SERIAL_USE_FLEXCOM1
sdObjectInit(&SDFLEX1);
iqObjectInit(&SDFLEX1.iqueue, sdFlex_in_buf1, sizeof sdFlex_in_buf1, NULL, &SDFLEX1);
oqObjectInit(&SDFLEX1.oqueue, sdFlex_out_buf1, sizeof sdFlex_out_buf1, notifyFlex1, &SDFLEX1);
SDFLEX1.flexcom = FLEXCOM1;
SDFLEX1.usart = USART1;
SDFLEX1.clock = SAMA_FLEXCOM1CLK;
sdObjectInit(&SFLEXD1);
iqObjectInit(&SFLEXD1.iqueue, sdFlex_in_buf1, sizeof sdFlex_in_buf1, NULL, &SFLEXD1);
oqObjectInit(&SFLEXD1.oqueue, sdFlex_out_buf1, sizeof sdFlex_out_buf1, notifyFlex1, &SFLEXD1);
SFLEXD1.flexcom = FLEXCOM1;
SFLEXD1.usart = USART1;
SFLEXD1.clock = SAMA_FLEXCOM1CLK;
aicSetSourcePriority(ID_USART1, SAMA_SERIAL_FLEXCOM1_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART1, SAMA_UART_FLEXCOM1_HANDLER);
aicSetSourceHandler(ID_USART1, SAMA_SERIAL_FLEXCOM1_HANDLER);
aicEnableInt(ID_USART1);
#endif
#if SAMA_SERIAL_USE_FLEXCOM2
sdObjectInit(&SDFLEX2);
iqObjectInit(&SDFLEX2.iqueue, sdFlex_in_buf2, sizeof sdFlex_in_buf2, NULL, &SDFLEX2);
oqObjectInit(&SDFLEX2.oqueue, sdFlex_out_buf2, sizeof sdFlex_out_buf2, notifyFlex2, &SDFLEX2);
SDFLEX2.flexcom = FLEXCOM2;
SDFLEX2.usart = USART2;
SDFLEX2.clock = SAMA_FLEXCOM2CLK;
sdObjectInit(&SFLEXD2);
iqObjectInit(&SFLEXD2.iqueue, sdFlex_in_buf2, sizeof sdFlex_in_buf2, NULL, &SFLEXD2);
oqObjectInit(&SFLEXD2.oqueue, sdFlex_out_buf2, sizeof sdFlex_out_buf2, notifyFlex2, &SFLEXD2);
SFLEXD2.flexcom = FLEXCOM2;
SFLEXD2.usart = USART2;
SFLEXD2.clock = SAMA_FLEXCOM2CLK;
aicSetSourcePriority(ID_USART2, SAMA_SERIAL_FLEXCOM2_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART2, SAMA_UART_FLEXCOM2_HANDLER);
aicSetSourceHandler(ID_USART2, SAMA_SERIAL_FLEXCOM2_HANDLER);
aicEnableInt(ID_USART2);
#endif
#if SAMA_SERIAL_USE_FLEXCOM3
sdObjectInit(&SDFLEX3);
iqObjectInit(&SDFLEX3.iqueue, sdFlex_in_buf3, sizeof sdFlex_in_buf3, NULL, &SDFLEX3);
oqObjectInit(&SDFLEX3.oqueue, sdFlex_out_buf3, sizeof sdFlex_out_buf3, notifyFlex3, &SDFLEX3);
SDFLEX3.flexcom = FLEXCOM3;
SDFLEX3.usart = USART3;
SDFLEX3.clock = SAMA_FLEXCOM3CLK;
sdObjectInit(&SFLEXD3);
iqObjectInit(&SFLEXD3.iqueue, sdFlex_in_buf3, sizeof sdFlex_in_buf3, NULL, &SFLEXD3);
oqObjectInit(&SFLEXD3.oqueue, sdFlex_out_buf3, sizeof sdFlex_out_buf3, notifyFlex3, &SFLEXD3);
SFLEXD3.flexcom = FLEXCOM3;
SFLEXD3.usart = USART3;
SFLEXD3.clock = SAMA_FLEXCOM3CLK;
aicSetSourcePriority(ID_USART3, SAMA_SERIAL_FLEXCOM3_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART3, SAMA_UART_FLEXCOM3_HANDLER);
aicSetSourceHandler(ID_USART3, SAMA_SERIAL_FLEXCOM3_HANDLER);
aicEnableInt(ID_USART3);
#endif
}
#if SAMA_SERIAL_USE_FLEXCOM4
sdObjectInit(&SDFLEX4);
iqObjectInit(&SDFLEX4.iqueue, sdFlex_in_buf4, sizeof sdFlex_in_buf4, NULL, &SDFLEX4);
oqObjectInit(&SDFLEX4.oqueue, sdFlex_out_buf4, sizeof sdFlex_out_buf4, notifyFlex4, &SDFLEX4);
SDFLEX4.flexcom = FLEXCOM4;
SDFLEX4.usart = USART4;
SDFLEX4.clock = SAMA_FLEXCOM4CLK;
sdObjectInit(&SFLEXD4);
iqObjectInit(&SFLEXD4.iqueue, sdFlex_in_buf4, sizeof sdFlex_in_buf4, NULL, &SFLEXD4);
oqObjectInit(&SFLEXD4.oqueue, sdFlex_out_buf4, sizeof sdFlex_out_buf4, notifyFlex4, &SFLEXD4);
SFLEXD4.flexcom = FLEXCOM4;
SFLEXD4.usart = USART4;
SFLEXD4.clock = SAMA_FLEXCOM4CLK;
aicSetSourcePriority(ID_USART4, SAMA_SERIAL_FLEXCOM4_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART4, SAMA_UART_FLEXCOM4_HANDLER);
aicSetSourceHandler(ID_USART4, SAMA_SERIAL_FLEXCOM4_HANDLER);
aicEnableInt(ID_USART4);
#endif
}
/**
* @brief Low level serial driver configuration and (re)start.
@ -896,27 +896,27 @@ void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM0
if (&SDFLEX0 == sdp) {
if (&SFLEXD0 == sdp) {
pmcEnableFLEXCOM0();
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM1
if (&SDFLEX1 == sdp) {
if (&SFLEXD1 == sdp) {
pmcEnableFLEXCOM1();
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM2
if (&SDFLEX2 == sdp) {
if (&SFLEXD2 == sdp) {
pmcEnableFLEXCOM2();
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM3
if (&SDFLEX3 == sdp) {
if (&SFLEXD3 == sdp) {
pmcEnableFLEXCOM3();
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM4
if (&SDFLEX4 == sdp) {
if (&SFLEXD4 == sdp) {
pmcEnableFLEXCOM4();
}
#endif
@ -970,28 +970,34 @@ void sd_lld_stop(SerialDriver *sdp) {
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM0
if (&SDFLEX0 == sdp) {
if (&SFLEXD0 == sdp) {
pmcDisableFLEXCOM0();
return;
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM1
if (&SDFLEX1 == sdp) {
if (&SFLEXD1 == sdp) {
pmcDisableFLEXCOM1();
return;
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM2
if (&SDFLEX2 == sdp) {
if (&SFLEXD2 == sdp) {
pmcDisableFLEXCOM2();
return;
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM3
if (&SDFLEX3 == sdp) {
if (&SFLEXD3 == sdp) {
pmcDisableFLEXCOM3();
return;
}
#endif
#if SAMA_SERIAL_USE_FLEXCOM4
if (&SFLEXD4 == sdp) {
pmcDisableFLEXCOM4();
return;
}
#endif
}
}

View File

@ -381,6 +381,87 @@
#error "SERIAL driver activated but no USART/UART peripheral assigned"
#endif
/* Checks on allocation of UARTx units.*/
#if SAMA_SERIAL_USE_UART0
#if defined(SAMA_UART0_IS_USED)
#error "SD0 requires UART0 but the peripheral is already used"
#else
#define SAMA_UART0_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_UART1
#if defined(SAMA_UART1_IS_USED)
#error "SD1 requires UART1 but the peripheral is already used"
#else
#define SAMA_UART1_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_UART2
#if defined(SAMA_UART2_IS_USED)
#error "SD2 requires UART2 but the peripheral is already used"
#else
#define SAMA_UART2_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_UART3
#if defined(SAMA_UART3_IS_USED)
#error "SD3 requires UART3 but the peripheral is already used"
#else
#define SAMA_UART3_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_UART4
#if defined(SAMA_UART4_IS_USED)
#error "SD4 requires UART4 but the peripheral is already used"
#else
#define SAMA_UART4_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_FLEXCOM0
#if defined(SAMA_FLEXCOM0_IS_USED)
#error "SFLEXD0 requires FLEXCOM0 but the peripheral is already used"
#else
#define SAMA_FLEXCOM0_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_FLEXCOM1
#if defined(SAMA_FLEXCOM1_IS_USED)
#error "SFLEXD1 requires FLEXCOM1 but the peripheral is already used"
#else
#define SAMA_FLEXCOM1_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_FLEXCOM2
#if defined(SAMA_FLEXCOM2_IS_USED)
#error "SFLEXD2 requires FLEXCOM2 but the peripheral is already used"
#else
#define SAMA_FLEXCOM2_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_FLEXCOM3
#if defined(SAMA_FLEXCOM3_IS_USED)
#error "SFLEXD3 requires FLEXCOM3 but the peripheral is already used"
#else
#define SAMA_FLEXCOM3_IS_USED
#endif
#endif
#if SAMA_SERIAL_USE_FLEXCOM4
#if defined(SAMA_FLEXCOM4_IS_USED)
#error "SFLEXD4 requires FLEXCOM4 but the peripheral is already used"
#else
#define SAMA_FLEXCOM4_IS_USED
#endif
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@ -454,19 +535,19 @@ extern SerialDriver SD3;
extern SerialDriver SD4;
#endif
#if SAMA_SERIAL_USE_FLEXCOM0 && !defined(__DOXYGEN__)
extern SerialDriver SDFLEX0;
extern SerialDriver SFLEXD0;
#endif
#if SAMA_SERIAL_USE_FLEXCOM1 && !defined(__DOXYGEN__)
extern SerialDriver SDFLEX1;
extern SerialDriver SFLEXD1;
#endif
#if SAMA_SERIAL_USE_FLEXCOM2 && !defined(__DOXYGEN__)
extern SerialDriver SDFLEX2;
extern SerialDriver SFLEXD2;
#endif
#if SAMA_SERIAL_USE_FLEXCOM3 && !defined(__DOXYGEN__)
extern SerialDriver SDFLEX3;
extern SerialDriver SFLEXD3;
#endif
#if SAMA_SERIAL_USE_FLEXCOM4 && !defined(__DOXYGEN__)
extern SerialDriver SDFLEX4;
extern SerialDriver SFLEXD4;
#endif
#ifdef __cplusplus

View File

@ -30,6 +30,58 @@
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local macros. */
/*===========================================================================*/
#if SAMA_UART_USE_UART
/**
* @brief Enable write protection on UART registers block.
*
* @param[in] uartp pointer to a UART register block
*
* @notapi
*/
#define uartEnableWP(uartp) { \
uartp->UART_WPMR = UART_WPMR_WPKEY_PASSWD | UART_WPMR_WPEN; \
}
/**
* @brief Disable write protection on UART registers block.
*
* @param[in] uartp pointer to a UART register block
*
* @notapi
*/
#define uartDisableWP(uartp) { \
uartp->UART_WPMR = UART_WPMR_WPKEY_PASSWD; \
}
#endif
#if SAMA_UART_USE_FLEXCOM
/**
* @brief Enable write protection on FLEXCOM registers block.
*
* @param[in] uartp pointer to a FLEXCOM register block
*
* @notapi
*/
#define uartFlexEnableWP(uartp) { \
uartp->US_WPMR = US_WPMR_WPKEY_PASSWD | US_WPMR_WPEN; \
}
/**
* @brief Disable write protection on FLEXCOM registers block.
*
* @param[in] uartp pointer to a FLEXCOM register block
*
* @notapi
*/
#define uartFlexDisableWP(uartp) { \
uartp->US_WPMR = US_WPMR_WPKEY_PASSWD; \
}
#endif
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
@ -39,12 +91,12 @@
UARTDriver UARTD0;
#endif
/** @brief USART1 UART driver identifier.*/
/** @brief UART1 UART driver identifier.*/
#if SAMA_UART_USE_UART1 || defined(__DOXYGEN__)
UARTDriver UARTD1;
#endif
/** @brief USART2 UART driver identifier.*/
/** @brief UART2 UART driver identifier.*/
#if SAMA_UART_USE_UART2 || defined(__DOXYGEN__)
UARTDriver UARTD2;
#endif
@ -59,6 +111,31 @@ UARTDriver UARTD3;
UARTDriver UARTD4;
#endif
/** @brief FLEXCOM0 UART driver identifier.*/
#if SAMA_UART_USE_FLEXCOM0 || defined(__DOXYGEN__)
UARTDriver UARTFLEXD0;
#endif
/** @brief FLEXCOM1 UART driver identifier.*/
#if SAMA_UART_USE_FLEXCOM1 || defined(__DOXYGEN__)
UARTDriver UARTFLEXD1;
#endif
/** @brief FLEXCOM2 UART driver identifier.*/
#if SAMA_UART_USE_FLEXCOM2 || defined(__DOXYGEN__)
UARTDriver UARTFLEXD2;
#endif
/** @brief FLEXCOM3 UART driver identifier.*/
#if SAMA_UART_USE_FLEXCOM3 || defined(__DOXYGEN__)
UARTDriver UARTFLEXD3;
#endif
/** @brief FLEXCOM4 UART driver identifier.*/
#if SAMA_UART_USE_FLEXCOM4 || defined(__DOXYGEN__)
UARTDriver UARTFLEXD4;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
@ -81,11 +158,11 @@ UARTDriver UARTD4;
static uartflags_t translate_errors(uint32_t isr) {
uartflags_t sts = 0;
if (isr & UART_SR_OVRE)
if (isr & (UART_SR_OVRE | US_CSR_OVRE))
sts |= UART_OVERRUN_ERROR;
if (isr & UART_SR_PARE)
if (isr & (UART_SR_PARE | US_CSR_PARE))
sts |= UART_PARITY_ERROR;
if (isr & UART_SR_FRAME)
if (isr & (UART_SR_FRAME | US_CSR_FRAME))
sts |= UART_SR_FRAME;
return sts;
}
@ -128,11 +205,51 @@ static void uart_stop(UARTDriver *uartp) {
dmaChannelDisable(uartp->dmarx);
dmaChannelDisable(uartp->dmatx);
/* Stops UART operations.*/
uartp->uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX;
#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM
if (uartp->uart != NULL)
#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */
#if SAMA_UART_USE_UART
{
Uart *u = uartp->uart;
/* Resets UART's register */
uartp->uart->UART_MR = 0;
/* Disabling write protection */
uartDisableWP(u);
/* Stops UART operations.*/
uartp->uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX;
/* Resets UART's register */
uartp->uart->UART_MR = 0;
/* Enabling write protection */
uartEnableWP(u);
}
#endif /* SAMA_UART_USE_UART */
#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM
else if (uartp->usart != NULL)
#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */
#if SAMA_UART_USE_FLEXCOM
{
Usart *us = uartp->usart;
/* Disabling write protection */
uartFlexDisableWP(us);
/* Stops UART operations.*/
us->US_CR = US_CR_RSTRX | US_CR_RSTTX;
/* Resets UART's register */
us->US_MR = 0;
/* Disabling write protection */
uartFlexEnableWP(us);
}
#endif /* SAMA_UART_USE_FLEXCOM */
#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM
else {
osalDbgAssert(FALSE, "invalid state");
}
#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */
}
/**
@ -142,33 +259,89 @@ static void uart_stop(UARTDriver *uartp) {
* @param[in] uartp pointer to the @p UARTDriver object
*/
static void uart_start(UARTDriver *uartp) {
uint32_t cr;
const uint32_t tmo = uartp->config->timeout;
Uart *u = uartp->uart;
#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM
if (uartp->uart != NULL)
#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */
#if SAMA_UART_USE_UART
{
Uart *u = uartp->uart;
/* Defensive programming, starting from a clean state.*/
uart_stop(uartp);
/* Defensive programming, starting from a clean state.*/
uart_stop(uartp);
/* Baud rate setting.*/
u->UART_BRGR = UART_BRGR_CD(uartp->clock / (16 * uartp->config->speed));
/* Disabling write protection */
uartDisableWP(u);
/* Clearing pending flags */
u->UART_CR = UART_CR_RSTSTA;
/* Baud rate setting.*/
u->UART_BRGR = UART_BRGR_CD(uartp->clock / (16 * uartp->config->speed));
/* Enabling interrupts */
u->UART_IER = UART_IER_OVRE | UART_IER_FRAME | UART_IER_PARE;
/* Clearing pending flags */
u->UART_CR = UART_CR_RSTSTA;
cr = UART_CR_RXEN | UART_CR_TXEN;
u->UART_CR = uartp->config->cr | cr;
u->UART_MR = uartp->config->mr;
/* Enabling interrupts */
u->UART_IER = UART_IER_OVRE | UART_IER_FRAME | UART_IER_PARE;
/* Set receive timeout and checks if it is really applied.*/
if (tmo > 0) {
/*
* TODO: insert Function parameters check
*/
u->UART_RTOR = tmo;
cr = UART_CR_RXEN | UART_CR_TXEN;
u->UART_CR = uartp->config->cr | cr;
u->UART_MR = uartp->config->mr;
/* Set receive timeout and checks if it is really applied.*/
if (tmo > 0) {
/*
* TODO: insert Function parameters check
*/
u->UART_RTOR = tmo;
}
/* Enabling write protection */
uartEnableWP(u);
}
#endif /* SAMA_UART_USE_UART */
#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM
else if (uartp->usart != NULL)
#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */
#if SAMA_UART_USE_FLEXCOM
{
Usart *us = uartp->usart;
/* Defensive programming, starting from a clean state.*/
uart_stop(uartp);
/* Disabling write protection */
uartFlexDisableWP(us);
/* Baud rate setting.*/
us->US_BRGR = US_BRGR_CD(uartp->clock / (16 * uartp->config->speed));
/* Clearing pending flags */
us->US_CR = US_CR_RSTSTA;
/* Enabling interrupts */
us->US_IER = US_IER_OVRE | US_IER_FRAME | US_IER_PARE;
cr = US_CR_RXEN | US_CR_TXEN;
us->US_CR = uartp->config->cr | cr;
us->US_MR = uartp->config->mr;
/* Set receive timeout and checks if it is really applied.*/
if (tmo > 0) {
/*
* TODO: insert Function parameters check
*/
us->US_RTOR = tmo;
}
/* Enabling write protection */
uartFlexEnableWP(us);
}
#endif /* SAMA_UART_USE_FLEXCOM */
#if SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM
else {
osalDbgAssert(FALSE, "invalid state");
}
#endif /* SAMA_UART_USE_UART && SAMA_UART_USE_FLEXCOM */
/* Starting the receiver idle loop.*/
uart_enter_rx_idle_loop(uartp);
@ -227,6 +400,7 @@ static void uart_lld_serve_tx_end_irq(UARTDriver *uartp, uint32_t flags) {
_uart_tx1_isr_code(uartp);
}
#if SAMA_UART_USE_UART
/**
* @brief UART common service routine.
*
@ -253,6 +427,37 @@ static void serve_uart_irq(UARTDriver *uartp) {
_uart_tx2_isr_code(uartp);
}
}
#endif
#if SAMA_UART_USE_FLEXCOM
/**
* @brief UART common service routine.
*
* @param[in] uartp pointer to the @p UARTDriver object
*/
static void serve_uartFlex_irq(UARTDriver *uartp) {
Usart *us = uartp->usart;
uint32_t imr = us->US_IMR;
uint32_t sr;
/* Reading and clearing status.*/
sr = us->US_CSR;
us->US_CR |= US_CR_RSTSTA;
if (sr & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE)) {
_uart_rx_error_isr_code(uartp, translate_errors(sr));
}
if ((imr & US_IMR_TXEMPTY) && (sr & (US_CSR_TXRDY | US_CSR_TXEMPTY))) {
/* TC interrupt disabled.*/
us->US_IDR |= US_IDR_TXEMPTY;
/* End of transmission, a callback is generated.*/
_uart_tx2_isr_code(uartp);
}
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
@ -338,6 +543,86 @@ OSAL_IRQ_HANDLER(SAMA_UART4_HANDLER) {
}
#endif /* SAMA_UART_USE_UART4 */
#if SAMA_UART_USE_FLEXCOM0 || defined(__DOXYGEN__)
/**
* @brief FLEXCOM0 IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM0_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_irq(&UARTFLEXD0);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
#endif /* SAMA_UART_USE_FLEXCOM0 */
#if SAMA_UART_USE_FLEXCOM1 || defined(__DOXYGEN__)
/**
* @brief FLEXCOM1 IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM1_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_irq(&UARTFLEXD1);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
#endif /* SAMA_UART_USE_FLEXCOM1 */
#if SAMA_UART_USE_FLEXCOM2 || defined(__DOXYGEN__)
/**
* @brief FLEXCOM2 IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM2_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_irq(&UARTFLEXD2);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
#endif /* SAMA_UART_USE_FLEXCOM2 */
#if SAMA_UART_USE_FLEXCOM3 || defined(__DOXYGEN__)
/**
* @brief FLEXCOM3 IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM3_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_irq(&UARTFLEXD3);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
#endif /* SAMA_UART_USE_FLEXCOM3 */
#if SAMA_UART_USE_FLEXCOM4 || defined(__DOXYGEN__)
/**
* @brief FLEXCOM4 IRQ handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(SAMA_UART_FLEXCOM4_HANDLER) {
OSAL_IRQ_PROLOGUE();
serve_uartFlex_irq(&UARTFLEXD4);
aicAckInt();
OSAL_IRQ_EPILOGUE();
}
#endif /* SAMA_UART_USE_FLEXCOM4 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
@ -499,8 +784,164 @@ void uart_lld_init(void) {
UARTD4.dmatx = 0;
#endif
#if SAMA_UART_USE_FLEXCOM0
uartObjectInit(&UARTFLEXD0);
UARTFLEXD0.flexcom = FLEXCOM0;
UARTFLEXD0.usart = USART0;
UARTFLEXD0.clock = SAMA_FLEXCOM0CLK;
UARTFLEXD0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_PER2MEM |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF1 |
XDMAC_CC_DIF_AHB_IF0 |
XDMAC_CC_SAM_FIXED_AM |
XDMAC_CC_DAM_INCREMENTED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM0_RX);
UARTFLEXD0.txdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_MEM2PER |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF0 |
XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_INCREMENTED_AM |
XDMAC_CC_DAM_FIXED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM0_TX);
UARTFLEXD0.dmarx = 0;
UARTFLEXD0.dmatx = 0;
#endif
#if SAMA_UART_USE_FLEXCOM1
uartObjectInit(&UARTFLEXD1);
UARTFLEXD1.flexcom = FLEXCOM1;
UARTFLEXD1.usart = USART1;
UARTFLEXD1.clock = SAMA_FLEXCOM1CLK;
UARTFLEXD1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_PER2MEM |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF1 |
XDMAC_CC_DIF_AHB_IF0 |
XDMAC_CC_SAM_FIXED_AM |
XDMAC_CC_DAM_INCREMENTED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM1_RX);
UARTFLEXD1.txdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_MEM2PER |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF0 |
XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_INCREMENTED_AM |
XDMAC_CC_DAM_FIXED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM1_TX);
UARTFLEXD1.dmarx = 0;
UARTFLEXD1.dmatx = 0;
#endif
#if SAMA_UART_USE_FLEXCOM2
uartObjectInit(&UARTFLEXD2);
UARTFLEXD2.flexcom = FLEXCOM2;
UARTFLEXD2.usart = USART2;
UARTFLEXD2.clock = SAMA_FLEXCOM2CLK;
UARTFLEXD2.rxdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_PER2MEM |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF1 |
XDMAC_CC_DIF_AHB_IF0 |
XDMAC_CC_SAM_FIXED_AM |
XDMAC_CC_DAM_INCREMENTED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM2_RX);
UARTFLEXD2.txdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_MEM2PER |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF0 |
XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_INCREMENTED_AM |
XDMAC_CC_DAM_FIXED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM2_TX);
UARTFLEXD2.dmarx = 0;
UARTFLEXD2.dmatx = 0;
#endif
#if SAMA_UART_USE_FLEXCOM3
uartObjectInit(&UARTFLEXD3);
UARTFLEXD3.flexcom = FLEXCOM3;
UARTFLEXD3.usart = USART3;
UARTFLEXD3.clock = SAMA_FLEXCOM3CLK;
UARTFLEXD3.rxdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_PER2MEM |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF1 |
XDMAC_CC_DIF_AHB_IF0 |
XDMAC_CC_SAM_FIXED_AM |
XDMAC_CC_DAM_INCREMENTED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM3_RX);
UARTFLEXD3.txdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_MEM2PER |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF0 |
XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_INCREMENTED_AM |
XDMAC_CC_DAM_FIXED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM3_TX);
UARTFLEXD3.dmarx = 0;
UARTFLEXD3.dmatx = 0;
#endif
#if SAMA_UART_USE_FLEXCOM4
uartObjectInit(&UARTFLEXD4);
UARTFLEXD4.flexcom = FLEXCOM4;
UARTFLEXD4.usart = USART4;
UARTFLEXD4.clock = SAMA_FLEXCOM4CLK;
UARTFLEXD4.rxdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_PER2MEM |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF1 |
XDMAC_CC_DIF_AHB_IF0 |
XDMAC_CC_SAM_FIXED_AM |
XDMAC_CC_DAM_INCREMENTED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM4_RX);
UARTFLEXD4.txdmamode = XDMAC_CC_TYPE_PER_TRAN |
XDMAC_CC_MBSIZE_SINGLE |
XDMAC_CC_DSYNC_MEM2PER |
XDMAC_CC_PROT_SEC |
XDMAC_CC_CSIZE_CHK_1 |
XDMAC_CC_DWIDTH_BYTE |
XDMAC_CC_SIF_AHB_IF0 |
XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_INCREMENTED_AM |
XDMAC_CC_DAM_FIXED_AM |
XDMAC_CC_PERID(PERID_FLEXCOM4_TX);
UARTFLEXD4.dmarx = 0;
UARTFLEXD4.dmatx = 0;
#endif
}
/**
* @brief Configures and activates the UART peripheral.
*
@ -513,11 +954,11 @@ void uart_lld_start(UARTDriver *uartp) {
if (uartp->state == UART_STOP) {
#if SAMA_UART_USE_UART0
if (&UARTD0 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART0_IRQ_PRIORITY,
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART0_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART0_IRQ_PRIORITY,
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART0_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
pmcEnableUART0();
@ -537,11 +978,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if SAMA_UART_USE_UART1
if (&UARTD1 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART1_IRQ_PRIORITY,
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART1_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART1_IRQ_PRIORITY,
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART1_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
pmcEnableUART1();
@ -561,11 +1002,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if SAMA_UART_USE_UART2
if (&UARTD2 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART2_IRQ_PRIORITY,
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART2_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART2_IRQ_PRIORITY,
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART2_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
pmcEnableUART2();
@ -585,11 +1026,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if SAMA_UART_USE_UART3
if (&UARTD3 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART3_IRQ_PRIORITY,
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART3_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART3_IRQ_PRIORITY,
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART3_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
pmcEnableUART3();
@ -609,11 +1050,11 @@ void uart_lld_start(UARTDriver *uartp) {
#if SAMA_UART_USE_UART4
if (&UARTD4 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART4_IRQ_PRIORITY,
uartp->dmarx = dmaChannelAllocate(SAMA_UART_UART4_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART4_IRQ_PRIORITY,
uartp->dmatx = dmaChannelAllocate(SAMA_UART_UART4_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
pmcEnableUART4();
@ -631,6 +1072,136 @@ void uart_lld_start(UARTDriver *uartp) {
}
#endif
#if SAMA_UART_USE_FLEXCOM0
if (&UARTFLEXD0 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
/* Enabling USART on FLEXCOM */
uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART;
pmcEnableFLEXCOM0();
aicSetSourcePriority(ID_USART0, SAMA_UART_FLEXCOM0_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART0, SAMA_UART_FLEXCOM0_HANDLER);
aicEnableInt(ID_USART0);
/* Configuring destination and mode of txdma channel*/
dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR);
dmaChannelSetMode(uartp->dmatx, uartp->txdmamode);
/* Configuring source and mode of rxdma channel*/
dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR);
dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode);
}
#endif
#if SAMA_UART_USE_FLEXCOM1
if (&UARTFLEXD1 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
/* Enabling USART on FLEXCOM */
uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART;
pmcEnableFLEXCOM1();
aicSetSourcePriority(ID_USART1, SAMA_UART_FLEXCOM1_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART1, SAMA_UART_FLEXCOM1_HANDLER);
aicEnableInt(ID_USART1);
/* Configuring destination and mode of txdma channel*/
dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR);
dmaChannelSetMode(uartp->dmatx, uartp->txdmamode);
/* Configuring source and mode of rxdma channel*/
dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR);
dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode);
}
#endif
#if SAMA_UART_USE_FLEXCOM2
if (&UARTFLEXD2 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
/* Enabling USART on FLEXCOM */
uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART;
pmcEnableFLEXCOM2();
aicSetSourcePriority(ID_USART2, SAMA_UART_FLEXCOM2_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART2, SAMA_UART_FLEXCOM2_HANDLER);
aicEnableInt(ID_USART2);
/* Configuring destination and mode of txdma channel*/
dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR);
dmaChannelSetMode(uartp->dmatx, uartp->txdmamode);
/* Configuring source and mode of rxdma channel*/
dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR);
dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode);
}
#endif
#if SAMA_UART_USE_FLEXCOM3
if (&UARTFLEXD3 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
/* Enabling USART on FLEXCOM */
uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART;
pmcEnableFLEXCOM3();
aicSetSourcePriority(ID_USART3, SAMA_UART_FLEXCOM3_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART3, SAMA_UART_FLEXCOM3_HANDLER);
aicEnableInt(ID_USART3);
/* Configuring destination and mode of txdma channel*/
dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR);
dmaChannelSetMode(uartp->dmatx, uartp->txdmamode);
/* Configuring source and mode of rxdma channel*/
dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR);
dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode);
}
#endif
#if SAMA_UART_USE_FLEXCOM4
if (&UARTFLEXD4 == uartp) {
uartp->dmarx = dmaChannelAllocate(SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_rx_end_irq,
(void *)uartp);
uartp->dmatx = dmaChannelAllocate(SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY,
(sama_dmaisr_t)uart_lld_serve_tx_end_irq,
(void *)uartp);
/* Enabling USART on FLEXCOM */
uartp->flexcom->FLEX_MR = FLEX_MR_OPMODE_USART;
pmcEnableFLEXCOM4();
aicSetSourcePriority(ID_USART4, SAMA_UART_FLEXCOM4_IRQ_PRIORITY);
aicSetSourceHandler(ID_USART4, SAMA_UART_FLEXCOM4_HANDLER);
aicEnableInt(ID_USART4);
/* Configuring destination and mode of txdma channel*/
dmaChannelSetDestination(uartp->dmatx, &uartp->usart->US_THR);
dmaChannelSetMode(uartp->dmatx, uartp->txdmamode);
/* Configuring source and mode of rxdma channel*/
dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR);
dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode);
}
#endif
/* Static DMA setup, the transfer size depends on the USART settings,
it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/
// if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M0)
@ -693,6 +1264,40 @@ void uart_lld_stop(UARTDriver *uartp) {
}
#endif
#if SAMA_UART_USE_FLEXCOM0
if (&UARTFLEXD0 == uartp) {
pmcDisableFLEXCOM0();
return;
}
#endif
#if SAMA_UART_USE_FLEXCOM1
if (&UARTFLEXD1 == uartp) {
pmcDisableFLEXCOM1();
return;
}
#endif
#if SAMA_UART_USE_FLEXCOM2
if (&UARTFLEXD2 == uartp) {
pmcDisableFLEXCOM2();
return;
}
#endif
#if SAMA_UART_USE_FLEXCOM3
if (&UARTFLEXD3 == uartp) {
pmcDisableFLEXCOM3();
return;
}
#endif
#if SAMA_UART_USE_FLEXCOM4
if (&UARTFLEXD4 == uartp) {
pmcDisableFLEXCOM4();
return;
}
#endif
}
}
@ -709,16 +1314,23 @@ void uart_lld_stop(UARTDriver *uartp) {
*/
void uart_lld_start_send(UARTDriver *uartp, size_t n, const void *txbuf) {
/* TX DMA channel preparation.*/
dmaChannelSetSource(uartp->dmatx, txbuf);
dmaChannelSetTransactionSize(uartp->dmatx, n);
/* Only enable TC interrupt if there's a callback attached to it.
Also we need to clear TC flag which could be set before. */
if (uartp->config->txend2_cb != NULL) {
uartp->uart->UART_IER = UART_IER_TXEMPTY;
#if SAMA_UART_USE_UART
if (uartp->uart != NULL)
uartp->uart->UART_IER = UART_IER_TXEMPTY;
#endif
#if SAMA_UART_USE_FLEXCOM
if (uartp->usart != NULL)
uartp->usart->US_IER = US_IER_TXEMPTY;
#endif
}
/* TX DMA channel preparation.*/
dmaChannelSetSource(uartp->dmatx, txbuf);
dmaChannelSetTransactionSize(uartp->dmatx, n);
/* Starting transfer.*/
dmaChannelEnable(uartp->dmatx);
}
@ -768,7 +1380,14 @@ void uart_lld_start_receive(UARTDriver *uartp, size_t n, void *rxbuf) {
uartp->dmarx->xdmac->XDMAC_CHID[uartp->dmarx->chid].XDMAC_CNDC = 0;
/* RX DMA channel preparation.*/
dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR);
#if SAMA_UART_USE_UART
if (uartp->uart != NULL)
dmaChannelSetSource(uartp->dmarx, &uartp->uart->UART_RHR);
#endif
#if SAMA_UART_USE_FLEXCOM
if (uartp->usart != NULL)
dmaChannelSetSource(uartp->dmarx, &uartp->usart->US_RHR);
#endif
dmaChannelSetDestination(uartp->dmarx, rxbuf);
dmaChannelSetTransactionSize(uartp->dmarx, n);
dmaChannelSetMode(uartp->dmarx, uartp->rxdmamode);

View File

@ -41,7 +41,7 @@
*/
/**
* @brief UART driver on UART0 enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @details If set to @p TRUE the support for UART0 is included.
* @note The default is @p FALSE.
*/
#if !defined(SAMA_UART_USE_UART0) || defined(__DOXYGEN__)
@ -84,6 +84,51 @@
#define SAMA_UART_USE_UART4 FALSE
#endif
/**
* @brief UART driver on FLEXCOM0 enable switch.
* @details If set to @p TRUE the support for FLEXCOM0 is included.
* @note The default is @p FALSE.
*/
#if !defined(SAMA_UART_USE_FLEXCOM0) || defined(__DOXYGEN__)
#define SAMA_UART_USE_FLEXCOM0 FALSE
#endif
/**
* @brief UART driver on FLEXCOM1 enable switch.
* @details If set to @p TRUE the support for FLEXCOM1 is included.
* @note The default is @p FALSE.
*/
#if !defined(SAMA_UART_USE_FLEXCOM1) || defined(__DOXYGEN__)
#define SAMA_UART_USE_FLEXCOM1 FALSE
#endif
/**
* @brief UART driver on FLEXCOM2 enable switch.
* @details If set to @p TRUE the support for FLEXCOM2 is included.
* @note The default is @p FALSE.
*/
#if !defined(SAMA_UART_USE_FLEXCOM2) || defined(__DOXYGEN__)
#define SAMA_UART_USE_FLEXCOM2 FALSE
#endif
/**
* @brief UART driver on FLEXCOM3 enable switch.
* @details If set to @p TRUE the support for FLEXCOM3 is included.
* @note The default is @p FALSE.
*/
#if !defined(SAMA_UART_USE_FLEXCOM3) || defined(__DOXYGEN__)
#define SAMA_UART_USE_FLEXCOM3 FALSE
#endif
/**
* @brief UART driver on FLEXCOM4 enable switch.
* @details If set to @p TRUE the support for FLEXCOM4 is included.
* @note The default is @p FALSE.
*/
#if !defined(SAMA_UART_USE_FLEXCOM4) || defined(__DOXYGEN__)
#define SAMA_UART_USE_FLEXCOM4 FALSE
#endif
/**
* @brief UART0 interrupt priority level setting.
*/
@ -119,6 +164,111 @@
#define SAMA_UART_UART4_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM0 interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM0_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM0_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM1 interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM1_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM2 interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM2_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM3 interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM3_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM4 interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM4_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM4_IRQ_PRIORITY 4
#endif
/**
* @brief UART0 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_UART0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_UART0_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief UART1 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_UART1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_UART1_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief UART2 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_UART2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_UART2_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief UART3 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_UART3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_UART3_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief UART4 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_UART4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_UART4_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM0 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM0_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM1 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM1_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM2 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM2_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM3 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM3_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief FLEXCOM4 DMA interrupt priority level setting.
*/
#if !defined(SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define SAMA_UART_FLEXCOM4_DMA_IRQ_PRIORITY 4
#endif
/**
* @brief UART DMA error hook.
* @note The default action for DMA errors is a system halt because DMA
@ -133,17 +283,115 @@
/* Derived constants and error checks. */
/*===========================================================================*/
/*TODO: check every peripheral */
#if SAMA_UART_USE_UART0 && SAMA_SERIAL_USE_UART0
#error "UART0 already in use"
#endif
/**
* @brief At least an UART unit is in use.
*/
#define SAMA_UART_USE_UART (SAMA_UART_USE_UART0 || \
SAMA_UART_USE_UART1 || \
SAMA_UART_USE_UART2 || \
SAMA_UART_USE_UART3 || \
SAMA_UART_USE_UART4)
/**
* @brief At least an FLEXCOM unit is in use.
*/
#define SAMA_UART_USE_FLEXCOM (SAMA_UART_USE_FLEXCOM0 || \
SAMA_UART_USE_FLEXCOM1 || \
SAMA_UART_USE_FLEXCOM2 || \
SAMA_UART_USE_FLEXCOM3 || \
SAMA_UART_USE_FLEXCOM4)
#if !SAMA_UART_USE_UART0 && !SAMA_UART_USE_UART1 && \
!SAMA_UART_USE_UART2 && !SAMA_UART_USE_UART3 && \
!SAMA_UART_USE_UART4
!SAMA_UART_USE_UART4 && \
!SAMA_UART_USE_FLEXCOM0 && !SAMA_UART_USE_FLEXCOM1 && \
!SAMA_UART_USE_FLEXCOM2 && !SAMA_UART_USE_FLEXCOM3 && \
!SAMA_UART_USE_FLEXCOM4
#error "UART driver activated but no USART/UART peripheral assigned"
#endif
/* Checks on allocation of UARTx units.*/
#if SAMA_UART_USE_UART0
#if defined(SAMA_UART0_IS_USED)
#error "UARTD0 requires UART0 but the peripheral is already used"
#else
#define SAMA_UART0_IS_USED
#endif
#endif
#if SAMA_UART_USE_UART1
#if defined(SAMA_UART1_IS_USED)
#error "UARTD1 requires UART1 but the peripheral is already used"
#else
#define SAMA_UART1_IS_USED
#endif
#endif
#if SAMA_UART_USE_UART2
#if defined(SAMA_UART2_IS_USED)
#error "UARTD2 requires UART2 but the peripheral is already used"
#else
#define SAMA_UART2_IS_USED
#endif
#endif
#if SAMA_UART_USE_UART3
#if defined(SAMA_UART3_IS_USED)
#error "UARTD3 requires UART3 but the peripheral is already used"
#else
#define SAMA_UART3_IS_USED
#endif
#endif
#if SAMA_UART_USE_UART4
#if defined(SAMA_UART4_IS_USED)
#error "UARTD4 requires UART4 but the peripheral is already used"
#else
#define SAMA_UART4_IS_USED
#endif
#endif
#if SAMA_UART_USE_FLEXCOM0
#if defined(SAMA_FLEXCOM0_IS_USED)
#error "UARTFLEXD0 requires FLEXCOM0 but the peripheral is already used"
#else
#define SAMA_FLEXCOM0_IS_USED
#endif
#endif
#if SAMA_UART_USE_FLEXCOM1
#if defined(SAMA_FLEXCOM1_IS_USED)
#error "UARTFLEXD1 requires FLEXCOM1 but the peripheral is already used"
#else
#define SAMA_FLEXCOM1_IS_USED
#endif
#endif
#if SAMA_UART_USE_FLEXCOM2
#if defined(SAMA_FLEXCOM2_IS_USED)
#error "UARTFLEXD2 requires FLEXCOM2 but the peripheral is already used"
#else
#define SAMA_FLEXCOM2_IS_USED
#endif
#endif
#if SAMA_UART_USE_FLEXCOM3
#if defined(SAMA_FLEXCOM3_IS_USED)
#error "UARTFLEXD3 requires FLEXCOM3 but the peripheral is already used"
#else
#define SAMA_FLEXCOM3_IS_USED
#endif
#endif
#if SAMA_UART_USE_FLEXCOM4
#if defined(SAMA_FLEXCOM4_IS_USED)
#error "UARTFLEXD4 requires FLEXCOM4 but the peripheral is already used"
#else
#define SAMA_FLEXCOM4_IS_USED
#endif
#endif
#if !defined(SAMA_DMA_REQUIRED)
#define SAMA_DMA_REQUIRED
#endif
@ -281,10 +529,18 @@ struct UARTDriver {
UART_DRIVER_EXT_FIELDS
#endif
/* End of the mandatory fields.*/
#if SAMA_UART_USE_UART
/**
* @brief Pointer to the UART registers block.
*/
Uart *uart;
#endif
#if SAMA_UART_USE_FLEXCOM
/* Pointer to the FLEXCOM registers block.*/
Flexcom *flexcom;
/* Pointer to the USART registers block.*/
Usart *usart;
#endif
/**
* @brief Clock frequency for the associated USART/UART.
*/
@ -339,6 +595,26 @@ extern UARTDriver UARTD3;
extern UARTDriver UARTD4;
#endif
#if SAMA_UART_USE_FLEXCOM0 && !defined(__DOXYGEN__)
extern UARTDriver UARTFLEXD0;
#endif
#if SAMA_UART_USE_FLEXCOM1 && !defined(__DOXYGEN__)
extern UARTDriver UARTFLEXD1;
#endif
#if SAMA_UART_USE_FLEXCOM2 && !defined(__DOXYGEN__)
extern UARTDriver UARTFLEXD2;
#endif
#if SAMA_UART_USE_FLEXCOM3 && !defined(__DOXYGEN__)
extern UARTDriver UARTFLEXD3;
#endif
#if SAMA_UART_USE_FLEXCOM4 && !defined(__DOXYGEN__)
extern UARTDriver UARTFLEXD4;
#endif
#ifdef __cplusplus
extern "C" {
#endif