- /******************************************************************************
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * @brief
- * Demonstrate how to implement a USB mouse device.
- * It use PC0 ~ PC5 to control mouse direction and mouse key.
- * It also supports USB suspend and remote wakeup.
- * @note
- * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
- ******************************************************************************/
- #include <stdio.h>
- #include "NUC123.h"
- #include "hid_mouse.h"
- #include "common.h"
- #define CLK_PLLCON_60MHz_XTAL 0xC026 // 60MHz
- #define CLK_PLLCON_72MHz_XTAL 0xC02E // 72MHz
- #define CLK_PLLCON_144MHz_XTAL 0x402E // 144MHz
- /*--------------------------------------------------------------------------*/
- void SYS_Init(void)
- {
- /* Enable XT1_OUT (PF0) and XT1_IN (PF1) */
- SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;
- /*---------------------------------------------------------------------------------------------------------*/
- /* 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 Flash Access Delay */
- FMC->FATCON |= FMC_FATCON_FOMSEL1_Msk | FMC_FATCON_FOMSEL0_Msk;
- /* Set core clock */
- CLK_SetCoreClock(72000000);
- /* Enable module clock */
- CLK_EnableModuleClock(UART0_MODULE);
- CLK_EnableModuleClock(USBD_MODULE);
- /* Select module clock source */
- CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_CLKDIV_UART(1));
- CLK_SetModuleClock(USBD_MODULE, 0, CLK_CLKDIV_USB(3));
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Set GPB multi-function pins for UART0 RXD and TXD */
- SYS->GPB_MFP |= (SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD);
- /* Set PC.13 as CLKO function pin */
- //SYS->GPC_MFP = SYS_GPC_MFP_PC13_CLKO;
- //SYS->ALT_MFP = SYS_ALT_MFP_PC13_CLKO;
- /* Enable CLKO (PC.13) for monitor HCLK. CLKO = HCLK/8 Hz*/
- //CLK_EnableCKO(CLK_CLKSEL2_FRQDIV_S_HCLK, 2, NULL);
- }
- void UART0_Init(void)
- {
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init UART */
- /*---------------------------------------------------------------------------------------------------------*/
- /* Reset IP */
- SYS->IPRSTC2 |= SYS_IPRSTC2_UART0_RST_Msk;
- SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;
- /* Configure UART0 and set UART0 Baudrate */
- UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HXT, 115200);
- UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
- }
- void GPIO_Init(void)
- {
- /* Enable PC0~5 interrupt for wakeup */
- PC->ISRC |= 0x3f;
- PC->IEN |= 0x3f | (0x3f << 16);
- PC->DBEN |= 0x3f; // Enable key debounce
- GPIO->DBNCECON = 0x16; // Debounce time is about 6ms
- NVIC_EnableIRQ(GPCDF_IRQn);
- }
- void GPCDF_IRQHandler(void)
- {
- PC->ISRC = 0x3f;
- //PB4 ^= 1;
- }
- unsigned int Check_Sum_read_flash(uint32_t u32StartAddr, uint32_t u32EndAddr)
- {
- uint32_t u32Addr;
- uint32_t u32data=0,temp;
-
- for (u32Addr = u32StartAddr; u32Addr < u32EndAddr; u32Addr += 4)
- {
- //temp=Read_Flash(u32Addr);
- temp=FMC_Read(u32Addr);
- u32data += (temp&0xff);
- u32data += (temp>>8)&0xff;
- u32data += (temp>>16)&0xff;
- u32data += (temp>>24)&0xff;
- }
- return u32data;
- }
- #define IAP_COMMAND_RAM (0x20004000-4)
- #define IAP_SIG 0X5AA55771
- volatile unsigned int CHECKSUM, AP_FLASH_CHECKSUM;
- typedef void (FUNC_PTR)(void);
-
-
- static int load_image_to_flash(uint32_t image_base, uint32_t image_limit)
- {
- uint32_t u32ImageSize;
- u32ImageSize = image_limit - image_base;
- if (u32ImageSize == 0) {
- //printf(" ERROR: Loader Image is 0 bytes!\n");
- return -1;
- }
- if (u32ImageSize > APROM_SIZE) {
- //printf(" ERROR: Loader Image is larger than %d KBytes!\n", APROM_SIZE/1024);
- return -1;
- }
- //printf("OK.\n");
- return 0;
- }
- extern uint32_t loaderImage1Base, loaderImage1Limit;
- uint32_t jump_flag;
- /*---------------------------------------------------------------------------------------------------------*/
- /* Main Function */
- /*---------------------------------------------------------------------------------------------------------*/
- int32_t main(void)
- {
- uint32_t *IAP_COMMAND;
- uint32_t i;
- FUNC_PTR *ResetFunc;
- IAP_COMMAND = (uint32_t *)IAP_COMMAND_RAM; //for ram command
-
- //for backrom file
- load_image_to_flash((uint32_t)&loaderImage1Base, (uint32_t)&loaderImage1Limit);
-
- /* Unlock protected registers */
- SYS_UnlockReg();
- SYS_Init();
- UART0_Init();
- GPIO_Init();
- /*enable FMC ISP function */
- //for flash operation
- FMC_Open();
- //FMC_SetVectorPageAddr(0x0);
- FMC_EnableAPUpdate();
- if(*IAP_COMMAND==IAP_SIG)
- goto JMP_IAP;
-
-
- //read flash backup checksum
- CHECKSUM=FMC_Read(CHECKSUM_ADDRESS);
-
- //CHECK SUM
- AP_FLASH_CHECKSUM=Check_Sum_read_flash(APROM_ADDRESS,APROM_ADDRESS_END);
- if(CHECKSUM == AP_FLASH_CHECKSUM){
- goto JMP_APROM;
- }
-
- //if checksum is ok, jump to IAP
- JMP_IAP:
- USBD_Open(&gsInfo, HID_ClassRequest, NULL); //OPEN USB FUNCTION.
- /* Endpoint configuration */
- HID_Init();
- USBD_Start();
- NVIC_EnableIRQ(USBD_IRQn);
- USBD_SET_PAYLOAD_LEN(EP4,64);
- USBD_SET_PAYLOAD_LEN(EP5,64);
- //PB4 = 0; // LED to show system is on line
-
- //DO IAP FLOW
- jump_flag=0;
- while(1)
- {
- if(jump_flag==1)
- {
- for(i=0;i<100;i++)
- CLK_SysTickDelay(5000);
- break;
- }
- //HID_UpdateMouseData();
- //HID_UpdateKbData();
- }
-
- JMP_APROM:
- //FMC_DisableAPUpdate();
- //FMC_Close();
- //BranchTo(APROM_ADDRESS);
- *IAP_COMMAND=0;
- /* Disable all interrupts before change VECMAP */
- NVIC->ICER[0] = 0xFFFFFFFF;
- /* Set vector table of startup AP address */
- FMC_SetVectorPageAddr(0x8000);
-
- /* Reset All IP before boot to new AP */
- SYS->IPRSTC2 = 0xFFFFFFFF;
- SYS->IPRSTC2 = 0;
-
- /* Obtain Reset Handler address of new boot. */
- ResetFunc = (FUNC_PTR *)M32(4);
- /* Set Main Stack Pointer register of new boot */
- __set_MSP(M32(0));
-
- /* Call reset handler of new boot */
- ResetFunc();
-
- while(1);
- }
- typedef __packed struct
- {
- uint32_t u8Cmd;
- uint32_t address;
- uint32_t data;
- uint32_t pid;
- } CMD_T;
- CMD_T rCmd, tCmd;
- void EP5_Handler(void) /* Interrupt out handler */
- {
- uint8_t *ptr4;
- uint8_t *ptr5;
- uint32_t erase_addrss;
- /* Interrupt In */
- ptr4 = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP4));
- /* Interrupt OUT */
- ptr5 = (uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP5));
- //USBD_MemCopy(&g_u8PageBuff[0], ptr5, EP5_MAX_PKT_SIZE);
-
- //do iap command in here
- /*
- for(t=0;t<64;t++)
- {
- printf("0x%x\n\r",g_u8PageBuff[t]);
- g_u8PageBuff[t]=g_u8PageBuff[t]+sss;
- }
- sss=sss+1;
- */
- USBD_MemCopy((uint8_t *)&rCmd, ptr5, 64);
- //check verison
- if(rCmd.u8Cmd==ISP_COMMAND_VERSION)
- {
- tCmd.u8Cmd=ISP_COMMAND_VERSION;
- tCmd.data=ISP_VERION;
-
- }
-
- //erase
- if(rCmd.u8Cmd==ISP_COMMAND_ERASE_APROM)
- {
- tCmd.u8Cmd=ISP_COMMAND_ERASE_APROM;
- for(erase_addrss=APROM_ADDRESS;erase_addrss<APROM_ADDRESS+APROM_SIZE;erase_addrss=erase_addrss+512)
- {
- if(FMC_Erase(erase_addrss)!=0)
- {
- tCmd.data=0;//false
- goto finish;
- }
- }
- tCmd.data=1;//true
- }
-
- //program
- if(rCmd.u8Cmd==ISP_COMMAND_PROGRAM_APROM)
- {
- tCmd.u8Cmd=ISP_COMMAND_PROGRAM_APROM;
- FMC_Write(rCmd.address,rCmd.data);
- if(FMC_Read(rCmd.address)!=rCmd.data)
- tCmd.data=0;//false
- else
- tCmd.data=1;//pass
- }
-
- if(rCmd.u8Cmd==ISP_COMMAND_JUMP_APROM)
- {
- tCmd.u8Cmd=ISP_COMMAND_JUMP_APROM;
- tCmd.data=1;
- jump_flag=1;
- }
-
- finish:
- tCmd.pid=rCmd.pid;
-
- //end iap
- USBD_MemCopy(ptr4, (uint8_t *)&tCmd, EP4_MAX_PKT_SIZE);
- USBD_SET_PAYLOAD_LEN(EP4, EP4_MAX_PKT_SIZE);
-
- USBD_SET_PAYLOAD_LEN(EP5, EP5_MAX_PKT_SIZE);
- // g_u8EP5Ready = 1;
- }
- /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/
|