![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
spimaster
Dependencies: mbed SDFileSystem
Diff: SDspimaster.cpp
- Revision:
- 2:6d633bb5c09d
- Child:
- 3:4c39249bcd56
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDspimaster.cpp Sun Dec 05 03:05:32 2021 +0000 @@ -0,0 +1,192 @@ +#include "SDspimaster.h" +#include "mbed_debug.h" + +// Register Address +const uint8_t TRANS_TYPE_REG = 0x2; +const uint8_t TRANS_CTRL_REG =0x3; +const uint8_t TRANS_STS_REG =0x4; +const uint8_t TRANS_ERROR_REG =0x5; +const uint8_t RX_FIFO_DATA_REG =0x10; +const uint8_t TX_FIFO_DATA_REG =0x20; +const uint8_t ADDR_7_0_REG =0x7; +const uint8_t ADDR_15_8_REG =0x8; +const uint8_t ADDR_23_16_REG =0x9; +const uint8_t ADDR_31_24_REG =0xa; + + + +// Reg Value states +// TRANS_TYPE_REG +const uint8_t DIRECT_ACCESS =0; +const uint8_t INIT_SD =1; +const uint8_t READ_SD_BLOCK =2; +const uint8_t WRITE_SD_BLOCK =3; + +//TRANS_CTRL_REG +const uint8_t TRANS_START =1; + +//TRANS_STS_REG +const uint8_t TRANS_BUSY =1; + +//TRANS_ERROR_REG +const uint8_t NO_ERROR =0; + +//the variable below should be replaced by a specific pin +// the name is the same as the data sheet of spimaster + +uint8_t clk_i; +uint8_t address_i; +uint8_t data_i; +uint8_t data_o; +uint8_t write_en; +uint8_t rst_i; + + + +SDspimaster::SDspimaster(const char* name) : + FATFileSystem(name), _is_initialized(0) { + rst_i = 1; + rst_i = 0; + +} + +void read_reg(uint8_t addr, uint8_t* value){ + clk_i = 1; + write_en = 0; + address_i = addr; + clk_i = 0; + *value = data_o; + +} + +void write_reg(uint8_t addr, uint8_t value){ + clk_i = 1; + address_i = addr; + data_i = value; + write_en = 1; + clk_i = 0; + +} + +void write_address(uint32_t addr) { + write_reg(ADDR_7_0_REG, (addr >> 0) & 0xff); + write_reg(ADDR_15_8_REG, (addr >> 8) & 0xff); + write_reg(ADDR_23_16_REG, (addr >> 16) & 0xff); + write_reg(ADDR_31_24_REG, (addr >> 25) & 0xff); +} + +int write_block(uint32_t addr, const uint8_t* buffer) { + uint8_t state; + for(uint32_t i = 0; i <= 512; i++) { + write_reg(TX_FIFO_DATA_REG, buffer[i]); + } + write_address(addr); + write_reg( TRANS_TYPE_REG, WRITE_SD_BLOCK); + write_reg(TRANS_CTRL_REG, TRANS_START); + read_reg(TRANS_STS_REG, &state); + while(state == TRANS_BUSY) + read_reg(TRANS_STS_REG, &state); + read_reg(TRANS_ERROR_REG,&state); + + if((state>>4) & 0x3 != NO_ERROR) + return 1; + + return 0; +} + +int read_block(uint32_t addr, uint8_t* buffer) { + uint8_t state; + write_address(addr); + write_reg( TRANS_TYPE_REG, READ_SD_BLOCK); + write_reg(TRANS_CTRL_REG, TRANS_START); + read_reg(TRANS_STS_REG, &state); + while(state == TRANS_BUSY) + read_reg(TRANS_STS_REG, &state); + read_reg(TRANS_ERROR_REG,&state); + if((state>>2) & 0x3 != NO_ERROR) + return 1; + + for(uint32_t i = 0; i <= 512; i++) { + read_reg(RX_FIFO_DATA_REG, &buffer[i]); + } + + + return 0; +} + +int SDspimaster::disk_initialize() { + uint8_t state; + write_reg( TRANS_TYPE_REG, INIT_SD); + write_reg(TRANS_CTRL_REG, TRANS_START); + read_reg(TRANS_STS_REG, &state); + while(state == TRANS_BUSY) + read_reg(TRANS_STS_REG, &state); + read_reg(TRANS_ERROR_REG,&state); + + if(state & 0x3 != NO_ERROR) + return 1; + + _is_initialized = 1; + return 0; +} + +int SDspimaster::disk_status() { + //returns 0 when initialized + if (_is_initialized) { + return 0; + } else { + return 1; + } +} + +int SDspimaster::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) { + if (!_is_initialized) { + return -1; + } + + for (uint32_t b = block_number; b < block_number + count; b++) { + // set write address for single block (CMD24) + + if (write_block(b, buffer) != 0) { + return 1; + } + + // send the data block + buffer += 512; + } + + return 0; +} + +int SDspimaster::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) { + if (!_is_initialized) { + return -1; + } + + for (uint32_t b = block_number; b < block_number + count; b++) { + // set write address for single block (CMD24) + + + if (read_block(b, buffer) != 0) { + return 1; + } + + // send the data block + buffer += 512; + } + + return 0; +} + +int SDspimaster::disk_sync() { return 0; } + +// Not implement right +uint32_t SDspimaster::disk_sectors() { return -1; } + + + + + + + +