int flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { status_t status; flexspi_transfer_t flashXfer; SetFlexSPIDiv(DIV_ERASE_PGM); /* Write enable */ status = flexspi_nor_write_enable(base, address); if (status != kStatus_Success) { return status; } flashXfer.deviceAddress = address; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Command; flashXfer.SeqNumber = 4; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return -1; } status = flexspi_nor_wait_bus_busy(base); SetFlexSPIDiv(DIV_READ); return 0; }
int flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src) { status_t status; flexspi_transfer_t flashXfer; SetFlexSPIDiv(DIV_ERASE_PGM); /* Write neable */ status = flexspi_nor_write_enable(base, address); if (status != kStatus_Success) { return status; } /* Prepare page program command */ flashXfer.deviceAddress = address; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 2; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM; flashXfer.data = (uint32_t *)src; flashXfer.dataSize = FLASH_PAGE_SIZE; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return -1; } status = flexspi_nor_wait_bus_busy(base); SetFlexSPIDiv(DIV_READ); return 0; }
static status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; status_t status; uint32_t writeValue = 0x40; /* Write neable */ status = flexspi_nor_write_enable(base, 0); if (status != kStatus_Success) { return status; } /* Enable quad mode. */ flashXfer.deviceAddress = 0; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG; flashXfer.data = &writeValue; flashXfer.dataSize = 1; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { dbg_log(DBG_ERROR, "flexspi tranfer error\n"); dbg_here return status; }
SECTION("itcm") status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address) { status_t status; flexspi_transfer_t flashXfer; rt_uint32_t level; level = rt_hw_interrupt_disable(); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); /* Write enable */ status = flexspi_nor_write_enable(base, address); if (status != kStatus_Success) { FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; } flashXfer.deviceAddress = address; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Command; flashXfer.SeqNumber = 4; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_ERASESECTOR; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; } status = flexspi_nor_wait_bus_busy(base); rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLEXSPI_NOR_SECTOR_SIZE); rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLEXSPI_NOR_SECTOR_SIZE); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; }
static status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) { /* Wait status ready. */ bool isBusy; uint32_t readValue; status_t status; flexspi_transfer_t flashXfer; flashXfer.deviceAddress = 0; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Read; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG; flashXfer.data = &readValue; flashXfer.dataSize = 1; do { status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } if (FLASH_BUSY_STATUS_POL) { if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { isBusy = true; } else { isBusy = false; } } else { if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { isBusy = false; } else { isBusy = true; } } } while (isBusy); return status; }
SECTION("itcm") status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr) { flexspi_transfer_t flashXfer; status_t status; /* Write neable */ flashXfer.deviceAddress = baseAddr; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Command; flashXfer.SeqNumber = 2; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEENABLE; status = FLEXSPI_TransferBlocking(base, &flashXfer); return status; }
SECTION("itcm") status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src) { status_t status; flexspi_transfer_t flashXfer; rt_uint32_t level; level = rt_hw_interrupt_disable(); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); /* Write neable */ status = flexspi_nor_write_enable(base, address); if (status != kStatus_Success) { rt_hw_interrupt_enable(level); return status; } /* Prepare page program command */ flashXfer.deviceAddress = address; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 2; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_PAGEPROGRAM; flashXfer.data = (uint32_t *)src; flashXfer.dataSize = FLASH_PAGE_SIZE; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { rt_hw_interrupt_enable(level); return status; } status = flexspi_nor_wait_bus_busy(base); rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLASH_PAGE_SIZE); rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE,(void *)(FLEXSPI_AMBA_BASE+address),FLASH_PAGE_SIZE); FLEXSPI_Enable(FLEXSPI, false); CLOCK_DisableClock(FLEXSPI_CLOCK); CLOCK_SetDiv(kCLOCK_FlexspiDiv, 0); /* flexspi clock 332M, DDR mode, internal clock 166M. */ CLOCK_EnableClock(FLEXSPI_CLOCK); FLEXSPI_Enable(FLEXSPI, true); FLEXSPI_SoftwareReset(FLEXSPI); rt_hw_interrupt_enable(level); return status; }
status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base) { /* Wait status ready. */ bool isBusy; uint32_t readValue; status_t status; flexspi_transfer_t flashXfer; flashXfer.deviceAddress = 0; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Read; flashXfer.SeqNumber = 2; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_READSTATUS; flashXfer.data = &readValue; flashXfer.dataSize = 2; do { status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } if (readValue & 0x8000) { isBusy = false; } else { isBusy = true; } if (readValue & 0x3200) { status = kStatus_Fail; break; } } while (isBusy); return status; }
SECTION("itcm") status_t flexspi_nor_hyperbus_write(FLEXSPI_Type *base, uint32_t addr, uint32_t *buffer, uint32_t bytes) { flexspi_transfer_t flashXfer; status_t status; flashXfer.deviceAddress = addr * 2; flashXfer.port = kFLEXSPI_PortA1; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = HYPERFLASH_CMD_LUT_SEQ_IDX_WRITEDATA; flashXfer.data = buffer; flashXfer.dataSize = bytes; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } return status; }