#define TRUE  1
#define FALSE 0

#include "stm32h7xx_hal.h"
#include <stdbool.h>
#include <string.h>

#include "ff.h"
#include "diskio.h"
#include "fatfs_sd.h"

static volatile DSTATUS Stat = STA_NOINIT;	/* Disk Status */
static uint8_t CardType;                    /* Type 0:MMC, 1:SDC, 2:Block addressing */
static uint8_t PowerFlag = 0;				/* Power flag */

/***************************************
 * SPI functions
 **************************************/

/* slave select */
static void SELECT(void)
{
	HAL_GPIO_WritePin(SD_CS_PORT, SD_CS_PIN, GPIO_PIN_RESET);
}

/* slave deselect */
static void DESELECT(void)
{
	HAL_GPIO_WritePin(SD_CS_PORT, SD_CS_PIN, GPIO_PIN_SET);
}

static void SPI_Start(SPI_TypeDef *spi, uint16_t len)
{
	spi->CR2 = len;

	uint32_t cr1 = spi->CR1 | SPI_CR1_SPE;

	spi->CR1 = cr1; // enable
	spi->CR1 = cr1 | SPI_CR1_CSTART; // start
}

static void SPI_End(SPI_TypeDef *spi)
{
	// clear EOT/TXTF
	spi->IFCR |= SPI_IFCR_EOTC | SPI_IFCR_TXTFC;

	spi->CR1 &= ~SPI_CR1_SPE; // disable
}

/* SPI transmit a byte */
static void SPI_TxByte(uint8_t data)
{
  SPI_TypeDef *spi = (HSPI_SDCARD)->Instance;

  SPI_Start(spi, 1);

  // wait for tx space
  while(!(spi->SR & SPI_FLAG_TXP));

  *((__IO uint8_t *)&spi->TXDR) = data;

  // wait for end
  while(!(spi->SR & SPI_FLAG_EOT));

  // end
  SPI_End(spi);
}

/* SPI receive a byte */
static uint8_t SPI_RxByte(void)
{
  uint8_t data;

  SPI_TypeDef *spi = (HSPI_SDCARD)->Instance;

  SPI_Start(spi, 1);

  while(!(spi->SR & SPI_FLAG_TXP));

  *((__IO uint8_t *)&spi->TXDR) = 0xFF;

  // wait for a byte
  while(!(spi->SR & (SPI_FLAG_RXWNE | SPI_FLAG_FRLVL)));

  data = *((__IO uint8_t *)&spi->RXDR);

  // wait for end
  while(!(spi->SR & SPI_FLAG_EOT));

  // end
  SPI_End(spi);

  return data;
}

/* SPI receive a byte via pointer */
static void SPI_RxBytePtr(uint8_t *buff)
{
	*buff = SPI_RxByte();
}

/***************************************
 * SD functions
 **************************************/

/* wait SD ready */
static uint8_t SD_ReadyWait(void)
{
	uint8_t res;

	/* timeout 500ms */
	uint32_t timeout = HAL_GetTick() + 500;

	/* if SD goes ready, receives 0xFF */
	do {
		res = SPI_RxByte();
	} while ((res != 0xFF) && HAL_GetTick() < timeout);

	return res;
}

/* power on */
static void SD_PowerOn(void)
{
	uint32_t cnt = 0x1FFF;

	/* transmit bytes to wake up */
	DESELECT();
	for(int i = 0; i < 10; i++)
	{
		SPI_TxByte(0xFF);
	}

	/* slave select */
	SELECT();

	/* make idle state */
  // SD_SendCmd?
  SPI_TxByte(CMD0);		/* CMD0:GO_IDLE_STATE */
	SPI_TxByte(0);
	SPI_TxByte(0);
	SPI_TxByte(0);
	SPI_TxByte(0);
  SPI_TxByte(0x95);		/* CRC */

	/* wait response */
	while ((SPI_RxByte() != 0x01) && cnt)
	{
		cnt--;
	}

	DESELECT();
	SPI_TxByte(0XFF);

	PowerFlag = 1;
}

/* power off */
static void SD_PowerOff(void)
{
	PowerFlag = 0;
}

/* check power flag */
static uint8_t SD_CheckPower(void)
{
	return PowerFlag;
}

