/*! \file main.c \brief transfer data from FLASH to RAM */ /* Copyright (C) 2017 GigaDevice 2017-06-06, V1.0.0, firmware for GD32F3x0 */ #include "gd32f3x0.h" #include #include "gd32f3x0_eval.h" #define TRANSFER_NUM 0x400 /* Configuration value in bytes */ #define FMC_PAGE_SIZE ((uint16_t)0x800) #define BANK0_WRITE_START_ADDR ((uint32_t)0x08004000) void rcu_config(void); void nvic_config(void); void led_config(void); __IO uint32_t g_dmacomplete_flag = 0; uint8_t g_destbuf[TRANSFER_NUM]; const uint32_t transdata = 0x3210ABCD; fmc_state_enum fmcstatus = FMC_READY; /*! \brief main function \param[in] none \param[out] none \retval none */ int main(void) { uint32_t i, count; uint32_t *ptrd; uint32_t address = 0x00; ErrStatus access_flag = SUCCESS; dma_parameter_struct dma_init_struct; uint32_t wperror = 0; /* system clocks configuration */ rcu_config(); /* NVIC configuration */ nvic_config(); /* LED configuration */ led_config() ; /* unlock the flash bank1 program erase controller */ fmc_unlock(); /* define the number of page to be erased */ count = TRANSFER_NUM / FMC_PAGE_SIZE; /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); /* erase the flash pages */ for(i = 0; i <= count; i++){ fmcstatus = fmc_page_erase(BANK0_WRITE_START_ADDR + (FMC_PAGE_SIZE * i)); wperror += (fmcstatus == FMC_WPERR); fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); } if(wperror != 0){ while(1); } /* unlock the flash bank1 program erase controller */ fmc_lock(); ptrd = (uint32_t*)BANK0_WRITE_START_ADDR; count = TRANSFER_NUM / sizeof(*ptrd); for(i = 0; i < count; i++){ if(0xFFFFFFFF != *ptrd){ access_flag = ERROR; break; } ptrd++; } if(ERROR == access_flag){ while(1); } /* unlock the flash bank1 program erase controller */ fmc_unlock(); /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); /* program flash bank1 */ address = BANK0_WRITE_START_ADDR; wperror = 0; count = BANK0_WRITE_START_ADDR + TRANSFER_NUM; while(address < count){ fmcstatus = fmc_word_program(address, transdata); address = address + 4; wperror += (FMC_WPERR == fmcstatus); fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_WPERR | FMC_FLAG_END); } if(wperror != 0){ while(1); } fmc_lock(); memset(g_destbuf ,0 ,TRANSFER_NUM); /* DMA channel0 initialize */ dma_deinit(DMA_CH0); dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_addr = (uint32_t)g_destbuf; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = TRANSFER_NUM; dma_init_struct.periph_addr = (uint32_t)BANK0_WRITE_START_ADDR; dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_ENABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_init(DMA_CH0, dma_init_struct); /* DMA channel0 mode configuration */ dma_circulation_disable(DMA_CH0); dma_memory_to_memory_enable(DMA_CH0); /* DMA channel0 interrupt configuration */ dma_interrupt_enable(DMA_CH0, DMA_INT_FTF); /* enable DMA transfer */ dma_channel_enable(DMA_CH0); /* wait DMA interrupt */ while(0 == g_dmacomplete_flag); /* compare destdata with transdata */ ptrd = (uint32_t *)g_destbuf; count = TRANSFER_NUM / sizeof(*ptrd); for(i = 0; i < count; i++){ if(transdata != *ptrd){ access_flag = ERROR; break; } ptrd++; } /* transfer sucess */ if(access_flag != ERROR){ gd_eval_led_on(LED1); gd_eval_led_on(LED2); gd_eval_led_on(LED3); gd_eval_led_on(LED4); }else{ gd_eval_led_on(LED1); gd_eval_led_on(LED3); } while(1); } /*! \brief configure LED \param[in] none \param[out] none \retval none */ void led_config(void) { gd_eval_led_init(LED1); gd_eval_led_init(LED2); gd_eval_led_init(LED3); gd_eval_led_init(LED4); /* LED off */ gd_eval_led_off(LED1); gd_eval_led_off(LED3); gd_eval_led_off(LED2); gd_eval_led_off(LED4); } /*! \brief configure the different system clocks \param[in] none \param[out] none \retval none */ void rcu_config(void) { /* enable DMA clock */ rcu_periph_clock_enable(RCU_DMA); } /*! \brief configure the nested vectored interrupt controller \param[in] none \param[out] none \retval none */ void nvic_config(void) { nvic_irq_enable(DMA_Channel0_IRQn, 0, 0); }