Skip to content

Commit 6a42cb6

Browse files
committed
Workaround for SAM3 sam-ba bug on chip identification.
Reading an non-existent register on SAM3 will lock sam-ba bootloader. We can use the CPUID register on 0xE000ED00 (that is common to SAM3 and SAMD21) to first distinguish the architecture and do the specific CPU identification afterwards.
1 parent ed8802c commit 6a42cb6

File tree

1 file changed

+20
-19
lines changed

1 file changed

+20
-19
lines changed

src/Samba.cpp

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ Samba::init()
142142
if (_debug)
143143
printf("Unsupported ARM920T architecture\n");
144144
}
145+
// Check for supported M0+ processor
146+
else if (cid == 0x10010000 || cid == 0x10010005)
147+
{
148+
return true;
149+
}
145150
else
146151
{
147152
if (_debug)
@@ -565,34 +570,30 @@ Samba::version()
565570
uint32_t
566571
Samba::chipId()
567572
{
568-
uint32_t vector;
569-
uint32_t cid;
570-
571573
// Read the ARM reset vector
572-
vector = readWord(0x0);
574+
uint32_t vector = readWord(0x0);
573575

574576
// If the vector is a ARM7TDMI branch, then assume Atmel SAM7 registers
575577
if ((vector & 0xff000000) == 0xea000000)
576578
{
577-
cid = readWord(0xfffff240);
579+
return readWord(0xfffff240);
578580
}
581+
579582
// Else use the Atmel SAM3 or SAM4 or M0+ registers
580-
else
583+
584+
// The M0+, M3 and M4 have the CPUID register at a common addresss 0xe000ed00
585+
uint32_t cpuid_reg = readWord(0xe000ed00);
586+
uint16_t part_no = cpuid_reg & 0x0000fff0;
587+
// Check if it is Cortex M0+
588+
if (part_no == 0xC600)
581589
{
582-
// Check if it is Cortex M0+
583-
cid = readWord(0x41002018); // This is DSU_DID register
584-
if (cid != 0)
585-
{
586-
// M0+ device cid will be 0x10010000.
587-
}
588-
else
589-
{
590-
// M3 or M4
591-
cid = readWord(0x400e0740);
592-
if (cid == 0)
593-
cid = readWord(0x400e0940);
594-
}
590+
return readWord(0x41002018); // DSU_DID register
595591
}
592+
593+
// Else assume M3 or M4
594+
uint32_t cid = readWord(0x400e0740);
595+
if (cid == 0)
596+
cid = readWord(0x400e0940);
596597
return cid;
597598
}
598599

0 commit comments

Comments
 (0)