d_flash.c
Go to the documentation of this file.
1 /*
2 MIT LICENSE
3 
4 Copyright 2014-2019 Inertial Sense, Inc. - http://inertialsense.com
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
7 
8 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9 
10 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT, IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11 */
12 
13 #include <asf.h>
14 #include <stdlib.h>
15 #include "globals.h"
16 #include "../misc/bootloaderShared.h"
17 #include "../misc/rtos.h"
18 #include "d_flash.h"
19 #include "user_board.h"
20 
22 
23 uint32_t flash_update_block(uint32_t address, const void* newData, int dataSize, int noPageErase)
24 {
25 
26 #if 0
27  // Debug: If flash write has already failed, do not try to write again, we want to
28  // dump the flash memory to see what it looks like
29  if ((g_sysParams.genFaultCode & GFC_FLASH_WRITE_FAILURE))
30  {
31  return FLASH_RC_OK;
32  }
33 #endif
34 
35  uint32_t result;
36 
39  (noPageErase==0 && address % BOOTLOADER_FLASH_BLOCK_SIZE != 0) ||
40  dataSize > (int)BOOTLOADER_FLASH_BLOCK_SIZE )
41  {
42  result = FLASH_RC_INVALID;
43  }
44  else if (memcmp((const void*)address, newData, dataSize) == 0)
45  {
46  // memory is identical, do not write
47  result = FLASH_RC_OK;
48  }
49  else // if contents are different, perform the flash write
50  {
51  // indicate attempted flash write
53 
54  // assume failure unless we succeed
55  result = FLASH_RC_ERROR;
56 
57  // http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf
58  // page 45
59 
60  // unlock the block
62  flash_unlock(address, address + dataSize - 1, 0, 0);
63 
64  // try up to 10 times to write flash, recommended by Atmel
65  for (int i = 0; i < 10; i++)
66  {
67  if(!noPageErase)
68  { // erase flash - Only works for 16 pages (8192 bytes) and NOT less.
69  result = flash_erase_page(address, IFLASH_ERASE_PAGES_16);
70  }
71  else
72  { // skip flash erase
73  result = FLASH_RC_OK;
74  }
75 
76  // erase flash - Only works for 16 pages (8192 bytes) and NOT less.
77  if (result == FLASH_RC_OK)
78  {
79  // write new flash
80  flash_write(address, newData, dataSize, 0);
81 
82  if (memcmp((const void*)address, newData, dataSize) == 0)
83  {
84  // lock the block
85  flash_lock(address, address + dataSize - 1, 0, 0);
86  result = FLASH_RC_OK;
87  break;
88  }
89  }
90  time_delay(2);
91  }
92 
94  }
95 
96  if (result != FLASH_RC_OK)
97  {
98 #if !defined(PLATFORM_IS_EVB_2)
99  g_sysParams.genFaultCode |= GFC_FLASH_WRITE_FAILURE;
100 #endif
101  }
102 
103  return result;
104 }
105 
106 uint32_t flash_erase_block(uint32_t address)
107 {
108  if (address < BOOTLOADER_FLASH_USER_DATA_START_ADDRESS || address >= BOOTLOADER_FLASH_USER_DATA_END_ADDRESS || address % BOOTLOADER_FLASH_BLOCK_SIZE != 0)
109  {
110  return FLASH_RC_INVALID;
111  }
112 
113  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT; // restart watchdog
114 
115  flash_unlock(address, address + BOOTLOADER_FLASH_BLOCK_SIZE - 1, 0, 0);
116  return flash_erase_page(address, IFLASH_ERASE_PAGES_16);
117 }
118 
119 extern uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr);
120 __no_inline RAMFUNC void flash_erase_chip(void)
121 {
122  LED_COLOR_RED();
123 
124  cpu_irq_disable();
125  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT; // restart watchdog
126 
127  // Make sure all blocks are unlocked
129 
130  // Issue erase - After this we cannot access any functions in flash as it will be gone.
132  while ((EFC->EEFC_FSR & EEFC_FSR_FRDY) != EEFC_FSR_FRDY)
133  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT;
134 
135  //Clear GPNVM Bits
136  EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(0) | EEFC_FCR_FCMD(EFC_FCMD_CGPB); //Protect bit
137  while ((EFC->EEFC_FSR & EEFC_FSR_FRDY) != EEFC_FSR_FRDY)
138  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT;
139 
140  EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(1) | EEFC_FCR_FCMD(EFC_FCMD_CGPB); //Enter SAM-BA
141  while ((EFC->EEFC_FSR & EEFC_FSR_FRDY) != EEFC_FSR_FRDY)
142  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT;
143 
144  EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(7) | EEFC_FCR_FCMD(EFC_FCMD_CGPB); //TCM config
145  while ((EFC->EEFC_FSR & EEFC_FSR_FRDY) != EEFC_FSR_FRDY)
146  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT;
147 
148  EFC->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(8) | EEFC_FCR_FCMD(EFC_FCMD_CGPB); //TCM config
149  while ((EFC->EEFC_FSR & EEFC_FSR_FRDY) != EEFC_FSR_FRDY)
150  WDT->WDT_CR = 0xA5000000 | WDT_CR_WDRSTT;
151 
152  LEDS_ALL_OFF();
153 
154  //Reset Device
156  while(1);
157 }
158 
159 uint32_t flash_get_user_signature(volatile void* ptr, uint32_t size)
160 {
161  return flash_read_user_signature((uint32_t*)ptr, size / sizeof(uint32_t));
162 }
163 
164 uint32_t flash_set_user_signature(const volatile void *ptr, uint32_t size)
165 {
166  // get copy of user signature in critical section
168 
169  uint32_t* ptrCopy = (uint32_t*)pvPortMalloc(size);
170  memcpy(ptrCopy, (const void*)ptr, size);
171 
173 
174  // erase user signature first
175  flash_erase_user_signature();
176 
177  // perform flash write with copy of data outside critical section, size for this function is
178  // number of 32 bit words.
179  uint32_t result = flash_write_user_signature(ptrCopy, size / sizeof(uint32_t));
180  vPortFree(ptrCopy);
181  return result;
182 }
183 
185 {
186  return s_flashWriteInProgress;
187 }
__no_inline RAMFUNC void flash_erase_chip(void)
Definition: d_flash.c:120
#define cpu_irq_disable()
Disable interrupts globally.
Operation OK.
Definition: flash_efc.h:64
void vPortFree(void *pv) PRIVILEGED_FUNCTION
Definition: heap_4.c:311
#define LEDS_ALL_OFF()
Definition: user_board.h:273
uint32_t flash_erase_block(uint32_t address)
Definition: d_flash.c:106
#define RAMFUNC
Definition: ISConstants.h:251
#define RSTC_CR_KEY_PASSWD
(RSTC_CR) Writing any other value in this field aborts the write operation.
#define LED_COLOR_RED()
Definition: user_board.h:251
#define EEFC_FCR_FCMD(value)
void * pvPortMalloc(size_t xSize) PRIVILEGED_FUNCTION
Definition: heap_4.c:155
#define EEFC_FCR_FARG(value)
#define RSTC
(RSTC ) Base Address
Definition: same70j19.h:532
#define NULL
Definition: nm_bsp.h:52
Efc hardware registers.
uint32_t flash_write_count
Definition: globals.h:52
uint32_t flash_lock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
Lock all the regions in the given address range. The actual lock range is reported through two output...
Definition: flash_efc.c:703
#define WDT_CR_WDRSTT
(WDT_CR) Watchdog Restart
#define WDT
(WDT ) Base Address
Definition: same70j19.h:535
uint32_t flash_update_block(uint32_t address, const void *newData, int dataSize, int noPageErase)
Definition: d_flash.c:23
#define EEFC_FCR_FKEY_PASSWD
Definition: efc.c:100
#define END_CRITICAL_SECTION
Definition: rtos.h:34
User board definition template.
#define BOOTLOADER_FLASH_USER_DATA_END_ADDRESS
#define BOOTLOADER_FLASH_BLOCK_SIZE
General error.
Definition: flash_efc.h:67
#define RSTC_CR_PROCRST
(RSTC_CR) Processor Reset
Invalid argument input.
Definition: flash_efc.h:68
uint32_t flash_get_user_signature(volatile void *ptr, uint32_t size)
Definition: d_flash.c:159
#define EFC
(EFC ) Base Address
Definition: same70j19.h:528
uint32_t efc_perform_fcr(Efc *p_efc, uint32_t ul_fcr)
Perform command.
Definition: efc.c:418
uint32_t flash_write(uint32_t ul_address, const void *p_buffer, uint32_t ul_size, uint32_t ul_erase_flag)
Write a data buffer on flash.
Definition: flash_efc.c:607
#define BEGIN_CRITICAL_SECTION
Definition: rtos.h:33
uint32_t flash_set_user_signature(const volatile void *ptr, uint32_t size)
Definition: d_flash.c:164
#define IFLASH_ADDR
Definition: same70j19.h:566
int flash_write_in_progress(void)
Definition: d_flash.c:184
void time_delay(uint32_t ms)
Definition: d_time.c:84
#define IFLASH_SIZE
Definition: same70j19.h:556
Autogenerated API include file for the Atmel Software Framework (ASF)
nvr_manage_t g_nvr_manage_config
Definition: globals.c:23
#define EFC_FCMD_EA
Erase all.
#define EEFC_FSR_FRDY
(EEFC_FSR) Flash Ready Status (cleared when Flash is busy)
#define BOOTLOADER_FLASH_USER_DATA_START_ADDRESS
static int s_flashWriteInProgress
Definition: d_flash.c:21
uint32_t flash_unlock(uint32_t ul_start, uint32_t ul_end, uint32_t *pul_actual_start, uint32_t *pul_actual_end)
Unlock all the regions in the given address range. The actual unlock range is reported through two ou...
Definition: flash_efc.c:752
#define EFC_FCMD_CGPB
Clear GPNVM Bit.


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:57