spimaster

Dependencies:   mbed SDFileSystem

Revision:
2:6d633bb5c09d
Child:
3:4c39249bcd56
diff -r e4d7342be507 -r 6d633bb5c09d SDspimaster.cpp
--- /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; }
+
+
+
+
+
+
+
+