main.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*!
  2. \file main.c
  3. \brief main flash pages write protection
  4. */
  5. /*
  6. Copyright (C) 2017 GigaDevice
  7. 2017-06-06, V1.0.0, firmware for GD32F3x0
  8. */
  9. #include "gd32f3x0.h"
  10. #include "gd32f3x0_eval.h"
  11. #include "main.h"
  12. /*!
  13. \brief enable some pages' write protection function by configuring option byte
  14. \param[in] wp_pages_bitmap: bitmap of pages which need to be enabled write protection function
  15. \param[out] none
  16. \retval none
  17. */
  18. void fmc_ob_write_protection_enable(uint16_t wp_pages_bitmap)
  19. {
  20. uint8_t ob_user;
  21. uint16_t ob_data;
  22. uint16_t old_wp, new_wp;
  23. /* unlock the main flash and option byte */
  24. fmc_unlock();
  25. ob_unlock();
  26. /* clear all pending flags */
  27. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  28. /* backup the old OB_USER, OB_DATA and OB_WP */
  29. ob_user = ob_user_get();
  30. ob_data = ob_data_get();
  31. old_wp = ob_write_protection_get();
  32. /* it's need to do operation just when the pages indicated by wp_pages_bitmap have not been enabled */
  33. if(0 != (old_wp & wp_pages_bitmap)){
  34. /* caculate the new write protectiom bitmap */
  35. new_wp = ((~old_wp) | wp_pages_bitmap);
  36. /* erase the option byte before modify the content */
  37. ob_erase();
  38. /* restore the OB_USER and OB_DATA */
  39. ob_user_write(ob_user);
  40. ob_data_program(OB_DATA_ADDR0, (uint8_t)ob_data);
  41. ob_data_program(OB_DATA_ADDR1, (uint8_t)(ob_data >> 8));
  42. /* enable the new write protection in option byte */
  43. ob_write_protection_enable(new_wp);
  44. /* lock the option byte firstly and then lock the main flash after operation */
  45. ob_lock();
  46. fmc_lock();
  47. /* reload the option byte and generate a system reset */
  48. ob_reset();
  49. }
  50. }
  51. /*!
  52. \brief disable some pages' write protection function by configuring option byte
  53. \param[in] wp_pages_bitmap: bitmap of pages which need to be disabled write protection function
  54. \param[out] none
  55. \retval none
  56. */
  57. void fmc_ob_write_protection_disable(uint16_t wp_pages_bitmap)
  58. {
  59. uint8_t ob_user;
  60. uint16_t ob_data;
  61. uint16_t old_wp, new_wp;
  62. /* unlock the main flash and option byte */
  63. fmc_unlock();
  64. ob_unlock();
  65. /* clear all pending flags */
  66. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  67. /* backup the old OB_USER, OB_DATA and OB_WP */
  68. ob_user = ob_user_get();
  69. ob_data = ob_data_get();
  70. old_wp = ob_write_protection_get();
  71. /* it's need to do operation just when the pages indicated by wp_pages_bitmap have been enabled */
  72. if((old_wp & wp_pages_bitmap) != wp_pages_bitmap){
  73. /* caculate the new write protectiom bitmap */
  74. new_wp = ~(old_wp | wp_pages_bitmap);
  75. /* erase the option byte before modify the content */
  76. ob_erase();
  77. /* restore the OB_USER and OB_DATA */
  78. ob_user_write(ob_user);
  79. ob_data_program(OB_DATA_ADDR0, (uint8_t)ob_data);
  80. ob_data_program(OB_DATA_ADDR1, (uint8_t)(ob_data >> 8));
  81. /* enable the new write protection in option byte */
  82. ob_write_protection_enable(new_wp);
  83. /* lock the option byte firstly and then lock the main flash after operation */
  84. ob_lock();
  85. fmc_lock();
  86. /* reload the option byte and generate a system reset */
  87. ob_reset();
  88. }
  89. }
  90. /*!
  91. \brief erase and program flash, meanwhile check the operation result
  92. \param[in] none
  93. \param[out] none
  94. \retval none
  95. */
  96. void fmc_erase_and_program(void)
  97. {
  98. uint32_t *ptr = (uint32_t *)ERASE_PAGE_START_ADDR;
  99. /* unlock the flash program/erase controller */
  100. fmc_unlock();
  101. /* clear all pending flags */
  102. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  103. /* erase target page */
  104. fmc_page_erase(ERASE_PAGE_START_ADDR);
  105. /* check the erase result, light the LED3 if the result is failed */
  106. if(0xFFFFFFFF != (*ptr)){
  107. gd_eval_led_on(LED3);
  108. return;
  109. }
  110. /* program target address */
  111. fmc_word_program(PROGRAM_ADDRESS, PROGRAM_DATA);
  112. /* check the program result, light the LED3 if the result is failed */
  113. if(PROGRAM_DATA != (*ptr)){
  114. gd_eval_led_on(LED3);
  115. return;
  116. }
  117. /* light the LED4 if the erase and program result are both successful */
  118. gd_eval_led_on(LED4);
  119. /* clear all pending flags */
  120. fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
  121. /* lock the main FMC after the operation */
  122. fmc_lock();
  123. }
  124. /*!
  125. \brief main function
  126. \param[in] none
  127. \param[out] none
  128. \retval none
  129. */
  130. int main(void)
  131. {
  132. /* initialize the LED1 and LED2 */
  133. gd_eval_led_init(LED1);
  134. gd_eval_led_init(LED2);
  135. gd_eval_led_init(LED3);
  136. gd_eval_led_init(LED4);
  137. /* configure the keys */
  138. gd_eval_key_init(KEY_WAKEUP, KEY_MODE_EXTI);
  139. gd_eval_key_init(KEY_TAMPER, KEY_MODE_EXTI);
  140. gd_eval_key_init(KEY_USER, KEY_MODE_EXTI);
  141. /* check the write protection result and light corresponding LEDs */
  142. if(WP_ALL_PAGES_BITMAP == ob_write_protection_get()){
  143. gd_eval_led_on(LED1);
  144. }else{
  145. gd_eval_led_on(LED2);
  146. }
  147. /* erase and program flash,
  148. failure (light LED3) indicates the page is in write protection,
  149. success (light LED4) indicates the page is not in write protection */
  150. fmc_erase_and_program();
  151. while(1);
  152. }