/* receive data block */
static bool SD_RxDataBlock(BYTE *buff, uint16_t len)
{
	uint8_t token;

	/* timeout 200ms */
  uint32_t timeout = HAL_GetTick() + 200;

	/* loop until receive a response or timeout */
	do {
		token = SPI_RxByte();
	} while((token == 0xFF) && HAL_GetTick() < timeout);

	/* invalid response */
	if(token != 0xFE) return FALSE;

	/* receive data */
	if(len > 16)
	{
		// manual txrx
		SPI_Start((HSPI_SDCARD)->Instance, len + 2);

		// the only length that will be used here is 512
		uint32_t *buff32 = (uint32_t *)buff;
		const uint32_t *end = buff32 + len / 4;

		// fill the 16 byte fifo
		for(int i = 0; i < 4; i++)
			*((__IO uint32_t *)&(HSPI_SDCARD)->Instance->TXDR) = 0xFFFFFFFF;

		while(true)
		{
			if(((HSPI_SDCARD)->Instance->SR & SPI_FLAG_RXWNE))
			{
				*(buff32++) = *((__IO uint32_t *)&(HSPI_SDCARD)->Instance->RXDR);

				if(buff32 != end)
					*((__IO uint32_t *)&(HSPI_SDCARD)->Instance->TXDR) = 0xFFFFFFFF; // refill tx
				else
					break;
			}
		}

		// get CRC
		*((__IO uint16_t *)&(HSPI_SDCARD)->Instance->TXDR) = 0xFFFF;
		while(!((HSPI_SDCARD)->Instance->SR & SPI_SR_RXPLVL_1));
		uint16_t crc = *((__IO uint16_t *)&(HSPI_SDCARD)->Instance->RXDR);

		while(!((HSPI_SDCARD)->Instance->SR & SPI_FLAG_EOT)); // wait for end

		// end
		SPI_End((HSPI_SDCARD)->Instance);
	}
	else
	{
		while(len--)
			SPI_RxBytePtr(buff++);

		/* discard CRC */
		SPI_RxByte();
		SPI_RxByte();
	}
	return TRUE;
}

/* transmit data block */
#if FF_FS_READONLY == 0
static bool SD_TxDataBlock(const uint8_t *buff, BYTE token)
{
	uint8_t resp;
	uint8_t i = 0;

	/* wait SD ready */
	if (SD_ReadyWait() != 0xFF) return FALSE;

	/* transmit token */
	SPI_TxByte(token);

	/* if it's not STOP token, transmit data */
	if (token != 0xFD)
	{
    // manual tx
    const int len = 512;
		SPI_Start((HSPI_SDCARD)->Instance, len);

		// the only length that will be used here is 512
		uint32_t *buff32 = (uint32_t *)buff;
		const uint32_t *end = buff32 + len / 4;

		// fill the 16 byte fifo
		for(int i = 0; i < 4; i++)
			*((__IO uint32_t *)&(HSPI_SDCARD)->Instance->TXDR) = *buff32++;

		while(buff32 != end)
		{
			if(((HSPI_SDCARD)->Instance->SR & SPI_FLAG_TXP))
				*((__IO uint32_t *)&(HSPI_SDCARD)->Instance->TXDR) = *buff32++;
		}

		while(!((HSPI_SDCARD)->Instance->SR & SPI_FLAG_EOT)); // wait for end

		// end
		SPI_End((HSPI_SDCARD)->Instance);

		/* discard CRC */
		SPI_RxByte();
		SPI_RxByte();

		/* receive response */
		while (i <= 64)
		{
			resp = SPI_RxByte();

			/* transmit 0x05 accepted */
			if ((resp & 0x1F) == 0x05) break;
			i++;
		}

		/* recv buffer clear */
		while (SPI_RxByte() == 0);
	}
	else
		return TRUE;

	/* transmit 0x05 accepted */
	if ((resp & 0x1F) == 0x05) return TRUE;

	return FALSE;
}
#endif /*  FF_FS_READONLY */

