Browse Source

update:fatfs升级至15

Dozingfiretruck 3 years ago
parent
commit
c3759bda0a

+ 1 - 9
components/fatfs/diskio.h

@@ -55,7 +55,7 @@ DRESULT diskio_close(BYTE pdrv);
 #define STA_PROTECT		0x04	/* Write protected */
 
 
-/* Command code for disk_ioctrl function */
+/* Command code for disk_ioctrl fucntion */
 
 /* Generic command (Used by FatFs) */
 #define CTRL_SYNC			0	/* Complete pending write process (needed at FF_FS_READONLY == 0) */
@@ -85,14 +85,6 @@ DRESULT diskio_close(BYTE pdrv);
 #define ATA_GET_MODEL		21	/* Get model name */
 #define ATA_GET_SN			22	/* Get serial number */
 
-/* MMC card type flags (MMC_GET_TYPE) */
-#define CT_MMC		0x01		/* MMC ver 3 */
-#define CT_SD1		0x02		/* SD ver 1 */
-#define CT_SD2		0x04		/* SD ver 2 */
-#define CT_SDC		(CT_SD1|CT_SD2)	/* SD */
-#define CT_BLOCK	0x08		/* Block addressing */
-
-
 #ifdef __cplusplus
 }
 #endif

+ 2 - 1
components/fatfs/diskio_impl.c

@@ -1,5 +1,5 @@
 /*-----------------------------------------------------------------------*/
-/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
+/* Low level disk I/O module SKELETON for FatFs     (C)ChaN, 2019        */
 /*-----------------------------------------------------------------------*/
 /* If a working storage control module is available, it should be        */
 /* attached to the FatFs via a glue function rather than modifying it.   */
@@ -102,3 +102,4 @@ DWORD get_fattime (void) {
 			| (0U >> 1) /* Sec = 0 */
 	;
 }
+

+ 326 - 244
components/fatfs/diskio_spitf.c

@@ -16,12 +16,9 @@
 #include "ff.h"			/* Obtains integer types */
 #include "diskio.h"		/* Declarations of disk functions */
 
-#define LUAT_LOG_TAG "luat.fatfs"
+#define LUAT_LOG_TAG "fatfs"
 #include "luat_log.h"
 
-// 与 diskio_spitf.c 对齐
-
-
 extern BYTE FATFS_DEBUG; // debug log, 0 -- disable , 1 -- enable
 
 /*--------------------------------------------------------------------------
@@ -30,20 +27,19 @@ extern BYTE FATFS_DEBUG; // debug log, 0 -- disable , 1 -- enable
 
 ---------------------------------------------------------------------------*/
 
-/* MMC/SD command (SPI mode) */
+/* MMC/SD command */
 #define CMD0	(0)			/* GO_IDLE_STATE */
-#define CMD1	(1)			/* SEND_OP_COND */
+#define CMD1	(1)			/* SEND_OP_COND (MMC) */
 #define	ACMD41	(0x80+41)	/* SEND_OP_COND (SDC) */
 #define CMD8	(8)			/* SEND_IF_COND */
 #define CMD9	(9)			/* SEND_CSD */
 #define CMD10	(10)		/* SEND_CID */
 #define CMD12	(12)		/* STOP_TRANSMISSION */
-#define CMD13	(13)		/* SEND_STATUS */
 #define ACMD13	(0x80+13)	/* SD_STATUS (SDC) */
 #define CMD16	(16)		/* SET_BLOCKLEN */
 #define CMD17	(17)		/* READ_SINGLE_BLOCK */
 #define CMD18	(18)		/* READ_MULTIPLE_BLOCK */
-#define CMD23	(23)		/* SET_BLOCK_COUNT */
+#define CMD23	(23)		/* SET_BLOCK_COUNT (MMC) */
 #define	ACMD23	(0x80+23)	/* SET_WR_BLK_ERASE_COUNT (SDC) */
 #define CMD24	(24)		/* WRITE_BLOCK */
 #define CMD25	(25)		/* WRITE_MULTIPLE_BLOCK */
@@ -53,128 +49,121 @@ extern BYTE FATFS_DEBUG; // debug log, 0 -- disable , 1 -- enable
 #define CMD55	(55)		/* APP_CMD */
 #define CMD58	(58)		/* READ_OCR */
 
+#define SD_ACMD_SD_SEND_OP_COND		  41 /*!< ACMD41*/
 
-static
-DSTATUS Stat = STA_NOINIT;	/* Disk status */
+/* MMC card type flags (MMC_GET_TYPE) */
+#define CT_MMC3		0x01		/* MMC ver 3 */
+#define CT_MMC4		0x02		/* MMC ver 4+ */
+#define CT_MMC		0x03		/* MMC */
+#define CT_SDC1		0x02		/* SDC ver 1 */
+#define CT_SDC2		0x04		/* SDC ver 2+ */
+#define CT_SDC		0x0C		/* SDC */
+#define CT_BLOCK	0x10		/* Block addressing */
+
+
+static volatile DSTATUS Stat = STA_NOINIT;	/* Physical drive status */
 
 static
 BYTE CardType;			/* b0:MMC, b1:SDv1, b2:SDv2, b3:Block addressing */
 
-
-// static void dly_us(BYTE us) {
-// 	if (us < 1) {
-// 		return;
-// 	}
-// 	us += 999;
-// 	luat_timer_mdelay(us/1000);
-// }
 #define dly_us luat_timer_us_delay
+#define dly_ms luat_timer_mdelay
 
-/*-----------------------------------------------------------------------*/
-/* Transmit bytes to the card (bitbanging)                               */
-/*-----------------------------------------------------------------------*/
+static void spitf_cs_low(luat_fatfs_spi_t* userdata){
+	if(userdata->type == 1){
+		luat_gpio_set(userdata->spi_device->spi_config.cs, 0);
+	}else{
+		luat_gpio_set(userdata->spi_cs, 0);
+	}
+}
 
-static
-void xmit_mmc (
-	const BYTE* buff,	/* Data to be sent */
-	UINT bc,				/* Number of bytes to send */
-	luat_fatfs_spi_t* userdata
-)
-{
-	#if 0
-	BYTE d;
+static void spitf_cs_high(luat_fatfs_spi_t* userdata){
+	if(userdata->type == 1){
+		luat_gpio_set(userdata->spi_device->spi_config.cs, 1);
+	}else{
+		luat_gpio_set(userdata->spi_cs, 1);
+	}
+}
 
+static void spitf_transfer(const char* send_buf, size_t send_length, char* recv_buf, size_t recv_length,luat_fatfs_spi_t* userdata){
+	if(userdata->type == 1){
+		luat_spi_device_transfer(userdata->spi_device, send_buf, send_length, recv_buf, recv_length);
+	}else{
+		luat_spi_transfer(userdata->spi_id, send_buf, send_length, recv_buf, recv_length);
+	}
+}
 
-	do {
-		d = *buff++;	/* Get a byte to be sent */
-		if (d & 0x80) DI_H(); else DI_L();	/* bit7 */
-		CK_H(); CK_L();
-		if (d & 0x40) DI_H(); else DI_L();	/* bit6 */
-		CK_H(); CK_L();
-		if (d & 0x20) DI_H(); else DI_L();	/* bit5 */
-		CK_H(); CK_L();
-		if (d & 0x10) DI_H(); else DI_L();	/* bit4 */
-		CK_H(); CK_L();
-		if (d & 0x08) DI_H(); else DI_L();	/* bit3 */
-		CK_H(); CK_L();
-		if (d & 0x04) DI_H(); else DI_L();	/* bit2 */
-		CK_H(); CK_L();
-		if (d & 0x02) DI_H(); else DI_L();	/* bit1 */
-		CK_H(); CK_L();
-		if (d & 0x01) DI_H(); else DI_L();	/* bit0 */
-		CK_H(); CK_L();
-	} while (--bc);
-	#endif
-	if (FATFS_DEBUG)
-		LLOGD("[FatFS]xmit_mmc bc=%d\r\n", bc);
+static void spitf_send(const char *send_buf, size_t length,luat_fatfs_spi_t* userdata){
 	if(userdata->type == 1){
-		luat_spi_device_send(userdata->spi_device, (char*)buff, bc);
+		luat_spi_device_send(userdata->spi_device, send_buf, length);
 	}else{
-		luat_spi_send(userdata->spi_id, (const char*)buff, bc);
+		luat_spi_send(userdata->spi_id, send_buf, length);
+	}
+}
+
+static void spitf_recv(char *recv_buf, size_t length,luat_fatfs_spi_t* userdata){
+	if(userdata->type == 1){
+		luat_spi_device_recv(userdata->spi_device, recv_buf, length);
+	}else{
+		luat_spi_recv(userdata->spi_id, recv_buf, length);
 	}
-	
 }
 
+static uint8_t spitf_crc7(uint8_t * buf, int cnt){
+	int i,a;
+	uint8_t crc,Data;
+	crc=0;
+	for (a=0;a<cnt;a++){
+		Data=buf[a];
+		for (i=0;i<8;i++){
+		crc <<= 1;
+		if ((Data & 0x80)^(crc & 0x80))
+		crc ^=0x09;
+		Data <<= 1;
+		}
+	}
+	crc=(crc<<1)|1;
+	return(crc);
+}
 
+static uint8_t spitf_send_cmd(uint8_t cmd, uint32_t arg, uint8_t cs_high,luat_fatfs_spi_t* userdata){
+	uint32_t i = 0x00;
+	uint8_t r1;
+	spitf_cs_low(userdata);
+	userdata->transfer_buf[0] = (cmd | 0x40); /*!< Construct byte 1 */
+	userdata->transfer_buf[1] = (uint8_t)(arg >> 24); /*!< Construct byte 2 */
+	userdata->transfer_buf[2] = (uint8_t)(arg >> 16); /*!< Construct byte 3 */
+	userdata->transfer_buf[3] = (uint8_t)(arg >> 8); /*!< Construct byte 4 */
+	userdata->transfer_buf[4] = (uint8_t)(arg); /*!< Construct byte 5 */
+	userdata->transfer_buf[5] = spitf_crc7(userdata->transfer_buf,5); /*!< Construct CRC: byte 6 */
+	userdata->transfer_buf[6] = 0xFF;
+	spitf_send((const char *)(userdata->transfer_buf),7,userdata);
+
+	for (size_t i = 0; i < 10; i++){
+		spitf_recv(&r1, 1,userdata);
+		if ((r1&0x80) == 0) break;
+	}
+	if (cs_high){
+		spitf_cs_high(userdata);
+		userdata->transfer_buf[0] = 0xFF; 
+		spitf_send((const char *)(userdata->transfer_buf),1,userdata);
+	}
+	return r1;
+}
 
 /*-----------------------------------------------------------------------*/
-/* Receive bytes from the card (bitbanging)                              */
+/* Transmit bytes to the card (bitbanging)                               */
 /*-----------------------------------------------------------------------*/
 
-static
-void rcvr_mmc (
-	BYTE *buff,	/* Pointer to read buffer */
-	UINT bc,		/* Number of bytes to receive */
+/* Exchange a byte */
+static BYTE xchg_spi (
+	BYTE dat,	/* Data to send */
 	luat_fatfs_spi_t* userdata
 )
 {
-	#if 0
-	BYTE r;
-
-
-	DI_H();	/* Send 0xFF */
-
-	do {
-		r = 0;	 if (DO) r++;	/* bit7 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit6 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit5 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit4 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit3 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit2 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit1 */
-		CK_H(); CK_L();
-		r <<= 1; if (DO) r++;	/* bit0 */
-		CK_H(); CK_L();
-		*buff++ = r;			/* Store a received byte */
-	} while (--bc);
-	#endif
-	//u8* buf2 = 0x00;
-	//u8** buf = &buf2;
-	// BYTE tmp[bc];
-	
-	// for(size_t i = 0; i < bc; i++)
-	// {
-	// 	tmp[i] = 0xFF;
-	// }
-	
-	//DWORD t = luat_spi_transfer(userdata->spi_id, tmp, buff, bc);
-	//s32 t = platform_spi_recv(0, buf, bc);
-	if(userdata->type == 1){
-		luat_spi_device_recv(userdata->spi_device, (char*)buff, bc);
-	}else{
-		luat_spi_recv(userdata->spi_id, (char*)buff, bc);
-	}
-		
-	//memcpy(buff, buf2, bc);
-	//if (FATFS_DEBUG)
-	//	LLOGD("[FatFS]rcvr_mmc first resp byte=%02X, t=%d\r\n", buf2[0], t);
-	//free(buf2);
+	BYTE buff;
+	spitf_transfer((const char *)&dat, 1, (char *)&buff, 1, userdata);
+	return buff;
 }
 
 
@@ -184,19 +173,18 @@ void rcvr_mmc (
 /*-----------------------------------------------------------------------*/
 
 static
-int wait_ready (luat_fatfs_spi_t* userdata)	/* 1:OK, 0:Timeout */
+int wait_ready (UINT wt,luat_fatfs_spi_t* userdata)	/* 1:OK, 0:Timeout */
 {
 	BYTE d;
 	UINT tmr;
 
-
-	for (tmr = 5000; tmr; tmr--) {	/* Wait for ready in timeout of 500ms */
-		rcvr_mmc(&d, 1, userdata);
+	for (tmr = wt; tmr; tmr--) {	/* Wait for ready in timeout of 500ms */
+		d = xchg_spi(0xFF,userdata);
 		if (d == 0xFF) break;
-		dly_us(100);
+		dly_us(1000);
 	}
 
-	return tmr ? 1 : 0;
+	return (d == 0xFF) ? 1 : 0;
 }
 
 
@@ -208,15 +196,11 @@ int wait_ready (luat_fatfs_spi_t* userdata)	/* 1:OK, 0:Timeout */
 static
 void spi_cs_deselect (luat_fatfs_spi_t* userdata)
 {
-	BYTE d;
-
-	//CS_H();				/* Set CS# high */
-	//platform_pio_op(0, 1 << userdata->spi_cs, 0);
 	if(userdata->type == 1){
-		// rcvr_mmc(&d, 1);
+		// xchg_spi(userdata);
 	}else{
 		luat_gpio_set(userdata->spi_cs, 1);
-		rcvr_mmc(&d, 1, userdata);	/* Dummy clock (force DO hi-z for multiple slave SPI) */
+		xchg_spi(0xFF,userdata);	/* Dummy clock (force DO hi-z for multiple slave SPI) */
 	}
 	
 }
@@ -230,24 +214,47 @@ void spi_cs_deselect (luat_fatfs_spi_t* userdata)
 static
 int spi_cs_select (luat_fatfs_spi_t* userdata)	/* 1:OK, 0:Timeout */
 {
-	BYTE d;
-
-	//CS_L();				/* Set CS# low */
-	//platform_pio_op(0, 1 << userdata->spi_cs, 1);
 	if(userdata->type == 1){
-		rcvr_mmc(&d, 1, userdata);
+		xchg_spi(0xFF,userdata);
 	}else{
 		luat_gpio_set(userdata->spi_cs, 0);
-		rcvr_mmc(&d, 1, userdata);	/* Dummy clock (force DO enabled) */
+		xchg_spi(0xFF,userdata);	/* Dummy clock (force DO enabled) */
 	}
 	
-	if (wait_ready(userdata)) return 1;	/* Wait for card ready */
+	if (wait_ready(500,userdata)) return 1;	/* Wait for card ready */
 
 	spi_cs_deselect(userdata);
 	return 0;			/* Failed */
 }
 
 
+/* Receive multiple byte */
+static void rcvr_spi_multi (
+	BYTE *buff,		/* Pointer to data buffer */
+	UINT btr,		/* Number of bytes to receive (even number) */
+	luat_fatfs_spi_t* userdata
+)
+{
+	if(userdata->type == 1){
+		luat_spi_device_recv(userdata->spi_device, (char*)buff, btr);
+	}else{
+		luat_spi_recv(userdata->spi_id, (char*)buff, btr);
+	}
+}
+
+/* Send multiple byte */
+static void xmit_spi_multi (
+	const BYTE *buff,	/* Pointer to the data */
+	UINT btx,			/* Number of bytes to send (even number) */
+	luat_fatfs_spi_t* userdata
+)
+{
+	if(userdata->type == 1){
+		luat_spi_device_send(userdata->spi_device, (const char*)buff, btx);
+	}else{
+		luat_spi_send(userdata->spi_id, (const char*)buff, btx);
+	}
+}
 
 /*-----------------------------------------------------------------------*/
 /* Receive a data packet from the card                                   */
@@ -260,19 +267,20 @@ int rcvr_datablock (	/* 1:OK, 0:Failed */
 	luat_fatfs_spi_t* userdata
 )
 {
-	BYTE d[2];
+	BYTE token;
 	UINT tmr;
 
 
-	for (tmr = 1000; tmr; tmr--) {	/* Wait for data packet in timeout of 100ms */
-		rcvr_mmc(d, 1, userdata);
-		if (d[0] != 0xFF) break;
+	for (tmr = 2000; tmr; tmr--) {	/* Wait for data packet in timeout of 100ms */
+		token = xchg_spi(0xFF,userdata);
+		if (token != 0xFF) break;
 		dly_us(100);
 	}
-	if (d[0] != 0xFE) return 0;		/* If not valid data token, return with error */
+	if (token != 0xFE) return 0;		/* If not valid data token, return with error */
 
-	rcvr_mmc(buff, btr, userdata);			/* Receive the data block into buffer */
-	rcvr_mmc(d, 2, userdata);					/* Discard CRC */
+	rcvr_spi_multi(buff, btr, userdata);			/* Receive the data block into buffer */
+
+	xchg_spi(0xFF,userdata);xchg_spi(0xFF,userdata);					/* Discard CRC */
 
 	return 1;						/* Return with success */
 }
@@ -290,18 +298,15 @@ int xmit_datablock (	/* 1:OK, 0:Failed */
 	luat_fatfs_spi_t* userdata
 )
 {
-	BYTE d[2];
-
+	BYTE resp;
+	if (!wait_ready(500,userdata)) return 0;
 
-	if (!wait_ready(userdata)) return 0;
-
-	d[0] = token;
-	xmit_mmc(d, 1, userdata);				/* Xmit a token */
+	xchg_spi(token, userdata);				/* Xmit a token */
 	if (token != 0xFD) {		/* Is it data token? */
-		xmit_mmc(buff, 512, userdata);	/* Xmit the 512 byte data block to MMC */
-		rcvr_mmc(d, 2, userdata);			/* Xmit dummy CRC (0xFF,0xFF) */
-		rcvr_mmc(d, 1, userdata);			/* Receive data response */
-		if ((d[0] & 0x1F) != 0x05)	/* If not accepted, return with error */
+		xmit_spi_multi(buff, 512, userdata);	/* Data */
+		xchg_spi(0xFF, userdata);xchg_spi(0xFF, userdata);/* Dummy CRC */
+		resp = xchg_spi(0xFF, userdata);			/* Receive data response */
+		if ((resp & 0x1F) != 0x05)	/* If not accepted, return with error */
 			return 0;
 	}
 
@@ -321,13 +326,12 @@ BYTE send_cmd (		/* Returns command response (bit7==1:Send failed)*/
 	luat_fatfs_spi_t* userdata
 )
 {
-	BYTE n, d, buf[6];
-
+	BYTE n, res;
 
 	if (cmd & 0x80) {	/* ACMD<n> is the command sequense of CMD55-CMD<n> */
 		cmd &= 0x7F;
-		n = send_cmd(CMD55, 0, userdata);
-		if (n > 1) return n;
+		res = send_cmd(CMD55, 0, userdata);
+		if (res > 1) return res;
 	}
 
 	/* Select the card and wait for ready except to stop multiple block read */
@@ -337,25 +341,25 @@ BYTE send_cmd (		/* Returns command response (bit7==1:Send failed)*/
 	}
 
 	/* Send a command packet */
-	buf[0] = 0x40 | cmd;			/* Start + Command index */
-	buf[1] = (BYTE)(arg >> 24);		/* Argument[31..24] */
-	buf[2] = (BYTE)(arg >> 16);		/* Argument[23..16] */
-	buf[3] = (BYTE)(arg >> 8);		/* Argument[15..8] */
-	buf[4] = (BYTE)arg;				/* Argument[7..0] */
-	n = 0x01;						/* Dummy CRC + Stop */
+	xchg_spi((0x40 | cmd),userdata);				/* Start + command index */
+	xchg_spi((BYTE)(arg >> 24),userdata);		/* Argument[31..24] */
+	xchg_spi((BYTE)(arg >> 16),userdata);		/* Argument[23..16] */
+	xchg_spi((BYTE)(arg >> 8),userdata);			/* Argument[15..8] */
+	xchg_spi((BYTE)arg,userdata);				/* Argument[7..0] */
+	n = 0x01;							/* Dummy CRC + Stop */
 	if (cmd == CMD0) n = 0x95;		/* (valid CRC for CMD0(0)) */
 	if (cmd == CMD8) n = 0x87;		/* (valid CRC for CMD8(0x1AA)) */
-	buf[5] = n;
-	xmit_mmc(buf, 6, userdata);
+	if (cmd == CMD8 || cmd == CMD10 || cmd == CMD17|| cmd == CMD24) n = 0xFF;
+	xchg_spi(n,userdata);
 
 	/* Receive command response */
-	if (cmd == CMD12) rcvr_mmc(&d, 1, userdata);	/* Skip a stuff byte when stop reading */
+	if (cmd == CMD12) xchg_spi(0xFF,userdata);	/* Skip a stuff byte when stop reading */
 	n = 10;								/* Wait for a valid response in timeout of 10 attempts */
 	do
-		rcvr_mmc(&d, 1, userdata);
-	while ((d & 0x80) && --n);
+		res = xchg_spi(0xFF,userdata);
+	while ((res & 0x80) && --n);
 
-	return d;			/* Return with the response value */
+	return res;			/* Return with the response value */
 }
 
 
@@ -366,97 +370,102 @@ BYTE send_cmd (		/* Returns command response (bit7==1:Send failed)*/
 
 ---------------------------------------------------------------------------*/
 
-
-/*-----------------------------------------------------------------------*/
-/* Get Disk Status                                                       */
-/*-----------------------------------------------------------------------*/
-
-DSTATUS spitf_status (
-	luat_fatfs_spi_t* userdata
-)
-{
-	//if (drv) return STA_NOINIT;
-
-	return Stat;
+static void FCLK_FAST(luat_fatfs_spi_t* userdata){
+	if(userdata->type == 1){
+		userdata->spi_device->spi_config.bandrate = userdata->fast_speed;
+		luat_spi_device_config(userdata->spi_device);
+	}else{
+		luat_spi_t fatfs_spi_conf = {
+			.id = userdata->spi_id,
+			.cs = 255,
+			.CPHA = 0,
+			.CPOL = 0,
+			.dataw = 8,
+			.bandrate = userdata->fast_speed,
+			.bit_dict = 1,
+			.master = 1,
+			.mode = 0,
+		};
+		luat_spi_setup(&fatfs_spi_conf);
+	}
 }
 
-
-
-/*-----------------------------------------------------------------------*/
-/* Initialize Disk Drive                                                 */
-/*-----------------------------------------------------------------------*/
-
 DSTATUS spitf_initialize (
 	luat_fatfs_spi_t* userdata
 )
 {
-	BYTE n, ty, cmd, buf[4];
-	UINT tmr;
-	DSTATUS s;
-
-
-	//if (drv) return RES_NOTRDY;
-
-	//dly_us(10000);			/* 10ms */
-	//CS_INIT(); CS_H();		/* Initialize port pin tied to CS */
-	//CK_INIT(); CK_L();		/* Initialize port pin tied to SCLK */
-	//DI_INIT();				/* Initialize port pin tied to DI */
-	//DO_INIT();				/* Initialize port pin tied to DO */
-
-	//luat_spi_close(userdata->spi_id);
-	//luat_spi_setup(userdata->spi_id, 400*1000/*400khz*/, 0, 0, 8, 1, 1);
-
-	spi_cs_deselect(userdata);
-
-	for (n = 10; n; n--) rcvr_mmc(buf, 1, userdata);	/* Apply 80 dummy clocks and the card gets ready to receive command */
-
-	ty = 0;
-	if (send_cmd(CMD0, 0, userdata) == 1) {			/* Enter Idle state */
-		if (send_cmd(CMD8, 0x1AA, userdata) == 1) {	/* SDv2? */
-			rcvr_mmc(buf, 4, userdata);							/* Get trailing return value of R7 resp */
-			if (buf[2] == 0x01 && buf[3] == 0xAA) {		/* The card can work at vdd range of 2.7-3.6V */
-				for (tmr = 1000; tmr; tmr--) {			/* Wait for leaving idle state (ACMD41 with HCS bit) */
-					if (send_cmd(ACMD41, 1UL << 30, userdata) == 0) break;
-					dly_us(1000);
-				}
-				if (tmr && send_cmd(CMD58, 0, userdata) == 0) {	/* Check CCS bit in the OCR */
-					rcvr_mmc(buf, 4, userdata);
-					ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 */
-				}
-			}
-		} else {							/* SDv1 or MMCv3 */
-			if (send_cmd(ACMD41, 0, userdata) <= 1) 	{
-				ty = CT_SD1; cmd = ACMD41;	/* SDv1 */
-			} else {
-				ty = CT_MMC; cmd = CMD1;	/* MMCv3 */
+	DSTATUS ret = 1;
+	uint8_t r1 = 0;
+	char buf[4] = {0xFF}; 
+
+	CardType = 0;
+	spitf_cs_high(userdata);
+	for (uint8_t i = 0; i < 10; i++){
+		spitf_send(&buf,1,userdata);
+	} 
+	r1 = spitf_send_cmd(CMD0, 0, 1,userdata);		/* Idle state */
+	if (r1 != 0x01) return ret;
+
+	r1 = spitf_send_cmd(CMD8, 0x1AA, 0,userdata); 
+
+	if (r1 == 0x05){		// V1.0 or MMC
+		// r1 = spitf_send_cmd(CMD1, 0, 1,userdata); 
+		// if (r1 != 0x00) return ret;
+	}else if(r1 == 0x01){	// V2.0
+		LLOGD("card is V2.0");
+		spitf_recv(buf, 4, userdata);
+		if (buf[2] == 0x01 && buf[3] == 0xAA) {
+			for (size_t i = 0; i < 2000; i++){
+				r1 = spitf_send_cmd(CMD55,0, 1,userdata);
+				if (r1 != 0x01) continue;
+				r1 = spitf_send_cmd(SD_ACMD_SD_SEND_OP_COND,0x40000000, 1,userdata);
+				if (r1 == 0x00) break;
+				dly_us(1000);
 			}
-			for (tmr = 1000; tmr; tmr--) {			/* Wait for leaving idle state */
-				if (send_cmd(cmd, 0, userdata) == 0) break;
+			if (r1 != 0x00) return ret;
+			for (size_t i = 0; i < 1000; i++){
+				r1 = spitf_send_cmd(CMD58,0, 0,userdata);
+				if (r1 == 0x00) break;
 				dly_us(1000);
 			}
-			if (!tmr || send_cmd(CMD16, 512, userdata) != 0)	/* Set R/W block length to 512 */
-				ty = 0;
+			if (r1 != 0x00) return ret;
+			spitf_recv(buf, 4,userdata);
+			CardType = (buf[0] & 0x40) ? CT_SDC2 | CT_BLOCK : CT_SDC2;	/* Card id SDv2 */
 		}
 	}
-	CardType = ty;
-	s = ty ? 0 : STA_NOINIT;
-	Stat = s;
 
+	// LLOGD("CardType:%d",CardType);
 	spi_cs_deselect(userdata);
 
-	//luat_spi_close(userdata->spi_id);
-	//spi.setup(id,0,0,8,400*1000,1)
-	//luat_spi_setup(userdata->spi_id, 1000*1000/*1Mhz*/, 0, 0, 8, 1, 1);
+	if (CardType) {			/* OK */
+		FCLK_FAST(userdata);			/* Set fast clock */
+		Stat &= ~STA_NOINIT;	/* Clear STA_NOINIT flag */
+	} else {			/* Failed */
+		Stat = STA_NOINIT;
+	}
 
-	return s;
+	return Stat;
 }
 
 
+/*-----------------------------------------------------------------------*/
+/* Get Disk Status                                                       */
+/*-----------------------------------------------------------------------*/
+
+DSTATUS spitf_status (
+	luat_fatfs_spi_t* userdata
+)
+{
+	//if (drv) return STA_NOINIT;
+
+	return Stat;
+}
 
 /*-----------------------------------------------------------------------*/
 /* Read Sector(s)                                                        */
 /*-----------------------------------------------------------------------*/
 
+
 DRESULT spitf_read (
 	luat_fatfs_spi_t* userdata,
 	BYTE *buff,			/* Pointer to the data buffer to store read data */
@@ -464,20 +473,27 @@ DRESULT spitf_read (
 	UINT count			/* Sector count (1..128) */
 )
 {
-	BYTE cmd;
-
+	if (!count) return RES_PARERR;		/* Check parameter */
+	if (spitf_status(userdata) & STA_NOINIT) return RES_NOTRDY;	/* Check if drive is ready */
 
-	if (spitf_status(userdata) & STA_NOINIT) return RES_NOTRDY;
 	if (!(CardType & CT_BLOCK)) sector *= 512;	/* Convert LBA to byte address if needed */
 
-	cmd = count > 1 ? CMD18 : CMD17;			/*  READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
-	if (send_cmd(cmd, sector, userdata) == 0) {
-		do {
-			if (!rcvr_datablock(buff, 512, userdata)) break;
-			buff += 512;
-		} while (--count);
-		if (cmd == CMD18) send_cmd(CMD12, 0, userdata);	/* STOP_TRANSMISSION */
+	if (count == 1) {	/* Single sector read */
+		if ((send_cmd(CMD17,  sector, userdata) == 0)	/* READ_SINGLE_BLOCK */
+			&& rcvr_datablock(buff, 512, userdata)) {
+			count = 0;
+		}
+	}
+	else {				/* Multiple sector read */
+		if (send_cmd(CMD18,  sector, userdata) == 0) {	/* READ_MULTIPLE_BLOCK */
+			do {
+				if (!rcvr_datablock(buff, 512, userdata)) break;
+				buff += 512;
+			} while (--count);
+			send_cmd(CMD12, 0, userdata);				/* STOP_TRANSMISSION */
+		}
 	}
+
 	spi_cs_deselect(userdata);
 
 	return count ? RES_ERROR : RES_OK;
@@ -496,6 +512,7 @@ DRESULT spitf_write (
 	UINT count			/* Sector count (1..128) */
 )
 {
+	if (!count) return RES_PARERR;		/* Check parameter */
 	if (spitf_status(userdata) & STA_NOINIT) return RES_NOTRDY;
 	if (!(CardType & CT_BLOCK)) sector *= 512;	/* Convert LBA to byte address if needed */
 
@@ -525,6 +542,7 @@ DRESULT spitf_write (
 /* Miscellaneous Functions                                               */
 /*-----------------------------------------------------------------------*/
 
+
 DRESULT spitf_ioctl (
 	luat_fatfs_spi_t* userdata,
 	BYTE ctrl,		/* Control code */
@@ -533,12 +551,13 @@ DRESULT spitf_ioctl (
 {
 	DRESULT res;
 	BYTE n, csd[16];
-	DWORD cs;
-
+	DWORD st, ed, csize;
+	LBA_t *dp;
 
 	if (spitf_status(userdata) & STA_NOINIT) return RES_NOTRDY;	/* Check if card is in the socket */
 
 	res = RES_ERROR;
+
 	switch (ctrl) {
 		case CTRL_SYNC :		/* Make sure that no pending write process */
 			if (spi_cs_select(userdata)) res = RES_OK;
@@ -547,22 +566,85 @@ DRESULT spitf_ioctl (
 		case GET_SECTOR_COUNT :	/* Get number of sectors on the disk (DWORD) */
 			if ((send_cmd(CMD9, 0, userdata) == 0) && rcvr_datablock(csd, 16, userdata)) {
 				if ((csd[0] >> 6) == 1) {	/* SDC ver 2.00 */
-					cs = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
-					*(DWORD*)buff = cs << 10;
+					csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
+					*(DWORD*)buff = csize << 10;
 				} else {					/* SDC ver 1.XX or MMC */
 					n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
-					cs = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
-					*(DWORD*)buff = cs << (n - 9);
+					csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
+					*(DWORD*)buff = csize << (n - 9);
 				}
 				res = RES_OK;
 			}
 			break;
 
 		case GET_BLOCK_SIZE :	/* Get erase block size in unit of sector (DWORD) */
-			*(DWORD*)buff = 128;
+			if (CardType & CT_SDC2) {	/* SDC ver 2+ */
+				if (send_cmd(ACMD13, 0, userdata) == 0) {	/* Read SD status */
+					xchg_spi(0xFF, userdata);
+					if (rcvr_datablock(csd, 16, userdata)) {				/* Read partial block */
+						for (n = 64 - 16; n; n--) xchg_spi(0xFF, userdata);	/* Purge trailing data */
+						*(DWORD*)buff = 16UL << (csd[10] >> 4);
+						res = RES_OK;
+					}
+				}
+			} else {					/* SDC ver 1 or MMC */
+				if ((send_cmd(CMD9, 0, userdata) == 0) && rcvr_datablock(csd, 16, userdata)) {	/* Read CSD */
+					if (CardType & CT_SDC1) {	/* SDC ver 1.XX */
+						*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
+					} else {					/* MMC */
+						*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
+					}
+					res = RES_OK;
+				}
+			}
+			break;
+
+		case CTRL_TRIM :	/* Erase a block of sectors (used when _USE_ERASE == 1) */
+			if (!(CardType & CT_SDC)) break;				/* Check if the card is SDC */
+			if (disk_ioctl(0, MMC_GET_CSD, csd)) break;	/* Get CSD */
+			if (!(csd[10] & 0x40)) break;					/* Check if ERASE_BLK_EN = 1 */
+			dp = buff; st = (DWORD)dp[0]; ed = (DWORD)dp[1];	/* Load sector block */
+			if (!(CardType & CT_BLOCK)) {
+				st *= 512; ed *= 512;
+			}
+			if (send_cmd(CMD32, st, userdata) == 0 && send_cmd(CMD33, ed, userdata) == 0 && send_cmd(CMD38, 0, userdata) == 0 && wait_ready(30000,userdata)) {	/* Erase sector block */
+				res = RES_OK;	/* FatFs does not check result of this command */
+			}
+			break;
+
+		/* Following commands are never used by FatFs module */
+
+		case MMC_GET_TYPE:		/* Get MMC/SDC type (BYTE) */
+			*(BYTE*)buff = CardType;
 			res = RES_OK;
 			break;
 
+		case MMC_GET_CSD:		/* Read CSD (16 bytes) */
+			if (send_cmd(CMD9, 0, userdata) == 0 && rcvr_datablock((BYTE*)buff, 16, userdata)) {	/* READ_CSD */
+				res = RES_OK;
+			}
+			break;
+
+		case MMC_GET_CID:		/* Read CID (16 bytes) */
+			if (send_cmd(CMD10, 0, userdata) == 0 && rcvr_datablock((BYTE*)buff, 16, userdata)) {	/* READ_CID */
+				res = RES_OK;
+			}
+			break;
+
+		case MMC_GET_OCR:		/* Read OCR (4 bytes) */
+			if (send_cmd(CMD58, 0, userdata) == 0) {	/* READ_OCR */
+				for (n = 0; n < 4; n++) *(((BYTE*)buff) + n) = xchg_spi(0xFF, userdata);
+				res = RES_OK;
+			}
+			break;
+
+		case MMC_GET_SDSTAT:	/* Read SD status (64 bytes) */
+			if (send_cmd(ACMD13, 0, userdata) == 0) {	/* SD_STATUS */
+				xchg_spi(0xFF, userdata);
+				if (rcvr_datablock((BYTE*)buff, 64, userdata)) res = RES_OK;
+			}
+			break;
+
 		default:
 			res = RES_PARERR;
 	}

File diff suppressed because it is too large
+ 230 - 161
components/fatfs/ff.c


+ 39 - 32
components/fatfs/ff.h

@@ -1,8 +1,8 @@
 /*----------------------------------------------------------------------------/
-/  FatFs - Generic FAT Filesystem module  R0.14b                              /
+/  FatFs - Generic FAT Filesystem module  R0.15                               /
 /-----------------------------------------------------------------------------/
 /
-/ Copyright (C) 2021, ChaN, all right reserved.
+/ Copyright (C) 2022, ChaN, all right reserved.
 /
 / FatFs module is an open source software. Redistribution and use of FatFs in
 / source and binary forms, with or without modification, are permitted provided
@@ -20,7 +20,7 @@
 
 
 #ifndef FF_DEFINED
-#define FF_DEFINED	86631	/* Revision ID */
+#define FF_DEFINED	80286	/* Revision ID */
 
 #ifdef __cplusplus
 extern "C" {
@@ -131,10 +131,11 @@ extern const char* VolumeStr[FF_VOLUMES];	/* User defied volume ID */
 
 typedef struct {
 	BYTE	fs_type;		/* Filesystem type (0:not mounted) */
-	BYTE	pdrv;			/* Associated physical drive */
+	BYTE	pdrv;			/* Volume hosting physical drive */
+	BYTE	ldrv;			/* Logical drive number (used only when FF_FS_REENTRANT) */
 	BYTE	n_fats;			/* Number of FATs (1 or 2) */
-	BYTE	wflag;			/* win[] flag (b0:dirty) */
-	BYTE	fsi_flag;		/* FSINFO flags (b7:disabled, b0:dirty) */
+	BYTE	wflag;			/* win[] status (b0:dirty) */
+	BYTE	fsi_flag;		/* FSINFO status (b7:disabled, b0:dirty) */
 	WORD	id;				/* Volume mount ID */
 	WORD	n_rootdir;		/* Number of root directory entries (FAT12/16) */
 	WORD	csize;			/* Cluster size [sectors] */
@@ -147,9 +148,6 @@ typedef struct {
 #if FF_FS_EXFAT
 	BYTE*	dirbuf;			/* Directory entry block scratchpad buffer for exFAT */
 #endif
-#if FF_FS_REENTRANT
-	FF_SYNC_t	sobj;		/* Identifier of sync object */
-#endif
 #if !FF_FS_READONLY
 	DWORD	last_clst;		/* Last allocated cluster */
 	DWORD	free_clst;		/* Number of free clusters */
@@ -163,10 +161,10 @@ typedef struct {
 #endif
 #endif
 	DWORD	n_fatent;		/* Number of FAT entries (number of clusters + 2) */
-	DWORD	fsize;			/* Size of an FAT [sectors] */
+	DWORD	fsize;			/* Number of sectors per FAT */
 	LBA_t	volbase;		/* Volume base sector */
 	LBA_t	fatbase;		/* FAT base sector */
-	LBA_t	dirbase;		/* Root directory base sector/cluster */
+	LBA_t	dirbase;		/* Root directory base sector (FAT12/16) or cluster (FAT32/exFAT) */
 	LBA_t	database;		/* Data base sector */
 #if FF_FS_EXFAT
 	LBA_t	bitbase;		/* Allocation bitmap base sector */
@@ -181,7 +179,7 @@ typedef struct {
 
 typedef struct {
 	FATFS*	fs;				/* Pointer to the hosting volume of this object */
-	WORD	id;				/* Hosting volume mount ID */
+	WORD	id;				/* Hosting volume's mount ID */
 	BYTE	attr;			/* Object attribute */
 	BYTE	stat;			/* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
 	DWORD	sclust;			/* Object data start cluster (0:no cluster or root directory) */
@@ -250,7 +248,7 @@ typedef struct {
 	WORD	ftime;			/* Modified time */
 	BYTE	fattrib;		/* File attribute */
 #if FF_USE_LFN
-	TCHAR	altname[FF_SFN_BUF + 1];/* Altenative file name */
+	TCHAR	altname[FF_SFN_BUF + 1];/* Alternative file name */
 	TCHAR	fname[FF_LFN_BUF + 1];	/* Primary file name */
 #else
 	TCHAR	fname[12 + 1];	/* File name */
@@ -298,8 +296,10 @@ typedef enum {
 
 
 
+
+/*--------------------------------------------------------------*/
+/* FatFs Module Application Interface                           */
 /*--------------------------------------------------------------*/
-/* FatFs module application interface                           */
 
 FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);				/* Open or create a file */
 FRESULT f_close (FIL* fp);											/* Close an open file object */
@@ -322,7 +322,7 @@ FRESULT f_utime (const TCHAR* path, const FILINFO* fno);			/* Change timestamp o
 FRESULT f_chdir (const TCHAR* path);								/* Change current directory */
 FRESULT f_chdrive (const TCHAR* path);								/* Change current drive */
 FRESULT f_getcwd (TCHAR* buff, UINT len);							/* Get current directory */
-FRESULT f_getfree(const TCHAR* path, DWORD* nclst, FATFS** fatfs);	/* Get number of free clusters on the drive */
+FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs);	/* Get number of free clusters on the drive */
 FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn);	/* Get volume label */
 FRESULT f_setlabel (const TCHAR* label);							/* Set volume label */
 FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf);	/* Forward data to the stream */
@@ -336,6 +336,8 @@ int f_puts (const TCHAR* str, FIL* cp);								/* Put a string to the file */
 int f_printf (FIL* fp, const TCHAR* str, ...);						/* Put a formatted string to the file */
 TCHAR* f_gets (TCHAR* buff, int len, FIL* fp);						/* Get a string from the file */
 
+/* Some API fucntions are implemented as macro */
+
 #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
 #define f_error(fp) ((fp)->err)
 #define f_tell(fp) ((fp)->fptr)
@@ -349,38 +351,43 @@ TCHAR* f_gets (TCHAR* buff, int len, FIL* fp);						/* Get a string from the fil
 
 
 /*--------------------------------------------------------------*/
-/* Additional user defined functions                            */
+/* Additional Functions                                         */
+/*--------------------------------------------------------------*/
 
-/* RTC function */
+/* RTC function (provided by user) */
 #if !FF_FS_READONLY && !FF_FS_NORTC
-DWORD get_fattime (void);
+DWORD get_fattime (void);	/* Get current time */
 #endif
 
-/* LFN support functions */
-#if FF_USE_LFN >= 1						/* Code conversion (defined in unicode.c) */
+
+/* LFN support functions (defined in ffunicode.c) */
+
+#if FF_USE_LFN >= 1
 WCHAR ff_oem2uni (WCHAR oem, WORD cp);	/* OEM code to Unicode conversion */
 WCHAR ff_uni2oem (DWORD uni, WORD cp);	/* Unicode to OEM code conversion */
 DWORD ff_wtoupper (DWORD uni);			/* Unicode upper-case conversion */
 #endif
-#if FF_USE_LFN == 3						/* Dynamic memory allocation */
-void* ff_memalloc (UINT msize);			/* Allocate memory block */
-void ff_memfree (void* mblock);			/* Free memory block */
-#endif
 
-/* Sync functions */
-#if FF_FS_REENTRANT
-int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj);	/* Create a sync object */
-int ff_req_grant (FF_SYNC_t sobj);		/* Lock sync object */
-void ff_rel_grant (FF_SYNC_t sobj);		/* Unlock sync object */
-int ff_del_syncobj (FF_SYNC_t sobj);	/* Delete a sync object */
+
+/* O/S dependent functions (samples available in ffsystem.c) */
+
+#if FF_USE_LFN == 3		/* Dynamic memory allocation */
+void* ff_memalloc (UINT msize);		/* Allocate memory block */
+void ff_memfree (void* mblock);		/* Free memory block */
+#endif
+#if FF_FS_REENTRANT	/* Sync functions */
+int ff_mutex_create (int vol);		/* Create a sync object */
+void ff_mutex_delete (int vol);		/* Delete a sync object */
+int ff_mutex_take (int vol);		/* Lock sync object */
+void ff_mutex_give (int vol);		/* Unlock sync object */
 #endif
 
 
 
 
 /*--------------------------------------------------------------*/
-/* Flags and offset address                                     */
-
+/* Flags and Offset Address                                     */
+/*--------------------------------------------------------------*/
 
 /* File access mode and open method flags (3rd argument of f_open) */
 #define	FA_READ				0x01

+ 16 - 21
components/fatfs/ffconf.h

@@ -1,8 +1,8 @@
 /*---------------------------------------------------------------------------/
-/  FatFs Functional Configurations
+/  Configurations of FatFs Module
 /---------------------------------------------------------------------------*/
 
-#define FFCONF_DEF	86631	/* Revision ID */
+#define FFCONF_DEF	80286	/* Revision ID */
 
 /*---------------------------------------------------------------------------/
 / Function Configurations
@@ -68,7 +68,7 @@
 /   2: Enable with LF-CRLF conversion.
 /
 /  FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
-   makes f_printf() support floating point argument. These features want C99 or later.
+/  makes f_printf() support floating point argument. These features want C99 or later.
 /  When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
 /  encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
 /  to be read/written via those functions.
@@ -178,7 +178,7 @@
 /  logical drives. Number of items must not be less than FF_VOLUMES. Valid
 /  characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
 /  compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
-/  not defined, a user defined volume string table needs to be defined as:
+/  not defined, a user defined volume string table is needed as:
 /
 /  const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
 */
@@ -190,7 +190,7 @@
 /  number and only an FAT volume found on the physical drive will be mounted.
 /  When this function is enabled (1), each logical drive number can be bound to
 /  arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
-/  funciton will be available. */
+/  function will be available. */
 
 
 #define FF_MIN_SS		512
@@ -240,10 +240,10 @@
 #define FF_FS_NORTC		0
 #define FF_NORTC_MON	1
 #define FF_NORTC_MDAY	1
-#define FF_NORTC_YEAR	2020
-/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
-/  any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
-/  the timestamp function. Every object modified by FatFs will have a fixed timestamp
+#define FF_NORTC_YEAR	2022
+/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
+/  an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
+/  timestamp feature. Every object modified by FatFs will have a fixed timestamp
 /  defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
 /  To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
 /  added to the project to read current time form real-time clock. FF_NORTC_MON,
@@ -253,7 +253,7 @@
 
 #define FF_FS_NOFSINFO	0
 /* If you need to know correct free space on the FAT32 volume, set bit 0 of this
-/  option, and f_getfree() function at first time after volume mount will force
+/  option, and f_getfree() function at the first time after volume mount will force
 /  a full FAT scan. Bit 1 controls the use of last allocated cluster number.
 /
 /  bit0=0: Use free cluster count in the FSINFO if available.
@@ -275,26 +275,21 @@
 /      lock control is independent of re-entrancy. */
 
 
-/* #include <somertos.h>	// O/S definitions */
 #define FF_FS_REENTRANT	0
 #define FF_FS_TIMEOUT	1000
-#define FF_SYNC_t		HANDLE
 /* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
 /  module itself. Note that regardless of this option, file access to different
 /  volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
 /  and f_fdisk() function, are always not re-entrant. Only file/directory access
-/  to the same volume is under control of this function.
+/  to the same volume is under control of this featuer.
 /
-/   0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
+/   0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
 /   1: Enable re-entrancy. Also user provided synchronization handlers,
-/      ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
-/      function, must be added to the project. Samples are available in
-/      option/syscall.c.
+/      ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give()
+/      function, must be added to the project. Samples are available in ffsystem.c.
 /
-/  The FF_FS_TIMEOUT defines timeout period in unit of time tick.
-/  The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
-/  SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
-/  included somewhere in the scope of ff.h. */
+/  The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
+*/
 
 
 

+ 130 - 92
components/fatfs/ffsystem.c

@@ -1,34 +1,31 @@
 /*------------------------------------------------------------------------*/
-/* Sample Code of OS Dependent Functions for FatFs                        */
-/* (C)ChaN, 2018                                                          */
+/* A Sample Code of User Provided OS Dependent Functions for FatFs        */
 /*------------------------------------------------------------------------*/
 
-
 #include "ff.h"
 #include "luat_base.h"
 #include "luat_malloc.h"
 
 
-#if FF_USE_LFN == 3	/* Dynamic memory allocation */
+#if FF_USE_LFN == 3	/* Use dynamic memory allocation */
 
 /*------------------------------------------------------------------------*/
-/* Allocate a memory block                                                */
+/* Allocate/Free a Memory Block                                           */
 /*------------------------------------------------------------------------*/
 
+#include <stdlib.h>		/* with POSIX API */
+
+
 void* ff_memalloc (	/* Returns pointer to the allocated memory block (null if not enough core) */
 	UINT msize		/* Number of bytes to allocate */
 )
 {
-	return luat_heap_malloc(msize);	/* Allocate a new memory block with POSIX API */
+	return luat_heap_malloc((size_t)msize);	/* Allocate a new memory block with POSIX API */
 }
 
 
-/*------------------------------------------------------------------------*/
-/* Free a memory block                                                    */
-/*------------------------------------------------------------------------*/
-
 void ff_memfree (
-	void* mblock	/* Pointer to the memory block to free (nothing to do if null) */
+	void* mblock	/* Pointer to the memory block to free (no effect if null) */
 )
 {
 	luat_heap_free(mblock);	/* Free the memory block with POSIX API */
@@ -38,135 +35,176 @@ void ff_memfree (
 
 
 
-#if FF_FS_REENTRANT	/* Mutal exclusion */
 
+#if FF_FS_REENTRANT	/* Mutal exclusion */
 /*------------------------------------------------------------------------*/
-/* Create a Synchronization Object                                        */
+/* Definitions of Mutex                                                   */
 /*------------------------------------------------------------------------*/
-/* This function is called in f_mount() function to create a new
-/  synchronization object for the volume, such as semaphore and mutex.
-/  When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
-*/
 
-//const osMutexDef_t Mutex[FF_VOLUMES];	/* Table of CMSIS-RTOS mutex */
+#define OS_TYPE	0	/* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */
+
+
+#if   OS_TYPE == 0	/* Win32 */
+#include <windows.h>
+static HANDLE Mutex[FF_VOLUMES + 1];	/* Table of mutex handle */
 
+#elif OS_TYPE == 1	/* uITRON */
+#include "itron.h"
+#include "kernel.h"
+static mtxid Mutex[FF_VOLUMES + 1];		/* Table of mutex ID */
 
-int ff_cre_syncobj (	/* 1:Function succeeded, 0:Could not create the sync object */
-	BYTE vol,			/* Corresponding volume (logical drive number) */
-	FF_SYNC_t* sobj		/* Pointer to return the created sync object */
+#elif OS_TYPE == 2	/* uc/OS-II */
+#include "includes.h"
+static OS_EVENT *Mutex[FF_VOLUMES + 1];	/* Table of mutex pinter */
+
+#elif OS_TYPE == 3	/* FreeRTOS */
+#include "FreeRTOS.h"
+#include "semphr.h"
+static SemaphoreHandle_t Mutex[FF_VOLUMES + 1];	/* Table of mutex handle */
+
+#elif OS_TYPE == 4	/* CMSIS-RTOS */
+#include "cmsis_os.h"
+static osMutexId Mutex[FF_VOLUMES + 1];	/* Table of mutex ID */
+
+#endif
+
+
+
+/*------------------------------------------------------------------------*/
+/* Create a Mutex                                                         */
+/*------------------------------------------------------------------------*/
+/* This function is called in f_mount function to create a new mutex
+/  or semaphore for the volume. When a 0 is returned, the f_mount function
+/  fails with FR_INT_ERR.
+*/
+
+int ff_mutex_create (	/* Returns 1:Function succeeded or 0:Could not create the mutex */
+	int vol				/* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
 )
 {
-	/* Win32 */
-	*sobj = CreateMutex(NULL, FALSE, NULL);
-	return (int)(*sobj != INVALID_HANDLE_VALUE);
-
-	/* uITRON */
-//	T_CSEM csem = {TA_TPRI,1,1};
-//	*sobj = acre_sem(&csem);
-//	return (int)(*sobj > 0);
-
-	/* uC/OS-II */
-//	OS_ERR err;
-//	*sobj = OSMutexCreate(0, &err);
-//	return (int)(err == OS_NO_ERR);
-
-	/* FreeRTOS */
-//	*sobj = xSemaphoreCreateMutex();
-//	return (int)(*sobj != NULL);
-
-	/* CMSIS-RTOS */
-//	*sobj = osMutexCreate(&Mutex[vol]);
-//	return (int)(*sobj != NULL);
+#if OS_TYPE == 0	/* Win32 */
+	Mutex[vol] = CreateMutex(NULL, FALSE, NULL);
+	return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);
+
+#elif OS_TYPE == 1	/* uITRON */
+	T_CMTX cmtx = {TA_TPRI,1};
+
+	Mutex[vol] = acre_mtx(&cmtx);
+	return (int)(Mutex[vol] > 0);
+
+#elif OS_TYPE == 2	/* uC/OS-II */
+	OS_ERR err;
+
+	Mutex[vol] = OSMutexCreate(0, &err);
+	return (int)(err == OS_NO_ERR);
+
+#elif OS_TYPE == 3	/* FreeRTOS */
+	Mutex[vol] = xSemaphoreCreateMutex();
+	return (int)(Mutex[vol] != NULL);
+
+#elif OS_TYPE == 4	/* CMSIS-RTOS */
+	osMutexDef(cmsis_os_mutex);
+
+	Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));
+	return (int)(Mutex[vol] != NULL);
+
+#endif
 }
 
 
 /*------------------------------------------------------------------------*/
-/* Delete a Synchronization Object                                        */
+/* Delete a Mutex                                                         */
 /*------------------------------------------------------------------------*/
-/* This function is called in f_mount() function to delete a synchronization
-/  object that created with ff_cre_syncobj() function. When a 0 is returned,
-/  the f_mount() function fails with FR_INT_ERR.
+/* This function is called in f_mount function to delete a mutex or
+/  semaphore of the volume created with ff_mutex_create function.
 */
 
-int ff_del_syncobj (	/* 1:Function succeeded, 0:Could not delete due to an error */
-	FF_SYNC_t sobj		/* Sync object tied to the logical drive to be deleted */
+void ff_mutex_delete (	/* Returns 1:Function succeeded or 0:Could not delete due to an error */
+	int vol				/* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
 )
 {
-	/* Win32 */
-	return (int)CloseHandle(sobj);
+#if OS_TYPE == 0	/* Win32 */
+	CloseHandle(Mutex[vol]);
 
-	/* uITRON */
-//	return (int)(del_sem(sobj) == E_OK);
+#elif OS_TYPE == 1	/* uITRON */
+	del_mtx(Mutex[vol]);
 
-	/* uC/OS-II */
-//	OS_ERR err;
-//	OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
-//	return (int)(err == OS_NO_ERR);
+#elif OS_TYPE == 2	/* uC/OS-II */
+	OS_ERR err;
 
-	/* FreeRTOS */
-//  vSemaphoreDelete(sobj);
-//	return 1;
+	OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);
 
-	/* CMSIS-RTOS */
-//	return (int)(osMutexDelete(sobj) == osOK);
+#elif OS_TYPE == 3	/* FreeRTOS */
+	vSemaphoreDelete(Mutex[vol]);
+
+#elif OS_TYPE == 4	/* CMSIS-RTOS */
+	osMutexDelete(Mutex[vol]);
+
+#endif
 }
 
 
 /*------------------------------------------------------------------------*/
-/* Request Grant to Access the Volume                                     */
+/* Request a Grant to Access the Volume                                   */
 /*------------------------------------------------------------------------*/
-/* This function is called on entering file functions to lock the volume.
+/* This function is called on enter file functions to lock the volume.
 /  When a 0 is returned, the file function fails with FR_TIMEOUT.
 */
 
-int ff_req_grant (	/* 1:Got a grant to access the volume, 0:Could not get a grant */
-	FF_SYNC_t sobj	/* Sync object to wait */
+int ff_mutex_take (	/* Returns 1:Succeeded or 0:Timeout */
+	int vol			/* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
 )
 {
-	/* Win32 */
-	return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
+#if OS_TYPE == 0	/* Win32 */
+	return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);
+
+#elif OS_TYPE == 1	/* uITRON */
+	return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);
+
+#elif OS_TYPE == 2	/* uC/OS-II */
+	OS_ERR err;
 
-	/* uITRON */
-//	return (int)(wai_sem(sobj) == E_OK);
+	OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));
+	return (int)(err == OS_NO_ERR);
 
-	/* uC/OS-II */
-//	OS_ERR err;
-//	OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
-//	return (int)(err == OS_NO_ERR);
+#elif OS_TYPE == 3	/* FreeRTOS */
+	return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);
 
-	/* FreeRTOS */
-//	return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
+#elif OS_TYPE == 4	/* CMSIS-RTOS */
+	return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);
 
-	/* CMSIS-RTOS */
-//	return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
+#endif
 }
 
 
+
 /*------------------------------------------------------------------------*/
-/* Release Grant to Access the Volume                                     */
+/* Release a Grant to Access the Volume                                   */
 /*------------------------------------------------------------------------*/
-/* This function is called on leaving file functions to unlock the volume.
+/* This function is called on leave file functions to unlock the volume.
 */
 
-void ff_rel_grant (
-	FF_SYNC_t sobj	/* Sync object to be signaled */
+void ff_mutex_give (
+	int vol			/* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
 )
 {
-	/* Win32 */
-	ReleaseMutex(sobj);
+#if OS_TYPE == 0	/* Win32 */
+	ReleaseMutex(Mutex[vol]);
 
-	/* uITRON */
-//	sig_sem(sobj);
+#elif OS_TYPE == 1	/* uITRON */
+	unl_mtx(Mutex[vol]);
 
-	/* uC/OS-II */
-//	OSMutexPost(sobj);
+#elif OS_TYPE == 2	/* uC/OS-II */
+	OSMutexPost(Mutex[vol]);
 
-	/* FreeRTOS */
-//	xSemaphoreGive(sobj);
+#elif OS_TYPE == 3	/* FreeRTOS */
+	xSemaphoreGive(Mutex[vol]);
 
-	/* CMSIS-RTOS */
-//	osMutexRelease(sobj);
-}
+#elif OS_TYPE == 4	/* CMSIS-RTOS */
+	osMutexRelease(Mutex[vol]);
 
 #endif
+}
+
+#endif	/* FF_FS_REENTRANT */
 

+ 22 - 22
components/fatfs/ffunicode.c

@@ -1,13 +1,13 @@
 /*------------------------------------------------------------------------*/
-/* Unicode handling functions for FatFs R0.13+                            */
+/* Unicode Handling Functions for FatFs R0.13 and Later                   */
+/*------------------------------------------------------------------------*/
+/* This module will occupy a huge memory in the .rodata section when the  */
+/* FatFs is configured for LFN with DBCS. If the system has a Unicode     */
+/* library for the code conversion, this module should be modified to use */
+/* it to avoid silly memory consumption.                                  */
 /*------------------------------------------------------------------------*/
-/* This module will occupy a huge memory in the .const section when the    /
-/  FatFs is configured for LFN with DBCS. If the system has any Unicode    /
-/  utilitiy for the code conversion, this module should be modified to use /
-/  that function to avoid silly memory consumption.                        /
-/-------------------------------------------------------------------------*/
 /*
-/ Copyright (C) 2014, ChaN, all right reserved.
+/ Copyright (C) 2022, ChaN, all right reserved.
 /
 / FatFs module is an open source software. Redistribution and use of FatFs in
 / source and binary forms, with or without modification, are permitted provided
@@ -25,7 +25,7 @@
 
 #include "ff.h"
 
-#if FF_USE_LFN	/* This module will be blanked if non-LFN configuration */
+#if FF_USE_LFN != 0	/* This module will be blanked if in non-LFN configuration */
 
 #define MERGE2(a, b) a ## b
 #define CVTBL(tbl, cp) MERGE2(tbl, cp)
@@ -15214,8 +15214,8 @@ static const WCHAR uc869[] = {	/*  CP869(Greek 2) to Unicode conversion table */
 
 
 /*------------------------------------------------------------------------*/
-/* OEM <==> Unicode conversions for static code page configuration        */
-/* SBCS fixed code page                                                   */
+/* OEM <==> Unicode Conversions for Static Code Page Configuration with   */
+/* SBCS Fixed Code Page                                                   */
 /*------------------------------------------------------------------------*/
 
 #if FF_CODE_PAGE != 0 && FF_CODE_PAGE < 900
@@ -15225,7 +15225,7 @@ WCHAR ff_uni2oem (	/* Returns OEM code character, zero on error */
 )
 {
 	WCHAR c = 0;
-	const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
+	const WCHAR* p = CVTBL(uc, FF_CODE_PAGE);
 
 
 	if (uni < 0x80) {	/* ASCII? */
@@ -15247,7 +15247,7 @@ WCHAR ff_oem2uni (	/* Returns Unicode character in UTF-16, zero on error */
 )
 {
 	WCHAR c = 0;
-	const WCHAR *p = CVTBL(uc, FF_CODE_PAGE);
+	const WCHAR* p = CVTBL(uc, FF_CODE_PAGE);
 
 
 	if (oem < 0x80) {	/* ASCII? */
@@ -15267,8 +15267,8 @@ WCHAR ff_oem2uni (	/* Returns Unicode character in UTF-16, zero on error */
 
 
 /*------------------------------------------------------------------------*/
-/* OEM <==> Unicode conversions for static code page configuration        */
-/* DBCS fixed code page                                                   */
+/* OEM <==> Unicode Conversions for Static Code Page Configuration with   */
+/* DBCS Fixed Code Page                                                   */
 /*------------------------------------------------------------------------*/
 
 #if FF_CODE_PAGE >= 900
@@ -15277,7 +15277,7 @@ WCHAR ff_uni2oem (	/* Returns OEM code character, zero on error */
 	WORD	cp		/* Code page for the conversion */
 )
 {
-	const WCHAR *p;
+	const WCHAR* p;
 	WCHAR c = 0, uc;
 	UINT i = 0, n, li, hi;
 
@@ -15313,7 +15313,7 @@ WCHAR ff_oem2uni (	/* Returns Unicode character in UTF-16, zero on error */
 	WORD	cp		/* Code page for the conversion */
 )
 {
-	const WCHAR *p;
+	const WCHAR* p;
 	WCHAR c = 0;
 	UINT i = 0, n, li, hi;
 
@@ -15346,7 +15346,7 @@ WCHAR ff_oem2uni (	/* Returns Unicode character in UTF-16, zero on error */
 
 
 /*------------------------------------------------------------------------*/
-/* OEM <==> Unicode conversions for dynamic code page configuration       */
+/* OEM <==> Unicode Conversions for Dynamic Code Page Configuration       */
 /*------------------------------------------------------------------------*/
 
 #if FF_CODE_PAGE == 0
@@ -15360,7 +15360,7 @@ WCHAR ff_uni2oem (	/* Returns OEM code character, zero on error */
 	WORD	cp		/* Code page for the conversion */
 )
 {
-	const WCHAR *p;
+	const WCHAR* p;
 	WCHAR c = 0, uc;
 	UINT i, n, li, hi;
 
@@ -15412,7 +15412,7 @@ WCHAR ff_oem2uni (	/* Returns Unicode character in UTF-16, zero on error */
 	WORD	cp		/* Code page for the conversion */
 )
 {
-	const WCHAR *p;
+	const WCHAR* p;
 	WCHAR c = 0;
 	UINT i, n, li, hi;
 
@@ -15458,14 +15458,14 @@ WCHAR ff_oem2uni (	/* Returns Unicode character in UTF-16, zero on error */
 
 
 /*------------------------------------------------------------------------*/
-/* Unicode up-case conversion                                             */
+/* Unicode Up-case Conversion                                             */
 /*------------------------------------------------------------------------*/
 
 DWORD ff_wtoupper (	/* Returns up-converted code point */
 	DWORD uni		/* Unicode code point to be up-converted */
 )
 {
-	const WORD *p;
+	const WORD* p;
 	WORD uc, bc, nc, cmd;
 	static const WORD cvt1[] = {	/* Compressed up conversion table for U+0000 - U+0FFF */
 		/* Basic Latin */
@@ -15590,4 +15590,4 @@ DWORD ff_wtoupper (	/* Returns up-converted code point */
 }
 
 
-#endif /* #if FF_USE_LFN */
+#endif /* #if FF_USE_LFN != 0 */

Some files were not shown because too many files changed in this diff