-
-
Save anonymous/be60193ced7dbe85670b75ddea4d86db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "FlashManager.hpp" | |
extern "C" { | |
#include "spi_master.h" | |
} | |
FlashManager::FlashManager(freertos_spi_if *spi, SPI_C * spi_c_in) { | |
freertos_spi = spi; | |
spi_c = spi_c_in; | |
device.id = 0; | |
spi_disable(spi_c->OurSPI); | |
spi_set_clock_polarity(spi_c->OurSPI, device.id, 0); //Clock Polarity 0 | |
spi_set_clock_phase(spi_c->OurSPI, device.id, 1); // !Clock Phase 0 | |
spi_set_bits_per_transfer(spi_c->OurSPI, device.id, SPI_CSR_BITS_8_BIT); | |
spi_set_baudrate_div(spi_c->OurSPI, device.id, 2); | |
spi_set_transfer_delay(spi_c->OurSPI, device.id, 0x400, 0x100); | |
spi_configure_cs_behavior(spi_c->OurSPI, device.id, SPI_CS_KEEP_LOW); | |
spi_set_peripheral_chip_select_value(spi_c->OurSPI, spi_get_pcs(device.id)); | |
spi_enable(spi_c->OurSPI); | |
spi_enable_clock(spi_c->OurSPI); | |
U8 readData[2]; | |
FlashCommand cmd; | |
cmd.opcode = READ_SR; | |
cmd.address=0; | |
writeOpcode(cmd); | |
spi_read_packet(SPI, &readData[0], 2); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
//testFlashComms(); | |
} | |
void FlashManager::testFlashComms() { | |
U8 testData[256]; | |
U8 readData[256]; | |
for(int i=0; i < 256; i++) { | |
testData[i] = i; | |
} | |
eraseFlash(); | |
FlashCommand cmd; | |
cmd.opcode = READ_SR; | |
cmd.address=0; | |
writeOpcode(cmd); | |
uint32_t data = 0; | |
spi_read_packet(SPI, (uint8_t*)&data, 1); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
clearLockBits(); | |
clearLockBits(); | |
writeOpcode(cmd); | |
spi_read_packet(SPI, &readData[0], 2); | |
eraseBlock(0); | |
writeDataToFlash(0, &(testData[0]), 256); | |
waitForNotBusy(); | |
cmd.opcode = FASTER_READ_ARRAY; | |
cmd.address = 0;//0x8DFF; | |
writeFullCommand(cmd,1); | |
spi_read_packet(SPI, &readData[0], 256); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
for(int i=0; i<256; i++) { | |
printf("Test value[%d]: %d : %d : %d\n", i, testData[i], readData[i], (testData[i] == readData[i])); | |
} | |
} | |
void FlashManager::readStatusRegisters() { | |
U8 readData[2]; | |
FlashCommand cmd; | |
cmd.opcode = READ_SR; | |
cmd.address=0; | |
writeOpcode(cmd); | |
spi_read_packet(SPI, &readData[0], 2); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
} | |
void FlashManager::readSecurityRegisters() { | |
U8 readData[2]; | |
FlashCommand cmd; | |
cmd.opcode = READ_SECTOR_PROTECT; | |
cmd.address = 0; | |
for(; cmd.address < (8*1024*1024);cmd.address+=(64*1024)) { | |
writeFullCommand(cmd,0); | |
spi_read_packet(SPI, &readData[0], 1); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
} | |
cmd.opcode = READ_SECTOR_LOCKDOWN; | |
cmd.address = 0; | |
for(; cmd.address < (8*1024*1024);cmd.address+=(64*1024)) { | |
writeFullCommand(cmd,0); | |
spi_read_packet(SPI, &readData[0], 1); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
} | |
} | |
void FlashManager::clearLockBits() { | |
U8 lockCmd[3]; | |
writeEnable(); | |
lockCmd[0] = WRITE_SR1; | |
lockCmd[1] = 0x02; | |
spi_deselect_device(SPI, &device); | |
spi_select_device(SPI, &device); | |
spi_write_packet(SPI, &(lockCmd[0]), 2); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
spi_deselect_device(SPI, &device); | |
waitForNotBusy(); | |
// writeEnable(); | |
// lockCmd[0] = WRITE_SR2; | |
// lockCmd[1] = 0x00; | |
// spi_deselect_device(SPI, &device); | |
// spi_select_device(SPI, &device); | |
// spi_write_packet(SPI, &(lockCmd[0]), 2); | |
// while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
// spi_deselect_device(SPI, &device); | |
// waitForNotBusy(); | |
} | |
void FlashManager::unlockAllSectors() { | |
// FlashCommand cmd; | |
// cmd.opcode = UNPROTECT_SECTOR; | |
// cmd.address = 0; | |
// for(; cmd.address < (8*1024*1024);cmd.address+=(64*1024)) { | |
// writeEnable(); | |
// writeFullCommand(cmd,0); | |
// spi_deselect_device(SPI, &device); | |
// waitForNotBusy(); | |
// } | |
} | |
void FlashManager::writeEnable() { | |
FlashCommand cmd; | |
cmd.opcode = WRITE_ENABLE; | |
writeOpcode(cmd); | |
} | |
//Seriosuly, watch out. Data must be programmed on 256 byte boundaries and must be erased first. | |
//len is length in bytes | |
void FlashManager::writeDataToFlash(U32 addr, U8*data, U32 len) { | |
FlashCommand cmd; | |
writeEnable(); | |
cmd.opcode = PROGRAM; | |
cmd.address = addr; | |
writeFullCommand(cmd, 0); | |
spi_write_packet(SPI, data, len); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
} | |
void FlashManager::readDataFromFlash(U32 addr, U8 *data, U32 len) { | |
FlashCommand cmd; | |
cmd.opcode = FASTER_READ_ARRAY; | |
cmd.address = addr; | |
writeFullCommand(cmd,1); | |
spi_read_packet(SPI, &data[0], len); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
} | |
void FlashManager::writeOpcode(FlashCommand cmd) { | |
spi_deselect_device(SPI, &device); | |
spi_select_device(SPI, &device); | |
spi_write_packet(SPI, &cmd.data[0], 1); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
} | |
void FlashManager::writeFullCommand(FlashCommand cmd, U8 dummy) { | |
U8 t = cmd.data[3]; | |
cmd.data[3] = cmd.data[1]; | |
cmd.data[1] = t; | |
spi_deselect_device(SPI, &device); | |
spi_select_device(SPI, &device); | |
spi_write_packet(SPI, &cmd.data[0], 4); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
if(dummy != 0) { | |
spi_write_packet(SPI, &cmd.data[0], dummy); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
} | |
} | |
void FlashManager::waitForNotBusy() { | |
FlashCommand cmd; | |
U8 readData; | |
int busy = 1; | |
cmd.opcode = READ_SR; | |
cmd.address=0; | |
writeOpcode(cmd); | |
while(busy) { | |
spi_read_packet(SPI, &readData, 1); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 1); | |
if(!(readData & 0x1)) | |
busy = 0; | |
} | |
} | |
void FlashManager::eraseBlock(U32 addr) { | |
writeEnable(); | |
FlashCommand cmd; | |
cmd.opcode = BLOCK_ERASE_4K; | |
cmd.address = 0; | |
spi_deselect_device(SPI, &device); | |
spi_select_device(SPI, &device); | |
spi_write_packet(SPI, &cmd.data[0], 4); | |
spi_deselect_device(SPI, &device); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
waitForNotBusy(); | |
} | |
void FlashManager::eraseFlash() { | |
writeEnable(); | |
FlashCommand cmd; | |
cmd.opcode = CHIP_ERASE; | |
cmd.address = 0; | |
spi_deselect_device(SPI, &device); | |
spi_select_device(SPI, &device); | |
spi_write_packet(SPI, &cmd.data[0], 1); | |
while((spi_read_status(spi_c->OurSPI) & SPI_SR_RDRF) == 0); | |
spi_deselect_device(SPI, &device); | |
waitForNotBusy(); | |
} | |
void FlashManager::sleep(void) { | |
FlashCommand cmd; | |
cmd.opcode = DEEP_POWER_DOWN; | |
writeOpcode(cmd); | |
} | |
void FlashManager::wake(void) { | |
FlashCommand cmd; | |
cmd.opcode = RESUME_FROM_DEEP_POWER_DOWN; | |
writeOpcode(cmd); | |
waitForNotBusy(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment