GadgetSeed  0.9.6
spi_mmc.c
[詳解]
1 /** @file
2  @brief MMC ドライバ
3 
4  SPIドライバ使用
5 
6  @date 2008.01.02
7  @author Takashi SHUDO
8 */
9 
10 #include "device.h"
11 #include "device/spi_ioctl.h"
12 #include "device/sd_ioctl.h"
13 #include "tkprintf.h"
14 
15 //#define DEBUGKBITS 0x03
16 #include "dkprintf.h"
17 
18 
19 static struct st_device *mmc_spi;
20 
21 /*-----------------------------------------------------------------------*/
22 /* MMC/SDSC/SDHC (in SPI mode) control module (C)ChaN, 2007 */
23 /*-----------------------------------------------------------------------*/
24 /* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros are */
25 /* platform dependent. */
26 /*-----------------------------------------------------------------------*/
27 
28 
29 #include "diskio.h"
30 
31 /* MMC/SD command (in SPI) */
32 #define CMD0 (0x40+0) /* GO_IDLE_STATE */
33 #define CMD1 (0x40+1) /* SEND_OP_COND */
34 #define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
35 #define CMD8 (0x40+8) /* SEND_IF_COND */
36 #define CMD9 (0x40+9) /* SEND_CSD */
37 #define CMD10 (0x40+10) /* SEND_CID */
38 #define CMD12 (0x40+12) /* STOP_TRANSMISSION */
39 #define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
40 #define CMD16 (0x40+16) /* SET_BLOCKLEN */
41 #define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
42 #define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
43 #define CMD23 (0x40+23) /* SET_BLOCK_COUNT */
44 #define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
45 #define CMD24 (0x40+24) /* WRITE_BLOCK */
46 #define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
47 #define CMD41 (0x40+41) /* SEND_OP_COND (ACMD) */
48 #define CMD55 (0x40+55) /* APP_CMD */
49 #define CMD58 (0x40+58) /* READ_OCR */
50 
51 
52 /* Control signals (Platform dependent) */
53 
54 static void SELECT(void)
55 {
56  ioctl_device(mmc_spi, IOCMD_SPI_CS0ASSERT, 0, 0);
57 }
58 
59 static BYTE rcvr_spi(void);
60 
61 static void DESELECT(void)
62 {
63  ioctl_device(mmc_spi, IOCMD_SPI_CS0NEGATE, 0, 0);
64  //ioctl_device(mmc_spi, IOCMD_SPI_FORCE_UNLOCK, 0, 0);
65  rcvr_spi();
66 }
67 
68 /*--------------------------------------------------------------------------
69 
70  Module Private Functions
71 
72 ---------------------------------------------------------------------------*/
73 
74 static volatile
75 DSTATUS Stat = STA_NOINIT; /* Disk status */
76 
77 static
78 BYTE CardType; /* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */
79 
80 
81 
82 /*-----------------------------------------------------------------------*/
83 /* Transmit a byte to MMC via SPI (Platform dependent) */
84 /*-----------------------------------------------------------------------*/
85 
86 static
87 void xmit_spi (BYTE dat)
88 {
89  putc_device(mmc_spi, dat);
90 }
91 
92 
93 
94 /*-----------------------------------------------------------------------*/
95 /* Receive a byte from MMC via SPI (Platform dependent) */
96 /*-----------------------------------------------------------------------*/
97 
98 static
99 BYTE rcvr_spi (void)
100 {
101  unsigned char rd;
102  getc_device(mmc_spi, &rd);
103  DKPRINTF(0x01, "rcvr_spi %02X\n", rd);
104 
105  return rd;
106 }
107 
108 
109 
110 /*-----------------------------------------------------------------------*/
111 /* Wait for card ready */
112 /*-----------------------------------------------------------------------*/
113 
114 #include "timer.h"
115 
116 static
117 BYTE wait_ready (void)
118 {
119  BYTE res;
120  unsigned long tt = get_kernel_time() + 500; // 500ms
121 
122  rcvr_spi();
123  do {
124  res = rcvr_spi();
125  } while ((res != 0xFF) && (tt > get_kernel_time()));
126  if(res != 0xFF) {
127  SYSERR_PRINT("MMC wait ready timeout(%02X)\n", res);
128  }
129  return res;
130 }
131 
132 
133 
134 /*-----------------------------------------------------------------------*/
135 /* Deselect the card and release SPI bus */
136 /*-----------------------------------------------------------------------*/
137 
138 static
139 void release_spi (void)
140 {
141  DESELECT();
142 }
143 
144 
145 
146 /*-----------------------------------------------------------------------*/
147 /* Power Control (Platform dependent) */
148 /*-----------------------------------------------------------------------*/
149 /* When the target system does not support socket power control, there */
150 /* is nothing to do in these functions and chk_power always returns 1. */
151 
152 static
153 void power_on (void)
154 {
155  DESELECT();
156 
157  wait_time(10);
158 
159  DKPRINTF(0x01, "MMC On\n");
160 }
161 
162 
163 static
164 void power_off (void)
165 {
166  SELECT(); /* Wait for card ready */
167  wait_ready();
168  DESELECT();
169  rcvr_spi();
170 
171  Stat |= STA_NOINIT; /* Set STA_NOINIT */
172  DKPRINTF(0x01, "MMC Off\n");
173 }
174 
175 
176 
177 /*-----------------------------------------------------------------------*/
178 /* Receive a data packet from MMC */
179 /*-----------------------------------------------------------------------*/
180 
181 static
182 int rcvr_datablock (
183  BYTE *buff, /* Data buffer to store received data */
184  UINT btr /* Byte count (must be even number) */
185 )
186 {
187  BYTE token;
188 
189 //#define PKT_TOUT 100
190 #define PKT_TOUT 200
191  unsigned long Timer1 = PKT_TOUT + get_kernel_time();
192  unsigned long now_time = Timer1;
193 
194  DKPRINTF(0x01, "MMC read block buf=%08X size=%d\n", (int)buff, (int)btr);
195 
196  do { /* Wait for data packet in timeout of 100ms */
197  token = rcvr_spi();
198  } while ((token == 0xFF) && (Timer1 > (now_time = get_kernel_time())));
199  if(token != 0xFE) {
200  SYSERR_PRINT("data read error(token = %02X)\n", token);
201  SYSERR_PRINT("time = %ld\n", now_time - (Timer1 - PKT_TOUT));
202  return 0; /* If not valid data token, retutn with error */
203  }
204 
205 #ifdef NOTUSE_BLOCKREAD
206  do { /* Receive the data block into buffer */
207  *buff++ = rcvr_spi();
208  *buff++ = rcvr_spi();
209  } while (btr -= 2);
210 #else
211 // ioctl_device(mmc_spi, IOCMD_SPI_SPEED, 24000000UL); // SCK 24MHz
212 // ioctl_device(mmc_spi, IOCMD_SPI_SPEED, 12000000UL); // SCK 12MHz
213  read_device(mmc_spi, buff, btr);
214 #endif
215  rcvr_spi(); /* Discard CRC */
216  rcvr_spi();
217 
218  return 1; /* Return with success */
219 }
220 
221 
222 
223 /*-----------------------------------------------------------------------*/
224 /* Send a data packet to MMC */
225 /*-----------------------------------------------------------------------*/
226 
227 #if _READONLY == 0
228 static
229 int xmit_datablock (
230  const BYTE *buff, /* 512 byte data block to be transmitted */
231  BYTE token /* Data/Stop token */
232 )
233 {
234  BYTE resp;
235 #ifdef NOTUSE_BLOCKREAD
236  BYTE wc;
237 #endif
238 
239  if (wait_ready() != 0xFF) return 0;
240 
241  xmit_spi(token); /* Xmit data token */
242  if (token != 0xFD) { /* Is data token */
243 #ifdef NOTUSE_BLOCKREAD
244  wc = 0;
245  do { /* Xmit the 512 byte data block to MMC */
246  xmit_spi(*buff++);
247  xmit_spi(*buff++);
248  } while (--wc);
249 #else
250  write_device(mmc_spi, (unsigned char *)buff, 512);
251 #endif
252  xmit_spi(0xFF); /* CRC (Dummy) */
253  xmit_spi(0xFF);
254  resp = rcvr_spi(); /* Reveive data response */
255  if ((resp & 0x1F) != 0x05) { /* If not accepted, return with error */
256  SYSERR_PRINT("xmit_datablock() error(%02X)\n", resp);
257  return 0;
258  }
259  }
260 
261  return 1;
262 }
263 #endif /* _READONLY */
264 
265 
266 
267 /*-----------------------------------------------------------------------*/
268 /* Send a command packet to MMC */
269 /*-----------------------------------------------------------------------*/
270 
271 static
272 BYTE send_cmd (
273  BYTE cmd, /* Command byte */
274  DWORD arg /* Argument */
275 )
276 {
277  BYTE n, res;
278 
279  DKPRINTF(0x01, "MMC_cmd(%02X,%02X)\n", (int)cmd, (int)arg);
280 
281  if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
282  cmd &= 0x7F;
283  res = send_cmd(CMD55, 0);
284  if (res > 1) return res;
285  }
286 
287  /* Select the card and wait for ready */
288  DESELECT();
289  SELECT();
290  if (wait_ready() != 0xFF) return 0xFF;
291 
292  /* Send command packet */
293  xmit_spi(cmd); /* Start + Command index */
294  xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
295  xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
296  xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
297  xmit_spi((BYTE)arg); /* Argument[7..0] */
298  n = 0x01; /* Dummy CRC + Stop */
299  if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
300  if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
301  xmit_spi(n);
302 
303  /* Receive command response */
304  if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
305  n = 10; /* Wait for a valid response in timeout of 10 attempts */
306  do
307  res = rcvr_spi();
308  while ((res & 0x80) && --n);
309 
310  return res; /* Return with the response value */
311 }
312 
313 
314 
315 /*--------------------------------------------------------------------------
316 
317  Public Functions
318 
319 ---------------------------------------------------------------------------*/
320 
321 
322 /*-----------------------------------------------------------------------*/
323 /* Initialize Disk Drive */
324 /*-----------------------------------------------------------------------*/
325 
326 static DSTATUS mmc_disk_initialize (
327  BYTE drv /* Physical drive nmuber (0) */
328 )
329 {
330  BYTE n, ty, cmd, ocr[4];
331 
332  if (drv) return STA_NOINIT; /* Supports only single drive */
333  if (Stat & STA_NODISK) return Stat; /* No card in the socket */
334 
335  power_on(); /* Force socket power on */
336  ioctl_device(mmc_spi, IOCMD_SPI_SPEED, 400000UL, 0); // SCK 400KHz
337 
338  for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */
339 
340  ty = 0;
341  if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
342  unsigned long Timer1 = 1000 + get_kernel_time(); /* Initialization timeout of 1000 msec */
343  if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */
344  for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 resp */
345  if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
346  while ((Timer1 > get_kernel_time()) && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
347  if ((Timer1 > get_kernel_time()) && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
348  for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
349  ty = (ocr[0] & 0x40) ? 12 : 4;
350  }
351  }
352  } else { /* SDSC or MMC */
353  if (send_cmd(ACMD41, 0) <= 1) {
354  ty = 2; cmd = ACMD41; /* SDSC */
355  } else {
356  ty = 1; cmd = CMD1; /* MMC */
357  }
358  while ((Timer1 > get_kernel_time()) && send_cmd(cmd, 0)); /* Wait for leaving idle state */
359  if (!(Timer1 > get_kernel_time()) || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
360  ty = 0;
361  }
362  } else {
363  //SYSERR_PRINT("MMC COMMAND(CMD0) error\n");
364  }
365  CardType = ty;
366  release_spi();
367 
368  if (ty) { /* Initialization succeded */
369 // ioctl_device(mmc_spi, IOCMD_SPI_SPEED, 24000000UL, 0); // SCK 24MHz
370  ioctl_device(mmc_spi, IOCMD_SPI_SPEED, 12000000UL, 0); // SCK 12MHz
371  Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
372  } else { /* Initialization failed */
373  power_off();
374  //SYSERR_PRINT("MMC Initialization failed %d\n", ty);
375  }
376 
377  return Stat;
378 }
379 
380 
381 #if 0
382 /*-----------------------------------------------------------------------*/
383 /* Get Disk Status */
384 /*-----------------------------------------------------------------------*/
385 
386 static DSTATUS mmc_disk_status (
387  BYTE drv /* Drive number (0) */
388 )
389 {
390  return (drv) ? STA_NODISK : Stat;
391 }
392 #endif
393 
394 
395 /*-----------------------------------------------------------------------*/
396 /* Read Sector(s) */
397 /*-----------------------------------------------------------------------*/
398 
399 static DRESULT mmc_disk_read (
400  BYTE drv, /* Physical drive nmuber (0) */
401  BYTE *buff, /* Pointer to the data buffer to store read data */
402  DWORD sector, /* Start sector number (LBA) */
403  BYTE count /* Sector count (1..255) */
404 )
405 {
406  if (drv || !count) return RES_PARERR;
407  if (Stat & STA_NOINIT) return RES_NOTRDY;
408 
409  if (!(CardType & 8)) sector *= 512; /* Convert to byte address if needed */
410 
411  ioctl_device(mmc_spi, IOCMD_SPI_CS0ASSERT, 0, 0);
412 
413  if (count == 1) { /* Single block read */
414  if (send_cmd(CMD17, sector) == 0) { /* READ_SINGLE_BLOCK */
415  if(rcvr_datablock(buff, 512) != 0) {
416  count = 0;
417  } else {
418  SYSERR_PRINT("MMC single block read error\n");
419  }
420  } else {
421  SYSERR_PRINT("MMC CMD17 error\n");
422  }
423  }
424  else { /* Multiple block read */
425  if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
426  do {
427  if (!rcvr_datablock(buff, 512)) {
428  SYSERR_PRINT("MMC multiple block read error\n");
429  break;
430  }
431  buff += 512;
432  } while (--count);
433  send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
434  }
435  }
436  release_spi();
437 
438  return count ? RES_ERROR : RES_OK;
439 }
440 
441 
442 
443 /*-----------------------------------------------------------------------*/
444 /* Write Sector(s) */
445 /*-----------------------------------------------------------------------*/
446 
447 #if _READONLY == 0
448 static DRESULT mmc_disk_write (
449  BYTE drv, /* Physical drive nmuber (0) */
450  const BYTE *buff, /* Pointer to the data to be written */
451  DWORD sector, /* Start sector number (LBA) */
452  BYTE count /* Sector count (1..255) */
453 )
454 {
455  if (drv || !count) return RES_PARERR;
456  if (Stat & STA_NOINIT) return RES_NOTRDY;
457  if (Stat & STA_PROTECT) return RES_WRPRT;
458 
459  if (!(CardType & 8)) sector *= 512; /* Convert to byte address if needed */
460 
461 // ioctl_device(mmc_spi, IOCMD_SPI_CSASSERT, 0);
462 
463  if (count == 1) { /* Single block write */
464  if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
465  && xmit_datablock(buff, 0xFE))
466  count = 0;
467  }
468  else { /* Multiple block write */
469  if (CardType & 6) send_cmd(ACMD23, count);
470  if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
471  do {
472  if (!xmit_datablock(buff, 0xFC)) break;
473  buff += 512;
474  } while (--count);
475  if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
476  count = 1;
477  }
478  }
479  release_spi();
480 
481  return count ? RES_ERROR : RES_OK;
482 }
483 #endif /* _READONLY == 0 */
484 
485 
486 
487 /*-----------------------------------------------------------------------*/
488 /* Miscellaneous Functions */
489 /*-----------------------------------------------------------------------*/
490 
491 static DRESULT mmc_disk_ioctl (
492  BYTE drv, /* Physical drive nmuber (0) */
493  BYTE ctrl, /* Control code */
494  void *buff /* Buffer to send/receive control data */
495 )
496 {
497  DRESULT res;
498  BYTE n, csd[16], *ptr = buff;
499  WORD csize;
500 
501 
502  if (drv) return RES_PARERR;
503  if (Stat & STA_NOINIT) return RES_NOTRDY;
504 
505  res = RES_ERROR;
506 
507  ioctl_device(mmc_spi, IOCMD_SPI_CS0ASSERT, 0, 0);
508 
509  switch (ctrl) {
510  case CTRL_SYNC : /* Make sure that no pending write process */
511  SELECT();
512  if (wait_ready() == 0xFF)
513  res = RES_OK;
514  break;
515 
516  case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
517  if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
518  if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
519  csize = csd[9] + ((WORD)csd[8] << 8) + 1;
520  *(DWORD*)buff = (DWORD)csize << 10;
521  } else { /* SDC ver 1.XX or MMC */
522  n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
523  csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
524  *(DWORD*)buff = (DWORD)csize << (n - 9);
525  }
526  res = RES_OK;
527  }
528  break;
529 
530  case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
531  *(WORD*)buff = 512;
532  res = RES_OK;
533  break;
534 
535  case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
536  if (CardType & 4) { /* SDC ver 2.00 */
537  if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */
538  rcvr_spi();
539  if (rcvr_datablock(csd, 16)) { /* Read partial block */
540  for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */
541  *(DWORD*)buff = 16UL << (csd[10] >> 4);
542  res = RES_OK;
543  }
544  }
545  } else { /* SDC ver 1.XX or MMC */
546  if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */
547  if (CardType & 2) { /* SDC ver 1.XX */
548  *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
549  } else { /* MMC */
550  *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
551  }
552  res = RES_OK;
553  }
554  }
555  break;
556 
557  case MMC_GET_TYPE : /* Get card type flags (1 byte) */
558  *ptr = CardType;
559  res = RES_OK;
560  break;
561 
562  case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
563  if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
564  && rcvr_datablock(ptr, 16))
565  res = RES_OK;
566  break;
567 
568  case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
569  if (send_cmd(CMD10, 0) == 0 /* READ_CID */
570  && rcvr_datablock(ptr, 16))
571  res = RES_OK;
572  break;
573 
574  case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
575  if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
576  for (n = 4; n; n--) *ptr++ = rcvr_spi();
577  res = RES_OK;
578  }
579  break;
580 
581  case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */
582  if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */
583  rcvr_spi();
584  if (rcvr_datablock(ptr, 64))
585  res = RES_OK;
586  }
587  break;
588 
589  default:
590  res = RES_PARERR;
591  }
592 
593  release_spi();
594 
595  return res;
596 }
597 
598 /*
599  GadgetSeed ドライバ
600 */
601 
602 static int mmc_register(struct st_device *dev, char *param)
603 {
604  mmc_spi = open_device(param);
605  if(mmc_spi == 0) {
606  SYSERR_PRINT("cannot open device \"%s\"\n", param);
607  return -1;
608  }
609 
610  ioctl_device(mmc_spi, IOCMD_SPI_SPEED, 400000UL, 0); // SCK 400KHz
611  Stat = STA_NOINIT;
612 
613  power_off();
614 
615  return 0;
616 }
617 
618 static int mmc_unregister(struct st_device *dev)
619 {
620  return 0;
621 }
622 
623 static int mmc_open(struct st_device *dev)
624 {
625  DSTATUS stat;
626 
627  stat = mmc_disk_initialize(0);
628 
629  if(stat) {
630  //SYSERR_PRINT("MMC Initialize error(%d)\n", (int)stat);
631  return -1;
632  }
633 
634  return 0;
635 }
636 
637 static int mmc_close(struct st_device *dev)
638 {
639  Stat = STA_NOINIT;
640 
641  power_off();
642 
643  return 0;
644 }
645 
646 #define S_SIZ 512
647 
648 static int mmc_block_read(struct st_device *dev, void *data, unsigned int sector, unsigned int count)
649 {
650  if(mmc_disk_read(0, data, sector, count) == RES_OK) {
651  return count;
652  } else {
653  SYSERR_PRINT("MMC read error(data=%p,size=%d)\n", data, count);
654  return 0;
655  }
656 }
657 
658 static int mmc_block_write(struct st_device *dev, const void *data, unsigned int sector, unsigned int count)
659 {
660  if(mmc_disk_write(0, data, sector, count) == RES_OK) {
661  return count;
662  } else {
663  SYSERR_PRINT("MMC write error(data=%p,size=%d)\n", data, count);
664  return 0;
665  }
666 }
667 
668 static int mmc_ioctl(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
669 {
670  int rt = 0;
671 
672  switch(com) {
674  {
675  unsigned int sectorcount = 0;
676  mmc_disk_ioctl(0, GET_SECTOR_COUNT, (void *)&sectorcount);
677  rt = (int)sectorcount;
678  }
679  break;
680 
682  {
683  WORD sectorsize = 0;
684  mmc_disk_ioctl(0, GET_SECTOR_SIZE, (void *)&sectorsize);
685  rt = (int)sectorsize;
686  }
687  break;
688 
690  {
691  unsigned int blocksize = 0;
692  mmc_disk_ioctl(0, GET_BLOCK_SIZE, (void *)&blocksize);
693  rt = (int)blocksize;
694  }
695  break;
696 
697  default:
698  SYSERR_PRINT("Unknow command %08lX arg %08lX\n", com, arg);
699  return 0;
700  }
701 
702  return rt;
703 }
704 
705 static int mmc_sync(struct st_device *dev)
706 {
707  mmc_disk_ioctl(0, CTRL_SYNC, 0);
708 
709  return 0;
710 }
711 
712 static int mmc_suspend(struct st_device *dev)
713 {
714  power_off();
715 
716  return 0;
717 }
718 
719 static int mmc_resume(struct st_device *dev)
720 {
721  return mmc_open(dev); // 暫定
722 }
723 
724 const struct st_device mmc_device = {
726  .explan = "MMC/SD SPI mode Strage",
727  .register_dev = mmc_register,
728  .unregister_dev = mmc_unregister,
729  .open = mmc_open,
730  .close = mmc_close,
731  .block_read = mmc_block_read,
732  .block_write = mmc_block_write,
733  .ioctl = mmc_ioctl,
734  .sync = mmc_sync,
735  .suspend = mmc_suspend,
736  .resume = mmc_resume,
737 };
#define IOCMD_SD_GET_SECTOR_COUNT
セクタ数を取得する
Definition: sd_ioctl.h:17
#define IOCMD_SPI_CS0NEGATE
CS0をネゲートする
Definition: spi_ioctl.h:22
#define IOCMD_SD_GET_BLOCK_SIZE
消去ブロックサイズを取得する
Definition: sd_ioctl.h:19
struct st_device * open_device(char *name)
デバイスをオープンする
Definition: device.c:262
SPIドライバ ioctl 用マクロ定義
int write_device(struct st_device *dev, const void *buf, unsigned int count)
デバイスにデータを書き込む
Definition: device.c:451
int read_device(struct st_device *dev, void *buf, unsigned int count)
デバイスよりデータを読み出す
Definition: device.c:378
#define IOCMD_SPI_SPEED
com : 転送速度を設定する, arg : 転送速度(bps)
Definition: spi_ioctl.h:18
#define DEF_DEV_NAME_SD
標準ストレージデバイス名(MMC,SD等)
Definition: sd_ioctl.h:15
カーネルタイマ
#define IOCMD_SD_GET_SECTOR_SIZE
1セクタサイズを取得する
Definition: sd_ioctl.h:18
カーネル用機能限定printf
int getc_device(struct st_device *dev, unsigned char *data)
デバイスよりデータを1バイト読み出す
Definition: device.c:429
#define IOCMD_SPI_CS0ASSERT
CS0をアサートしたままにする
Definition: spi_ioctl.h:21
int putc_device(struct st_device *dev, unsigned char data)
デバイスにデータを1バイト書き込む
Definition: device.c:502
void wait_time(unsigned int time)
指定時間待つ
Definition: timer.c:216
ストレージデバイスドライバ ioctl 用マクロ定義
unsigned long long get_kernel_time(void)
カーネル時間を取得する
Definition: timer.c:192
デバイスドライバAPI
デバイスドライバ構造体
Definition: device.h:25
カーネル、ドライバ(非タスク)デバッグ用マクロ
int ioctl_device(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
デバイスを制御する
Definition: device.c:525
char name[MAX_DEVNAMELRN]
デバイス名文字列
Definition: device.h:26