Skip to content

Commit cd2ad92

Browse files
committed
Applied commit 66dd8cf without loosing compatibility
Tested with ATSAMD21x18
1 parent 88d826b commit cd2ad92

File tree

3 files changed

+132
-100
lines changed

3 files changed

+132
-100
lines changed

src/Device.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ Device::create()
411411
case 0x10010056: // E15B WLCSP
412412
case 0x10010063: // E15C WLCSP
413413
_family = FAMILY_SAMD21;
414-
flashPtr = new NvmFlash(_samba, "ATSAMD21x15", 0x2000, 512, 64, 1, 16, 0x20000800, 0x20001000, 0x41004000, true) ;
414+
flashPtr = new NvmFlashD2x(_samba, "ATSAMD21x15", 0x2000, 512, 64, 1, 16, 0x20000800, 0x20001000, true) ;
415415
break;
416416

417417
case 0x10010002: // J16A
@@ -423,23 +423,23 @@ Device::create()
423423
case 0x10010055: // E16B WLCSP
424424
case 0x10010062: // E16C WLCSP
425425
_family = FAMILY_SAMD21;
426-
flashPtr = new NvmFlash(_samba, "ATSAMD21x16", 0x2000, 1024, 64, 1, 16, 0x20001000, 0x20002000, 0x41004000, true) ;
426+
flashPtr = new NvmFlashD2x(_samba, "ATSAMD21x16", 0x2000, 1024, 64, 1, 16, 0x20001000, 0x20002000, true) ;
427427
break;
428428

429429
case 0x10010001: // J17A
430430
case 0x10010006: // G17A
431431
case 0x1001000b: // E17A
432432
case 0x10010010: // G17A WLCSP
433433
_family = FAMILY_SAMD21;
434-
flashPtr = new NvmFlash(_samba, "ATSAMD21x17", 0x2000, 2048, 64, 1, 16, 0x20002000, 0x20004000, 0x41004000, true) ;
434+
flashPtr = new NvmFlashD2x(_samba, "ATSAMD21x17", 0x2000, 2048, 64, 1, 16, 0x20002000, 0x20004000, true) ;
435435
break;
436436

437437
case 0x10010000: // J18A
438438
case 0x10010005: // G18A
439439
case 0x1001000a: // E18A
440440
case 0x1001000f: // G18A WLCSP
441441
_family = FAMILY_SAMD21;
442-
flashPtr = new NvmFlash(_samba, "ATSAMD21x18", 0x2000, 4096, 64, 1, 16, 0x20004000, 0x20008000, 0x41004000, true) ;
442+
flashPtr = new NvmFlashD2x(_samba, "ATSAMD21x18", 0x2000, 4096, 64, 1, 16, 0x20004000, 0x20008000, true) ;
443443
break;
444444

445445
//
@@ -448,24 +448,24 @@ Device::create()
448448
case 0x1001001e: // E16A
449449
case 0x1001001b: // G16A
450450
_family = FAMILY_SAMR21;
451-
flashPtr = new NvmFlash(_samba, "ATSAMR21x16", 0x2000, 1024, 64, 1, 16, 0x20001000, 0x20002000, 0x41004000, true) ;
451+
flashPtr = new NvmFlashD2x(_samba, "ATSAMR21x16", 0x2000, 1024, 64, 1, 16, 0x20001000, 0x20002000, true) ;
452452
break;
453453

454454
case 0x1001001d: // E17A
455455
case 0x1001001a: // G17A
456456
_family = FAMILY_SAMR21;
457-
flashPtr = new NvmFlash(_samba, "ATSAMR21x17", 0x2000, 2048, 64, 1, 16, 0x20002000, 0x20004000, 0x41004000, true) ;
457+
flashPtr = new NvmFlashD2x(_samba, "ATSAMR21x17", 0x2000, 2048, 64, 1, 16, 0x20002000, 0x20004000, true) ;
458458
break;
459459

460460
case 0x1001001c: // E18A
461461
case 0x10010019: // G18A
462462
_family = FAMILY_SAMR21;
463-
flashPtr = new NvmFlash(_samba, "ATSAMR21x18", 0x2000, 4096, 64, 1, 16, 0x20004000, 0x20008000, 0x41004000, true) ;
463+
flashPtr = new NvmFlashD2x(_samba, "ATSAMR21x18", 0x2000, 4096, 64, 1, 16, 0x20004000, 0x20008000, true) ;
464464
break;
465465

