Skip to content

Commit 0cf0127

Browse files
committed
Portenta: correctly handle the various board revisions
1 parent f2e5117 commit 0cf0127

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#define OTP_QSPI_MAGIC 0xB5
2+
3+
typedef struct {
4+
uint8_t magic;
5+
uint8_t version;
6+
union {
7+
uint16_t board_functionalities;
8+
struct {
9+
uint8_t usb_high_speed :1;
10+
uint8_t ethernet :1;
11+
uint8_t wifi :1;
12+
uint8_t video :1;
13+
uint8_t nxp_crypto :1;
14+
uint8_t mchp_crypto :1;
15+
} _board_functionalities;
16+
};
17+
uint16_t revision;
18+
uint16_t carrier;
19+
uint8_t external_ram_size;
20+
uint8_t external_flash_size;
21+
uint16_t vid;
22+
uint16_t pid;
23+
uint8_t mac_address[6];
24+
uint8_t mac_address_2[6];
25+
} PortentaBoardInfo;
26+
27+
typedef struct {
28+
uint8_t magic;
29+
uint8_t version;
30+
uint8_t clock_source;
31+
uint8_t usb_speed;
32+
uint8_t ethernet;
33+
uint8_t wifi;
34+
uint8_t ram_size;
35+
uint8_t qspi_size;
36+
uint8_t video;
37+
uint8_t crypto;
38+
uint8_t extclock;
39+
} PortentaBootloaderInfo;

variants/PORTENTA_H7_M7/variant.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Arduino.h"
22
#include "pinDefinitions.h"
3+
#include "mbed.h"
34

45
RTC_HandleTypeDef RTCHandle;
56

@@ -235,6 +236,68 @@ void fixup3V1Rail() {
235236
i2c.write(8 << 1, data, sizeof(data));
236237
}
237238

239+
#include "QSPIFBlockDevice.h"
240+
241+
class SecureQSPIFBlockDevice: public QSPIFBlockDevice {
242+
public:
243+
virtual int readSecure(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size) {
244+
int ret = 0;
245+
ret &= _qspi.command_transfer(0xB1, -1, nullptr, 0, nullptr, 0);
246+
ret &= read(buffer, addr, size);
247+
ret &= _qspi.command_transfer(0xC1, -1, nullptr, 0, nullptr, 0);
248+
return ret;
249+
}
250+
};
251+
252+
#include "portenta_info.h"
253+
254+
static uint8_t *_boardInfo = (uint8_t*)(0x801F000);
255+
static bool has_otp_info = false;
256+
257+
// 8Kbit secure OTP area (on MX25L12833F)
258+
bool getSecureFlashData() {
259+
static SecureQSPIFBlockDevice root;
260+
static PortentaBoardInfo* info = new PortentaBoardInfo();
261+
root.init();
262+
auto ret = root.readSecure(info, 0, sizeof(PortentaBoardInfo));
263+
if (info->magic == OTP_QSPI_MAGIC) {
264+
_boardInfo = (uint8_t*)info;
265+
has_otp_info = true;
266+
} else {
267+
delete info;
268+
}
269+
return ret == 0;
270+
}
271+
272+
uint8_t* boardInfo() {
273+
return _boardInfo;
274+
}
275+
276+
uint16_t boardRevision() {
277+
return (((PortentaBoardInfo*)_boardInfo)->revision);
278+
}
279+
280+
uint8_t bootloaderVersion() {
281+
return _boardInfo[1];
282+
}
283+
284+
uint32_t lowSpeedClockInUse() {
285+
return __HAL_RCC_GET_LPTIM4_SOURCE();
286+
}
287+
288+
#define BOARD_REVISION(x,y) (x << 8 | y)
289+
290+
extern "C" bool isLSEAvailableAndPrecise() {
291+
if (has_otp_info && (boardRevision() >= BOARD_REVISION(4,10))) {
292+
return true;
293+
}
294+
if (__HAL_RCC_GET_LPTIM4_SOURCE() == RCC_LPTIM4CLKSOURCE_LSI || bootloaderVersion() < 24) {
295+
// LSE is either not mounted, imprecise or the BL already configures RTC clock with LSI (and we are doomed)
296+
return false;
297+
}
298+
return true;
299+
}
300+
238301
extern "C" void lp_ticker_reconfigure_with_lsi();
239302

240303
void initVariant() {
@@ -246,18 +309,28 @@ void initVariant() {
246309
// Disable the FMC bank1 (enabled after reset)
247310
// See https://github.com/STMicroelectronics/STM32CubeH7/blob/beced99ac090fece04d1e0eb6648b8075e156c6c/Projects/STM32H747I-DISCO/Applications/OpenAMP/OpenAMP_RTOS_PingPong/Common/Src/system_stm32h7xx.c#L215
248311
FMC_Bank1_R->BTCR[0] = 0x000030D2;
312+
313+
getSecureFlashData();
314+
if (has_otp_info && (boardRevision() >= BOARD_REVISION(4,10))) {
315+
// LSE works and also keeps counting in VBAT mode
316+
return;
317+
}
318+
249319
// Check that the selected lsi clock is ok
250320
if (__HAL_RCC_GET_LPTIM4_SOURCE() == RCC_LPTIM4CLKSOURCE_LSI) {
251321
// rtc is not mounted, no need to do other actions
252322
return;
253323
}
324+
254325
// Use micros() to check the lptim precision
255326
// if the error is > 1% , reconfigure the clock using lsi
256327
uint32_t start_ms = millis();
257328
uint32_t start_us = micros();
258329
while (micros() - start_us < 100000);
259330
if (millis() - start_ms != 100) {
260331
lp_ticker_reconfigure_with_lsi();
332+
// reconfiguring RTC clock would trigger a backup subsystem reset;
333+
// keep the clock configured in the BL
261334
}
262335
}
263336

0 commit comments

Comments
 (0)