[DemoCode下载] M051的FMC操作演示

[复制链接]
963|6
 楼主| zhuomuniao110 发表于 2019-9-30 00:21 | 显示全部楼层 |阅读模式
fm, se, ck, PLL
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /*                                                                                                         */
  3. /* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved.                                         */
  4. /*                                                                                                         */
  5. /*---------------------------------------------------------------------------------------------------------*/
  6. #include <stdio.h>
  7. #include "M051Series.h"
  8. #include "LCD_Driver.h"

  9. #define PLLCON_SETTING      CLK_PLLCON_50MHz_HXT
  10. #define PLL_CLOCK           50000000



  11. #define LDROM_BASE      FMC_LDROM_BASE
  12. #define PAGE_SIZE       FMC_FLASH_PAGE_SIZE

  13. volatile uint8_t g_u8IsPress = FALSE;

  14. #ifndef LDROM
  15. extern uint32_t g_u32LoaderImageBase;
  16. extern uint32_t g_u32LoaderImageLimit;
  17. #endif

  18. void EINT0_IRQHandler(void)
  19. {
  20.     /* Clear P3.2 interrupt flag */
  21.     P3->ISRC = 1 << 2;

  22.     g_u8IsPress = TRUE;
  23. }

  24. void SYS_Init(void)
  25. {

  26.     /*---------------------------------------------------------------------------------------------------------*/
  27.     /* Init System Clock                                                                                       */
  28.     /*---------------------------------------------------------------------------------------------------------*/

  29.     /* Unlock protected registers */
  30.     SYS_UnlockReg();

  31.     /* Enable Internal RC clock */
  32.     CLK->PWRCON |= CLK_PWRCON_IRC22M_EN_Msk;

  33.     /* Waiting for IRC22M clock ready */
  34.     CLK_WaitClockReady(CLK_CLKSTATUS_IRC22M_STB_Msk);

  35.     /* Switch HCLK clock source to internal RC */
  36.     CLK->CLKSEL0 = CLK_CLKSEL0_HCLK_S_HIRC;

  37.     /* Set PLL to power down mode and PLL_STB bit in CLKSTATUS register will be cleared by hardware.*/
  38.     CLK->PLLCON |= CLK_PLLCON_PD_Msk;

  39.     /* Enable external 12MHz XTAL, 10kHz */
  40.     CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk | CLK_PWRCON_IRC10K_EN_Msk;

  41.     /* Enable PLL and Set PLL frequency */
  42.     CLK->PLLCON = PLLCON_SETTING;

  43.     /* Waiting for clock ready */
  44.     CLK_WaitClockReady(CLK_CLKSTATUS_PLL_STB_Msk | CLK_CLKSTATUS_XTL12M_STB_Msk  | CLK_CLKSTATUS_IRC10K_STB_Msk);

  45.     /* Switch HCLK clock source to PLL, STCLK to HCLK/2 */
  46.     CLK->CLKSEL0 = CLK_CLKSEL0_STCLK_S_HCLK_DIV2 | CLK_CLKSEL0_HCLK_S_PLL;

  47.     /* Enable IP clock */
  48.     CLK->AHBCLK = CLK_AHBCLK_ISP_EN_Msk;
  49.     CLK->APBCLK = CLK_APBCLK_UART0_EN_Msk | CLK_APBCLK_SPI0_EN_Msk;

  50.     /* IP clock source */
  51.     CLK->CLKSEL1 = CLK_CLKSEL1_UART_S_PLL;

  52.     /* Update System Core Clock */
  53.     /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  54.     //SystemCoreClockUpdate();
  55.     PllClock        = PLL_CLOCK;            // PLL
  56.     SystemCoreClock = PLL_CLOCK / 1;        // HCLK
  57.     CyclesPerUs     = PLL_CLOCK / 1000000;  // For SYS_SysTickDelay()


  58.     /*---------------------------------------------------------------------------------------------------------*/
  59.     /* Init I/O Multi-function                                                                                 */
  60.     /*---------------------------------------------------------------------------------------------------------*/
  61.     /* Set P3 multi-function pins for UART0 RXD and TXD  */
  62.     SYS->P3_MFP = SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0;
  63.     /* Set P1.4, P1.5, P1.6, P1.7 for SPI0 */
  64.     SYS->P1_MFP = SYS_MFP_P14_SPISS0 | SYS_MFP_P15_MOSI_0 | SYS_MFP_P16_MISO_0 | SYS_MFP_P17_SPICLK0;

  65.     /* Lock protected registers */
  66.     SYS_LockReg();
  67. }


  68. void UART0_Init(void)
  69. {
  70.     /*---------------------------------------------------------------------------------------------------------*/
  71.     /* Init UART                                                                                               */
  72.     /*---------------------------------------------------------------------------------------------------------*/
  73.     UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(PLL_CLOCK, 115200);
  74.     UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;

  75. }


  76. void GPIO_Init(void)
  77. {
  78.     /*set P2.0 as output*/
  79.     GPIO_SetMode(P2, (1 << 0), GPIO_PMD_OUTPUT);

  80.     /* Enable debunce function of P3.2 (EINT0) */
  81.     GPIO_ENABLE_DEBOUNCE(P3, (1 << 2));

  82.     /* Set debounce time. it is about 6.4 ms */
  83.     GPIO_SET_DEBOUNCE_TIME(GPIO_DBCLKSRC_LIRC, GPIO_DBCLKSEL_64);

  84.     /*Initialize external interrupt*/
  85.     GPIO_EnableInt(P3, 2, GPIO_INT_FALLING);
  86.     NVIC_EnableIRQ(EINT0_IRQn);
  87. }

  88. #ifndef LDROM

  89. /*---------------------------------------------------------------------------------------------------------*/
  90. /*  Main Function                                                                                          */
  91. /*---------------------------------------------------------------------------------------------------------*/
  92. int32_t main(void)
  93. {
  94.     int32_t  i32Err = 0;
  95.     uint32_t u32Data, u32ImageSize, i, j, *pu32Loader;

  96.     /* Init system, IP clock and multi-function I/O */
  97.     SYS_Init();

  98.     /* Init UART0 for printf */
  99.     UART0_Init();

  100.     /* Init GPIO P2.0 (output) and P3.2 (EINT0) */
  101.     GPIO_Init();

  102.     /* Init SPI0 and LCD */
  103.     LCD_Init();
  104.     LCD_EnableBackLight();
  105.     LCD_ClearScreen();


  106.     /*
  107.         This sample shows how to switch between APROM and LDROM.
  108.         Target:
  109.             Smpl_FMC
  110.                 Smpl_FMC is the code for APROM. It will program the firmware to LDROM and
  111.                 user can press SW_INT to change to boot from LDROM.
  112.                 In APROM, the LED blanking interval is 200ms.
  113.             Smpl_LDROM
  114.                 Smpl_LDROM is the code for LDROM. User can press SW_INT to change to boot from APROM.
  115.                 In LDROM, the LED blanking interval is 1000ms.
  116.     */
  117.     LCD_Print(0, "Boot from APROM");
  118.     LCD_Print(1, "Press SW_INT   ");
  119.     while(1)
  120.     {
  121.         if(g_u8IsPress)
  122.         {
  123.             g_u8IsPress = FALSE;

  124.             /* Unlock protected registers to write ISP Control Register (ISPCON) */
  125.             SYS_UnlockReg();

  126.             /* Program sample LD code to LDROM */

  127.             /* Enable ISP LDROM update function */
  128.             FMC->ISPCON = FMC_ISPCON_LDUEN_Msk | FMC_ISPCON_ISPEN_Msk;

  129.             /* Page Erase LDROM */
  130.             for(i = 0; i < 4096; i += PAGE_SIZE)
  131.                 FMC_Erase(LDROM_BASE + i);


  132.             /* Erase Verify */
  133.             i32Err = 0;
  134.             for(i = LDROM_BASE; i < (LDROM_BASE + 4096); i += 4)
  135.             {
  136.                 u32Data = FMC_Read(i);

  137.                 if(u32Data != 0xFFFFFFFF)
  138.                 {
  139.                     i32Err = 1;
  140.                 }
  141.             }


  142.             u32ImageSize = (uint32_t)&g_u32LoaderImageLimit - (uint32_t)&g_u32LoaderImageBase;

  143.             pu32Loader = (uint32_t *)&g_u32LoaderImageBase;
  144.             for(i = 0; i < u32ImageSize; i += PAGE_SIZE)
  145.             {
  146.                 FMC_Erase(LDROM_BASE + i);
  147.                 for(j = 0; j < PAGE_SIZE; j += 4)
  148.                 {
  149.                     FMC_Write(LDROM_BASE + i + j, pu32Loader[(i + j) / 4]);
  150.                 }
  151.             }

  152.             /* Verify loader */
  153.             i32Err = 0;
  154.             for(i = 0; i < u32ImageSize; i += PAGE_SIZE)
  155.             {
  156.                 for(j = 0; j < PAGE_SIZE; j += 4)
  157.                 {
  158.                     u32Data = FMC_Read(LDROM_BASE + i + j);
  159.                     if(u32Data != pu32Loader[(i + j) / 4])
  160.                         i32Err = 1;

  161.                     if(i + j >= u32ImageSize)
  162.                         break;
  163.                 }


  164.             }

  165.             if(i32Err)
  166.             {
  167.                 LCD_ClearScreen();
  168.                 LCD_Print(0, "LDROM write fail");
  169.             }
  170.             else
  171.             {
  172.                 /* Switch to boot from LDROM */
  173.                 FMC->ISPCON = FMC_ISPCON_BS_LDROM;
  174.                 SYS_ResetCPU();
  175.             }

  176.             while(1);
  177.         }
  178.         else
  179.         {
  180.             /* LED blanking for 200ms */
  181.             P2->DOUT ^= 1;
  182.             CLK_SysTickDelay(100000);
  183.         }



  184.     }
  185. }

  186. #else
  187. /*---------------------------------------------------------------------------------------------------------*/
  188. /*  Main Function for LDROM                                                                                */
  189. /*---------------------------------------------------------------------------------------------------------*/
  190. int32_t main(void)
  191. {

  192.     /* Init system, IP clock and multi-function I/O */
  193.     SYS_Init();

  194.     /* Init UART0 for printf */
  195.     UART0_Init();

  196.     /* Init GPIO P2.0 (output) and P3.2 (EINT0) */
  197.     GPIO_Init();

  198.     /* Init SPI0 and LCD */
  199.     LCD_Init();
  200.     LCD_EnableBackLight();
  201.     LCD_ClearScreen();

  202.     LCD_Print(0, "Boot from LDROM");
  203.     LCD_Print(1, "Press SW_INT   ");

  204.     while(1)
  205.     {
  206.         if(g_u8IsPress)
  207.         {
  208.             g_u8IsPress = FALSE;

  209.             /* Switch to boot from APROM */
  210.             SYS_UnlockReg();
  211.             FMC->ISPCON = FMC_ISPCON_BS_APROM;
  212.             SYS_ResetCPU();
  213.             while(1);
  214.         }
  215.         else
  216.         {
  217.             /* LED blanking for 1000ms */
  218.             P2->DOUT ^= 1;
  219.             CLK_SysTickDelay(300000);
  220.             CLK_SysTickDelay(200000);
  221.         }
  222.     }
  223. }

  224. #endif




 楼主| zhuomuniao110 发表于 2019-9-30 00:22 | 显示全部楼层
现在好多单片机都提供这个接口了,那么怎么用呢,这个例子给你演示。
yiy 发表于 2019-9-30 16:10 来自手机 | 显示全部楼层
这些时钟配置可以用那个时钟配置工具配吗?
heisexingqisi 发表于 2019-9-30 20:21 | 显示全部楼层
看起来很不错,这个功能很强吧
wanduzi 发表于 2019-10-9 21:19 | 显示全部楼层
新唐大部分都具备FMC功能,可以用多余的空间存储数据
wanduzi 发表于 2019-10-9 21:59 | 显示全部楼层
一系列的时钟配置如果可以图形化做就好了。
21mengnan 发表于 2019-10-9 21:59 | 显示全部楼层
BL也要用到这个功能吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

233

主题

3529

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部