Go to the documentation of this file.00001
00042 #include <sys/atom.h>
00043 #include <dev/nvmem.h>
00044
00045 #include <stdint.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048
00049 #include <arch/avr32.h>
00050 #include <arch/avr32/flashc.h>
00051
00052 #include <avr32/io.h>
00053
00054
00059
00062 #ifndef FLASH_CONF_SECTOR
00063 #define FLASH_CONF_SECTOR 0x0003FF00
00064 #endif
00065
00066
00076 #ifndef FLASH_CONF_SIZE
00077 #define FLASH_CONF_SIZE AVR32_FLASHC_PAGE_SIZE
00078 #endif
00079
00080 #ifndef FLASH_WRITE_WAIT
00081 #define FLASH_WRITE_WAIT 60000
00082 #endif
00083
00084 #ifndef FLASH_ERASE_WAIT
00085 #define FLASH_ERASE_WAIT 60000
00086 #endif
00087
00088 #ifndef FLASH_CHIP_ERASE_WAIT
00089 #define FLASH_CHIP_ERASE_WAIT 600000
00090 #endif
00091
00092
00093 typedef uint32_t flashdat_t;
00094 typedef unsigned long flashadr_t;
00095 typedef volatile flashdat_t *flashptr_t;
00096
00097 static int flashc_is_ready(void)
00098 {
00099 return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK) != 0);
00100 }
00101
00106 int Avr32FlashcCmd(unsigned int cmd, uint32_t tmo)
00107 {
00108 int rc = 0;
00109
00110
00111 while (!flashc_is_ready()) {
00112 if (tmo && --tmo < 1) {
00113 return -1;
00114 }
00115 }
00116
00117
00118 NutEnterCritical();
00119
00120
00121 outr(AVR32_FLASHC.fcmd, AVR32_FLASHC_FCMD_KEY_KEY | cmd);
00122
00123
00124 while (!flashc_is_ready()) {
00125 if (tmo && --tmo < 1) {
00126 rc = -1;
00127 break;
00128 }
00129 }
00130
00131
00132 NutExitCritical();
00133
00134
00135 if (AVR32_FLASHC.fsr & (AVR32_FLASHC_FSR_LOCKE_MASK | AVR32_FLASHC_FSR_PROGE_MASK)) {
00136 rc = -1;
00137 }
00138 return rc;
00139 }
00140
00150 int Avr32FlashcSectorRead(unsigned int off, void *data, unsigned int len)
00151 {
00152 memcpy(data, (void *) (uptr_t) (AVR32_FLASH_ADDRESS + off), len);
00153
00154 return 0;
00155 }
00156
00169 int Avr32FlashcSectorWrite(unsigned int off, CONST void *data, unsigned int len)
00170 {
00171 flashptr_t dp = (flashptr_t) (uptr_t) (AVR32_FLASH_ADDRESS + off);
00172 int rc;
00173 unsigned int i;
00174
00175 if (data) {
00176 flashptr_t sp = (flashptr_t) data;
00177
00178
00179 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00180 *dp++ = *sp++;
00181 }
00182 } else {
00183
00184 for (i = 0; i < len; i += sizeof(flashdat_t)) {
00185 *dp++ = (flashdat_t) (-1);
00186 }
00187 }
00188
00189
00190 Avr32FlashcSectorErase(off);
00191
00192 rc = Avr32FlashcCmd((off & AVR32_FLASHC_FCMD_PAGEN_MASK) | AVR32_FLASHC_FCMD_CMD_WP, FLASH_WRITE_WAIT);
00193
00194 return rc;
00195 }
00196
00200 int Avr32FlashcSectorErase(unsigned int off)
00201 {
00202 return Avr32FlashcCmd((off & AVR32_FLASHC_FCMD_PAGEN_MASK) | AVR32_FLASHC_FCMD_CMD_EP, FLASH_ERASE_WAIT);
00203 }
00204
00212 int Avr32FlashcRegionLock(unsigned int off)
00213 {
00214 return Avr32FlashcCmd((off & AVR32_FLASHC_FCMD_PAGEN_MASK) | AVR32_FLASHC_FCMD_CMD_LP, FLASH_WRITE_WAIT);
00215 }
00216
00224 int Avr32FlashcRegionUnlock(unsigned int off)
00225 {
00226 return Avr32FlashcCmd((off & AVR32_FLASHC_FCMD_PAGEN_MASK) | AVR32_FLASHC_FCMD_CMD_UP, FLASH_WRITE_WAIT);
00227 }
00228
00240 int Avr32FlashcParamRead(unsigned int pos, void *data, unsigned int len)
00241 {
00242 return Avr32FlashcSectorRead(FLASH_CONF_SECTOR + pos, data, len);
00243 }
00244
00259 int Avr32FlashcParamWrite(unsigned int pos, CONST void *data, unsigned int len)
00260 {
00261 int rc = -1;
00262 uint8_t *buff;
00263
00264
00265 if ((buff = malloc(FLASH_CONF_SIZE)) != NULL) {
00266
00267 rc = Avr32FlashcSectorRead(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00268
00269 if (memcmp(buff + pos, data, len)) {
00270
00271 memcpy(buff + pos, data, len);
00272
00273 if (Avr32FlashcRegionUnlock(FLASH_CONF_SECTOR) == 0) {
00274 rc = Avr32FlashcSectorWrite(FLASH_CONF_SECTOR, buff, FLASH_CONF_SIZE);
00275 Avr32FlashcRegionLock(FLASH_CONF_SECTOR);
00276 }
00277 }
00278 free(buff);
00279 }
00280 return rc;
00281 }
00282