Skip to content

Commit

Permalink
[sam] Read unique ID correctly for SAMG55
Browse files Browse the repository at this point in the history
  • Loading branch information
mcbridejc committed Feb 8, 2022
1 parent ac46099 commit e6efd55
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 10 deletions.
2 changes: 1 addition & 1 deletion ext/hathach/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def prepare(module, options):

module.add_submodule(TinyUsbDeviceModule())
module.add_submodule(TinyUsbHostModule())
module.depends(":cmsis:device", ":architecture:interrupt", ":platform:usb")
module.depends(":cmsis:device", ":architecture:atomic", ":architecture:interrupt", ":platform:usb")
return True


Expand Down
50 changes: 41 additions & 9 deletions ext/hathach/tusb_port.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <modm/platform/device.hpp>
#include <modm/architecture/interface/interrupt.hpp>
#include <modm/architecture/interface/atomic_lock.hpp>
#include "tusb.h"

%% for irq in irqs | sort
Expand All @@ -21,37 +22,68 @@ MODM_ISR({{irq}})
}
%% endfor

%% if "samg55" in target.string

// Read unique ID using the flash controller
// This function is placed in RAM, because code cannot be fetched from flash
// while reading the unique ID.
modm_ramcode void read_efc_uid(uint32_t *uid)
{
// Disable interrupts -- we can't fetch code
// This function was measured to take 660ns on a SAMG55 running at 100MHz
modm::atomic::Lock lck;

// Issue Start Read Unique Identifier command
EFC->EEFC_FCR = EEFC_FCR_FCMD_STUI | EEFC_FCR_FKEY_PASSWD;
// Wait for flash controller ready bit to go low
while(EFC->EEFC_FSR & EEFC_FSR_FRDY) {};

for(uint32_t i=0; i<4; i++) {
uid[i] = *(uint32_t*)(IFLASH_ADDR + i * 4);
}

// Issue Stop Read Unique Identifier command
EFC->EEFC_FCR = EEFC_FCR_FCMD_SPUI | EEFC_FCR_FKEY_PASSWD;
// Wait for flash controller ready bit to go high
while(!(EFC->EEFC_FSR & EEFC_FSR_FRDY)) {};
}

%% endif

extern "C" uint8_t
tusb_get_device_serial(uint16_t *serial_str)
{
constexpr uint8_t SERIAL_BYTE_LEN = 16;
uint8_t raw_id[SERIAL_BYTE_LEN];

%% if "samg55" in target.string
read_efc_uid((uint32_t*)raw_id);
%% else

uint32_t *id_addresses[4] =
{
%% if target.platform in ["stm32"]
%% if target.platform in ["stm32"]
((uint32_t *) UID_BASE), ((uint32_t *) UID_BASE) + 1,
((uint32_t *) UID_BASE) + 2, ((uint32_t *) UID_BASE) + 3
%% elif target.platform in ["sam"]
%% if "samd51" in target.string
%% elif target.platform in ["sam"]
%% if "samd51" in target.string
(uint32_t *)0x008061FC, (uint32_t *)0x00806010,
(uint32_t *)0x00806014, (uint32_t *)0x00806018
%% else
%% else
(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040,
(uint32_t *)0x0080A044, (uint32_t *)0x0080A048
%% endif
%% elif target.platform in ["rp"]
%% endif
%% elif target.platform in ["rp"]
/* sysinfo CHIP_ID and GIT_REV */
((uint32_t *)0x40000000),((uint32_t *)0x40000040),
((uint32_t *)0x40000000),((uint32_t *)0x40000040),
%% endif
%% endif
};

uint8_t raw_id[SERIAL_BYTE_LEN];

for (int i = 0; i < 4; i++)
for (int k = 0; k < 4; k++)
raw_id[4 * i + (3 - k)] = (*(id_addresses[i]) >> k * 8) & 0xff;
%% endif

const auto fn_nibble = [](uint8_t nibble)
{
Expand Down

0 comments on commit e6efd55

Please sign in to comment.