Skip to content

Commit e6efd55

Browse files
committed
[sam] Read unique ID correctly for SAMG55
1 parent ac46099 commit e6efd55

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

ext/hathach/module.lb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def prepare(module, options):
5656

5757
module.add_submodule(TinyUsbDeviceModule())
5858
module.add_submodule(TinyUsbHostModule())
59-
module.depends(":cmsis:device", ":architecture:interrupt", ":platform:usb")
59+
module.depends(":cmsis:device", ":architecture:atomic", ":architecture:interrupt", ":platform:usb")
6060
return True
6161

6262

ext/hathach/tusb_port.cpp.in

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <modm/platform/device.hpp>
1414
#include <modm/architecture/interface/interrupt.hpp>
15+
#include <modm/architecture/interface/atomic_lock.hpp>
1516
#include "tusb.h"
1617

1718
%% for irq in irqs | sort
@@ -21,37 +22,68 @@ MODM_ISR({{irq}})
2122
}
2223
%% endfor
2324

25+
%% if "samg55" in target.string
26+
27+
// Read unique ID using the flash controller
28+
// This function is placed in RAM, because code cannot be fetched from flash
29+
// while reading the unique ID.
30+
modm_ramcode void read_efc_uid(uint32_t *uid)
31+
{
32+
// Disable interrupts -- we can't fetch code
33+
// This function was measured to take 660ns on a SAMG55 running at 100MHz
34+
modm::atomic::Lock lck;
35+
36+
// Issue Start Read Unique Identifier command
37+
EFC->EEFC_FCR = EEFC_FCR_FCMD_STUI | EEFC_FCR_FKEY_PASSWD;
38+
// Wait for flash controller ready bit to go low
39+
while(EFC->EEFC_FSR & EEFC_FSR_FRDY) {};
40+
41+
for(uint32_t i=0; i<4; i++) {
42+
uid[i] = *(uint32_t*)(IFLASH_ADDR + i * 4);
43+
}
44+
45+
// Issue Stop Read Unique Identifier command
46+
EFC->EEFC_FCR = EEFC_FCR_FCMD_SPUI | EEFC_FCR_FKEY_PASSWD;
47+
// Wait for flash controller ready bit to go high
48+
while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY)) {};
49+
}
50+
51+
%% endif
2452

2553
extern "C" uint8_t
2654
tusb_get_device_serial(uint16_t *serial_str)
2755
{
2856
constexpr uint8_t SERIAL_BYTE_LEN = 16;
57+
uint8_t raw_id[SERIAL_BYTE_LEN];
58+
59+
%% if "samg55" in target.string
60+
read_efc_uid((uint32_t*)raw_id);
61+
%% else
2962

3063
uint32_t *id_addresses[4] =
3164
{
32-
%% if target.platform in ["stm32"]
65+
%% if target.platform in ["stm32"]
3366
((uint32_t *) UID_BASE), ((uint32_t *) UID_BASE) + 1,
3467
((uint32_t *) UID_BASE) + 2, ((uint32_t *) UID_BASE) + 3
35-
%% elif target.platform in ["sam"]
36-
%% if "samd51" in target.string
68+
%% elif target.platform in ["sam"]
69+
%% if "samd51" in target.string
3770
(uint32_t *)0x008061FC, (uint32_t *)0x00806010,
3871
(uint32_t *)0x00806014, (uint32_t *)0x00806018
39-
%% else
72+
%% else
4073
(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040,
4174
(uint32_t *)0x0080A044, (uint32_t *)0x0080A048
42-
%% endif
43-
%% elif target.platform in ["rp"]
75+
%% endif
76+
%% elif target.platform in ["rp"]
4477
/* sysinfo CHIP_ID and GIT_REV */
4578
((uint32_t *)0x40000000),((uint32_t *)0x40000040),
4679
((uint32_t *)0x40000000),((uint32_t *)0x40000040),
47-
%% endif
80+
%% endif
4881
};
4982

50-
uint8_t raw_id[SERIAL_BYTE_LEN];
51-
5283
for (int i = 0; i < 4; i++)
5384
for (int k = 0; k < 4; k++)
5485
raw_id[4 * i + (3 - k)] = (*(id_addresses[i]) >> k * 8) & 0xff;
86+
%% endif
5587

5688
const auto fn_nibble = [](uint8_t nibble)
5789
{

0 commit comments

Comments
 (0)