- /**************************************************************************//**
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * [url=home.php?mod=space&uid=895143]@version[/url] V1.00
- * @brief
- * Two Single-Wire Loopback data test.
- *
- * SPDX-License-Identifier: Apache-2.0
- * [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2017 Nuvoton Technology Corp. All rights reserved.
- *
- ******************************************************************************/
- #include "stdio.h"
- #include "string.h"
- #include "NuMicro.h"
- #define PLL_CLOCK FREQ_96MHZ
- #define BUFSIZE 128
- /*---------------------------------------------------------------------------------------------------------*/
- /* Global variables */
- /*---------------------------------------------------------------------------------------------------------*/
- uint8_t g_u8RecData[BUFSIZE] = {0};
- uint8_t g_u8TxData [BUFSIZE] = {0};
- volatile uint32_t g_u32RecLen = 0;
- volatile int32_t g_i32RecOK = FALSE;
- /*---------------------------------------------------------------------------------------------------------*/
- /* Define functions prototype */
- /*---------------------------------------------------------------------------------------------------------*/
- int32_t main(void);
- void UART1_TEST_HANDLE(void);
- void UART02_TEST_HANDLE(void);
- void UART_FunctionTest(void);
- void SYS_Init(void)
- {
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init System Clock */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Unlock protected registers */
- SYS_UnlockReg();
- /* Enable HIRC clock (Internal RC 48MHz) */
- CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
- /* Wait for HIRC clock ready */
- while(!(CLK->STATUS & CLK_STATUS_HIRCSTB_Msk));
- /* Select HCLK clock source as HIRC and and HCLK source divider as 1 */
- CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC;
- CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | CLK_CLKDIV0_HCLK(1);
- /* Enable UART0/1/2 peripheral clock */
- CLK->APBCLK0 |= (CLK_APBCLK0_UART0CKEN_Msk | CLK_APBCLK0_UART1CKEN_Msk | CLK_APBCLK0_UART2CKEN_Msk);
- /* Select IP clock source */
- /* Select UART0 clock source is HIRC */
- CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_UART0SEL_Msk)) | CLK_CLKSEL1_UART0SEL_HIRC;
- CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_UART0DIV_Msk)) | CLK_CLKDIV0_UART0(1);
- /* Select UART1 clock source is HIRC */
- CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_UART1SEL_Msk)) | CLK_CLKSEL1_UART1SEL_HIRC;
- CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_UART1DIV_Msk)) | CLK_CLKDIV0_UART1(1);
- /* Select UART2 clock source is HIRC */
- CLK->CLKSEL3 = (CLK->CLKSEL3 & (~CLK_CLKSEL3_UART2SEL_Msk)) | CLK_CLKSEL3_UART2SEL_HIRC;
- CLK->CLKDIV4 = (CLK->CLKDIV4 & (~CLK_CLKDIV4_UART2DIV_Msk)) | CLK_CLKDIV4_UART2(1);
- /* Update System Core Clock */
- /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
- SystemCoreClockUpdate();
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Set PB multi-function pins for UART0 RXD=PB.12 and TXD=PB.13 */
- SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) | \
- (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);
- /* Set PA multi-function pins for UART1 RXD */
- SYS->GPA_MFPL = (SYS->GPA_MFPL & ~(SYS_GPA_MFPL_PA2MFP_Msk)) | SYS_GPA_MFPL_PA2MFP_UART1_RXD;
- /* Set PB multi-function pins for UART2 RXD */
- SYS->GPB_MFPL = (SYS->GPB_MFPL & ~(SYS_GPB_MFPL_PB0MFP_Msk)) | SYS_GPB_MFPL_PB0MFP_UART2_RXD;
- /* The RX pin needs to pull-high for single-wire */
- /* If the external circuit doesn't pull-high, set GPIO pin as Quasi-directional mode for this purpose here */
- PA->MODE &= (PA->MODE & ~GPIO_MODE_MODE2_Msk) | (GPIO_MODE_QUASI << GPIO_MODE_MODE2_Pos);
- PB->MODE = (PB->MODE & ~GPIO_MODE_MODE0_Msk) | (GPIO_MODE_QUASI << GPIO_MODE_MODE0_Pos);
- /* Lock protected registers */
- SYS_LockReg();
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init UART0 */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART0_Init()
- {
- /* Configure UART0 and set UART0 baud rate */
- UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HIRC, 115200);
- UART0->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init Single Wire(UART1) */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART1_Init()
- {
- /* Configure Single Wire(UART1) and set Single Wire(UART1) baud rate */
- UART1->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HIRC, 115200);
- UART1->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
- UART1->FUNCSEL = ((UART1->FUNCSEL & (~UART_FUNCSEL_FUNCSEL_Msk)) | UART_FUNCSEL_SINGLE_WIRE);
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init Single Wire(UART2) */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART2_Init()
- {
- /* Configure Single Wire(UART2) and set Single Wire(UART2) baud rate */
- UART2->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HIRC, 115200);
- UART2->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
- UART2->FUNCSEL = ((UART2->FUNCSEL & (~UART_FUNCSEL_FUNCSEL_Msk)) | UART_FUNCSEL_SINGLE_WIRE);
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* UART Test Sample */
- /* Test Item */
- /* Debug port control the Single wire 1(UART1) send data to Single wire 2(UART2) or Single wire 2(UART1) */
- /* send data to Single wire 1(UART1) */
- /*---------------------------------------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------------------------------------*/
- /* Main Function */
- /*---------------------------------------------------------------------------------------------------------*/
- int32_t main(void)
- {
- /* Init System, peripheral clock and multi-function I/O */
- SYS_Init();
- /* Init UART0 for printf */
- UART0_Init();
- /* Init UART1 and UART2 for Single Wire Test*/
- UART1_Init();
- UART2_Init();
- /*---------------------------------------------------------------------------------------------------------*/
- /* SAMPLE CODE */
- /*---------------------------------------------------------------------------------------------------------*/
- printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
- printf("\nUART Sample Program\n");
- /* UART sample function */
- UART_FunctionTest();
- while (1);
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* ISR to handle UART Channel 1 interrupt event */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART13_IRQHandler(void)
- {
- UART1_TEST_HANDLE();
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* UART1 Callback function */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART1_TEST_HANDLE()
- {
- uint32_t u32IntSts = UART1->INTSTS;
- if (u32IntSts & UART_INTSTS_RDAIF_Msk)
- {
- /* Get all the input characters */
- while (UART_IS_RX_READY(UART1))
- {
- /* Get the character from UART Buffer */
- g_u8RecData[g_u32RecLen] = UART_READ(UART1);
- if (g_u32RecLen == BUFSIZE - 1)
- {
- g_i32RecOK = TRUE;
- g_u32RecLen = 0;
- }
- else
- {
- g_u32RecLen++;
- }
- }
- }
- if (u32IntSts & UART_INTSTS_SWBEIF_Msk)
- {
- printf("Single-wire Bit Error Detection \n");
- UART1->INTSTS = UART_INTSTS_SWBEIF_Msk;
- }
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* ISR to handle UART Channel 0/2 interrupt event */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART02_IRQHandler(void)
- {
- UART02_TEST_HANDLE();
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* UART0/2 Callback function */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART02_TEST_HANDLE()
- {
- uint32_t u32IntSts = UART2->INTSTS;
- if (u32IntSts & UART_INTSTS_RDAIF_Msk)
- {
- /* Get all the input characters */
- while (UART_IS_RX_READY(UART2))
- {
- /* Get the character from UART Buffer */
- g_u8RecData[g_u32RecLen] = UART_READ(UART2);
- if (g_u32RecLen == BUFSIZE - 1)
- {
- g_i32RecOK = TRUE;
- g_u32RecLen = 0;
- }
- else
- {
- g_u32RecLen++;
- }
- }
- }
- if (u32IntSts & UART_INTSTS_SWBEIF_Msk)
- {
- printf("Single-wire Bit Error Detection \n");
- UART2->INTSTS = UART_INTSTS_SWBEIF_Msk;
- }
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Bulid Source Pattern function */
- /*---------------------------------------------------------------------------------------------------------*/
- void Build_Src_Pattern(uint32_t u32Addr, uint8_t type, uint32_t u32Length)
- {
- uint32_t i = 0, pattern = 0;
- uint8_t *pAddr;
- pAddr = (uint8_t *)u32Addr;
- if (type == 0) pattern = 0x1f;
- else if (type == 1) pattern = 0x3f;
- else if (type == 2) pattern = 0x7f;
- else if (type == 3) pattern = 0xff;
- else pattern = 0xff;
- for (i = 0; i < u32Length ; i++)
- pAddr[i] = (i & pattern);
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* Verify that the received data is correct */
- /*---------------------------------------------------------------------------------------------------------*/
- uint8_t Check_Pattern(uint32_t u32Addr0, uint32_t u32Addr1, uint32_t u32Length)
- {
- uint32_t i = 0;
- uint8_t result = 1;
- uint8_t *pAddr0;
- uint8_t *pAddr1;
- pAddr0 = (uint8_t *)u32Addr0;
- pAddr1 = (uint8_t *)u32Addr1;
- for (i = 0; i < u32Length ; i++)
- {
- if (pAddr0[i] != pAddr1[i])
- {
- printf("Data Error Idex=%d,tx =%d,rx=%d\n", i, pAddr0[i], pAddr1[i]) ;
- result = 0;
- }
- }
- return result;
- }
- /*---------------------------------------------------------------------------------------------------------*/
- /* UART Function Test */
- /*---------------------------------------------------------------------------------------------------------*/
- void UART_FunctionTest()
- {
- char cmmd ;
- uint32_t u32i;
- printf("+-----------------------------------------------------------+\n");
- printf("| UART Single Wire Function Test |\n");
- printf("+-----------------------------------------------------------+\n");
- printf("| Description : |\n");
- printf("| The sample code will print input char on terminal |\n");
- printf("| The user must connect the UART1 RX pin(PA2) to |\n");
- printf("| UART_Rx Pin(PB0). |\n");
- printf("| Single Wire 1(PA2)send data to Single Wire 2(PB0). |\n");
- printf("| Single Wire 2(PB0)send data to Single Wire 1(PA2). |\n");
- printf("| Please enter any to start (Press '0' to exit) |\n");
- printf("+-----------------------------------------------------------+\n");
- /*
- Using a RS232 cable to connect UART0 and PC.UART0 is set to debug port.
- UART1 and UART2 is enable RDA and RLS interrupt.
- The user can use URT0 to control the transmission or reception of UART1(Single Wire mode)
- When UART1(Single Wire 1)transfers data to UART2(Single Wire 2), if data is valid,
- it will enter the interrupt and receive the data.And then check the received data.
- When UART2(Single Wire 2)transfers data to UART1(Single Wire 1), if data is valid,
- it will enter the interrupt and receive the data.And then check the received data.
- */
- /* Enable UART1 RDA/Time-out/Single-wire Bit Error Detection interrupt */
- NVIC_EnableIRQ(UART13_IRQn);
- UART1->INTEN |= (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk | UART_INTEN_SWBEIEN_Msk);
- /* Enable UART2 RDA/Time-out/Single-wire Bit Error Detection interrupt */
- NVIC_EnableIRQ(UART02_IRQn);
- UART2->INTEN |= (UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk | UART_INTEN_SWBEIEN_Msk);
- do
- {
- printf("+--------------------------------------------------------------+\n");
- printf("| UART Single Wire Test Item |\n");
- printf("+--------------------------------------------------------------+\n");
- printf("| (1)Single Wire 1(PA2)send data to Single Wire 2(PB0). |\n");
- printf("| (2)Single Wire 2(PB0)send data to Single Wire 1(PA2). |\n");
- printf("| (E)Exit |\n");
- printf("+--------------------------------------------------------------+\n");
- cmmd = getchar();
- switch (cmmd)
- {
- case '1':
- {
- printf("SW1(UART1) --> SW2(UART2)Test :");
- g_i32RecOK = FALSE;
- Build_Src_Pattern((uint32_t)g_u8TxData, UART_WORD_LEN_8, BUFSIZE);
- /* Check the Rx status is Idel */
- while (!UART_RX_IDLE(UART1)) {};
- /* Send data */
- for(u32i = 0; u32i < BUFSIZE; u32i++)
- {
- /* Send 1 byte data */
- UART1->DAT = g_u8TxData[u32i];
- /* Wait if Tx FIFO is full */
- while((UART1->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk)==0);
- }
- while (g_i32RecOK != TRUE) {}
- Check_Pattern((uint32_t)g_u8TxData, (uint32_t)g_u8RecData, BUFSIZE) ? printf(" Pass\n") : printf(" Fail\n");
- /* Clear the Tx and Rx data buffer */
- memset((uint8_t *)g_u8TxData, 0, BUFSIZE);
- memset((uint8_t *)g_u8RecData, 0, BUFSIZE);
- }
- break;
- case '2':
- {
- printf("SW2(UART2) --> SW1(UART1)Test :");
- g_i32RecOK = FALSE;
- Build_Src_Pattern((uint32_t)g_u8TxData, UART_WORD_LEN_8, BUFSIZE);
- /* Check the Rx status is Idel */
- while (!UART_RX_IDLE(UART2)) {};
- /* Send data */
- for(u32i = 0; u32i < BUFSIZE; u32i++)
- {
- /* Send 1 byte data */
- UART2->DAT = g_u8TxData[u32i];
- /* Wait if Tx FIFO is full */
- while((UART2->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk)==0);
- }
- while (g_i32RecOK != TRUE) {};
- Check_Pattern((uint32_t)g_u8TxData, (uint32_t)g_u8RecData, BUFSIZE) ? printf(" Pass\n") : printf(" Fail\n");
- /* Clear the Tx and Rx data buffer */
- memset((uint8_t *)g_u8TxData, 0, BUFSIZE);
- memset((uint8_t *)g_u8RecData, 0, BUFSIZE);
- }
- break;
- default:
- break;
- }
- }
- while ((cmmd != 'E') && (cmmd != 'e'));
- /* Disable UART1 RDA/Time-out interrupt */
- UART1->INTEN &= ~(UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk | UART_INTEN_SWBEIEN_Msk);
- /* Disable UART2 RDA/Time-out interrupt */
- UART2->INTEN &= ~(UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk | UART_INTEN_SWBEIEN_Msk);
- printf("\nUART Sample Demo End.\n");
- }
- /*** (C) COPYRIGHT 2017 Nuvoton Technology Corp. ***/
|