/*! \file main.c \brief main flash pages write protection */ /* Copyright (C) 2017 GigaDevice 2017-06-06, V1.0.0, firmware for GD32F3x0 */ #include "gd32f3x0.h" #include "gd32f3x0_eval.h" #include "main.h" /*! \brief enable some pages' write protection function by configuring option byte \param[in] wp_pages_bitmap: bitmap of pages which need to be enabled write protection function \param[out] none \retval none */ void fmc_ob_write_protection_enable(uint16_t wp_pages_bitmap) { uint8_t ob_user; uint16_t ob_data; uint16_t old_wp, new_wp; /* unlock the main flash and option byte */ fmc_unlock(); ob_unlock(); /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); /* backup the old OB_USER, OB_DATA and OB_WP */ ob_user = ob_user_get(); ob_data = ob_data_get(); old_wp = ob_write_protection_get(); /* it's need to do operation just when the pages indicated by wp_pages_bitmap have not been enabled */ if(0 != (old_wp & wp_pages_bitmap)){ /* caculate the new write protectiom bitmap */ new_wp = ((~old_wp) | wp_pages_bitmap); /* erase the option byte before modify the content */ ob_erase(); /* restore the OB_USER and OB_DATA */ ob_user_write(ob_user); ob_data_program(OB_DATA_ADDR0, (uint8_t)ob_data); ob_data_program(OB_DATA_ADDR1, (uint8_t)(ob_data >> 8)); /* enable the new write protection in option byte */ ob_write_protection_enable(new_wp); /* lock the option byte firstly and then lock the main flash after operation */ ob_lock(); fmc_lock(); /* reload the option byte and generate a system reset */ ob_reset(); } } /*! \brief disable some pages' write protection function by configuring option byte \param[in] wp_pages_bitmap: bitmap of pages which need to be disabled write protection function \param[out] none \retval none */ void fmc_ob_write_protection_disable(uint16_t wp_pages_bitmap) { uint8_t ob_user; uint16_t ob_data; uint16_t old_wp, new_wp; /* unlock the main flash and option byte */ fmc_unlock(); ob_unlock(); /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); /* backup the old OB_USER, OB_DATA and OB_WP */ ob_user = ob_user_get(); ob_data = ob_data_get(); old_wp = ob_write_protection_get(); /* it's need to do operation just when the pages indicated by wp_pages_bitmap have been enabled */ if((old_wp & wp_pages_bitmap) != wp_pages_bitmap){ /* caculate the new write protectiom bitmap */ new_wp = ~(old_wp | wp_pages_bitmap); /* erase the option byte before modify the content */ ob_erase(); /* restore the OB_USER and OB_DATA */ ob_user_write(ob_user); ob_data_program(OB_DATA_ADDR0, (uint8_t)ob_data); ob_data_program(OB_DATA_ADDR1, (uint8_t)(ob_data >> 8)); /* enable the new write protection in option byte */ ob_write_protection_enable(new_wp); /* lock the option byte firstly and then lock the main flash after operation */ ob_lock(); fmc_lock(); /* reload the option byte and generate a system reset */ ob_reset(); } } /*! \brief erase and program flash, meanwhile check the operation result \param[in] none \param[out] none \retval none */ void fmc_erase_and_program(void) { uint32_t *ptr = (uint32_t *)ERASE_PAGE_START_ADDR; /* unlock the flash program/erase controller */ fmc_unlock(); /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); /* erase target page */ fmc_page_erase(ERASE_PAGE_START_ADDR); /* check the erase result, light the LED3 if the result is failed */ if(0xFFFFFFFF != (*ptr)){ gd_eval_led_on(LED3); return; } /* program target address */ fmc_word_program(PROGRAM_ADDRESS, PROGRAM_DATA); /* check the program result, light the LED3 if the result is failed */ if(PROGRAM_DATA != (*ptr)){ gd_eval_led_on(LED3); return; } /* light the LED4 if the erase and program result are both successful */ gd_eval_led_on(LED4); /* clear all pending flags */ fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR); /* lock the main FMC after the operation */ fmc_lock(); } /*! \brief main function \param[in] none \param[out] none \retval none */ int main(void) { /* initialize the LED1 and LED2 */ gd_eval_led_init(LED1); gd_eval_led_init(LED2); gd_eval_led_init(LED3); gd_eval_led_init(LED4); /* configure the keys */ gd_eval_key_init(KEY_WAKEUP, KEY_MODE_EXTI); gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI); gd_eval_key_init(KEY_USER, KEY_MODE_EXTI); /* check the write protection result and light corresponding LEDs */ if(WP_ALL_PAGES_BITMAP == ob_write_protection_get()){ gd_eval_led_on(LED1); }else{ gd_eval_led_on(LED2); } /* erase and program flash, failure (light LED3) indicates the page is in write protection, success (light LED4) indicates the page is not in write protection */ fmc_erase_and_program(); while(1); }