Artur,
This is the code I use:
#include "System.h"
#include "fsl_flexspi.h"
#include "fsl_rtwdog.h"
#include "fsl_wdog.h"
#include "evkmimxrt1064_flexspi_nor_config.h"
#include "IAP.h"
typedef struct {
void (*RTWDOG_GetDefaultConfig)(rtwdog_config_t *config);
void (*RTWDOG_Init)(RTWDOG_Type *base, const rtwdog_config_t *config);
void (*RTWDOG_Deinit)(RTWDOG_Type *base);
void (*RTWDOG_Enable)(RTWDOG_Type *base);
void (*RTWDOG_Disable)(RTWDOG_Type *base);
void (*RTWDOG_EnableInterrupts)(RTWDOG_Type *base, uint32_t mask);
void (*RTWDOG_DisableInterrupts)(RTWDOG_Type *base, uint32_t mask);
uint32_t (*RTWDOG_GetStatusFlags)(RTWDOG_Type *base);
void (*RTWDOG_ClearStatusFlags)(RTWDOG_Type *base, uint32_t mask);
void (*RTWDOG_SetTimeoutValue)(RTWDOG_Type *base, uint16_t timeoutCount);
void (*RTWDOG_SetWindowValue)(RTWDOG_Type *base, uint16_t windowValue);
void (*RTWDOG_Unlock)(RTWDOG_Type *base);
void (*RTWDOG_Refresh)(RTWDOG_Type *base);
uint16_t (*RTWDOG_GetCounterValue)(RTWDOG_Type *base);
} rtwdog_driver_interface_t;
typedef struct {
void (*WDOG_GetDefaultConfig)(wdog_config_t *config);
void (*WDOG_Init)(WDOG_Type *base, const wdog_config_t *config);
void (*WDOG_Deinit)(WDOG_Type *base);
void (*WDOG_Enable)(WDOG_Type *base);
void (*WDOG_Disable)(WDOG_Type *base);
void (*WDOG_EnableInterrupts)(WDOG_Type *base, uint16_t mask);
uint16_t (*WDOG_GetStatusFlags)(WDOG_Type *base);
void (*WDOG_ClearInterruptStatus)(WDOG_Type *base, uint16_t mask);
void (*WDOG_SetTimeoutValue)(WDOG_Type *base, uint16_t timeoutCount);
void (*WDOG_SetInterrputTimeoutValue)(WDOG_Type *base, uint16_t timeoutCount);
void (*WDOG_DisablePowerDownEnable)(WDOG_Type *base);
void (*WDOG_Refresh)(WDOG_Type *base);
} wdog_driver_interface_t;
typedef struct _serial_nor_config_option {
union {
struct {
uint32_t max_freq : 4;
uint32_t misc_mode : 4;
uint32_t quad_mode_setting : 4;
uint32_t cmd_pads : 4;
uint32_t query_pads : 4;
uint32_t device_type : 4;
uint32_t option_size : 4;
uint32_t tag : 4;
} B;
uint32_t U;
} option0;
union {
struct {
uint32_t dummy_cycles : 8;
uint32_t reserved0 : 8;
uint32_t pinmux_group : 4;
uint32_t reserved1 : 8;
uint32_t flash_connection : 4;
} B;
uint32_t U;
} option1;
} serial_nor_config_option_t;
typedef enum _FlexSPIOperationType {
kFlexSpiOperation_Command,
kFlexSpiOperation_Config,
kFlexSpiOperation_Write,
kFlexSpiOperation_Read,
kFlexSpiOperation_End = kFlexSpiOperation_Read,
} flexspi_operation_t;
typedef struct _FlexSpiXfer {
flexspi_operation_t operation;
uint32_t baseAddress;
uint32_t seqId;
uint32_t seqNum;
bool isParallelModeEnable;
uint32_t *txBuffer;
uint32_t txSize;
uint32_t *rxBuffer;
uint32_t rxSize;
} flexspi_xfer_t;
typedef struct {
uint32_t version;
status_t (*init)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src);
status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config);
status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t lengthInBytes);
status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t addr, uint32_t lengthInBytes);
void (*clear_cache)(uint32_t instance);
status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer);
status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t seqNumber);
status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
} flexspi_nor_driver_interface_t;
typedef struct {
const uint32_t version;
const char *copyright;
void (*runBootloader)(void *arg);
const uint32_t *reserved0;
const flexspi_nor_driver_interface_t *flexSpiNorDriver;
const uint32_t *reserved1[2];
const rtwdog_driver_interface_t *rtwdogDriver;
const wdog_driver_interface_t *wdogDriver;
const uint32_t *reserved2;
} bootloader_api_entry_t;
#define g_bootloaderTree (*(bootloader_api_entry_t**)(0x0020001c))
status_t flexspi_nor_flash_init(uint32_t instance, flexspi_nor_config_t *config) {
return g_bootloaderTree->flexSpiNorDriver->init(instance, config);
}
status_t flexspi_nor_flash_page_program(uint32_t instance, flexspi_nor_config_t*config, uint32_t dstAddr, const uint32_t *src) {
return g_bootloaderTree->flexSpiNorDriver->program(instance, config, dstAddr, src);
}
status_t flexspi_nor_flash_erase_all(uint32_t instance, flexspi_nor_config_t *config) {
return g_bootloaderTree->flexSpiNorDriver->erase_all(instance, config);
}
status_t flexspi_nor_get_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option) {
return g_bootloaderTree->flexSpiNorDriver->get_config(instance, config, option);
}
status_t flexspi_nor_flash_erase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length) {
return g_bootloaderTree->flexSpiNorDriver->erase(instance, config, start, length);
}
status_t flexspi_nor_flash_read(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes) {
return g_bootloaderTree->flexSpiNorDriver->read(instance, config, dst, start, bytes);
}
void flexspi_nor_flash_clear_cache(uint32_t instance) {
g_bootloaderTree->flexSpiNorDriver->clear_cache(instance);
}
static flexspi_nor_config_t config;
static serial_nor_config_option_t option;
static status_t status;
static uint32_t instance = 1;
int initIAP(void) {
option.option0.U = 0xC0000008;
status = flexspi_nor_get_config(instance, &config, &option);
if (status != kStatus_Success) {
messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error erasing, rc=", status);
return status;
}
status = flexspi_nor_flash_init(instance, &config);
if (status != kStatus_Success) {
messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error init, rc=", status);
return status;
}
return kStatus_Success;
}
int eraseIAP(unsigned int startaddress, unsigned int length) {
unsigned int address;
for (address=startaddress - 0x70000000; address<=startaddress - 0x70000000 + length; address+=config.sectorSize) {
status = flexspi_nor_flash_erase(instance, &config, address , config.sectorSize);
if (status != kStatus_Success) {
messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error erasing, rc=%i, address=0x%08X", status, 0x70000000 + address);
return status;
}
}
return kStatus_Success;
}
int programIAP(unsigned int startAddress, unsigned int *page_buffer) {
status = flexspi_nor_flash_page_program(instance, &config, startAddress - 0x70000000, page_buffer);
if (status != kStatus_Success) {
messageDebug(DBG_INFO, __MODULE__, __LINE__, "Error programming, rc=%i, address=0x%08X", status, startAddress);
return status;
}
return kStatus_Success;
}
And according to that, the driverstuff is located at
#define g_bootloaderTree (*(bootloader_api_entry_t**)(0x0020001c))
And according to UM:
