spimaster
Dependencies: mbed SDFileSystem
SDspimaster.cpp@3:4c39249bcd56, 2021-12-05 (annotated)
- Committer:
- yutation
- Date:
- Sun Dec 05 05:11:38 2021 +0000
- Revision:
- 3:4c39249bcd56
- Parent:
- 2:6d633bb5c09d
spimaster
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yutation | 2:6d633bb5c09d | 1 | #include "SDspimaster.h" |
yutation | 2:6d633bb5c09d | 2 | #include "mbed_debug.h" |
yutation | 2:6d633bb5c09d | 3 | |
yutation | 2:6d633bb5c09d | 4 | // Register Address |
yutation | 2:6d633bb5c09d | 5 | const uint8_t TRANS_TYPE_REG = 0x2; |
yutation | 2:6d633bb5c09d | 6 | const uint8_t TRANS_CTRL_REG =0x3; |
yutation | 2:6d633bb5c09d | 7 | const uint8_t TRANS_STS_REG =0x4; |
yutation | 2:6d633bb5c09d | 8 | const uint8_t TRANS_ERROR_REG =0x5; |
yutation | 2:6d633bb5c09d | 9 | const uint8_t RX_FIFO_DATA_REG =0x10; |
yutation | 2:6d633bb5c09d | 10 | const uint8_t TX_FIFO_DATA_REG =0x20; |
yutation | 2:6d633bb5c09d | 11 | const uint8_t ADDR_7_0_REG =0x7; |
yutation | 2:6d633bb5c09d | 12 | const uint8_t ADDR_15_8_REG =0x8; |
yutation | 2:6d633bb5c09d | 13 | const uint8_t ADDR_23_16_REG =0x9; |
yutation | 2:6d633bb5c09d | 14 | const uint8_t ADDR_31_24_REG =0xa; |
yutation | 2:6d633bb5c09d | 15 | |
yutation | 2:6d633bb5c09d | 16 | |
yutation | 2:6d633bb5c09d | 17 | |
yutation | 2:6d633bb5c09d | 18 | // Reg Value states |
yutation | 2:6d633bb5c09d | 19 | // TRANS_TYPE_REG |
yutation | 2:6d633bb5c09d | 20 | const uint8_t DIRECT_ACCESS =0; |
yutation | 2:6d633bb5c09d | 21 | const uint8_t INIT_SD =1; |
yutation | 2:6d633bb5c09d | 22 | const uint8_t READ_SD_BLOCK =2; |
yutation | 2:6d633bb5c09d | 23 | const uint8_t WRITE_SD_BLOCK =3; |
yutation | 2:6d633bb5c09d | 24 | |
yutation | 2:6d633bb5c09d | 25 | //TRANS_CTRL_REG |
yutation | 2:6d633bb5c09d | 26 | const uint8_t TRANS_START =1; |
yutation | 2:6d633bb5c09d | 27 | |
yutation | 2:6d633bb5c09d | 28 | //TRANS_STS_REG |
yutation | 2:6d633bb5c09d | 29 | const uint8_t TRANS_BUSY =1; |
yutation | 2:6d633bb5c09d | 30 | |
yutation | 2:6d633bb5c09d | 31 | //TRANS_ERROR_REG |
yutation | 2:6d633bb5c09d | 32 | const uint8_t NO_ERROR =0; |
yutation | 2:6d633bb5c09d | 33 | |
yutation | 2:6d633bb5c09d | 34 | //the variable below should be replaced by a specific pin |
yutation | 3:4c39249bcd56 | 35 | // the names are the same the as the spimaster port name |
yutation | 3:4c39249bcd56 | 36 | // i and o are the input of output of spimaster instead of the mbed. |
yutation | 2:6d633bb5c09d | 37 | |
yutation | 2:6d633bb5c09d | 38 | uint8_t clk_i; |
yutation | 2:6d633bb5c09d | 39 | uint8_t address_i; |
yutation | 2:6d633bb5c09d | 40 | uint8_t data_i; |
yutation | 2:6d633bb5c09d | 41 | uint8_t data_o; |
yutation | 2:6d633bb5c09d | 42 | uint8_t write_en; |
yutation | 2:6d633bb5c09d | 43 | uint8_t rst_i; |
yutation | 3:4c39249bcd56 | 44 | uint8_t strobe_i; |
yutation | 3:4c39249bcd56 | 45 | uint8_t ack_o; |
yutation | 2:6d633bb5c09d | 46 | |
yutation | 2:6d633bb5c09d | 47 | |
yutation | 2:6d633bb5c09d | 48 | |
yutation | 2:6d633bb5c09d | 49 | SDspimaster::SDspimaster(const char* name) : |
yutation | 2:6d633bb5c09d | 50 | FATFileSystem(name), _is_initialized(0) { |
yutation | 3:4c39249bcd56 | 51 | clk_i = 1; |
yutation | 2:6d633bb5c09d | 52 | rst_i = 1; |
yutation | 3:4c39249bcd56 | 53 | rst_i = 1; |
yutation | 3:4c39249bcd56 | 54 | clk_i = 0; |
yutation | 3:4c39249bcd56 | 55 | clk_i = 1; |
yutation | 3:4c39249bcd56 | 56 | clk_i = 0; |
yutation | 2:6d633bb5c09d | 57 | rst_i = 0; |
yutation | 3:4c39249bcd56 | 58 | strobe_i = 0; |
yutation | 3:4c39249bcd56 | 59 | clk_i = 1; |
yutation | 3:4c39249bcd56 | 60 | clk_i = 0; |
yutation | 3:4c39249bcd56 | 61 | |
yutation | 2:6d633bb5c09d | 62 | |
yutation | 2:6d633bb5c09d | 63 | } |
yutation | 2:6d633bb5c09d | 64 | |
yutation | 2:6d633bb5c09d | 65 | void read_reg(uint8_t addr, uint8_t* value){ |
yutation | 2:6d633bb5c09d | 66 | write_en = 0; |
yutation | 2:6d633bb5c09d | 67 | address_i = addr; |
yutation | 3:4c39249bcd56 | 68 | strobe_i = 1; |
yutation | 3:4c39249bcd56 | 69 | clk_i = 1; |
yutation | 3:4c39249bcd56 | 70 | *value = data_o; |
yutation | 2:6d633bb5c09d | 71 | clk_i = 0; |
yutation | 3:4c39249bcd56 | 72 | |
yutation | 3:4c39249bcd56 | 73 | |
yutation | 2:6d633bb5c09d | 74 | |
yutation | 2:6d633bb5c09d | 75 | } |
yutation | 2:6d633bb5c09d | 76 | |
yutation | 2:6d633bb5c09d | 77 | void write_reg(uint8_t addr, uint8_t value){ |
yutation | 2:6d633bb5c09d | 78 | address_i = addr; |
yutation | 2:6d633bb5c09d | 79 | data_i = value; |
yutation | 2:6d633bb5c09d | 80 | write_en = 1; |
yutation | 3:4c39249bcd56 | 81 | strobe_i = 1; |
yutation | 3:4c39249bcd56 | 82 | clk_i = 1; |
yutation | 2:6d633bb5c09d | 83 | clk_i = 0; |
yutation | 2:6d633bb5c09d | 84 | |
yutation | 2:6d633bb5c09d | 85 | } |
yutation | 2:6d633bb5c09d | 86 | |
yutation | 2:6d633bb5c09d | 87 | void write_address(uint32_t addr) { |
yutation | 2:6d633bb5c09d | 88 | write_reg(ADDR_7_0_REG, (addr >> 0) & 0xff); |
yutation | 2:6d633bb5c09d | 89 | write_reg(ADDR_15_8_REG, (addr >> 8) & 0xff); |
yutation | 2:6d633bb5c09d | 90 | write_reg(ADDR_23_16_REG, (addr >> 16) & 0xff); |
yutation | 2:6d633bb5c09d | 91 | write_reg(ADDR_31_24_REG, (addr >> 25) & 0xff); |
yutation | 2:6d633bb5c09d | 92 | } |
yutation | 2:6d633bb5c09d | 93 | |
yutation | 2:6d633bb5c09d | 94 | int write_block(uint32_t addr, const uint8_t* buffer) { |
yutation | 2:6d633bb5c09d | 95 | uint8_t state; |
yutation | 2:6d633bb5c09d | 96 | for(uint32_t i = 0; i <= 512; i++) { |
yutation | 2:6d633bb5c09d | 97 | write_reg(TX_FIFO_DATA_REG, buffer[i]); |
yutation | 2:6d633bb5c09d | 98 | } |
yutation | 2:6d633bb5c09d | 99 | write_address(addr); |
yutation | 2:6d633bb5c09d | 100 | write_reg( TRANS_TYPE_REG, WRITE_SD_BLOCK); |
yutation | 2:6d633bb5c09d | 101 | write_reg(TRANS_CTRL_REG, TRANS_START); |
yutation | 2:6d633bb5c09d | 102 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 103 | while(state == TRANS_BUSY) |
yutation | 2:6d633bb5c09d | 104 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 105 | read_reg(TRANS_ERROR_REG,&state); |
yutation | 2:6d633bb5c09d | 106 | |
yutation | 2:6d633bb5c09d | 107 | if((state>>4) & 0x3 != NO_ERROR) |
yutation | 2:6d633bb5c09d | 108 | return 1; |
yutation | 2:6d633bb5c09d | 109 | |
yutation | 2:6d633bb5c09d | 110 | return 0; |
yutation | 2:6d633bb5c09d | 111 | } |
yutation | 2:6d633bb5c09d | 112 | |
yutation | 2:6d633bb5c09d | 113 | int read_block(uint32_t addr, uint8_t* buffer) { |
yutation | 2:6d633bb5c09d | 114 | uint8_t state; |
yutation | 2:6d633bb5c09d | 115 | write_address(addr); |
yutation | 2:6d633bb5c09d | 116 | write_reg( TRANS_TYPE_REG, READ_SD_BLOCK); |
yutation | 2:6d633bb5c09d | 117 | write_reg(TRANS_CTRL_REG, TRANS_START); |
yutation | 2:6d633bb5c09d | 118 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 119 | while(state == TRANS_BUSY) |
yutation | 2:6d633bb5c09d | 120 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 121 | read_reg(TRANS_ERROR_REG,&state); |
yutation | 2:6d633bb5c09d | 122 | if((state>>2) & 0x3 != NO_ERROR) |
yutation | 2:6d633bb5c09d | 123 | return 1; |
yutation | 2:6d633bb5c09d | 124 | |
yutation | 2:6d633bb5c09d | 125 | for(uint32_t i = 0; i <= 512; i++) { |
yutation | 2:6d633bb5c09d | 126 | read_reg(RX_FIFO_DATA_REG, &buffer[i]); |
yutation | 2:6d633bb5c09d | 127 | } |
yutation | 2:6d633bb5c09d | 128 | |
yutation | 2:6d633bb5c09d | 129 | |
yutation | 2:6d633bb5c09d | 130 | return 0; |
yutation | 2:6d633bb5c09d | 131 | } |
yutation | 2:6d633bb5c09d | 132 | |
yutation | 2:6d633bb5c09d | 133 | int SDspimaster::disk_initialize() { |
yutation | 2:6d633bb5c09d | 134 | uint8_t state; |
yutation | 2:6d633bb5c09d | 135 | write_reg( TRANS_TYPE_REG, INIT_SD); |
yutation | 2:6d633bb5c09d | 136 | write_reg(TRANS_CTRL_REG, TRANS_START); |
yutation | 2:6d633bb5c09d | 137 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 138 | while(state == TRANS_BUSY) |
yutation | 2:6d633bb5c09d | 139 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 140 | read_reg(TRANS_ERROR_REG,&state); |
yutation | 2:6d633bb5c09d | 141 | |
yutation | 2:6d633bb5c09d | 142 | if(state & 0x3 != NO_ERROR) |
yutation | 2:6d633bb5c09d | 143 | return 1; |
yutation | 2:6d633bb5c09d | 144 | |
yutation | 2:6d633bb5c09d | 145 | _is_initialized = 1; |
yutation | 2:6d633bb5c09d | 146 | return 0; |
yutation | 2:6d633bb5c09d | 147 | } |
yutation | 2:6d633bb5c09d | 148 | |
yutation | 2:6d633bb5c09d | 149 | int SDspimaster::disk_status() { |
yutation | 2:6d633bb5c09d | 150 | //returns 0 when initialized |
yutation | 2:6d633bb5c09d | 151 | if (_is_initialized) { |
yutation | 2:6d633bb5c09d | 152 | return 0; |
yutation | 2:6d633bb5c09d | 153 | } else { |
yutation | 2:6d633bb5c09d | 154 | return 1; |
yutation | 2:6d633bb5c09d | 155 | } |
yutation | 2:6d633bb5c09d | 156 | } |
yutation | 2:6d633bb5c09d | 157 | |
yutation | 2:6d633bb5c09d | 158 | int SDspimaster::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) { |
yutation | 2:6d633bb5c09d | 159 | if (!_is_initialized) { |
yutation | 2:6d633bb5c09d | 160 | return -1; |
yutation | 2:6d633bb5c09d | 161 | } |
yutation | 2:6d633bb5c09d | 162 | |
yutation | 2:6d633bb5c09d | 163 | for (uint32_t b = block_number; b < block_number + count; b++) { |
yutation | 2:6d633bb5c09d | 164 | // set write address for single block (CMD24) |
yutation | 2:6d633bb5c09d | 165 | |
yutation | 2:6d633bb5c09d | 166 | if (write_block(b, buffer) != 0) { |
yutation | 2:6d633bb5c09d | 167 | return 1; |
yutation | 2:6d633bb5c09d | 168 | } |
yutation | 2:6d633bb5c09d | 169 | |
yutation | 2:6d633bb5c09d | 170 | // send the data block |
yutation | 2:6d633bb5c09d | 171 | buffer += 512; |
yutation | 2:6d633bb5c09d | 172 | } |
yutation | 2:6d633bb5c09d | 173 | |
yutation | 2:6d633bb5c09d | 174 | return 0; |
yutation | 2:6d633bb5c09d | 175 | } |
yutation | 2:6d633bb5c09d | 176 | |
yutation | 2:6d633bb5c09d | 177 | int SDspimaster::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) { |
yutation | 2:6d633bb5c09d | 178 | if (!_is_initialized) { |
yutation | 2:6d633bb5c09d | 179 | return -1; |
yutation | 2:6d633bb5c09d | 180 | } |
yutation | 2:6d633bb5c09d | 181 | |
yutation | 2:6d633bb5c09d | 182 | for (uint32_t b = block_number; b < block_number + count; b++) { |
yutation | 2:6d633bb5c09d | 183 | // set write address for single block (CMD24) |
yutation | 2:6d633bb5c09d | 184 | |
yutation | 2:6d633bb5c09d | 185 | |
yutation | 2:6d633bb5c09d | 186 | if (read_block(b, buffer) != 0) { |
yutation | 2:6d633bb5c09d | 187 | return 1; |
yutation | 2:6d633bb5c09d | 188 | } |
yutation | 2:6d633bb5c09d | 189 | |
yutation | 2:6d633bb5c09d | 190 | // send the data block |
yutation | 2:6d633bb5c09d | 191 | buffer += 512; |
yutation | 2:6d633bb5c09d | 192 | } |
yutation | 2:6d633bb5c09d | 193 | |
yutation | 2:6d633bb5c09d | 194 | return 0; |
yutation | 2:6d633bb5c09d | 195 | } |
yutation | 2:6d633bb5c09d | 196 | |
yutation | 2:6d633bb5c09d | 197 | int SDspimaster::disk_sync() { return 0; } |
yutation | 2:6d633bb5c09d | 198 | |
yutation | 2:6d633bb5c09d | 199 | // Not implement right |
yutation | 2:6d633bb5c09d | 200 | uint32_t SDspimaster::disk_sectors() { return -1; } |
yutation | 2:6d633bb5c09d | 201 | |
yutation | 2:6d633bb5c09d | 202 | |
yutation | 2:6d633bb5c09d | 203 | |
yutation | 2:6d633bb5c09d | 204 | |
yutation | 2:6d633bb5c09d | 205 | |
yutation | 2:6d633bb5c09d | 206 | |
yutation | 2:6d633bb5c09d | 207 | |
yutation | 2:6d633bb5c09d | 208 |