{"id":606,"date":"2013-04-20T00:02:42","date_gmt":"2013-04-20T07:02:42","guid":{"rendered":"http:\/\/micromouseusa.com\/?p=606"},"modified":"2013-06-25T17:17:11","modified_gmt":"2013-06-26T00:17:11","slug":"how-to-use-flash-in-stm32-to-save-explored-maze-instead-of-using-eeprom","status":"publish","type":"post","link":"http:\/\/micromouseusa.com\/?p=606","title":{"rendered":"How to use FLASH in STM32 to save explored maze instead of using EEPROM"},"content":{"rendered":"<p>As we all know, STM32 doesn&#8217;t build in EEPROM in the package. When I was designing my current mouse, I added a external I2C interface EEPROM to save explored maze to prevent crash. Unfortunately, the EEPROM library from ST is too complected for me to use, so I have to give up on using external EEPROM that my mouse had.<\/p>\n<p>Instead, I heard from the other contestants at APEC 2013 that we can use internal flash to emulate EEPROM to store explored maze to prevent crash. I looked over several tutorial online, and the documentary from ST as well, about how the emulated EEPROM in STM32 works. Turned out that I realized the whole process is not efficient at all. Because the library ST provided wasn&#8217;t like write every thing straightly in sequence, instead, they use several pages in FLASH and use them alternatively. Though the emulating process is simpler than the I2C eeprom library that ST provided, but I want it be even simpler.<\/p>\n<p>Since the data I would like to store to flash in just a 16 by 16 two-dimension-array, and the overall size is smaller than a single page that the flash has in STM32, I decided to directly manipulate FLASH instead emulate EEPROM by using flash.<\/p>\n<p>There is something we must know for the Flash on STM32. The flash starts from address 0x8040000, and separated to several pages. The size for each page depends on the density. The low and medium density version is1KB per page, and the high density is 2KB per page. every time the you write data to FLSAH, you need to erase everything on the page that you are going to use, even if you only use just one byte on it. But for reading, it acts just as normal as other process in your program.<\/p>\n<p>you can only write as 16 bit data type otherwise it will cause error.<\/p>\n<p>At the end everything is quite easy for me, and most importantly, the code is very compact.<\/p>\n<p>\/\/note that the starting address for flash is 0x8000000 for F103 and F4<\/p>\n<p>\/\/you need to include flash.h in ST library<\/p>\n<p>\/\/what I did here is write a 16 by 16 2D array to FLASH starting at address 0x8040000(256KB, in the middle of FLASH since my STM32 has 512K FLASH) and then read it back to memory afterwards.<\/p>\n<p>\/\/notice you will lose the data in flash if you erase all flash when you download new code from computer<\/p>\n<p><span style=\"color: #ff6600;\">uint32_t startAddress = 0x8040000;\/\/starting from 256KB<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/0x8020000 starting 128KB<\/span><br \/>\n<span style=\"color: #ff6600;\">void writeFlash(void)<\/span><br \/>\n<span style=\"color: #ff6600;\">{<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0u32 i, j;<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0FLASH_Unlock();\/\/unlock flash writing<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0FLASH_ErasePage(startAddress);\/\/erase the entire page before you can write as I \/\/mentioned<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0for(i=0; i&lt;mSize; i++)<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0for(j=0; j&lt;mSize; j++)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0FLASH_ProgramHalfWord((startAddress + (i*mSize+j)*2),mazeWalls[i][j]);<\/span><\/p>\n<p><span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0FLASH_Lock();\/\/lock the flash for writing<br \/>\n<\/span><\/p>\n<p><span style=\"color: #ff6600;\">}<\/span><\/p>\n<p><span style=\"color: #ff6600;\">void readFlash(void)<\/span><br \/>\n<span style=\"color: #ff6600;\">{<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0u32 i, j;\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0for(i=0; i&lt;mSize; i++)<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0for(j=0; j&lt;mSize; j++)\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0<\/span><br \/>\n<span style=\"color: #ff6600;\">\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0mazeWalls[i][j] = *(uint16_t *)(startAddress + (i*mSize+j)*2);<\/span><br \/>\n<span style=\"color: #ff6600;\">}<\/span><\/p>\n<p>I tested the time consumption for each precess for my code. The writing process took little bit long, at about 15ms by writing 16&#215;16 elements with 16 bit unsigned integer(512Bytes). The reading was significantly faster since we just simply access the data in flash like other programs do, and the whole process for reading is just 59us by read and copy all 256 elements of 16 bit unsigned integer.<\/p>\n<p>Since we usually do data store and recover when mouse is stopped, 15ms wasn&#8217;t even a noticeable time for us. Besides, 15ms is faster than the time spent of emulating EEPROM. I didn&#8217;t have chance to test the time for emulating EEPROM, but as what I&#8217;ve heard from students at Lunghwa University of Science and Technology, the emulating process takes about 200ms to finish. I wasn&#8217;t sure how much data that he wrote but still, theoretically, acess FLASH directly should be faster than emulating EEPROM in this case.<\/p>\n<p>here is the official document about how emulating the EEPROM on STM32 works<\/p>\n<p><a href=\"http:\/\/micromouseusa.com\/wp-content\/uploads\/2013\/04\/STM32-EEPROM.pdf\">STM32 EEPROM<\/a><\/p>\n<p>I plan to post several articles about calibrating strategies for the next couple of weeks since all regional competitions are approaching.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As we all know, STM32 doesn&#8217;t build in EEPROM in the package. When I was designing my current mouse, I added a external I2C interface EEPROM to save explored maze to prevent crash. Unfortunately, the EEPROM library from ST is &hellip; <a href=\"http:\/\/micromouseusa.com\/?p=606\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[7],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/606"}],"collection":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=606"}],"version-history":[{"count":12,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/606\/revisions"}],"predecessor-version":[{"id":896,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=\/wp\/v2\/posts\/606\/revisions\/896"}],"wp:attachment":[{"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=606"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=606"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/micromouseusa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=606"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}