/* transmit command */
static BYTE SD_SendCmd(BYTE cmd, uint32_t arg)
{
	uint8_t crc, res;

	/* wait SD ready */
	if (SD_ReadyWait() != 0xFF) return 0xFF;

	/* transmit command */
	SPI_TxByte(cmd); 					/* Command */
	SPI_TxByte((uint8_t)(arg >> 24)); 	/* Argument[31..24] */
	SPI_TxByte((uint8_t)(arg >> 16)); 	/* Argument[23..16] */
	SPI_TxByte((uint8_t)(arg >> 8)); 	/* Argument[15..8] */
	SPI_TxByte((uint8_t)arg); 			/* Argument[7..0] */

	/* prepare CRC */
	if(cmd == CMD0) crc = 0x95;	/* CRC for CMD0(0) */
	else if(cmd == CMD8) crc = 0x87;	/* CRC for CMD8(0x1AA) */
	else crc = 1;

	/* transmit CRC */
	SPI_TxByte(crc);

	/* Skip a stuff byte when STOP_TRANSMISSION */
	if (cmd == CMD12) SPI_RxByte();

	/* receive response */
	uint8_t n = 10;
	do {
		res = SPI_RxByte();
	} while ((res & 0x80) && --n);

	return res;
}

/***************************************
 * user_diskio.c functions
 **************************************/

/* initialize SD */
DSTATUS SD_disk_initialize(BYTE drv)
{
	uint8_t n, type, ocr[4];

	/* single drive, drv should be 0 */
	if(drv) return STA_NOINIT;

	/* no disk */
	if(Stat & STA_NODISK) return Stat;

	/* power on */
	SD_PowerOn();

	/* slave select */
	SELECT();

	/* check disk type */
	type = 0;

	/* send GO_IDLE_STATE command */
	if (SD_SendCmd(CMD0, 0) == 1)
	{
		/* timeout 1 sec */
		uint32_t timeout = HAL_GetTick() + 1000;

		/* SDC V2+ accept CMD8 command, http://elm-chan.org/docs/mmc/mmc_e.html */
		if (SD_SendCmd(CMD8, 0x1AA) == 1)
		{
			/* operation condition register */
			for (n = 0; n < 4; n++)
			{
				ocr[n] = SPI_RxByte();
			}

			/* voltage range 2.7-3.6V */
			if (ocr[2] == 0x01 && ocr[3] == 0xAA)
			{
				/* ACMD41 with HCS bit */
				do {
					if (SD_SendCmd(CMD55, 0) <= 1 && SD_SendCmd(CMD41, 1UL << 30) == 0) break;
				} while (HAL_GetTick() < timeout);

				/* READ_OCR */
				if (HAL_GetTick() < timeout && SD_SendCmd(CMD58, 0) == 0)
				{
					/* Check CCS bit */
					for (n = 0; n < 4; n++)
					{
						ocr[n] = SPI_RxByte();
					}

					/* SDv2 (HC or SC) */
					type = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
				}
			}
		}
		else
		{
			/* SDC V1 or MMC */
			type = (SD_SendCmd(CMD55, 0) <= 1 && SD_SendCmd(CMD41, 0) <= 1) ? CT_SD1 : CT_MMC;

			do
			{
				if (type == CT_SD1)
				{
					if (SD_SendCmd(CMD55, 0) <= 1 && SD_SendCmd(CMD41, 0) == 0) break; /* ACMD41 */
				}
				else
				{
					if (SD_SendCmd(CMD1, 0) == 0) break; /* CMD1 */
				}

			} while (HAL_GetTick() < timeout);

			/* SET_BLOCKLEN */
			if (!(HAL_GetTick() >= timeout) || SD_SendCmd(CMD16, 512) != 0) type = 0;
		}
	}

	CardType = type;

	/* Idle */
	DESELECT();
	SPI_RxByte();

	/* Clear STA_NOINIT */
	if (type)
	{
		Stat &= ~STA_NOINIT;
	}
	else
	{
		/* Initialization failed */
		SD_PowerOff();
	}

	return Stat;
}

/* return disk status */
DSTATUS SD_disk_status(BYTE drv)
{
	if (drv) return STA_NOINIT;
	return Stat;
}

