#ifndef _MMC_DEF__H_
#define _MMC_DEF__H_


// размер одного блока чтения в байтах
#define BLOCK_SIZE	512L


/**
 * Константы для работы с картами MMC/SD.
 */

// команды, доступные в режиме SPI
// CMD0: R1, Software reset.
#define CMD_GO_IDLE_STATE 0x00

// CMD1: R1, Initiate initialization process.
#define CMD_SEND_OP_COND 0x01

// CMD8: R7, For only SDC V2. Check voltage range.
#define CMD_SEND_IF_COND 0x08

// CMD9: R1, Read CSD register.
#define CMD_SEND_CSD 0x09

// CMD10: R1, Read CID register.
#define CMD_SEND_CID 0x0a

// CMD12: R1, Stop to read data. 
#define CMD_STOP_TRANSMISSION 0x0c

// CMD13: R2 
#define CMD_SEND_STATUS 0x0d

// CMD16: R1 arg0[31:0]: block length, Change R/W block size. 
#define CMD_SET_BLOCKLEN 0x10

// CMD17: R1 arg0[31:0]: data address, Read a block.
#define CMD_READ_SINGLE_BLOCK 0x11

// CMD18: R1 arg0[31:0]: data address, Read multiple blocks.
#define CMD_READ_MULTIPLE_BLOCK 0x12

// CMD24: R1 arg0[31:0]: data address
#define CMD_WRITE_SINGLE_BLOCK 0x18

// CMD25: R1 arg0[31:0]: data address
#define CMD_WRITE_MULTIPLE_BLOCK 0x19

// CMD27: R1 
#define CMD_PROGRAM_CSD 0x1b

// CMD28: R1b arg0[31:0]: data address
#define CMD_SET_WRITE_PROT 0x1c

// CMD29: R1b arg0[31:0]: data address
#define CMD_CLR_WRITE_PROT 0x1d

// CMD30: R1 arg0[31:0]: write protect data address
#define CMD_SEND_WRITE_PROT 0x1e

// CMD32: R1 arg0[31:0]: data address
#define CMD_TAG_SECTOR_START 0x20

// CMD33: R1 arg0[31:0]: data address
#define CMD_TAG_SECTOR_END 0x21

// CMD34: R1 arg0[31:0]: data address
#define CMD_UNTAG_SECTOR 0x22

// CMD35: R1 arg0[31:0]: data address
#define CMD_TAG_ERASE_GROUP_START 0x23

// CMD36: R1 arg0[31:0]: data address
#define CMD_TAG_ERASE_GROUP_END 0x24

// CMD37: R1 arg0[31:0]: data address
#define CMD_UNTAG_ERASE_GROUP 0x25

// CMD38: R1b arg0[31:0]: stuff bits
#define CMD_ERASE 0x26

// ACMD41: R1 arg0[31:0]: OCR contents
#define CMD_SD_SEND_OP_COND 0x29

// CMD42: R1b arg0[31:0]: stuff bits

#define CMD_LOCK_UNLOCK 0x2a
// CMD55: R1 arg0[31:0]: stuff bits

#define CMD_APP 0x37
// CMD58: R3 arg0[31:0]: stuff bits

#define CMD_READ_OCR 0x3a
// CMD59: R1 arg0[31:1]: stuff bits, arg0[0:0]: crc option

#define CMD_CRC_ON_OFF 0x3b


// ответы команд
// R1: размер 1 байт
#define R1_IDLE_STATE			0
#define R1_ERASE_RESET			1
#define R1_ILL_COMMAND			2
#define R1_COM_CRC_ERR			3
#define R1_ERASE_SEQ_ERR		4
#define R1_ADDR_ERR				5
#define R1_PARAM_ERR				6
// R1b: как и для R1
// R2: размер 2 байта
#define R2_CARD_LOCKED			0
#define R2_WP_ERASE_SKIP		1
#define R2_ERR						2
#define R2_CARD_ERR				3
#define R2_CARD_ECC_FAIL		4
#define R2_WP_VIOLATION			5
#define R2_INVAL_ERASE			6
#define R2_OUT_OF_RANGE			7
#define R2_CSD_OVERWRITE		7
#define R2_IDLE_STATE			(R1_IDLE_STATE + 8)
#define R2_ERASE_RESET			(R1_ERASE_RESET + 8)
#define R2_ILL_COMMAND			(R1_ILL_COMMAND + 8)
#define R2_COM_CRC_ERR			(R1_COM_CRC_ERR + 8)
#define R2_ERASE_SEQ_ERR		(R1_ERASE_SEQ_ERR + 8)
#define R2_ADDR_ERR				(R1_ADDR_ERR + 8)
#define R2_PARAM_ERR				(R1_PARAM_ERR + 8)
// R3: размер 5 байт
#define R3_OCR_MASK				(0xffffffffUL)
#define R3_IDLE_STATE			(R1_IDLE_STATE + 32)
#define R3_ERASE_RESET			(R1_ERASE_RESET + 32)
#define R3_ILL_COMMAND			(R1_ILL_COMMAND + 32)
#define R3_COM_CRC_ERR			(R1_COM_CRC_ERR + 32)
#define R3_ERASE_SEQ_ERR		(R1_ERASE_SEQ_ERR + 32)
#define R3_ADDR_ERR				(R1_ADDR_ERR + 32)
#define R3_PARAM_ERR				(R1_PARAM_ERR + 32)
// Data Response: size 1 byte
#define DR_STATUS_MASK 0x0e
#define DR_STATUS_ACCEPTED 0x05
#define DR_STATUS_CRC_ERR 0x0a
#define DR_STATUS_WRITE_ERR 0x0c

// биты статуса для типов карт
#define MMC_SPEC_1 0
#define MMC_SPEC_2 1
#define MMC_SPEC_SDHC 2








// константы портов для доступа к sd/mmc
#define configure_pin_mosi() DDRB |= (1 << DDB3)
#define configure_pin_sck() DDRB |= (1 << DDB5)
#define configure_pin_ss() DDRB |= (1 << DDB2)
#define configure_pin_miso() DDRB &= ~(1 << DDB4)

#define select_card() PORTB &= ~(1 << PB2)
#define unselect_card() PORTB |= (1 << PB2)





#endif // _MMC_DEF__H_
