12
12
13
13
#include <modm/platform/device.hpp>
14
14
#include <modm/architecture/interface/interrupt.hpp>
15
+ #include <modm/architecture/interface/atomic_lock.hpp>
15
16
#include "tusb.h"
16
17
17
18
%% for irq in irqs | sort
@@ -21,37 +22,68 @@ MODM_ISR({{irq}})
21
22
}
22
23
%% endfor
23
24
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
24
52
25
53
extern "C" uint8_t
26
54
tusb_get_device_serial(uint16_t *serial_str)
27
55
{
28
56
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
29
62
30
63
uint32_t *id_addresses[4] =
31
64
{
32
- %% if target.platform in ["stm32"]
65
+ %% if target.platform in ["stm32"]
33
66
((uint32_t *) UID_BASE), ((uint32_t *) UID_BASE) + 1,
34
67
((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
37
70
(uint32_t *)0x008061FC, (uint32_t *)0x00806010,
38
71
(uint32_t *)0x00806014, (uint32_t *)0x00806018
39
- %% else
72
+ %% else
40
73
(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040,
41
74
(uint32_t *)0x0080A044, (uint32_t *)0x0080A048
42
- %% endif
43
- %% elif target.platform in ["rp"]
75
+ %% endif
76
+ %% elif target.platform in ["rp"]
44
77
/* sysinfo CHIP_ID and GIT_REV */
45
78
((uint32_t *)0x40000000),((uint32_t *)0x40000040),
46
79
((uint32_t *)0x40000000),((uint32_t *)0x40000040),
47
- %% endif
80
+ %% endif
48
81
};
49
82
50
- uint8_t raw_id[SERIAL_BYTE_LEN];
51
-
52
83
for (int i = 0; i < 4; i++)
53
84
for (int k = 0; k < 4; k++)
54
85
raw_id[4 * i + (3 - k)] = (*(id_addresses[i]) >> k * 8) & 0xff;
86
+ %% endif
55
87
56
88
const auto fn_nibble = [](uint8_t nibble)
57
89
{
0 commit comments