mirror of
https://github.com/cesanta/mongoose
synced 2026-08-25 22:26:06 -04:00
Add OTA for IMXRT1180
This commit is contained in:
parent
2aff813795
commit
e312219e80
5 changed files with 250 additions and 24 deletions
51
mongoose.c
51
mongoose.c
|
|
@ -11028,7 +11028,7 @@ bool mg_ota_end(void) {
|
|||
|
||||
|
||||
|
||||
#if MG_OTA >= MG_OTA_RT1020 && MG_OTA <= MG_OTA_RT1170
|
||||
#if MG_OTA >= MG_OTA_RT1020 && MG_OTA <= MG_OTA_RT1180
|
||||
|
||||
static bool mg_imxrt_write(void *, const void *, size_t);
|
||||
static bool mg_imxrt_swap(void);
|
||||
|
|
@ -11039,9 +11039,12 @@ static bool mg_imxrt_swap(void);
|
|||
#elif MG_OTA == MG_OTA_RT1064
|
||||
#define MG_IMXRT_FLASH_START 0x70000000
|
||||
#define FLEXSPI_NOR_INSTANCE 1
|
||||
#else // RT1170
|
||||
#elif MG_OTA == MG_OTA_RT1170
|
||||
#define MG_IMXRT_FLASH_START 0x30000000
|
||||
#define FLEXSPI_NOR_INSTANCE 1
|
||||
#else // RT1180 FlexSPI2
|
||||
#define MG_IMXRT_FLASH_START 0x04000000
|
||||
#define FLEXSPI_NOR_INSTANCE 2
|
||||
#endif
|
||||
|
||||
#if MG_OTA == MG_OTA_RT1050
|
||||
|
|
@ -11350,7 +11353,7 @@ struct mg_flexspi_nor_driver_interface {
|
|||
uint32_t *option);
|
||||
};
|
||||
#else
|
||||
// RT117x support ROM API version 1.7
|
||||
// RT117x and RT118x
|
||||
struct mg_flexspi_nor_driver_interface {
|
||||
uint32_t version;
|
||||
int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
|
||||
|
|
@ -11385,11 +11388,16 @@ struct mg_flexspi_nor_driver_interface {
|
|||
#define flexspi_nor \
|
||||
(*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x0020001c + \
|
||||
16)))
|
||||
#else
|
||||
#elif MG_OTA == MG_OTA_RT1170
|
||||
#define MG_FLEXSPI_BASE 0x400CC000
|
||||
#define flexspi_nor \
|
||||
(*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x0021001c + \
|
||||
12)))
|
||||
#else
|
||||
#define MG_FLEXSPI_BASE 0x445E0000
|
||||
#define flexspi_nor \
|
||||
(*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x1000001c + \
|
||||
12)))
|
||||
#endif
|
||||
|
||||
static bool s_flash_irq_disabled;
|
||||
|
|
@ -11434,6 +11442,13 @@ static struct mg_flexspi_nor_config default_config = {
|
|||
#else
|
||||
// Note: this QSPI configuration works for RTs supporting QSPI
|
||||
// Configuration for QSPI memory
|
||||
#if MG_OTA == MG_OTA_RT1180
|
||||
#define MG_FLEXSPI_QSPI_SERIAL_CLK_FREQ 5 // 100MHz
|
||||
#define MG_FLEXSPI_QSPI_FLASH_SIZE (16 * 1024 * 1024)
|
||||
#else
|
||||
#define MG_FLEXSPI_QSPI_SERIAL_CLK_FREQ 7 // 133MHz
|
||||
#define MG_FLEXSPI_QSPI_FLASH_SIZE (8 * 1024 * 1024)
|
||||
#endif
|
||||
static struct mg_flexspi_nor_config default_config = {
|
||||
.memConfig = {.tag = MG_FLEXSPI_CFG_BLK_TAG,
|
||||
.version = MG_FLEXSPI_CFG_BLK_VERSION,
|
||||
|
|
@ -11443,8 +11458,8 @@ static struct mg_flexspi_nor_config default_config = {
|
|||
.controllerMiscOption = MG_BIT(4),
|
||||
.deviceType = 1, // serial NOR
|
||||
.sflashPadType = 4,
|
||||
.serialClkFreq = 7, // 133MHz
|
||||
.sflashA1Size = 8 * 1024 * 1024,
|
||||
.serialClkFreq = MG_FLEXSPI_QSPI_SERIAL_CLK_FREQ,
|
||||
.sflashA1Size = MG_FLEXSPI_QSPI_FLASH_SIZE,
|
||||
.lookupTable = MG_FLEXSPI_QSPI_LUT},
|
||||
.pageSize = 256,
|
||||
.sectorSize = 4 * 1024,
|
||||
|
|
@ -11479,6 +11494,7 @@ MG_IRAM static int flexspi_nor_get_config(
|
|||
}
|
||||
#endif
|
||||
|
||||
#if MG_OTA == MG_OTA_RT1020 || MG_OTA == MG_OTA_RT1050
|
||||
MG_IRAM static void mg_spin(volatile uint32_t count) {
|
||||
while (count--) (void) 0;
|
||||
}
|
||||
|
|
@ -11487,6 +11503,7 @@ MG_IRAM static void flash_wait(void) {
|
|||
while ((*((volatile uint32_t *) (MG_FLEXSPI_BASE + 0xE0)) & MG_BIT(1)) == 0)
|
||||
mg_spin(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
MG_IRAM static bool flash_erase(struct mg_flexspi_nor_config *config,
|
||||
void *addr) {
|
||||
|
|
@ -11535,6 +11552,8 @@ MG_IRAM static bool mg_imxrt_write(void *addr, const void *buf, size_t len) {
|
|||
uint32_t *dst = (uint32_t *) addr;
|
||||
uint32_t *src = (uint32_t *) buf;
|
||||
uint32_t *end = (uint32_t *) ((char *) buf + len);
|
||||
char *flash_start = (char *) s_mg_flash_imxrt.start;
|
||||
char *flash_end = flash_start + s_mg_flash_imxrt.size;
|
||||
ok = true;
|
||||
|
||||
while (ok && src < end) {
|
||||
|
|
@ -11542,20 +11561,32 @@ MG_IRAM static bool mg_imxrt_write(void *addr, const void *buf, size_t len) {
|
|||
ok = false;
|
||||
break;
|
||||
}
|
||||
uint32_t status;
|
||||
uint32_t status = 0;
|
||||
uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_imxrt.start;
|
||||
if ((char *) buf >= (char *) s_mg_flash_imxrt.start) {
|
||||
if ((char *) buf >= flash_start && (char *) buf < flash_end) {
|
||||
// If we copy from FLASH to FLASH, then we first need to copy the source
|
||||
// to RAM
|
||||
size_t tmp_buf_size = s_mg_flash_imxrt.align / sizeof(uint32_t);
|
||||
uint32_t tmp[tmp_buf_size];
|
||||
|
||||
#if MG_OTA == MG_OTA_RT1020 || MG_OTA == MG_OTA_RT1050
|
||||
// ROM API 1.4 does not provide flexspi_nor_flash_read().
|
||||
// Manually copy byte by byte into the RAM buffer.
|
||||
for (size_t i = 0; i < tmp_buf_size; i++) {
|
||||
flash_wait();
|
||||
tmp[i] = src[i];
|
||||
}
|
||||
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
|
||||
(uint32_t) dst_ofs, tmp);
|
||||
#else
|
||||
// When supported, prefer the read API call.
|
||||
uint32_t src_ofs =
|
||||
(uint32_t) src - (uint32_t) s_mg_flash_imxrt.start;
|
||||
status = flexspi_nor->read(FLEXSPI_NOR_INSTANCE, config_ptr, tmp,
|
||||
src_ofs, s_mg_flash_imxrt.align);
|
||||
#endif
|
||||
if (status == 0) {
|
||||
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
|
||||
dst_ofs, tmp);
|
||||
}
|
||||
} else {
|
||||
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
|
||||
(uint32_t) dst_ofs, src);
|
||||
|
|
|
|||
86
mongoose.h
86
mongoose.h
|
|
@ -447,7 +447,7 @@ static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
|
|||
#endif
|
||||
|
||||
#if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_IMXRT10) && \
|
||||
!defined(MG_ENABLE_DRIVER_IMXRT11)
|
||||
!defined(MG_ENABLE_DRIVER_IMXRT11) && !defined(MG_ENABLE_DRIVER_NETC)
|
||||
#if defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
|
||||
defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVL6B) || \
|
||||
defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1064DVL6B) || \
|
||||
|
|
@ -462,6 +462,8 @@ static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
|
|||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_)
|
||||
#define MG_ENABLE_DRIVER_IMXRT11 1
|
||||
#elif defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
#define MG_ENABLE_DRIVER_NETC 1
|
||||
#else
|
||||
#error Select an Ethernet driver in mongoose_config.h
|
||||
#endif
|
||||
|
|
@ -493,13 +495,31 @@ static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
|
|||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_))
|
||||
#define MG_OTA MG_OTA_RT1170
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_))
|
||||
#define MG_OTA MG_OTA_RT1180
|
||||
#endif
|
||||
|
||||
#ifndef MG_IRAM
|
||||
#if defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
#define MG_IRAM \
|
||||
__attribute__((noinline, section(".data.$SRAM_ITC_cm33")))
|
||||
#else
|
||||
#define MG_IRAM __attribute__((noinline, section(".data_RAM2")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_ETH_RAM
|
||||
#if defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
#define MG_ETH_RAM __attribute__((section(".bss.$ETH_RAM")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_SET_MAC_ADDRESS
|
||||
#if defined(MG_ENABLE_DRIVER_NETC) && MG_ENABLE_DRIVER_NETC
|
||||
// No OCOTP_FUSES present on RT1186 to generate the UUID
|
||||
#define MG_SET_MAC_ADDRESS(mac) (void) (mac)
|
||||
#else
|
||||
#if defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11
|
||||
#define MG_OCOTP_FUSES ((volatile uint32_t *) 0x40cac900)
|
||||
#else
|
||||
|
|
@ -515,11 +535,70 @@ static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
|
|||
mac[5] = (MG_OCOTP_FUSES[4] >> 0) & 255; \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_IMXRT_WDOG1_TIMEOUT_MS
|
||||
#define MG_IMXRT_WDOG1_TIMEOUT_MS 10000
|
||||
#define MG_IMXRT_WDOG1_TIMEOUT_MS 10000U
|
||||
#endif
|
||||
|
||||
#if defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
|
||||
#define MG_IMXRT_RTWDOG1_UNLOCK() \
|
||||
do { \
|
||||
if ((RTWDOG1->CS & RTWDOG_CS_CMD32EN_MASK) != 0U) { \
|
||||
RTWDOG1->CNT = RTWDOG_UPDATE_KEY; \
|
||||
} else { \
|
||||
RTWDOG1->CNT = RTWDOG_UPDATE_KEY & 0xffffU; \
|
||||
RTWDOG1->CNT = RTWDOG_UPDATE_KEY >> 16; \
|
||||
} \
|
||||
while ((RTWDOG1->CS & RTWDOG_CS_ULK_MASK) == 0U) (void) 0; \
|
||||
} while (0)
|
||||
|
||||
#define MG_IMXRT_RTWDOG1_FEED() \
|
||||
do { \
|
||||
uint32_t primask_ = __get_PRIMASK(); \
|
||||
__disable_irq(); \
|
||||
if ((RTWDOG1->CS & RTWDOG_CS_CMD32EN_MASK) != 0U) { \
|
||||
RTWDOG1->CNT = RTWDOG_REFRESH_KEY; \
|
||||
} else { \
|
||||
RTWDOG1->CNT = RTWDOG_REFRESH_KEY & 0xffffU; \
|
||||
RTWDOG1->CNT = RTWDOG_REFRESH_KEY >> 16; \
|
||||
} \
|
||||
if (primask_ == 0U) __enable_irq(); \
|
||||
} while (0)
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_START
|
||||
#define MG_OTA_ROLLBACK_TIMER_START() \
|
||||
do { \
|
||||
uint32_t primask_ = __get_PRIMASK(); \
|
||||
SRC_GENERAL_REG->SRMASK &= ~SRC_GENERAL_SRMASK_WDOG1_MASK_MASK; \
|
||||
__disable_irq(); \
|
||||
MG_IMXRT_RTWDOG1_UNLOCK(); \
|
||||
RTWDOG1->WIN = 0U; \
|
||||
RTWDOG1->TOVAL = (MG_IMXRT_WDOG1_TIMEOUT_MS + 7U) / 8U; \
|
||||
RTWDOG1->CS = RTWDOG_CS_EN_MASK | RTWDOG_CS_UPDATE_MASK | \
|
||||
RTWDOG_CS_CLK(1U) | RTWDOG_CS_PRES_MASK | \
|
||||
RTWDOG_CS_CMD32EN_MASK; \
|
||||
while ((RTWDOG1->CS & RTWDOG_CS_RCS_MASK) == 0U) (void) 0; \
|
||||
if (primask_ == 0U) __enable_irq(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_FEED
|
||||
#define MG_OTA_ROLLBACK_TIMER_FEED() MG_IMXRT_RTWDOG1_FEED()
|
||||
#endif
|
||||
|
||||
// GPR5 survives RTWDOG global resets and is not reserved by the boot ROM.
|
||||
#ifndef MG_OTA_STATE_GET
|
||||
#define MG_OTA_STATE_GET() SRC_GENERAL_REG->GPR[5]
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_STATE_SET
|
||||
#define MG_OTA_STATE_SET(v) (SRC_GENERAL_REG->GPR[5] = (uint32_t) (v))
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define MG_IMXRT_WDOG1_FEED() \
|
||||
do { \
|
||||
WDOG1->WSR = 0x5555; \
|
||||
|
|
@ -562,6 +641,8 @@ static inline uint32_t mg_ota_esp32_state_set(uint32_t state) {
|
|||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ARCH == MG_ARCH_PICOSDK
|
||||
#if !defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP
|
||||
|
|
@ -4667,6 +4748,7 @@ extern void mg_mqtt_poll(struct mg_mgr *);
|
|||
#define MG_OTA_RT1060 302 // IMXRT1060
|
||||
#define MG_OTA_RT1064 303 // IMXRT1064
|
||||
#define MG_OTA_RT1170 304 // IMXRT1170
|
||||
#define MG_OTA_RT1180 305 // IMXRT1180
|
||||
#define MG_OTA_MCXN 310 // MCXN947
|
||||
#define MG_OTA_RW612 320 // FRDM-RW612
|
||||
#define MG_OTA_FLASH 900 // OTA via internal flash
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#endif
|
||||
|
||||
#if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_IMXRT10) && \
|
||||
!defined(MG_ENABLE_DRIVER_IMXRT11)
|
||||
!defined(MG_ENABLE_DRIVER_IMXRT11) && !defined(MG_ENABLE_DRIVER_NETC)
|
||||
#if defined(CPU_MIMXRT1021DAG5A) || defined(CPU_MIMXRT1024DAG5A) || \
|
||||
defined(CPU_MIMXRT1042XJM5B) || defined(CPU_MIMXRT1052DVL6B) || \
|
||||
defined(CPU_MIMXRT1062DVL6B) || defined(CPU_MIMXRT1064DVL6B) || \
|
||||
|
|
@ -51,6 +51,8 @@
|
|||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_)
|
||||
#define MG_ENABLE_DRIVER_IMXRT11 1
|
||||
#elif defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
#define MG_ENABLE_DRIVER_NETC 1
|
||||
#else
|
||||
#error Select an Ethernet driver in mongoose_config.h
|
||||
#endif
|
||||
|
|
@ -82,13 +84,31 @@
|
|||
defined(_MIMXRT1176_cm7_H_) || defined(_MIMXRT1176_cm4_H_) || \
|
||||
defined(_MIMXRT1176_H_))
|
||||
#define MG_OTA MG_OTA_RT1170
|
||||
#elif !defined(MG_OTA) && \
|
||||
(defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_))
|
||||
#define MG_OTA MG_OTA_RT1180
|
||||
#endif
|
||||
|
||||
#ifndef MG_IRAM
|
||||
#if defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
#define MG_IRAM \
|
||||
__attribute__((noinline, section(".data.$SRAM_ITC_cm33")))
|
||||
#else
|
||||
#define MG_IRAM __attribute__((noinline, section(".data_RAM2")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_ETH_RAM
|
||||
#if defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
#define MG_ETH_RAM __attribute__((section(".bss.$ETH_RAM")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_SET_MAC_ADDRESS
|
||||
#if defined(MG_ENABLE_DRIVER_NETC) && MG_ENABLE_DRIVER_NETC
|
||||
// No OCOTP_FUSES present on RT1186 to generate the UUID
|
||||
#define MG_SET_MAC_ADDRESS(mac) (void) (mac)
|
||||
#else
|
||||
#if defined(MG_ENABLE_DRIVER_IMXRT11) && MG_ENABLE_DRIVER_IMXRT11
|
||||
#define MG_OCOTP_FUSES ((volatile uint32_t *) 0x40cac900)
|
||||
#else
|
||||
|
|
@ -104,11 +124,70 @@
|
|||
mac[5] = (MG_OCOTP_FUSES[4] >> 0) & 255; \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MG_IMXRT_WDOG1_TIMEOUT_MS
|
||||
#define MG_IMXRT_WDOG1_TIMEOUT_MS 10000
|
||||
#define MG_IMXRT_WDOG1_TIMEOUT_MS 10000U
|
||||
#endif
|
||||
|
||||
#if defined(CPU_MIMXRT1186CVJ8C_cm33) || defined(MIMXRT1186_cm33_H_)
|
||||
|
||||
#define MG_IMXRT_RTWDOG1_UNLOCK() \
|
||||
do { \
|
||||
if ((RTWDOG1->CS & RTWDOG_CS_CMD32EN_MASK) != 0U) { \
|
||||
RTWDOG1->CNT = RTWDOG_UPDATE_KEY; \
|
||||
} else { \
|
||||
RTWDOG1->CNT = RTWDOG_UPDATE_KEY & 0xffffU; \
|
||||
RTWDOG1->CNT = RTWDOG_UPDATE_KEY >> 16; \
|
||||
} \
|
||||
while ((RTWDOG1->CS & RTWDOG_CS_ULK_MASK) == 0U) (void) 0; \
|
||||
} while (0)
|
||||
|
||||
#define MG_IMXRT_RTWDOG1_FEED() \
|
||||
do { \
|
||||
uint32_t primask_ = __get_PRIMASK(); \
|
||||
__disable_irq(); \
|
||||
if ((RTWDOG1->CS & RTWDOG_CS_CMD32EN_MASK) != 0U) { \
|
||||
RTWDOG1->CNT = RTWDOG_REFRESH_KEY; \
|
||||
} else { \
|
||||
RTWDOG1->CNT = RTWDOG_REFRESH_KEY & 0xffffU; \
|
||||
RTWDOG1->CNT = RTWDOG_REFRESH_KEY >> 16; \
|
||||
} \
|
||||
if (primask_ == 0U) __enable_irq(); \
|
||||
} while (0)
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_START
|
||||
#define MG_OTA_ROLLBACK_TIMER_START() \
|
||||
do { \
|
||||
uint32_t primask_ = __get_PRIMASK(); \
|
||||
SRC_GENERAL_REG->SRMASK &= ~SRC_GENERAL_SRMASK_WDOG1_MASK_MASK; \
|
||||
__disable_irq(); \
|
||||
MG_IMXRT_RTWDOG1_UNLOCK(); \
|
||||
RTWDOG1->WIN = 0U; \
|
||||
RTWDOG1->TOVAL = (MG_IMXRT_WDOG1_TIMEOUT_MS + 7U) / 8U; \
|
||||
RTWDOG1->CS = RTWDOG_CS_EN_MASK | RTWDOG_CS_UPDATE_MASK | \
|
||||
RTWDOG_CS_CLK(1U) | RTWDOG_CS_PRES_MASK | \
|
||||
RTWDOG_CS_CMD32EN_MASK; \
|
||||
while ((RTWDOG1->CS & RTWDOG_CS_RCS_MASK) == 0U) (void) 0; \
|
||||
if (primask_ == 0U) __enable_irq(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_ROLLBACK_TIMER_FEED
|
||||
#define MG_OTA_ROLLBACK_TIMER_FEED() MG_IMXRT_RTWDOG1_FEED()
|
||||
#endif
|
||||
|
||||
// GPR5 survives RTWDOG global resets and is not reserved by the boot ROM.
|
||||
#ifndef MG_OTA_STATE_GET
|
||||
#define MG_OTA_STATE_GET() SRC_GENERAL_REG->GPR[5]
|
||||
#endif
|
||||
|
||||
#ifndef MG_OTA_STATE_SET
|
||||
#define MG_OTA_STATE_SET(v) (SRC_GENERAL_REG->GPR[5] = (uint32_t) (v))
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define MG_IMXRT_WDOG1_FEED() \
|
||||
do { \
|
||||
WDOG1->WSR = 0x5555; \
|
||||
|
|
@ -150,3 +229,5 @@
|
|||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#define MG_OTA_RT1060 302 // IMXRT1060
|
||||
#define MG_OTA_RT1064 303 // IMXRT1064
|
||||
#define MG_OTA_RT1170 304 // IMXRT1170
|
||||
#define MG_OTA_RT1180 305 // IMXRT1180
|
||||
#define MG_OTA_MCXN 310 // MCXN947
|
||||
#define MG_OTA_RW612 320 // FRDM-RW612
|
||||
#define MG_OTA_FLASH 900 // OTA via internal flash
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "log.h"
|
||||
#include "ota.h"
|
||||
|
||||
#if MG_OTA >= MG_OTA_RT1020 && MG_OTA <= MG_OTA_RT1170
|
||||
#if MG_OTA >= MG_OTA_RT1020 && MG_OTA <= MG_OTA_RT1180
|
||||
|
||||
static bool mg_imxrt_write(void *, const void *, size_t);
|
||||
static bool mg_imxrt_swap(void);
|
||||
|
|
@ -13,9 +13,12 @@ static bool mg_imxrt_swap(void);
|
|||
#elif MG_OTA == MG_OTA_RT1064
|
||||
#define MG_IMXRT_FLASH_START 0x70000000
|
||||
#define FLEXSPI_NOR_INSTANCE 1
|
||||
#else // RT1170
|
||||
#elif MG_OTA == MG_OTA_RT1170
|
||||
#define MG_IMXRT_FLASH_START 0x30000000
|
||||
#define FLEXSPI_NOR_INSTANCE 1
|
||||
#else // RT1180 FlexSPI2
|
||||
#define MG_IMXRT_FLASH_START 0x04000000
|
||||
#define FLEXSPI_NOR_INSTANCE 2
|
||||
#endif
|
||||
|
||||
#if MG_OTA == MG_OTA_RT1050
|
||||
|
|
@ -324,7 +327,7 @@ struct mg_flexspi_nor_driver_interface {
|
|||
uint32_t *option);
|
||||
};
|
||||
#else
|
||||
// RT117x support ROM API version 1.7
|
||||
// RT117x and RT118x
|
||||
struct mg_flexspi_nor_driver_interface {
|
||||
uint32_t version;
|
||||
int (*init)(uint32_t instance, struct mg_flexspi_nor_config *config);
|
||||
|
|
@ -359,11 +362,16 @@ struct mg_flexspi_nor_driver_interface {
|
|||
#define flexspi_nor \
|
||||
(*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x0020001c + \
|
||||
16)))
|
||||
#else
|
||||
#elif MG_OTA == MG_OTA_RT1170
|
||||
#define MG_FLEXSPI_BASE 0x400CC000
|
||||
#define flexspi_nor \
|
||||
(*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x0021001c + \
|
||||
12)))
|
||||
#else
|
||||
#define MG_FLEXSPI_BASE 0x445E0000
|
||||
#define flexspi_nor \
|
||||
(*((struct mg_flexspi_nor_driver_interface **) (*(uint32_t *) 0x1000001c + \
|
||||
12)))
|
||||
#endif
|
||||
|
||||
static bool s_flash_irq_disabled;
|
||||
|
|
@ -408,6 +416,13 @@ static struct mg_flexspi_nor_config default_config = {
|
|||
#else
|
||||
// Note: this QSPI configuration works for RTs supporting QSPI
|
||||
// Configuration for QSPI memory
|
||||
#if MG_OTA == MG_OTA_RT1180
|
||||
#define MG_FLEXSPI_QSPI_SERIAL_CLK_FREQ 5 // 100MHz
|
||||
#define MG_FLEXSPI_QSPI_FLASH_SIZE (16 * 1024 * 1024)
|
||||
#else
|
||||
#define MG_FLEXSPI_QSPI_SERIAL_CLK_FREQ 7 // 133MHz
|
||||
#define MG_FLEXSPI_QSPI_FLASH_SIZE (8 * 1024 * 1024)
|
||||
#endif
|
||||
static struct mg_flexspi_nor_config default_config = {
|
||||
.memConfig = {.tag = MG_FLEXSPI_CFG_BLK_TAG,
|
||||
.version = MG_FLEXSPI_CFG_BLK_VERSION,
|
||||
|
|
@ -417,8 +432,8 @@ static struct mg_flexspi_nor_config default_config = {
|
|||
.controllerMiscOption = MG_BIT(4),
|
||||
.deviceType = 1, // serial NOR
|
||||
.sflashPadType = 4,
|
||||
.serialClkFreq = 7, // 133MHz
|
||||
.sflashA1Size = 8 * 1024 * 1024,
|
||||
.serialClkFreq = MG_FLEXSPI_QSPI_SERIAL_CLK_FREQ,
|
||||
.sflashA1Size = MG_FLEXSPI_QSPI_FLASH_SIZE,
|
||||
.lookupTable = MG_FLEXSPI_QSPI_LUT},
|
||||
.pageSize = 256,
|
||||
.sectorSize = 4 * 1024,
|
||||
|
|
@ -453,6 +468,7 @@ MG_IRAM static int flexspi_nor_get_config(
|
|||
}
|
||||
#endif
|
||||
|
||||
#if MG_OTA == MG_OTA_RT1020 || MG_OTA == MG_OTA_RT1050
|
||||
MG_IRAM static void mg_spin(volatile uint32_t count) {
|
||||
while (count--) (void) 0;
|
||||
}
|
||||
|
|
@ -461,6 +477,7 @@ MG_IRAM static void flash_wait(void) {
|
|||
while ((*((volatile uint32_t *) (MG_FLEXSPI_BASE + 0xE0)) & MG_BIT(1)) == 0)
|
||||
mg_spin(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
MG_IRAM static bool flash_erase(struct mg_flexspi_nor_config *config,
|
||||
void *addr) {
|
||||
|
|
@ -509,6 +526,8 @@ MG_IRAM static bool mg_imxrt_write(void *addr, const void *buf, size_t len) {
|
|||
uint32_t *dst = (uint32_t *) addr;
|
||||
uint32_t *src = (uint32_t *) buf;
|
||||
uint32_t *end = (uint32_t *) ((char *) buf + len);
|
||||
char *flash_start = (char *) s_mg_flash_imxrt.start;
|
||||
char *flash_end = flash_start + s_mg_flash_imxrt.size;
|
||||
ok = true;
|
||||
|
||||
while (ok && src < end) {
|
||||
|
|
@ -516,20 +535,32 @@ MG_IRAM static bool mg_imxrt_write(void *addr, const void *buf, size_t len) {
|
|||
ok = false;
|
||||
break;
|
||||
}
|
||||
uint32_t status;
|
||||
uint32_t status = 0;
|
||||
uint32_t dst_ofs = (uint32_t) dst - (uint32_t) s_mg_flash_imxrt.start;
|
||||
if ((char *) buf >= (char *) s_mg_flash_imxrt.start) {
|
||||
if ((char *) buf >= flash_start && (char *) buf < flash_end) {
|
||||
// If we copy from FLASH to FLASH, then we first need to copy the source
|
||||
// to RAM
|
||||
size_t tmp_buf_size = s_mg_flash_imxrt.align / sizeof(uint32_t);
|
||||
uint32_t tmp[tmp_buf_size];
|
||||
|
||||
#if MG_OTA == MG_OTA_RT1020 || MG_OTA == MG_OTA_RT1050
|
||||
// ROM API 1.4 does not provide flexspi_nor_flash_read().
|
||||
// Manually copy byte by byte into the RAM buffer.
|
||||
for (size_t i = 0; i < tmp_buf_size; i++) {
|
||||
flash_wait();
|
||||
tmp[i] = src[i];
|
||||
}
|
||||
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
|
||||
(uint32_t) dst_ofs, tmp);
|
||||
#else
|
||||
// When supported, prefer the read API call.
|
||||
uint32_t src_ofs =
|
||||
(uint32_t) src - (uint32_t) s_mg_flash_imxrt.start;
|
||||
status = flexspi_nor->read(FLEXSPI_NOR_INSTANCE, config_ptr, tmp,
|
||||
src_ofs, s_mg_flash_imxrt.align);
|
||||
#endif
|
||||
if (status == 0) {
|
||||
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
|
||||
dst_ofs, tmp);
|
||||
}
|
||||
} else {
|
||||
status = flexspi_nor->program(FLEXSPI_NOR_INSTANCE, config_ptr,
|
||||
(uint32_t) dst_ofs, src);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue