1 /*-----------------------------------------------------------------------*/
2 /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
3 /*-----------------------------------------------------------------------*/
4 /* If a working storage control module is available, it should be        */
5 /* attached to the FatFs via a glue function rather than modifying it.   */
6 /* This is an example of glue functions to attach various exsisting      */
7 /* storage control modules to the FatFs module with a defined API.       */
8 /*-----------------------------------------------------------------------*/
9 /*----------------------------------------------------------------------------/
10 /  FatFs - Generic FAT file system module  R0.12a                             /
11 /-----------------------------------------------------------------------------/
12 /
13 / Copyright (C) 2016, ChaN, all right reserved.
14 /
15 / FatFs module is an open source software. Redistribution and use of FatFs in
16 / source and binary forms, with or without modification, are permitted provided
17 / that the following condition is met:
18 
19 / 1. Redistributions of source code must retain the above copyright notice,
20 /    this condition and the following disclaimer.
21 /
22 / This software is provided by the copyright holder and contributors "AS IS"
23 / and any warranties related to this software are DISCLAIMED.
24 / The copyright owner or contributors be NOT LIABLE for any damages caused
25 / by use of this software.
26 /----------------------------------------------------------------------------*/
27 
28 #include <ff.h>
29 #include <diskio.h>	/* FatFs lower layer API */
30 #include <ffconf.h>
31 #include <disk/disk_access.h>
32 
33 static const char* const pdrv_str[] = {FF_VOLUME_STRS};
34 
35 /*-----------------------------------------------------------------------*/
36 /* Get Drive Status                                                      */
37 /*-----------------------------------------------------------------------*/
38 
disk_status(BYTE pdrv)39 DSTATUS disk_status(BYTE pdrv)
40 {
41 	__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
42 
43 	if (disk_access_status(pdrv_str[pdrv]) != 0) {
44 		return STA_NOINIT;
45 	} else {
46 		return RES_OK;
47 	}
48 }
49 
50 /*-----------------------------------------------------------------------*/
51 /* Initialize a Drive                                                    */
52 /*-----------------------------------------------------------------------*/
53 
disk_initialize(BYTE pdrv)54 DSTATUS disk_initialize(BYTE pdrv)
55 {
56 	__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
57 
58 	if (disk_access_init(pdrv_str[pdrv]) != 0) {
59 		return STA_NOINIT;
60 	} else {
61 		return RES_OK;
62 	}
63 }
64 
65 /*-----------------------------------------------------------------------*/
66 /* Read Sector(s)                                                        */
67 /*-----------------------------------------------------------------------*/
68 
disk_read(BYTE pdrv,BYTE * buff,DWORD sector,UINT count)69 DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
70 {
71 	__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
72 
73 	if (disk_access_read(pdrv_str[pdrv], buff, sector, count) != 0) {
74 		return RES_ERROR;
75 	} else {
76 		return RES_OK;
77 	}
78 
79 }
80 
81 /*-----------------------------------------------------------------------*/
82 /* Write Sector(s)                                                       */
83 /*-----------------------------------------------------------------------*/
disk_write(BYTE pdrv,const BYTE * buff,DWORD sector,UINT count)84 DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
85 {
86 	__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
87 
88 	if(disk_access_write(pdrv_str[pdrv], buff, sector, count) != 0) {
89 		return RES_ERROR;
90 	} else {
91 		return RES_OK;
92 	}
93 }
94 
95 /*-----------------------------------------------------------------------*/
96 /* Miscellaneous Functions                                               */
97 /*-----------------------------------------------------------------------*/
98 
disk_ioctl(BYTE pdrv,BYTE cmd,void * buff)99 DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
100 {
101 	int ret = RES_OK;
102 	uint32_t sector_size = 0;
103 
104 	__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
105 
106 	switch (cmd) {
107 	case CTRL_SYNC:
108 		if(disk_access_ioctl(pdrv_str[pdrv],
109 				DISK_IOCTL_CTRL_SYNC, buff) != 0) {
110 			ret = RES_ERROR;
111 		}
112 		break;
113 
114 	case GET_SECTOR_COUNT:
115 		if (disk_access_ioctl(pdrv_str[pdrv],
116 				DISK_IOCTL_GET_SECTOR_COUNT, buff) != 0) {
117 			ret = RES_ERROR;
118 		}
119 		break;
120 
121 	case GET_SECTOR_SIZE:
122 		/* Zephyr's DISK_IOCTL_GET_SECTOR_SIZE returns sector size as a
123 		 * 32-bit number while FatFS's GET_SECTOR_SIZE is supposed to
124 		 * return a 16-bit number.
125 		 */
126 		if ((disk_access_ioctl(pdrv_str[pdrv],
127 				DISK_IOCTL_GET_SECTOR_SIZE, &sector_size) == 0) &&
128 			(sector_size == (uint16_t)sector_size)) {
129 			*(uint16_t *)buff = (uint16_t)sector_size;
130 		} else {
131 			ret = RES_ERROR;
132 		}
133 		break;
134 
135 	case GET_BLOCK_SIZE:
136 		if (disk_access_ioctl(pdrv_str[pdrv],
137 				DISK_IOCTL_GET_ERASE_BLOCK_SZ, buff) != 0) {
138 			ret = RES_ERROR;
139 		}
140 		break;
141 
142 	default:
143 		ret = RES_PARERR;
144 		break;
145 	}
146 	return ret;
147 }
148