/*******************************************************************************
 *
 *      A U D I O   R E C O R D E R   S D   C A R D   D R I V E R
 *
 *      Copyright A Levido 2013 - All Rights Reserved
 *
 ******************************************************************************/
#ifndef _SDCARD_H
#define _SDCARD_H

#ifdef __cplusplus
extern "C" {
#endif
#include "genericTypeDefs.h"

// Typedefs
typedef UINT8 DSTATUS;

typedef enum {
	RES_OK = 0,		/* 0: Successful */
	RES_ERROR,		/* 1: R/W Error */
	RES_WRPRT,		/* 2: Write Protected */
	RES_NOTRDY,		/* 3: Not Ready */
	RES_PARERR		/* 4: Invalid Parameter */
} DRESULT;

// Disk Status Flags (DSTATUS)
#define STA_NOINIT		0x01	/* Drive not initialized */
#define STA_NODISK		0x02	/* No medium in the drive */
#define STA_PROTECT		0x04	/* Write protected */

// Command codes for disk_ioctrl fucntion
#define CTRL_SYNC		0	/* Flush disk cache (for write functions) */
#define GET_SECTOR_SIZE		2	/* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
#define MMC_GET_TYPE		10	/* Get card type */
#define MMC_GET_CSD		11	/* Get CSD */
#define MMC_GET_CID		12	/* Get CID */
#define MMC_GET_OCR		13	/* Get OCR */
#define MMC_GET_SDSTAT		14	/* Get SD status */

// 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 */

#define SD_DET_PERIOD   100             // 100 ms

/** Detect SD card status
 * Task regularly tests  the SD card presence and write protect switches and
 * posts events to the Control System */
void sdDetectStatus(void);

void sdShutdown();


void sdWakeup();
 void sdSetState(UINT32 s);

 /** Return true if SD card is present */
 UINT32 sdCardPresent(void);

/** Initialise the SD Card
 * Initialises the SD card and determines what type (MMC, SDv1 SC, SDv2 SC,
 * SDv2 HC). This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param drive  Number of the drive (must be zero)
 * @returns      Status flags */
DSTATUS disk_initialize(BYTE);

/** Return the disk status
 * This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param drive  Number of the drive (must be zero)
 * @returns      Status flags */
DSTATUS disk_status(BYTE);

/** Read one or more sectors from the SD card
 * This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param drive  Number of the drive (must be zero)
 * @param buff   Pointer to a buffer to hold the data (must be big enough!)
 * @param sector Sector number to start reading
 * @param count  Number of sectors to read
 * @returns      Result code @see DRESULT */
DRESULT disk_read(BYTE, BYTE*, DWORD, BYTE);

/** Write one or more sectors to the SD card
 * This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param drive  Number of the drive (must be zero)
 * @param buff   Pointer to a buffer containing the data to write
 * @param sector Sector number to start writing
 * @param count  Number of sectors to write
 * @returns      Result Code @see DRESULT */
DRESULT disk_write(BYTE, const BYTE*, DWORD, BYTE);

/** Disk control and information function
 * This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param drive  Number of the drive (must be zero)
 * @param ctrl   Control code
 * @param buff   Pointer to a buffer to hold the result
 * @returns      Result Code @see DRESULT */
DRESULT disk_ioctl(BYTE, BYTE, void*);

/** Convert OEM CodePage to anf From Unicode
 * This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param chr    Character to be converted
 * @param dir    Direction: 0 = Unicode to OEMCP, 1 = OEMCP to Unicode
 * @returns      The converted character */
UINT16 ff_convert(UINT16 chr, UINT dir);

/** Convert Unicode Char to upper Case
 * This function is called by the FAT file system and should not be
 * called by the application
 *
 * @param chrn   Character to be converted
 * @returns      The converted character */
UINT16 ff_wtoupper(UINT16 chr);

/* Functions & wrappers for USB MSD device driver******************************/

typedef  UINT32 MEDIA_INFORMATION;

/** Initialise the SD card
 * Wrapper for disk_initialise()
 * The USB MSD driver only checks that this pointer is non-NULL - no need to
 * use the Microchip MEDIA_INFORMATION structure
 * @returns pointer to a MEDIA_INFORMATION entity */
MEDIA_INFORMATION* msdInitMedia(void);

/** Read One Sector
 * Reads one sector from the sd card
 * Wrapper for disk_read()
 * @param addr  Address of sector to read
 * @param buff  Pointer to buffer containing data to write
 * @returns TRUE on success, FALSE on error */
BYTE msdSectorRead(DWORD addr, BYTE* buff);

/** Write One Sector
 * Writes one sector to the sd card
 * Wrapper for disk-write
 * @param addr  Address of sector to write
 * @param buff  Pointer to buffer to receive the data
 * @param wtz   Flag permitting write to sector zero
 * @returns TRUE on success, FALSE on error */
BYTE msdSectorWrite(DWORD addr, BYTE* buff, BYTE wtz);

/** Read the write protect status
 * @returns True if media write protected */
BYTE msdReadWP(void);

/** Read disk Capacity
 * Returns the capacity of the SD card in bytes
 * @returns Capacity of the card in bytes */
DWORD msdReadCapacity(void);

/** Read the media detect status
 * @returns True if media present and initialised */
BYTE msdMediaDetect(void);

/** Read the sector size
 * @returns Sector size in Bytes (always 512)*/
WORD msdReadSectorSize(void);

#ifdef __cplusplus
}
#endif

#endif