/* read sector */
DRESULT SD_disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
{
	/* pdrv should be 0 */
	if (pdrv || !count) return RES_PARERR;

	/* no disk */
	if (Stat & STA_NOINIT) return RES_NOTRDY;

	/* convert to byte address */
	if (!(CardType & CT_BLOCK)) sector *= 512;

	SELECT();

	if (count == 1)
	{
		/* READ_SINGLE_BLOCK */
		if ((SD_SendCmd(CMD17, sector) == 0) && SD_RxDataBlock(buff, 512)) count = 0;
	}
	else
	{
		/* READ_MULTIPLE_BLOCK */
		if (SD_SendCmd(CMD18, sector) == 0)
		{
			do {
				if (!SD_RxDataBlock(buff, 512)) break;
				buff += 512;
			} while (--count);

			/* STOP_TRANSMISSION */
			SD_SendCmd(CMD12, 0);
		}
	}

	/* Idle */
	DESELECT();
	SPI_RxByte();

	return count ? RES_ERROR : RES_OK;
}

/* write sector */
#if FF_FS_READONLY == 0
DRESULT SD_disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
{
	/* pdrv should be 0 */
	if (pdrv || !count) return RES_PARERR;

	/* no disk */
	if (Stat & STA_NOINIT) return RES_NOTRDY;

	/* write protection */
	if (Stat & STA_PROTECT) return RES_WRPRT;

	/* convert to byte address */
	if (!(CardType & CT_BLOCK)) sector *= 512;

	SELECT();

	if (count == 1)
	{
		/* WRITE_BLOCK */
		if ((SD_SendCmd(CMD24, sector) == 0) && SD_TxDataBlock(buff, 0xFE))
			count = 0;
	}
	else
	{
		/* WRITE_MULTIPLE_BLOCK */
		if (CardType & CT_SD1)
		{
			SD_SendCmd(CMD55, 0);
			SD_SendCmd(CMD23, count); /* ACMD23 */
		}

		if (SD_SendCmd(CMD25, sector) == 0)
		{
			do {
				if(!SD_TxDataBlock(buff, 0xFC)) break;
				buff += 512;
			} while (--count);

			/* STOP_TRAN token */
			if(!SD_TxDataBlock(0, 0xFD))
			{
				count = 1;
			}
		}
	}

	/* Idle */
	DESELECT();
	SPI_RxByte();

	return count ? RES_ERROR : RES_OK;
}
#endif /* FF_FS_READONLY */

/* ioctl */
DRESULT SD_disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
{
	DRESULT res;
	uint8_t n, csd[16], *ptr = (uint8_t*)buff;
	DWORD csize;

	/* pdrv should be 0 */
	if (drv) return RES_PARERR;
	res = RES_ERROR;

	if (ctrl == CTRL_POWER)
	{
		switch (*ptr)
		{
		case 0:
			SD_PowerOff();		/* Power Off */
			res = RES_OK;
			break;
		case 1:
			SD_PowerOn();		/* Power On */
			res = RES_OK;
			break;
		case 2:
			*(ptr + 1) = SD_CheckPower();
			res = RES_OK;		/* Power Check */
			break;
		default:
			res = RES_PARERR;
		}
	}
	else
	{
		/* no disk */
		if (Stat & STA_NOINIT) return RES_NOTRDY;

		SELECT();

		switch (ctrl)
		{
		case GET_SECTOR_COUNT:
			/* SEND_CSD */
			if ((SD_SendCmd(CMD9, 0) == 0) && SD_RxDataBlock(csd, 16))
			{
				if ((csd[0] >> 6) == 1)
				{
					/* SDC V2 */
					csize = csd[9] + ((WORD) csd[8] << 8) + ((DWORD) (csd[7] & 0x3F) << 16) + 1;
					*(DWORD*) buff = (DWORD) csize << 10;
				}
				else
				{
					/* MMC or SDC V1 */
					n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
					csize = (csd[8] >> 6) + ((WORD) csd[7] << 2) + ((WORD) (csd[6] & 3) << 10) + 1;
					*(DWORD*) buff = (DWORD) csize << (n - 9);
				}
				res = RES_OK;
			}
			break;
		case GET_SECTOR_SIZE:
			*(WORD*) buff = 512;
			res = RES_OK;
			break;
		case CTRL_SYNC:
			if (SD_ReadyWait() == 0xFF) res = RES_OK;
			break;
		default:
			res = RES_PARERR;
		}

		DESELECT();
		SPI_RxByte();
	}

	return res;
}
