/**************************************************************************//**
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* [url=home.php?mod=space&uid=895143]@version[/url] V1.00
* $Date: 8/20/19 5:36p $
* [url=home.php?mod=space&uid=247401]@brief[/url] Use UART to drive ESP8266 wifi chip and communication.
*
* @note
* Copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NUC230_240.h"
#include <string.h> //because using memset function
/*---------------------------------------------------------------------------*/
/* Define */
/*---------------------------------------------------------------------------*/
#define PLL_CLOCK 50000000
#define SYSTICK_TIMER 10000 // 10ms
#define KEY1 PA0
#define KEY2 PA1
#define KEY3 PA2
#define KEY4 PA3
#define KEY_NONE 0
#define KEY_SW1 1
#define KEY_SW2 2
#define KEY_SW3 3
#define KEY_SW4 4
#define RECEIVE_MAX_CHAR_NUMBER 100
#define RECEIVE_MAX_STRING 10
#define RECEIVE_MAX_VALIDCHAR_NUMBER 80
typedef struct
{
uint8_t u8CharNum;
uint8_t *pu8string;
} ATCMD_Type;
typedef struct
{
uint8_t u8String[RECEIVE_MAX_CHAR_NUMBER];
} ATREVSTRING_Type;
/*---------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------*/
uint32_t u32SysTimerCounter = 0;
uint32_t u32TimerOutCounter = 0;
uint32_t u32SysTimerKeyCounter = 0;
uint8_t u8KeyScan;
uint8_t u8KeyScanPrev = KEY_NONE;
uint8_t u8KeyGet;
uint8_t AT_StringCmdRst[] = {"AT+RST\r\n"};
uint8_t AT_StringCmdCwmode1[] = {"AT+CWMODE=1\r\n"};
uint8_t AT_StringCmdCwmode2[] = {"AT+CWMODE=2\r\n"};
uint8_t AT_StringCmdCwmode3[] = {"AT+CWMODE=3\r\n"};
uint8_t AT_StringCmdCipMux0[] = {"AT+CIPMUX=0\r\n"};
uint8_t AT_StringCmdCipMux1[] = {"AT+CIPMUX=1\r\n"};
uint8_t AT_StringCmdCipServer0[] = {"AT+CIPSERVER=0\r\n"};
uint8_t AT_StringCmdCipServer1[] = {"AT+CIPSERVER=1,8080\r\n"};
uint8_t AT_StringCmdAP[] = {"AT+CWSAP_CUR=\"Nuvoton_AP\","",5,0,4,0\r\n"};
uint8_t AT_StringIPD[] = {"\n+IPD,0,"};
ATCMD_Type atCmdRst = {sizeof(AT_StringCmdRst) / sizeof(uint8_t), AT_StringCmdRst};
ATCMD_Type atCmdCwmode1 = {sizeof(AT_StringCmdCwmode1) / sizeof(uint8_t), AT_StringCmdCwmode1};
ATCMD_Type atCmdCwmode2 = {sizeof(AT_StringCmdCwmode2) / sizeof(uint8_t), AT_StringCmdCwmode2};
ATCMD_Type atCmdCwmode3 = {sizeof(AT_StringCmdCwmode3) / sizeof(uint8_t), AT_StringCmdCwmode3};
ATCMD_Type atCmdCipmux0 = {sizeof(AT_StringCmdCipMux0) / sizeof(uint8_t), AT_StringCmdCipMux0};
ATCMD_Type atCmdCipmux1 = {sizeof(AT_StringCmdCipMux1) / sizeof(uint8_t), AT_StringCmdCipMux1};
ATCMD_Type atCmdCipserver0 = {sizeof(AT_StringCmdCipServer0) / sizeof(uint8_t), AT_StringCmdCipServer0};
ATCMD_Type atCmdCipserver1 = {sizeof(AT_StringCmdCipServer1) / sizeof(uint8_t), AT_StringCmdCipServer1};
ATCMD_Type atCmdAp = {sizeof(AT_StringCmdAP) / sizeof(uint8_t), AT_StringCmdAP};
ATREVSTRING_Type ReceiveArray[RECEIVE_MAX_STRING];
uint8_t u8ReceiveStringArrayHeader;
uint8_t u8ReceiveStringArrayTail;
uint8_t u8StringIndex;
uint8_t u8ReceiveData[RECEIVE_MAX_VALIDCHAR_NUMBER];
uint8_t u8ReceiveDataLength;
/*---------------------------------------------------------------------------*/
/* Functions */
/*---------------------------------------------------------------------------*/
__STATIC_INLINE void CLK_SysTickInit(uint32_t u32us)
{
SysTick->LOAD = u32us * CyclesPerUs;
SysTick->VAL = (0x00);
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Handler(void)
{
u32SysTimerCounter++;
if (u32TimerOutCounter > 0)
{
u32TimerOutCounter --;
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 0 interrupt event */
/*---------------------------------------------------------------------------------------------------------*/
void UART02_IRQHandler(void)
{
uint32_t u32IntSts = UART0->ISR;
uint8_t u8Data;
if (u32IntSts & UART_ISR_RDA_INT_Msk)
{
u8Data = UART_READ(UART0);
while (UART1->FSR & UART_FSR_TX_FULL_Msk);
UART_WRITE(UART1, u8Data);
if (u8Data == '\r')
{
ReceiveArray[u8ReceiveStringArrayTail].u8String[u8StringIndex++] = u8Data;
u8ReceiveStringArrayTail++;
u8StringIndex = 0;
if (u8ReceiveStringArrayTail >= RECEIVE_MAX_STRING)
{
if (u8ReceiveStringArrayHeader == 0)
{
u8ReceiveStringArrayTail = 0;
u8ReceiveStringArrayHeader++;
}
else
{
u8ReceiveStringArrayTail = 0;
}
}
else if (u8ReceiveStringArrayTail == u8ReceiveStringArrayHeader)
{
u8ReceiveStringArrayHeader++;
if (u8ReceiveStringArrayHeader >= RECEIVE_MAX_STRING)
{
u8ReceiveStringArrayHeader = 0;
}
}
}
else
{
ReceiveArray[u8ReceiveStringArrayTail].u8String[u8StringIndex++] = u8Data;
if (u8StringIndex >= RECEIVE_MAX_CHAR_NUMBER)
{
u8StringIndex--;
}
}
}
else
{
UART0->FSR |= UART_FSR_BIF_Msk | UART_FSR_FEF_Msk | UART_FSR_PEF_Msk;
u8Data = UART_READ(UART0);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 1 interrupt event */
/*---------------------------------------------------------------------------------------------------------*/
void UART1_IRQHandler(void)
{
uint32_t u32IntSts = UART1->ISR;
uint8_t u8Data;
if (u32IntSts & UART_ISR_RDA_INT_Msk)
{
u8Data = UART_READ(UART1);
while (UART0->FSR & UART_FSR_TX_FULL_Msk);
UART_WRITE(UART0, u8Data);
}
else
{
UART1->FSR |= UART_FSR_BIF_Msk | UART_FSR_FEF_Msk | UART_FSR_PEF_Msk;
u8Data = UART_READ(UART0);
}
}
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Enable Internal RC 22.1184MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);
/* Waiting for Internal RC clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);
/* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));
/* Enable external XTAL 12MHz clock */
CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);
/* Waiting for external XTAL clock ready */
CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);
/* Set core clock as PLL_CLOCK from PLL */
CLK_SetCoreClock(PLL_CLOCK);
/* Enable UART module clock */
CLK_EnableModuleClock(UART0_MODULE);
CLK_EnableModuleClock(UART1_MODULE);
/* Select UART module clock source */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set GPB multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB0_Msk | SYS_GPB_MFP_PB1_Msk);
SYS->GPB_MFP |= SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;
/* Set GPB multi-function pins for UART1 RXD and TXD */
SYS->GPB_MFP &= ~(SYS_GPB_MFP_PB4_Msk | SYS_GPB_MFP_PB5_Msk);
SYS->GPB_MFP |= SYS_GPB_MFP_PB4_UART1_RXD | SYS_GPB_MFP_PB5_UART1_TXD;
}
void UART_Init()
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init UART */
/*---------------------------------------------------------------------------------------------------------*/
/* Reset IP */
SYS_ResetModule(UART0_RST);
SYS_ResetModule(UART1_RST);
/* Configure UART0/UART1 and set UART0/UART1 Baudrate */
UART_Open(UART0, 115200);
UART_Open(UART1, 115200);
/* Enable Interrupt and install the call back function */
//set RX FIFO INT TRIGGER LEVEL
UART0->FCR &= ~(UART_FCR_RFITL_Msk | UART_FCR_RTS_TRI_LEV_Msk);
UART0->FCR |= ((0x0ul << UART_FCR_RFITL_Pos));
UART_DisableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_THRE_IEN_Msk | UART_IER_RLS_IEN_Msk));
UART_EnableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk));
UART1->FCR &= ~(UART_FCR_RFITL_Msk | UART_FCR_RTS_TRI_LEV_Msk);
UART1->FCR |= ((0x0ul << UART_FCR_RFITL_Pos));
UART_DisableInt(UART1, (UART_IER_RDA_IEN_Msk | UART_IER_THRE_IEN_Msk | UART_IER_RLS_IEN_Msk));
UART_EnableInt(UART1, (UART_IER_RDA_IEN_Msk | UART_IER_RLS_IEN_Msk));
}
void Initial_Key_Input(void)
{
GPIO_SetMode(PA, 0, GPIO_PMD_QUASI);
GPIO_SetMode(PA, 1, GPIO_PMD_QUASI);
GPIO_SetMode(PA, 2, GPIO_PMD_QUASI);
GPIO_SetMode(PA, 3, GPIO_PMD_QUASI);
}
uint8_t Get_Key_Input(void)
{
uint8_t u8temp = KEY_NONE;
if (KEY1 == 0)
{
u8temp = KEY_SW1;
}
if (KEY2 == 0)
{
u8temp = KEY_SW2;
}
if (KEY3 == 0)
{
u8temp = KEY_SW3;
}
if (KEY4 == 0)
{
u8temp = KEY_SW4;
}
return u8temp;
}
void Key_Process(uint8_t u8Key)
{
uint32_t u32cnt;
if (u8Key == KEY_NONE)
{
return;
}
switch (u8Key)
{
case KEY_SW1:
UART_Write(UART0, atCmdRst.pu8string, atCmdRst.u8CharNum); // Reset ESP8266
break;
case KEY_SW2:
UART_Write(UART0, atCmdCwmode3.pu8string, atCmdCwmode3.u8CharNum); // Set ESP8266 STA+AP mode
for (u32cnt = 0; u32cnt < 0xffff; u32cnt++);
UART_Write(UART0, atCmdCipmux1.pu8string, atCmdCipmux1.u8CharNum); // Set ESP8266 Multi-connection
for (u32cnt = 0; u32cnt < 0xffff; u32cnt++);
UART_Write(UART0, atCmdAp.pu8string, atCmdAp.u8CharNum); // Set ESP8266 AP Name, No Password
for (u32cnt = 0; u32cnt < 0xffff; u32cnt++);
UART_Write(UART0, atCmdCipserver1.pu8string, atCmdCipserver1.u8CharNum); // Set ESP8266 TCP Server mode, Port number 8080
for (u32cnt = 0; u32cnt < 0xffff; u32cnt++);
u8ReceiveStringArrayHeader = u8ReceiveStringArrayTail = 0;
memset(ReceiveArray, 0, sizeof(ReceiveArray));
default:
break;
}
}
uint32_t CharConvertToNumber(uint8_t *pu81, uint8_t u8number)
{
uint32_t uChar = 0;
uint8_t u8cnt;
for (u8cnt = 0; u8cnt < u8number; u8cnt++)
{
if ((*(pu81 + u8cnt) >= '0') && (*(pu81 + u8cnt) <= '9'))
{
uChar = uChar * 10 + (*(pu81 + u8cnt) - '0');
}
else
{
uChar = 0xFFFFFFFF;
break;
}
}
return uChar;
}
uint8_t StringCompare(uint8_t *pu81, uint8_t *pu82)
{
uint8_t u8cnt = 0, j;
uint8_t u8LengthString[4];
uint32_t u32Length;
for (u8cnt = 0;; u8cnt++)
{
if (u8cnt >= RECEIVE_MAX_CHAR_NUMBER)
{
return FALSE;
}
if (*(pu82 + u8cnt) == '\0')
{
break;
}
if (*(pu81 + u8cnt) != *(pu82 + u8cnt))
{
return FALSE;
}
}
for (j = 0; j < 5; j++)
{
if (*(pu81 + u8cnt + j) != ':')
{
u8LengthString[j] = *(pu81 + u8cnt + j);
}
else
{
break;
}
}
if (j == 5)
{
return FALSE; //error length
}
else
{
u32Length = CharConvertToNumber(u8LengthString, j);
}
u8cnt = u8cnt + j + 1; //+1 to filter ':'
if ((u8cnt + u32Length) >= RECEIVE_MAX_CHAR_NUMBER)
{
return FALSE;
}
for (j = 0; j < u32Length; j++)
{
u8ReceiveData[j] = *(pu81 + u8cnt + j);
}
u8ReceiveData[j] = '\0';
u8ReceiveDataLength = u32Length;
return TRUE;
}
int main(void)
{
/* Unlock protected registers */
SYS_UnlockReg();
/* Init System, IP clock and multi-function I/O */
SYS_Init();
/* Lock protected registers */
SYS_LockReg();
/* Init uart */
UART_Init();
/* Config systick */
CLK_SysTickInit(SYSTICK_TIMER);
while (1)
{
if ((u32SysTimerCounter - u32SysTimerKeyCounter) >= 20) //20*SYSTICK_TIMER
{
u32SysTimerKeyCounter = u32SysTimerCounter;
u8KeyScan = Get_Key_Input();
if (u8KeyScan == KEY_NONE)
{
u8KeyGet = u8KeyScanPrev;
}
u8KeyScanPrev = u8KeyScan;
if (u8KeyGet != KEY_NONE)
{
Key_Process(u8KeyGet);
u8KeyGet = KEY_NONE;
}
}
if (u8ReceiveStringArrayHeader != u8ReceiveStringArrayTail)
{
if (StringCompare(ReceiveArray[u8ReceiveStringArrayHeader].u8String, AT_StringIPD))
{
printf("\n %s", u8ReceiveData);
}
u8ReceiveStringArrayHeader++;
if (u8ReceiveStringArrayHeader >= RECEIVE_MAX_STRING)
{
u8ReceiveStringArrayHeader = 0;
}
}
}
}
/*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/