µGFX  2.9
version 2.9
gfile_petitfs_diskio_chibios.c
1 /*-----------------------------------------------------------------------*/
2 /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
3 /*-----------------------------------------------------------------------*/
4 /* This is a stub disk I/O module that acts as front end of the existing */
5 /* disk I/O modules and attach it to FatFs module with common interface. */
6 /*-----------------------------------------------------------------------*/
7 
8 #include "../../gfx.h"
9 
10 #if GFX_USE_GFILE && GFILE_NEED_PETITFS && GFX_USE_OS_CHIBIOS && !GFILE_PETITFS_EXTERNAL_LIB
11 
12 #include "gfile_petitfs_wrapper.h"
13 #include <string.h>
14 
15 #if HAL_USE_MMC_SPI && HAL_USE_SDC
16  #error "cannot specify both MMC_SPI and SDC drivers"
17 #endif
18 
19 #if HAL_USE_MMC_SPI
20  extern MMCDriver MMCD1;
21 #elif HAL_USE_SDC
22  extern SDCDriver SDCD1;
23 #else
24  #error "MMC_SPI or SDC driver must be specified"
25 #endif
26 
27 // WOW - Bugs galore!!! (in ChibiOS)
28 // Bugs:
29 // 1. ChibiOS DMA operations do not do the appropriate cache flushing or invalidating
30 // on cpu's that require it eg STM32F7 series.
31 // Instead they provide explicit dmaBufferInvalidate and dmaBufferFlush calls
32 // and rely on the user to explicitly flush the cache.
33 // Solution: We explicitly flush the cache after any possible DMA operation.
34 // 2. Unfortunately these explicit routines also have a bug. They assume that the
35 // specified data structure is aligned on a cache line boundary - not a good assumption.
36 // Solution: We increase the size provided to ChibiOS so that it does it properly.
37 // This assumes of course that we know the size of the cpu cache line.
38 #if CH_KERNEL_MAJOR > 2
39  #define CPU_CACHE_LINE_SIZE 32
40  #define CACHE_FLUSH(buf, sz) dmaBufferFlush((buf), (sz)+(CPU_CACHE_LINE_SIZE-1))
41  #define CACHE_INVALIDATE(buf, sz) dmaBufferInvalidate((buf), (sz)+(CPU_CACHE_LINE_SIZE-1))
42 #else
43  #define CACHE_FLUSH(buf, sz)
44  #define CACHE_INVALIDATE(buf, sz)
45 #endif
46 
47 /*-----------------------------------------------------------------------*/
48 /* Initialize a Drive */
49 
50 DSTATUS disk_initialize (void) {
51 #if HAL_USE_MMC_SPI
52  /* It is initialized externally, just reads the status.*/
53  if (blkGetDriverState(&MMCD1) != BLK_READY)
54  return STA_NOINIT;
55 #else
56  /* It is initialized externally, just reads the status.*/
57  if (blkGetDriverState(&SDCD1) != BLK_READY)
58  return STA_NOINIT;
59 #endif
60  // All good
61  return 0;
62 }
63 
64 /*-----------------------------------------------------------------------*/
65 /* Read Part Sector(s) */
66 
67 static BYTE sectBuf[512];
68 static DWORD sectpos = -1;
69 
70 DRESULT disk_readp (
71  BYTE* buff, /* [OUT] Pointer to the read buffer */
72  DWORD sector, /* [IN] Sector number */
73  UINT offset, /* [IN] Byte offset in the sector to start to read */
74  UINT count /* [IN] Number of bytes to read */
75  ) {
76 
77  if (sector != sectpos) {
78  #if HAL_USE_MMC_SPI
79  if (blkGetDriverState(&MMCD1) != BLK_READY)
80  return RES_NOTRDY;
81  if (mmcStartSequentialRead(&MMCD1, sector))
82  return RES_ERROR;
83  if (mmcSequentialRead(&MMCD1, sectBuf))
84  return RES_ERROR;
85  if (mmcStopSequentialRead(&MMCD1))
86  return RES_ERROR;
87  #else
88  if (blkGetDriverState(&SDCD1) != BLK_READY)
89  return RES_NOTRDY;
90  if (sdcRead(&SDCD1, sector, sectBuf, 1))
91  return RES_ERROR;
92  #endif
93  sectpos = sector;
94  CACHE_INVALIDATE(sectBuf, sizeof(sectBuf));
95  }
96  memcpy(buff, sectBuf + offset, count);
97  return RES_OK;
98 }
99 
100 #endif // GFX_USE_GFILE && GFILE_NEED_PETITFS && GFX_USE_OS_CHIBIOS && !GFILE_PETITFS_EXTERNAL_LIB
101 
102 
GFILE PETITFS wrapper.