change for use

Committer:
dank
Date:
Tue Dec 07 07:54:45 2021 +0000
Revision:
0:e882606c8174
sdhandler;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dank 0:e882606c8174 1 #ifndef INC_SDCOMMANDS_H_
dank 0:e882606c8174 2 #define INC_SDCOMMANDS_H_
dank 0:e882606c8174 3
dank 0:e882606c8174 4 #include "stdint.h"
dank 0:e882606c8174 5 #include "SPIRawHandler.h"
dank 0:e882606c8174 6
dank 0:e882606c8174 7 static const uint64_t CRC7 = 0b10001001;
dank 0:e882606c8174 8
dank 0:e882606c8174 9 static inline uint8_t cal(uint64_t cmdarg){
dank 0:e882606c8174 10 uint64_t t = cmdarg << 7;
dank 0:e882606c8174 11 for(uint8_t i = 46; i >= 7; i-- ){
dank 0:e882606c8174 12 if(t >> i == 1)t ^= CRC7 << (i - 7);
dank 0:e882606c8174 13 }
dank 0:e882606c8174 14 return t & 0xFF;
dank 0:e882606c8174 15 }
dank 0:e882606c8174 16
dank 0:e882606c8174 17 static inline void CMD(uint8_t cmd){
dank 0:e882606c8174 18 SpiRawWrite(0b01000000|cmd);
dank 0:e882606c8174 19 }
dank 0:e882606c8174 20
dank 0:e882606c8174 21 static inline void ARG(uint32_t arg){
dank 0:e882606c8174 22 SpiRawWrite(((uint8_t*)(&arg))[3]);
dank 0:e882606c8174 23 SpiRawWrite(((uint8_t*)(&arg))[2]);
dank 0:e882606c8174 24 SpiRawWrite(((uint8_t*)(&arg))[1]);
dank 0:e882606c8174 25 SpiRawWrite(((uint8_t*)(&arg))[0]);
dank 0:e882606c8174 26 }
dank 0:e882606c8174 27
dank 0:e882606c8174 28 static inline void CRC(uint8_t cmd,uint32_t arg){
dank 0:e882606c8174 29 SpiRawWrite((cal( ((uint64_t)(0b01000000|cmd) << 32) | arg ) << 1) | 1);
dank 0:e882606c8174 30 }
dank 0:e882606c8174 31
dank 0:e882606c8174 32 static inline void DMY(){
dank 0:e882606c8174 33 SpiRawWrite(0xFF);
dank 0:e882606c8174 34 }
dank 0:e882606c8174 35
dank 0:e882606c8174 36 static inline uint8_t WaitCmdRsp(){
dank 0:e882606c8174 37 uint8_t rsp;
dank 0:e882606c8174 38 for(uint8_t i = 0;i < 100;i++){
dank 0:e882606c8174 39 rsp = SpiRawRead();
dank 0:e882606c8174 40 if(rsp != 0xFF)break;
dank 0:e882606c8174 41 }
dank 0:e882606c8174 42 return rsp;
dank 0:e882606c8174 43 }
dank 0:e882606c8174 44
dank 0:e882606c8174 45 static inline uint8_t WaitDatTkn(){
dank 0:e882606c8174 46 uint8_t tkn;
dank 0:e882606c8174 47 for(uint8_t i = 0;i < 100;i++){
dank 0:e882606c8174 48 tkn = SpiRawRead();
dank 0:e882606c8174 49 if(tkn != 0xFF)break;
dank 0:e882606c8174 50 }
dank 0:e882606c8174 51 return tkn;
dank 0:e882606c8174 52 }
dank 0:e882606c8174 53
dank 0:e882606c8174 54 static inline void SendDatTkn(){
dank 0:e882606c8174 55 SpiRawWrite(0xFE);
dank 0:e882606c8174 56 }
dank 0:e882606c8174 57
dank 0:e882606c8174 58 static inline void SendDatTknMlt(){
dank 0:e882606c8174 59 SpiRawWrite(0xFC);
dank 0:e882606c8174 60 }
dank 0:e882606c8174 61
dank 0:e882606c8174 62 static inline void SendStpTkn(){
dank 0:e882606c8174 63 SpiRawWrite(0xFD);
dank 0:e882606c8174 64 }
dank 0:e882606c8174 65
dank 0:e882606c8174 66 static inline void WaitBsySts(){
dank 0:e882606c8174 67 while(SpiRawRead() == 0x00);
dank 0:e882606c8174 68 }
dank 0:e882606c8174 69
dank 0:e882606c8174 70 static inline uint8_t WaitDatRsp(){
dank 0:e882606c8174 71 return SpiRawRead() & 0b11111;
dank 0:e882606c8174 72 }
dank 0:e882606c8174 73
dank 0:e882606c8174 74 static inline uint32_t R7(){
dank 0:e882606c8174 75 uint32_t R7 = 0x00;
dank 0:e882606c8174 76 R7 |= SpiRawRead() << 24;
dank 0:e882606c8174 77 R7 |= SpiRawRead() << 16;
dank 0:e882606c8174 78 R7 |= SpiRawRead() << 8;
dank 0:e882606c8174 79 R7 |= SpiRawRead() << 0;
dank 0:e882606c8174 80 return R7 & 0xFFF;
dank 0:e882606c8174 81 }
dank 0:e882606c8174 82
dank 0:e882606c8174 83 static inline uint32_t OCR(){
dank 0:e882606c8174 84 uint32_t OCR = 0x00;
dank 0:e882606c8174 85 OCR |= SpiRawRead() << 24;
dank 0:e882606c8174 86 OCR |= SpiRawRead() << 16;
dank 0:e882606c8174 87 OCR |= SpiRawRead() << 8;
dank 0:e882606c8174 88 OCR |= SpiRawRead() << 0;
dank 0:e882606c8174 89 return OCR;
dank 0:e882606c8174 90 }
dank 0:e882606c8174 91
dank 0:e882606c8174 92 static inline void CSD(uint8_t *csd){
dank 0:e882606c8174 93 SpiRawReadMulti(csd,16);
dank 0:e882606c8174 94 }
dank 0:e882606c8174 95
dank 0:e882606c8174 96 static inline void CID(uint8_t *cid){
dank 0:e882606c8174 97 SpiRawReadMulti(cid,16);
dank 0:e882606c8174 98 }
dank 0:e882606c8174 99
dank 0:e882606c8174 100 static inline void ReadDataPacket(uint8_t *data){
dank 0:e882606c8174 101 SpiRawReadMulti(data,512);
dank 0:e882606c8174 102 }
dank 0:e882606c8174 103
dank 0:e882606c8174 104 static inline void SendDataPacket(uint8_t *data){
dank 0:e882606c8174 105 SpiRawWriteMulti(data,512);
dank 0:e882606c8174 106 }
dank 0:e882606c8174 107
dank 0:e882606c8174 108 void Dummy74Clacks(){
dank 0:e882606c8174 109 DMY();
dank 0:e882606c8174 110 DMY();
dank 0:e882606c8174 111 DMY();
dank 0:e882606c8174 112 DMY();
dank 0:e882606c8174 113 DMY();
dank 0:e882606c8174 114 DMY();
dank 0:e882606c8174 115 DMY();
dank 0:e882606c8174 116 DMY();
dank 0:e882606c8174 117 DMY();
dank 0:e882606c8174 118 DMY();
dank 0:e882606c8174 119 }
dank 0:e882606c8174 120
dank 0:e882606c8174 121 bool CMD0(){
dank 0:e882606c8174 122 uint8_t rsp;
dank 0:e882606c8174 123
dank 0:e882606c8174 124 SpiRawAsertSS();
dank 0:e882606c8174 125 CMD(0);
dank 0:e882606c8174 126 ARG(0);
dank 0:e882606c8174 127 CRC(0,0);
dank 0:e882606c8174 128 rsp = WaitCmdRsp();
dank 0:e882606c8174 129
dank 0:e882606c8174 130 SpiRawDeAsertSS();
dank 0:e882606c8174 131 return rsp == 0x01;
dank 0:e882606c8174 132 }
dank 0:e882606c8174 133
dank 0:e882606c8174 134 bool CMD8(uint32_t *r7){
dank 0:e882606c8174 135 uint8_t rsp;
dank 0:e882606c8174 136
dank 0:e882606c8174 137 SpiRawAsertSS();
dank 0:e882606c8174 138 CMD(8);
dank 0:e882606c8174 139 ARG(0x1AA);
dank 0:e882606c8174 140 CRC(8,0x1AA);
dank 0:e882606c8174 141 rsp = WaitCmdRsp();
dank 0:e882606c8174 142 *r7 = R7();
dank 0:e882606c8174 143 SpiRawDeAsertSS();
dank 0:e882606c8174 144 return rsp == 0x01;
dank 0:e882606c8174 145 }
dank 0:e882606c8174 146
dank 0:e882606c8174 147 bool ACMD41(){
dank 0:e882606c8174 148 uint8_t rsp;
dank 0:e882606c8174 149
dank 0:e882606c8174 150 SpiRawAsertSS();
dank 0:e882606c8174 151
dank 0:e882606c8174 152 CMD(55);
dank 0:e882606c8174 153 ARG(0);
dank 0:e882606c8174 154 CRC(55,0);
dank 0:e882606c8174 155 rsp = WaitCmdRsp();
dank 0:e882606c8174 156
dank 0:e882606c8174 157 SpiRawDeAsertSS();
dank 0:e882606c8174 158
dank 0:e882606c8174 159 if(rsp != 0x01)return false;
dank 0:e882606c8174 160
dank 0:e882606c8174 161 SpiRawAsertSS();
dank 0:e882606c8174 162
dank 0:e882606c8174 163 CMD(41);
dank 0:e882606c8174 164 ARG(1 << 30);
dank 0:e882606c8174 165 CRC(41,1 << 30);
dank 0:e882606c8174 166 rsp = WaitCmdRsp();
dank 0:e882606c8174 167
dank 0:e882606c8174 168 SpiRawDeAsertSS();
dank 0:e882606c8174 169 return rsp == 0x00;
dank 0:e882606c8174 170 }
dank 0:e882606c8174 171
dank 0:e882606c8174 172 bool CMD58(uint32_t *ocr){
dank 0:e882606c8174 173 uint8_t rsp;
dank 0:e882606c8174 174
dank 0:e882606c8174 175 SpiRawAsertSS();
dank 0:e882606c8174 176 CMD(58);
dank 0:e882606c8174 177 ARG(0);
dank 0:e882606c8174 178 CRC(58,0);
dank 0:e882606c8174 179 rsp = WaitCmdRsp();
dank 0:e882606c8174 180 *ocr = OCR();
dank 0:e882606c8174 181 SpiRawDeAsertSS();
dank 0:e882606c8174 182 return rsp == 0x00;
dank 0:e882606c8174 183 }
dank 0:e882606c8174 184
dank 0:e882606c8174 185 bool CMD9(uint8_t *csd){
dank 0:e882606c8174 186 uint8_t rsp;
dank 0:e882606c8174 187
dank 0:e882606c8174 188 SpiRawAsertSS();
dank 0:e882606c8174 189 CMD(9);
dank 0:e882606c8174 190 ARG(0);
dank 0:e882606c8174 191 CRC(9,0);
dank 0:e882606c8174 192 rsp = WaitCmdRsp();
dank 0:e882606c8174 193 CSD(csd);
dank 0:e882606c8174 194 SpiRawDeAsertSS();
dank 0:e882606c8174 195 return rsp == 0x00;
dank 0:e882606c8174 196 }
dank 0:e882606c8174 197
dank 0:e882606c8174 198 bool CMD10(uint8_t *cid){
dank 0:e882606c8174 199 uint8_t rsp;
dank 0:e882606c8174 200
dank 0:e882606c8174 201 SpiRawAsertSS();
dank 0:e882606c8174 202 CMD(10);
dank 0:e882606c8174 203 ARG(0);
dank 0:e882606c8174 204 CRC(10,0);
dank 0:e882606c8174 205 rsp = WaitCmdRsp();
dank 0:e882606c8174 206 CID(cid);
dank 0:e882606c8174 207 SpiRawDeAsertSS();
dank 0:e882606c8174 208 return rsp == 0x00;
dank 0:e882606c8174 209 }
dank 0:e882606c8174 210
dank 0:e882606c8174 211 bool CMD17(uint32_t sector,uint8_t *data){
dank 0:e882606c8174 212 uint8_t rsp;
dank 0:e882606c8174 213 bool flag = false;
dank 0:e882606c8174 214
dank 0:e882606c8174 215 SpiRawAsertSS();
dank 0:e882606c8174 216 CMD(17);
dank 0:e882606c8174 217 ARG(sector);
dank 0:e882606c8174 218 DMY();
dank 0:e882606c8174 219 rsp = WaitCmdRsp();
dank 0:e882606c8174 220
dank 0:e882606c8174 221 if(rsp == 0x00){
dank 0:e882606c8174 222 uint8_t tkn;
dank 0:e882606c8174 223 tkn = WaitDatTkn();
dank 0:e882606c8174 224
dank 0:e882606c8174 225 if(tkn == 0xFE){
dank 0:e882606c8174 226 ReadDataPacket(data);
dank 0:e882606c8174 227 DMY();
dank 0:e882606c8174 228 DMY();
dank 0:e882606c8174 229
dank 0:e882606c8174 230 flag = true;
dank 0:e882606c8174 231 }
dank 0:e882606c8174 232 }
dank 0:e882606c8174 233 SpiRawDeAsertSS();
dank 0:e882606c8174 234 return flag;
dank 0:e882606c8174 235 }
dank 0:e882606c8174 236
dank 0:e882606c8174 237 bool CMD18(uint32_t sector, uint8_t *data, uint16_t count){
dank 0:e882606c8174 238 uint8_t rsp;
dank 0:e882606c8174 239 bool flag = false;
dank 0:e882606c8174 240
dank 0:e882606c8174 241 SpiRawAsertSS();
dank 0:e882606c8174 242 CMD(18);
dank 0:e882606c8174 243 ARG(sector);
dank 0:e882606c8174 244 DMY();
dank 0:e882606c8174 245 rsp = WaitCmdRsp();
dank 0:e882606c8174 246
dank 0:e882606c8174 247 if(rsp == 0x00){
dank 0:e882606c8174 248 for(uint16_t i = 0;i < count;i++){
dank 0:e882606c8174 249 uint8_t tkn;
dank 0:e882606c8174 250 tkn = WaitDatTkn();
dank 0:e882606c8174 251
dank 0:e882606c8174 252 if(tkn == 0xFE){
dank 0:e882606c8174 253 ReadDataPacket(data + 512 * i);
dank 0:e882606c8174 254 DMY();
dank 0:e882606c8174 255 DMY();
dank 0:e882606c8174 256
dank 0:e882606c8174 257 if(i == count - 1)flag = true;
dank 0:e882606c8174 258 }else{
dank 0:e882606c8174 259 break;
dank 0:e882606c8174 260 }
dank 0:e882606c8174 261 }
dank 0:e882606c8174 262
dank 0:e882606c8174 263 CMD(12);
dank 0:e882606c8174 264 ARG(0);
dank 0:e882606c8174 265 DMY();
dank 0:e882606c8174 266
dank 0:e882606c8174 267 DMY();
dank 0:e882606c8174 268
dank 0:e882606c8174 269 rsp = WaitCmdRsp();
dank 0:e882606c8174 270
dank 0:e882606c8174 271 WaitBsySts();
dank 0:e882606c8174 272 }
dank 0:e882606c8174 273
dank 0:e882606c8174 274 SpiRawDeAsertSS();
dank 0:e882606c8174 275
dank 0:e882606c8174 276 return flag;
dank 0:e882606c8174 277 }
dank 0:e882606c8174 278
dank 0:e882606c8174 279 bool CMD24(uint32_t sector, uint8_t *data){
dank 0:e882606c8174 280 uint8_t rsp;
dank 0:e882606c8174 281 bool flag = false;
dank 0:e882606c8174 282
dank 0:e882606c8174 283 SpiRawAsertSS();
dank 0:e882606c8174 284 CMD(24);
dank 0:e882606c8174 285 ARG(sector);
dank 0:e882606c8174 286 DMY();
dank 0:e882606c8174 287 rsp = WaitCmdRsp();
dank 0:e882606c8174 288
dank 0:e882606c8174 289 if(rsp == 0x00){
dank 0:e882606c8174 290 DMY();
dank 0:e882606c8174 291 SendDatTkn();
dank 0:e882606c8174 292 SendDataPacket(data);
dank 0:e882606c8174 293 DMY();
dank 0:e882606c8174 294 DMY();
dank 0:e882606c8174 295
dank 0:e882606c8174 296 rsp = WaitDatRsp();
dank 0:e882606c8174 297 WaitBsySts();
dank 0:e882606c8174 298
dank 0:e882606c8174 299 if(rsp == 0b00101)flag = true;
dank 0:e882606c8174 300 }
dank 0:e882606c8174 301
dank 0:e882606c8174 302 SpiRawDeAsertSS();
dank 0:e882606c8174 303
dank 0:e882606c8174 304 return flag;
dank 0:e882606c8174 305 }
dank 0:e882606c8174 306
dank 0:e882606c8174 307 bool CMD25(uint32_t sector,uint8_t *data,uint16_t count){
dank 0:e882606c8174 308 uint8_t rsp;
dank 0:e882606c8174 309 bool flag = false;
dank 0:e882606c8174 310
dank 0:e882606c8174 311 SpiRawAsertSS();
dank 0:e882606c8174 312 CMD(25);
dank 0:e882606c8174 313 ARG(sector);
dank 0:e882606c8174 314 DMY();
dank 0:e882606c8174 315 rsp = WaitCmdRsp();
dank 0:e882606c8174 316
dank 0:e882606c8174 317 if(rsp == 0x00){
dank 0:e882606c8174 318 DMY();
dank 0:e882606c8174 319 for(uint16_t i = 0;i < count;i++){
dank 0:e882606c8174 320 SendDatTknMlt();
dank 0:e882606c8174 321 SendDataPacket(data + 512 * i);
dank 0:e882606c8174 322 DMY();
dank 0:e882606c8174 323 DMY();
dank 0:e882606c8174 324
dank 0:e882606c8174 325 rsp = WaitDatRsp();
dank 0:e882606c8174 326 WaitBsySts();
dank 0:e882606c8174 327
dank 0:e882606c8174 328 if(rsp != 0b00101)break;
dank 0:e882606c8174 329
dank 0:e882606c8174 330 if(i == count -1)flag = true;
dank 0:e882606c8174 331 }
dank 0:e882606c8174 332 SendStpTkn();
dank 0:e882606c8174 333
dank 0:e882606c8174 334 DMY();
dank 0:e882606c8174 335
dank 0:e882606c8174 336 WaitBsySts();
dank 0:e882606c8174 337 }
dank 0:e882606c8174 338
dank 0:e882606c8174 339 SpiRawDeAsertSS();
dank 0:e882606c8174 340
dank 0:e882606c8174 341 return flag;
dank 0:e882606c8174 342 }
dank 0:e882606c8174 343
dank 0:e882606c8174 344 #endif