drv_sdcard.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <rtdevice.h>
  10. #include <rtthread.h>
  11. #include <dfs_fs.h>
  12. #include "drv_sdcard.h"
  13. #include "fsl_card.h"
  14. static sd_card_t g_sd;
  15. static sd_card_t *card = &g_sd;
  16. static struct rt_device sdcard_device;
  17. static struct dfs_partition part;
  18. static rt_err_t vega_sdcard_init(rt_device_t dev)
  19. {
  20. return RT_EOK;
  21. }
  22. static rt_err_t vega_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  23. {
  24. return RT_EOK;
  25. }
  26. static rt_err_t vega_sdcard_close(rt_device_t dev)
  27. {
  28. return RT_EOK;
  29. }
  30. static rt_size_t vega_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  31. {
  32. status_t status;
  33. status = SD_ReadBlocks(card, buffer, part.offset + pos, size);
  34. if (status == kStatus_Success) return size;
  35. rt_kprintf("read failed: %d, pos 0x%08x, size %d\n", status, pos, size);
  36. return 0;
  37. }
  38. static rt_size_t vega_sdcard_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  39. {
  40. status_t status;
  41. status = SD_WriteBlocks(card, buffer, part.offset + pos, size);
  42. if (status == kStatus_Success) return size;
  43. rt_kprintf("write failed: %d, pos 0x%08x, size %d\n", status, pos, size);
  44. return 0;
  45. }
  46. static rt_err_t vega_sdcard_control(rt_device_t dev, int cmd, void *args)
  47. {
  48. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  49. {
  50. struct rt_device_blk_geometry *geometry;
  51. geometry = (struct rt_device_blk_geometry *)args;
  52. if (geometry == RT_NULL) return -RT_ERROR;
  53. if (dev->user_data == RT_NULL) return -RT_ERROR;
  54. geometry->bytes_per_sector = card->blockSize;
  55. geometry->block_size = card->blockSize;
  56. geometry->sector_count = card->blockCount;
  57. }
  58. return RT_EOK;
  59. }
  60. int rt_hw_sdcard_init(void)
  61. {
  62. /* set SDHC0 clock source */
  63. CLOCK_SetIpSrc(kCLOCK_Sdhc0, kCLOCK_IpSrcLpFllAsync);
  64. /* Save host information. */
  65. card->host.base = USDHC0;
  66. card->host.sourceClock_Hz = CLOCK_GetIpFreq(kCLOCK_Sdhc0);
  67. /* Init card. */
  68. if (SD_Init(card))
  69. {
  70. rt_kprintf("SD card init failed.\r\n");
  71. return -1;
  72. }
  73. else
  74. {
  75. bool status;
  76. rt_uint8_t *sector;
  77. /* get the first sector to read partition table */
  78. sector = (rt_uint8_t *) rt_malloc(card->blockSize);
  79. if (sector == RT_NULL)
  80. {
  81. rt_kprintf("allocate partition sector buffer failed\n");
  82. return -1;
  83. }
  84. status = SD_ReadBlocks(card, sector, 0, 1);
  85. if (status == true)
  86. {
  87. /* get the first partition */
  88. if (dfs_filesystem_get_partition(&part, sector, 0) != 0)
  89. {
  90. /* there is no partition */
  91. part.offset = 0;
  92. part.size = 0;
  93. }
  94. }
  95. else
  96. {
  97. /* there is no partition table */
  98. part.offset = 0;
  99. part.size = 0;
  100. }
  101. /* release sector buffer */
  102. rt_free(sector);
  103. /* register sdcard device */
  104. sdcard_device.type = RT_Device_Class_Block;
  105. sdcard_device.init = vega_sdcard_init;
  106. sdcard_device.open = vega_sdcard_open;
  107. sdcard_device.close = vega_sdcard_close;
  108. sdcard_device.read = vega_sdcard_read;
  109. sdcard_device.write = vega_sdcard_write;
  110. sdcard_device.control = vega_sdcard_control;
  111. /* no private */
  112. sdcard_device.user_data = (void*)card;
  113. rt_device_register(&sdcard_device, "sd0",
  114. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  115. }
  116. return 0;
  117. }
  118. INIT_DEVICE_EXPORT(rt_hw_sdcard_init);