#ifndef SDCOMM_SPI_H
#define SDCOMM_SPI_H
#include "types.h"

typedef struct
{
unsigned long int timeout_write;
unsigned long int timeout_read;
char busyflag;
} sd_context_t;

#define R1 				1
#define R1B 			2
#define R2 				3
#define R3 				4
#define R1X18			5
#define R7				6
//
#define MSK_IDLE 0x01
#define MSK_ERASE_RST 0x02
#define MSK_ILL_CMD 0x04
#define MSK_CRC_ERR 0x08
#define MSK_ERASE_SEQ_ERR 0x10
#define MSK_ADDR_ERR 0x20
#define MSK_PARAM_ERR 0x40
#define SD_TOK_READ_STARTBLOCK 0xFE
#define SD_TOK_WRITE_STARTBLOCK 0xFE
#define SD_TOK_READ_STARTBLOCK_M 0xFE
#define SD_TOK_WRITE_STARTBLOCK_M 0xFC
#define SD_TOK_STOP_MULTI 0xFD
/* Error token is 111XXXXX */
#define MSK_TOK_DATAERROR 0xE0
/* Bit fields */
#define MSK_TOK_ERROR 0x01
#define MSK_TOK_CC_ERROR 0x02
#define MSK_TOK_ECC_FAILED 0x04
#define MSK_TOK_CC_OUTOFRANGE 0x08
#define MSK_TOK_CC_LOCKED 0x10
/* Mask off the bits in the OCR corresponding to voltage range 3.2V to
* 3.4V, OCR bits 20 and 21 */
#define MSK_OCR_33 0xC0
/* Number of times to retry the probe cycle during initialization */
#define SD_INIT_TRY 50
/* Number of tries to wait for the card to go idle during initialization */
#define SD_IDLE_WAIT_MAX 50
#define SD_READ_TIMEOUT  	100000
#define SD_WRITE_TIMEOUT	100000
/* Hardcoded timeout for commands. 8 words, or 64 clocks. Do 10
* words instead */
#define SD_CMD_TIMEOUT 20
/******************************** Basic command set **************************/
/* Reset cards to idle state */
#define CMD0 0
#define CMD0_R R1
/* Read the OCR (MMC mode, do not use for SD cards) */
#define CMD1 1
#define CMD1_R R1
/* Card sends the CSD */
#define CMD8 8
#define CMD8_R R7
//
#define CMD9 9
#define CMD9_R R1X18
/* Card sends CID */
#define CMD10 10
#define CMD10_R R1X18
/* Stop a multiple block (stream) read/write operation */
#define CMD12 12
#define CMD12_R R1B
/* Get the addressed card's status register */
#define CMD13 13
#define CMD13_R R2
/***************************** Block read commands **************************/
/* Set the block length */
#define CMD16 16
#define CMD16_R R1
/* Read a single block */
#define CMD17 17
#define CMD17_R R1
/* Read multiple blocks until a CMD12 */
#define CMD18 18
#define CMD18_R R1
/***************************** Block write commands *************************/
/* Write a block of the size selected with CMD16 */
#define CMD24 24
#define CMD24_R R1
/* Multiple block write until a CMD12 */
#define CMD25 25
#define CMD25_R R1
/* Program the programmable bits of the CSD */
#define CMD27 27
#define CMD27_R R1
/***************************** Write protection *****************************/
/* Set the write protection bit of the addressed group */
#define CMD28 28
#define CMD28_R R1B
/* Clear the write protection bit of the addressed group */
#define CMD29 29
#define CMD29_R R1B
/* Ask the card for the status of the write protection bits */
#define CMD30 30
#define CMD30_R R1
/***************************** Erase commands *******************************/
/* Set the address of the first write block to be erased */
#define CMD32 32
#define CMD32_R R1
/* Set the address of the last write block to be erased */
#define CMD33 33
#define CMD33_R R1
/* Erase the selected write blocks */
#define CMD38 38
#define CMD38_R R1B
/***************************** Lock Card commands ***************************/
/* Commands from 42 to 54, not defined here */
/***************************** Application-specific commands ****************/
/* Flag that the next command is application-specific */
#define CMD55 55
#define CMD55_R R1
/* General purpose I/O for application-specific commands */
#define CMD56 56
#define CMD56_R R1
/* Read the OCR (SPI mode only) */
#define CMD58 58
#define CMD58_R R3
/* Turn CRC on or off */
#define CMD59 59
#define CMD59_R R1
/***************************** Application-specific commands ***************/
/* Get the SD card's status */
#define ACMD13 13
#define ACMD13_R R2
/* Get the number of written write blocks (Minus errors ) */
#define ACMD22 22
#define ACMD22_R R1
/* Set the number of write blocks to be pre-erased before writing */
#define ACMD23 23
#define ACMD23_R R1
/* Get the card's OCR (SD mode) */
#define ACMD41 41
#define ACMD41_R R1
/* Connect or disconnect the 50kOhm internal pull-up on CD/DAT[3] */
#define ACMD42 42
#define ACMD42_R R1
/* Get the SD configuration register */
#define ACMD51 42
#define ACMD51_R R1

#define ERROR_ALL_OK			  0
#define ERROR_NOT_SD_CARD		  1
#define ERROR_BAD_VOLTAGE_RANGE	  2
#define ERROR_SD_CARD_TIMEOUT	  3

typedef struct 
{
	unsigned char	TAAC;
	unsigned char	NSAC;
	unsigned char 	TRAN_SPEED;
	unsigned int	CCC;
	unsigned char	READ_BL_LEN;
	unsigned long	C_SIZE;
	unsigned char	C_SIZE_MULT;
	unsigned char	SECTOR_SIZE;
	unsigned char	FILE_FORMAT;
} CSD_REGISTER;

typedef struct 
{
	unsigned char	MID;		// Manufacturer ID
	unsigned int	OID;		// OEM ID
	unsigned char 	PNM[6];		// Product Name
	unsigned char	PRV;		// Product Revision
	unsigned char	PSN[4];		// Serial Number
	unsigned int	MDT;		// Manufacture Date M/Y from 2000
} CID_REGISTER;

typedef struct
{
	unsigned char	OCR[4];
} OCR_REGISTER;

typedef struct
{
	unsigned char	SD_VERSION;		// whether card is version 1 or 2
	unsigned char	CARD_TYPE;		// 0: not SD , 1: SD Standard Capacity , 2: SD HC (High Capacity)
	unsigned char	VOLTAGE_RANGE;	// 0: not supported 1: supported (3.3V)
	unsigned long	SIZE_KB;		// size in Kilobytes (filled in when CSD is read)
	unsigned char	ERROR;			// 0: no errors >0: errors
	CID_REGISTER	cid;			// CID Register
	CSD_REGISTER	csd;			// CSD Register
	OCR_REGISTER	ocr;			// OCR Register
} CARD_INFO;

#endif