466466
case 0x10010018: // E19A
467467
_family = FAMILY_SAMR21;
468-
flashPtr = new NvmFlash(_samba, "ATSAMR21x19", 0x2000, 4096, 64, 1, 16, 0x20004000, 0x20008000, 0x41004000, true) ;
468+
flashPtr = new NvmFlashD2x(_samba, "ATSAMR21x19", 0x2000, 4096, 64, 1, 16, 0x20004000, 0x20008000, true) ;
469469
break;
470470

471471
default:

src/NvmFlash.cpp

Lines changed: 85 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,6 @@
1717
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
///////////////////////////////////////////////////////////////////////////////
1919

20-
#include <stdint.h>
21-
#include <stdio.h>
22-
#include <stdlib.h>
23-
#include <memory>
24-
#include <iostream>
25-
#include <exception>
26-
27-
#include "Samba.h"
28-
#include "WordCopyApplet.h"
2920
#include "NvmFlash.h"
3021

3122
// System control brown out register.
@@ -37,41 +28,43 @@
3728
#define SYSCTRL_STATUS_REG_BOD33_RESET_ENABLE_BIT (0x8ul)
3829
#define SYSCTRL_STATUS_REG_BOD33_RESET_MASK (0xffffffe7ul)
3930

40-
// The base address of the NVM module in
41-
// main memory + offset to the CTRLA register
42-
#define NVM_CTRLA_REG (_regs+0x00)
43-
44-
#define NVM_CTRLB_REG (_regs+0x04)
45-
46-
// The NVM register that stores lock status
47-
#define NVM_LOCK_REG (_regs+0x20)
48-
49-
// The interrupt status register
50-
#define NVM_INT_STATUS_REG (_regs+0x14)
31+
// CMDEX field should be 0xA5 to allow execution of any command.
32+
#define CMDEX_KEY 0xa500
5133

5234
// NVM ready bit mask
5335
#define NVM_INT_STATUS_READY_MASK 0x1
5436

55-
// NVM input register to some of the CMDEX commands.
56-
#define NVM_ADDR_REG (_regs+0x1c)
57-
58-
// NVM STATUS register
59-
#define NVM_STATUS_REG (_regs+0x18)
60-
#define NVMCTRL_STATUS_MASK (0xFFEBu)
61-
62-
// CMDEX field should be 0xA5 to allow execution of any command.
63-
#define CMDEX_KEY (0xa500u)
64-
65-
// List of NVM Commands.//as per datasheet prefix CMDEX
66-
#define CMD_LOCK_REGION (CMDEX_KEY | 0x0040u)
67-
#define CMD_UNLOCK_REGION (CMDEX_KEY | 0x0041u)
68-
#define CMD_ERASE_ROW (CMDEX_KEY | 0x0002u)
69-
#define CMD_WRITE_PAGE (CMDEX_KEY | 0x0004u)
70-
#define CMD_SET_SECURITY_BIT (CMDEX_KEY | 0x0045u)
71-
#define CMD_CLEAR_PAGE_BUFFER (CMDEX_KEY | 0x0044u)
72-
73-
// This is the word size allowed by the communication layer of this bossa client, not the NVM word size which is 2 bytes
74-
#define SAMBA_API_WORD_SIZE (4ul) // bytes
37+
// NVM status mask
38+
#define NVM_CTRL_STATUS_MASK 0xFFEB
39+
40+
NvmFlashD2x::NvmFlashD2x(
41+
Samba& samba,
42+
const std::string& name,
43+
uint32_t addr,
44+
uint32_t pages,
45+
uint32_t size,
46+
uint32_t planes,
47+
uint32_t lockRegions,
48+
uint32_t user,
49+
uint32_t stack,
50+
bool canBrownout) : NvmFlash(samba, name, addr, pages, size, planes, lockRegions, user, stack, canBrownout)
51+
{
52+
_regBase = 0x41004000;
53+
54+
_regCTRLA = 0x00;
55+
_regCTRLB = 0x04;
56+
_regINTFLAG = 0x14;
57+
_regSTATUS = 0x18;
58+
_regADDR = 0x1c;
59+
_regLOCK = 0x20;
60+
61+
_cmdER = 0x02;
62+
_cmdWP = 0x04;
63+
_cmdLR = 0x40;
64+
_cmdUR = 0x41;
65+
_cmdSSB = 0x45;
66+
_cmdPBC = 0x44;
67+
}
7568

