spimaster
Dependencies: mbed SDFileSystem
SDspimaster.cpp@2:6d633bb5c09d, 2021-12-05 (annotated)
- Committer:
- yutation
- Date:
- Sun Dec 05 03:05:32 2021 +0000
- Revision:
- 2:6d633bb5c09d
- Child:
- 3:4c39249bcd56
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 | 2:6d633bb5c09d | 35 | // the name is the same as the data sheet of spimaster |
yutation | 2:6d633bb5c09d | 36 | |
yutation | 2:6d633bb5c09d | 37 | uint8_t clk_i; |
yutation | 2:6d633bb5c09d | 38 | uint8_t address_i; |
yutation | 2:6d633bb5c09d | 39 | uint8_t data_i; |
yutation | 2:6d633bb5c09d | 40 | uint8_t data_o; |
yutation | 2:6d633bb5c09d | 41 | uint8_t write_en; |
yutation | 2:6d633bb5c09d | 42 | uint8_t rst_i; |
yutation | 2:6d633bb5c09d | 43 | |
yutation | 2:6d633bb5c09d | 44 | |
yutation | 2:6d633bb5c09d | 45 | |
yutation | 2:6d633bb5c09d | 46 | SDspimaster::SDspimaster(const char* name) : |
yutation | 2:6d633bb5c09d | 47 | FATFileSystem(name), _is_initialized(0) { |
yutation | 2:6d633bb5c09d | 48 | rst_i = 1; |
yutation | 2:6d633bb5c09d | 49 | rst_i = 0; |
yutation | 2:6d633bb5c09d | 50 | |
yutation | 2:6d633bb5c09d | 51 | } |
yutation | 2:6d633bb5c09d | 52 | |
yutation | 2:6d633bb5c09d | 53 | void read_reg(uint8_t addr, uint8_t* value){ |
yutation | 2:6d633bb5c09d | 54 | clk_i = 1; |
yutation | 2:6d633bb5c09d | 55 | write_en = 0; |
yutation | 2:6d633bb5c09d | 56 | address_i = addr; |
yutation | 2:6d633bb5c09d | 57 | clk_i = 0; |
yutation | 2:6d633bb5c09d | 58 | *value = data_o; |
yutation | 2:6d633bb5c09d | 59 | |
yutation | 2:6d633bb5c09d | 60 | } |
yutation | 2:6d633bb5c09d | 61 | |
yutation | 2:6d633bb5c09d | 62 | void write_reg(uint8_t addr, uint8_t value){ |
yutation | 2:6d633bb5c09d | 63 | clk_i = 1; |
yutation | 2:6d633bb5c09d | 64 | address_i = addr; |
yutation | 2:6d633bb5c09d | 65 | data_i = value; |
yutation | 2:6d633bb5c09d | 66 | write_en = 1; |
yutation | 2:6d633bb5c09d | 67 | clk_i = 0; |
yutation | 2:6d633bb5c09d | 68 | |
yutation | 2:6d633bb5c09d | 69 | } |
yutation | 2:6d633bb5c09d | 70 | |
yutation | 2:6d633bb5c09d | 71 | void write_address(uint32_t addr) { |
yutation | 2:6d633bb5c09d | 72 | write_reg(ADDR_7_0_REG, (addr >> 0) & 0xff); |
yutation | 2:6d633bb5c09d | 73 | write_reg(ADDR_15_8_REG, (addr >> 8) & 0xff); |
yutation | 2:6d633bb5c09d | 74 | write_reg(ADDR_23_16_REG, (addr >> 16) & 0xff); |
yutation | 2:6d633bb5c09d | 75 | write_reg(ADDR_31_24_REG, (addr >> 25) & 0xff); |
yutation | 2:6d633bb5c09d | 76 | } |
yutation | 2:6d633bb5c09d | 77 | |
yutation | 2:6d633bb5c09d | 78 | int write_block(uint32_t addr, const uint8_t* buffer) { |
yutation | 2:6d633bb5c09d | 79 | uint8_t state; |
yutation | 2:6d633bb5c09d | 80 | for(uint32_t i = 0; i <= 512; i++) { |
yutation | 2:6d633bb5c09d | 81 | write_reg(TX_FIFO_DATA_REG, buffer[i]); |
yutation | 2:6d633bb5c09d | 82 | } |
yutation | 2:6d633bb5c09d | 83 | write_address(addr); |
yutation | 2:6d633bb5c09d | 84 | write_reg( TRANS_TYPE_REG, WRITE_SD_BLOCK); |
yutation | 2:6d633bb5c09d | 85 | write_reg(TRANS_CTRL_REG, TRANS_START); |
yutation | 2:6d633bb5c09d | 86 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 87 | while(state == TRANS_BUSY) |
yutation | 2:6d633bb5c09d | 88 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 89 | read_reg(TRANS_ERROR_REG,&state); |
yutation | 2:6d633bb5c09d | 90 | |
yutation | 2:6d633bb5c09d | 91 | if((state>>4) & 0x3 != NO_ERROR) |
yutation | 2:6d633bb5c09d | 92 | return 1; |
yutation | 2:6d633bb5c09d | 93 | |
yutation | 2:6d633bb5c09d | 94 | return 0; |
yutation | 2:6d633bb5c09d | 95 | } |
yutation | 2:6d633bb5c09d | 96 | |
yutation | 2:6d633bb5c09d | 97 | int read_block(uint32_t addr, uint8_t* buffer) { |
yutation | 2:6d633bb5c09d | 98 | uint8_t state; |
yutation | 2:6d633bb5c09d | 99 | write_address(addr); |
yutation | 2:6d633bb5c09d | 100 | write_reg( TRANS_TYPE_REG, READ_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 | if((state>>2) & 0x3 != NO_ERROR) |
yutation | 2:6d633bb5c09d | 107 | return 1; |
yutation | 2:6d633bb5c09d | 108 | |
yutation | 2:6d633bb5c09d | 109 | for(uint32_t i = 0; i <= 512; i++) { |
yutation | 2:6d633bb5c09d | 110 | read_reg(RX_FIFO_DATA_REG, &buffer[i]); |
yutation | 2:6d633bb5c09d | 111 | } |
yutation | 2:6d633bb5c09d | 112 | |
yutation | 2:6d633bb5c09d | 113 | |
yutation | 2:6d633bb5c09d | 114 | return 0; |
yutation | 2:6d633bb5c09d | 115 | } |
yutation | 2:6d633bb5c09d | 116 | |
yutation | 2:6d633bb5c09d | 117 | int SDspimaster::disk_initialize() { |
yutation | 2:6d633bb5c09d | 118 | uint8_t state; |
yutation | 2:6d633bb5c09d | 119 | write_reg( TRANS_TYPE_REG, INIT_SD); |
yutation | 2:6d633bb5c09d | 120 | write_reg(TRANS_CTRL_REG, TRANS_START); |
yutation | 2:6d633bb5c09d | 121 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 122 | while(state == TRANS_BUSY) |
yutation | 2:6d633bb5c09d | 123 | read_reg(TRANS_STS_REG, &state); |
yutation | 2:6d633bb5c09d | 124 | read_reg(TRANS_ERROR_REG,&state); |
yutation | 2:6d633bb5c09d | 125 | |
yutation | 2:6d633bb5c09d | 126 | if(state & 0x3 != NO_ERROR) |
yutation | 2:6d633bb5c09d | 127 | return 1; |
yutation | 2:6d633bb5c09d | 128 | |
yutation | 2:6d633bb5c09d | 129 | _is_initialized = 1; |
yutation | 2:6d633bb5c09d | 130 | return 0; |
yutation | 2:6d633bb5c09d | 131 | } |
yutation | 2:6d633bb5c09d | 132 | |
yutation | 2:6d633bb5c09d | 133 | int SDspimaster::disk_status() { |
yutation | 2:6d633bb5c09d | 134 | //returns 0 when initialized |
yutation | 2:6d633bb5c09d | 135 | if (_is_initialized) { |
yutation | 2:6d633bb5c09d | 136 | return 0; |
yutation | 2:6d633bb5c09d | 137 | } else { |
yutation | 2:6d633bb5c09d | 138 | return 1; |
yutation | 2:6d633bb5c09d | 139 | } |
yutation | 2:6d633bb5c09d | 140 | } |
yutation | 2:6d633bb5c09d | 141 | |
yutation | 2:6d633bb5c09d | 142 | int SDspimaster::disk_write(const uint8_t* buffer, uint32_t block_number, uint32_t count) { |
yutation | 2:6d633bb5c09d | 143 | if (!_is_initialized) { |
yutation | 2:6d633bb5c09d | 144 | return -1; |
yutation | 2:6d633bb5c09d | 145 | } |
yutation | 2:6d633bb5c09d | 146 | |
yutation | 2:6d633bb5c09d | 147 | for (uint32_t b = block_number; b < block_number + count; b++) { |
yutation | 2:6d633bb5c09d | 148 | // set write address for single block (CMD24) |
yutation | 2:6d633bb5c09d | 149 | |
yutation | 2:6d633bb5c09d | 150 | if (write_block(b, buffer) != 0) { |
yutation | 2:6d633bb5c09d | 151 | return 1; |
yutation | 2:6d633bb5c09d | 152 | } |
yutation | 2:6d633bb5c09d | 153 | |
yutation | 2:6d633bb5c09d | 154 | // send the data block |
yutation | 2:6d633bb5c09d | 155 | buffer += 512; |
yutation | 2:6d633bb5c09d | 156 | } |
yutation | 2:6d633bb5c09d | 157 | |
yutation | 2:6d633bb5c09d | 158 | return 0; |
yutation | 2:6d633bb5c09d | 159 | } |
yutation | 2:6d633bb5c09d | 160 | |
yutation | 2:6d633bb5c09d | 161 | int SDspimaster::disk_read(uint8_t* buffer, uint32_t block_number, uint32_t count) { |
yutation | 2:6d633bb5c09d | 162 | if (!_is_initialized) { |
yutation | 2:6d633bb5c09d | 163 | return -1; |
yutation | 2:6d633bb5c09d | 164 | } |
yutation | 2:6d633bb5c09d | 165 | |
yutation | 2:6d633bb5c09d | 166 | for (uint32_t b = block_number; b < block_number + count; b++) { |
yutation | 2:6d633bb5c09d | 167 | // set write address for single block (CMD24) |
yutation | 2:6d633bb5c09d | 168 | |
yutation | 2:6d633bb5c09d | 169 | |
yutation | 2:6d633bb5c09d | 170 | if (read_block(b, buffer) != 0) { |
yutation | 2:6d633bb5c09d | 171 | return 1; |
yutation | 2:6d633bb5c09d | 172 | } |
yutation | 2:6d633bb5c09d | 173 | |
yutation | 2:6d633bb5c09d | 174 | // send the data block |
yutation | 2:6d633bb5c09d | 175 | buffer += 512; |
yutation | 2:6d633bb5c09d | 176 | } |
yutation | 2:6d633bb5c09d | 177 | |
yutation | 2:6d633bb5c09d | 178 | return 0; |
yutation | 2:6d633bb5c09d | 179 | } |
yutation | 2:6d633bb5c09d | 180 | |
yutation | 2:6d633bb5c09d | 181 | int SDspimaster::disk_sync() { return 0; } |
yutation | 2:6d633bb5c09d | 182 | |
yutation | 2:6d633bb5c09d | 183 | // Not implement right |
yutation | 2:6d633bb5c09d | 184 | uint32_t SDspimaster::disk_sectors() { return -1; } |
yutation | 2:6d633bb5c09d | 185 | |
yutation | 2:6d633bb5c09d | 186 | |
yutation | 2:6d633bb5c09d | 187 | |
yutation | 2:6d633bb5c09d | 188 | |
yutation | 2:6d633bb5c09d | 189 | |
yutation | 2:6d633bb5c09d | 190 | |
yutation | 2:6d633bb5c09d | 191 | |
yutation | 2:6d633bb5c09d | 192 |