44 setPins(miso, mosi, clk, cs);
47 void setPins(
int miso,
int mosi,
int clk,
int cs = -1) {
54 void setMISO(
int miso) { this->miso = miso; }
56 void setMOSI(
int mosi) { this->mosi = mosi; }
58 void setCLK(
int clk) { this->clk = clk; }
60 void setCS(
int cs) { this->cs = cs; }
62 DSTATUS disk_status(BYTE drv)
override {
63 if (drv)
return STA_NOINIT;
67 DSTATUS disk_initialize(BYTE drv)
override {
68 BYTE n, ty, cmd, buf[4];
72 if (drv != 0)
return STA_NODISK;
73 if (miso == -1 || mosi == -1 || clk == -1)
return STA_NODISK;
90 if (
send_cmd(ACMD41, 1UL << 30) == 0)
break;
93 if (tmr &&
send_cmd(CMD58, 0) == 0) {
95 ty = (buf[0] & 0x40) ? CT_SDC2 | CT_BLOCK : CT_SDC2;
106 for (tmr = 1000; tmr; tmr--) {
110 if (!tmr ||
send_cmd(CMD16, 512) != 0)
115 s = ty ? STA_CLEAR : STA_NOINIT;
130 DWORD sect = (DWORD)sector;
132 if (disk_status(drv) & STA_NOINIT)
return RES_NOTRDY;
133 if (!(CardType & CT_BLOCK))
136 cmd = count > 1 ? CMD18
143 if (cmd == CMD18)
send_cmd(CMD12, 0);
147 return count ? RES_ERROR : RES_OK;
150 DRESULT disk_write(BYTE drv,
155 DWORD sect = (DWORD)sector;
157 if (disk_status(drv) & STA_NOINIT)
return RES_NOTRDY;
158 if (!(CardType & CT_BLOCK))
166 if (CardType & CT_SDC)
send_cmd(ACMD23, count);
178 return count ? RES_ERROR : RES_OK;
181 DRESULT disk_ioctl(BYTE drv,
189 if (disk_status(drv) & STA_NOINIT)
195 if (
select()) res = RES_OK;
198 case GET_SECTOR_COUNT:
200 if ((csd[0] >> 6) == 1) {
202 csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
203 *(LBA_t *)buff = cs << 10;
205 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) +
207 cs = (csd[8] >> 6) + ((WORD)csd[7] << 2) +
208 ((WORD)(csd[6] & 3) << 10) + 1;
209 *(LBA_t *)buff = cs << (n - 9);
216 *(DWORD *)buff = 128;
230 DSTATUS Stat = STA_NOINIT;
232 int miso = -1, mosi = -1, clk = -1, cs = -1;
235 if (cs != -1) pinMode(cs, OUTPUT);
236 set_pin_active(cs,
true);
237 pinMode(clk, OUTPUT);
238 set_pin_active(clk,
false);
239 pinMode(miso, INPUT);
240 pinMode(mosi, OUTPUT);
243 inline void set_pin_active(
int pin,
bool active) {
244 if (pin != -1) digitalWrite(pin, active);
247 inline bool read_data() {
return digitalRead(miso); }
258 set_pin_active(mosi,
true);
260 set_pin_active(mosi,
false);
261 set_pin_active(clk,
true);
262 set_pin_active(clk,
false);
264 set_pin_active(mosi,
true);
266 set_pin_active(mosi,
false);
267 set_pin_active(clk,
true);
268 set_pin_active(clk,
false);
270 set_pin_active(mosi,
true);
272 set_pin_active(mosi,
false);
273 set_pin_active(clk,
true);
274 set_pin_active(clk,
false);
276 set_pin_active(mosi,
true);
278 set_pin_active(mosi,
false);
279 set_pin_active(clk,
true);
280 set_pin_active(clk,
false);
282 set_pin_active(mosi,
true);
284 set_pin_active(mosi,
false);
285 set_pin_active(clk,
true);
286 set_pin_active(clk,
false);
288 set_pin_active(mosi,
true);
290 set_pin_active(mosi,
false);
291 set_pin_active(clk,
true);
292 set_pin_active(clk,
false);
294 set_pin_active(mosi,
true);
296 set_pin_active(mosi,
false);
297 set_pin_active(clk,
true);
298 set_pin_active(clk,
false);
300 set_pin_active(mosi,
true);
302 set_pin_active(mosi,
false);
303 set_pin_active(clk,
true);
304 set_pin_active(clk,
false);
314 set_pin_active(mosi,
true);
318 if (read_data()) r++;
319 set_pin_active(clk,
true);
320 set_pin_active(clk,
false);
322 if (read_data()) r++;
323 set_pin_active(clk,
true);
324 set_pin_active(clk,
false);
326 if (read_data()) r++;
327 set_pin_active(clk,
true);
328 set_pin_active(clk,
false);
330 if (read_data()) r++;
331 set_pin_active(clk,
true);
332 set_pin_active(clk,
false);
334 if (read_data()) r++;
335 set_pin_active(clk,
true);
336 set_pin_active(clk,
false);
338 if (read_data()) r++;
339 set_pin_active(clk,
true);
340 set_pin_active(clk,
false);
342 if (read_data()) r++;
343 set_pin_active(clk,
true);
344 set_pin_active(clk,
false);
346 if (read_data()) r++;
347 set_pin_active(clk,
true);
348 set_pin_active(clk,
false);
359 for (tmr = 5000; tmr; tmr--) {
361 if (d == 0xFF)
break;
362 delayMicroseconds(100);
372 set_pin_active(cs,
true);
381 set_pin_active(cs,
false);
397 for (tmr = 1000; tmr;
400 if (d[0] != 0xFF)
break;
401 delayMicroseconds(100);
403 if (d[0] != 0xFE)
return 0;
427 if ((d[0] & 0x1F) != 0x05)
450 if (!
select())
return 0xFF;
455 buf[1] = (BYTE)(arg >> 24);
456 buf[2] = (BYTE)(arg >> 16);
457 buf[3] = (BYTE)(arg >> 8);
460 if (cmd == CMD0) n = 0x95;
461 if (cmd == CMD8) n = 0x87;
469 while ((d & 0x80) && --n);
Empty IO implementation that we can use to test the compilation.
Definition: BaseIO.h:10
Accessing a SD card via SPI using bit banging.
Definition: SDBitBangSPIIO.h:41
BYTE send_cmd(BYTE cmd, DWORD arg)
Send a command packet to the card */.
Definition: SDBitBangSPIIO.h:435
int xmit_datablock(const BYTE *buff, BYTE token)
Send a data packet to the card */.
Definition: SDBitBangSPIIO.h:412
int select(void)
Select the card and wait for ready */.
Definition: SDBitBangSPIIO.h:377
void deselect(void)
Deselect the card and release SPI bus */.
Definition: SDBitBangSPIIO.h:369
int rcvr_datablock(BYTE *buff, UINT btr)
Receive a data packet from the card */.
Definition: SDBitBangSPIIO.h:390
void xmit_mmc(const BYTE *buff, UINT bc)
Transmit bytes to the card (bitbanging) */.
Definition: SDBitBangSPIIO.h:250
void rcvr_mmc(BYTE *buff, UINT bc)
Receive bytes from the card (bitbanging) */.
Definition: SDBitBangSPIIO.h:309
int wait_ready(void)
Wait for card ready */.
Definition: SDBitBangSPIIO.h:354