7669
/* This class is designed specifically for SAM Dxx architecture in mind */
7770
NvmFlash::NvmFlash(Samba& samba,
@@ -83,14 +76,10 @@ NvmFlash::NvmFlash(Samba& samba,
8376
uint32_t lockRegions,
8477
uint32_t user,
8578
uint32_t stack,
86-
uint32_t regs,
8779
bool canBrownout)
8880
: Flash(samba, name, addr, pages, size, planes, lockRegions, user, stack),
89-
_regs(regs), _canBrownout(canBrownout)
81+
_canBrownout(canBrownout)
9082
{
91-
// Upon power up the NVM controller goes through a power up sequence.
92-
// During this time, access to the NVM controller is halted. Upon power up the
93-
// the NVM controller is operational without any need for user configuration.
9483
}
9584

9685
NvmFlash::~NvmFlash()
@@ -109,42 +98,42 @@ NvmFlash::eraseAll()
10998
// Leave the first 8KB, where bootloader resides, erase the rest.
11099
// Row is a concept used for convinence. When writing you have to write
111100
// page(s). When erasing you have to erase row(s).
112-
101+
// Use the extended Samba command if available
113102
if (_samba.canChipErase())
114103
{
115104
_samba.chipErase(_addr);
116-
return;
117105
}
118-
119-
// Calculate the number of rows that samba occupies (should be 32 for 8KB/0x2000bytes).
120-
uint32_t starting_row = bootloaderSize / _size / flashRowPages;
121-
uint32_t total_rows = _pages / flashRowPages;
122-
123-
for (uint32_t row=starting_row; row<total_rows; row++)
106+
else
124107
{
125-
uint32_t addr_in_flash = (row * flashRowPages * pageSize());
126-
// The address is byte address, so convert it to word address.
127-
addr_in_flash = addr_in_flash / 2;
108+
// Calculate the number of rows that samba occupies (should be 32 for 8KB/0x2000bytes).
109+
uint32_t starting_row = bootloaderSize / _size / flashRowPages;
110+
uint32_t total_rows = _pages / flashRowPages;
128111

129-
// Safe wait. Check and see if this is needed all the time
130-
while (!nvmIsReady())
112+
for (uint32_t row=starting_row; row<total_rows; row++)
131113
{
132-
}
114+
uint32_t addr_in_flash = (row * flashRowPages * pageSize());
115+
// The address is byte address, so convert it to word address.
116+
addr_in_flash = addr_in_flash / 2;
117+
118+
// Safe wait. Check and see if this is needed all the time
119+
while (!nvmIsReady())
120+
;
133121

134-
// Clear error bits
135-
uint16_t status_reg = _samba.readWord(NVM_STATUS_REG) & 0xffff;
136-
_samba.writeWord(NVM_STATUS_REG, status_reg | NVMCTRL_STATUS_MASK);
122+
// Clear error bits
123+
uint16_t status_reg = readReg(_regSTATUS) & 0xffff;
124+
writeReg(_regSTATUS, status_reg | NVM_CTRL_STATUS_MASK);
137125

138-
// Issue erase command
139-
_samba.writeWord(NVM_ADDR_REG, addr_in_flash);
140-
executeNvmCommand(CMD_ERASE_ROW);
126+
// Issue erase command
127+
writeReg(_regADDR, addr_in_flash);
128+
executeNvmCommand(_cmdER);
129+
}
141130
}
142131
}
143132

144133
bool
145134
NvmFlash::nvmIsReady()
146135
{
147-
uint8_t int_flag = _samba.readByte(NVM_INT_STATUS_REG) & NVM_INT_STATUS_READY_MASK;
136+
uint8_t int_flag = readReg(_regINTFLAG) & NVM_INT_STATUS_READY_MASK;
148137

149138
return int_flag == 1;
150139
}
@@ -170,7 +159,7 @@ NvmFlash::getLockRegion(uint32_t region)
170159
throw FlashRegionError();
171160
}
172161

173-
uint32_t value = _samba.readWord(NVM_LOCK_REG);
162+
uint32_t value = readReg(_regLOCK);
174163

175164
return ((value & (1 << region)) == 0); // 0 -> locked, 1 -> unlocked,
176165
}
@@ -193,17 +182,17 @@ NvmFlash::setLockRegion(uint32_t region, bool enable)
193182
// on the NVM controller.
194183
uint32_t addr_to_lock = getAddressByRegion(region);
195184
// addr_to_lock = addr_to_lock & 0x1fffff;
196-
_samba.writeWord(NVM_ADDR_REG, addr_to_lock);
185+
writeReg(_regADDR, addr_to_lock);
197186

198-
executeNvmCommand(CMD_LOCK_REGION);
187+
executeNvmCommand(_cmdLR);
199188
}
200189
else
201190
{
202191
uint32_t addr_to_unlock = getAddressByRegion(region);
203192
addr_to_unlock = addr_to_unlock & 0x1fffff;
204-
_samba.writeWord(NVM_ADDR_REG, addr_to_unlock);
193+
writeReg(_regADDR, addr_to_unlock);
205194

206-
executeNvmCommand(CMD_UNLOCK_REGION);
195+
executeNvmCommand(_cmdUR);
207196
}
208197
}
209198
}
@@ -213,7 +202,7 @@ NvmFlash::setLockRegion(uint32_t region, bool enable)
213202
bool
214203
NvmFlash::getSecurity()
215204
{
216-
uint16_t status_reg_value = _samba.readWord(NVM_STATUS_REG) & 0xffff;
205+
uint16_t status_reg_value = readReg(_regSTATUS);
217206

218207
// If the 8th bit is 1 then security bit is set, else unset.
219208
return (((status_reg_value >> 8) & 0x1) == 1);
@@ -225,7 +214,7 @@ NvmFlash::setSecurity()
225214
{
226215
if (!getSecurity())
227216
{
228-
executeNvmCommand(CMD_SET_SECURITY_BIT);
217+
executeNvmCommand(_cmdSSB);
229218

230219
if (!getSecurity())
231220
{
@@ -310,16 +299,16 @@ NvmFlash::writePage(uint32_t page)
310299
}
311300

312301
// Clear page buffer
313-
executeNvmCommand(CMD_CLEAR_PAGE_BUFFER);
302+
executeNvmCommand(_cmdPBC);
314303

315304
// Clear error flags in target
316-
uint16_t status_reg = _samba.readWord(NVM_STATUS_REG) & 0xffff;
317-
_samba.writeWord(NVM_STATUS_REG, status_reg | NVMCTRL_STATUS_MASK);
305+
uint16_t status_reg = readReg(_regSTATUS) & 0xffff;
306+
writeReg(_regSTATUS, status_reg | NVM_CTRL_STATUS_MASK);
318307

319308
// Configure manual page write. This is critical for the write to work
320309
// irrespective of full page or partial page.
321-
uint32_t ctrlb_reg = _samba.readWord(NVM_CTRLB_REG);
322-
_samba.writeWord(NVM_CTRLB_REG, ctrlb_reg | (0x1 << 7));
310+
uint32_t ctrlb_reg = readReg(_regCTRLB);
311+
writeReg(_regCTRLB, ctrlb_reg | (0x1 << 7));
323312

324313
// Compute the start address.
325314
uint32_t addr = _addr + (page * _size );
@@ -335,9 +324,9 @@ NvmFlash::writePage(uint32_t page)
335324

336325
while (!nvmIsReady());
337326

338-
_samba.writeWord(NVM_ADDR_REG, addr_cached >> 1);
327+
writeReg(_regADDR, addr_cached >> 1);
339328
// Reset the buffer, so that subsequent reads are clear
340-
executeNvmCommand(CMD_WRITE_PAGE);
329+
executeNvmCommand(_cmdWP);
341330
}
342331

343332
void
@@ -355,6 +344,18 @@ NvmFlash::readPage(uint32_t page, uint8_t* buf)
355344
_samba.read(addr, buf, pageSize());
356345
}
357346

347+
uint32_t
348+
NvmFlash::readReg(uint8_t reg)
349+
{
350+
return _samba.readWord(_regBase + reg);
351+
}
352+
353+
void
354+
NvmFlash::writeReg(uint8_t reg, uint32_t value)
355+
{
356+
_samba.writeWord(_regBase + reg, value);
357+
}
358+
358359
// Returns the start address of a specified region number
359360
// based on the flash specifications. The returned address is
360361
// word address (not byte address).
@@ -374,20 +375,18 @@ NvmFlash::getAddressByRegion(uint32_t region_num)
374375
}
375376

376377
void
377-
NvmFlash::executeNvmCommand(uint32_t cmd)
378+
NvmFlash::executeNvmCommand(uint8_t cmd)
378379
{
379380
// Wait for the nvm controller to be ready
380381
while (!nvmIsReady())
381-
{
382-
}
382+
;
383383

384384
// Send the comamnd to nvm controller.
385-
_samba.writeWord(NVM_CTRLA_REG, cmd);
385+
writeReg(_regCTRLA, CMDEX_KEY | cmd);
386386

387387
// Wait till the operation completes.
388388
while (!nvmIsReady())
389-
{
390-
}
389+
;
391390

392391
//TODO : check and return return error status from nvm status flag.
393392
}

0 commit comments

Comments
 (0)