Пример #1
0
//the following command reads multiple blocks from the sd card starting at the specified block/sector
void SD_read_multiple_blocks(uint32_t sector,uint8_t* data,int numOfBlocks){
	PortEx_OUTCLR(BIT3_bm, PS_BANKB);	//pull SD cs low
	SPIInit(SPI_MODE_0_gc);
	SPICS(TRUE);
	while(SD_command(SDHC_CMD_READ_MULTIPLE_BLOCKS,sector,SDHC_DUMMY_BYTE,8) != SDHC_CMD_SUCCESS);	//send command to read data
	//do the following for however many sectors to be read in
	for (int j=0;j<numOfBlocks;j++){
		Buffer[1]=SDHC_DUMMY_BYTE;
		while(Buffer[1] != SDHC_DATA_TOKEN){
			Buffer[1] = SPI_write(SDHC_DUMMY_BYTE);	//wait for start of data token
		}
		for (int i=0;i<SDHC_SECTOR_SIZE;i++){
			data[(i+(j*SDHC_SECTOR_SIZE))] = SPI_write(SDHC_DUMMY_BYTE);	//read in the data
		}
		
		for (int i=0;i<2;i++){
			Buffer[i] = SPI_write(SDHC_DUMMY_BYTE);	//read in the 2 CRC bytes
		}
	}
	SD_command(SDHC_CMD_STOP_TRANSMISSION,SDHC_NO_ARGUMENTS,SDHC_DUMMY_BYTE,8);	//send command to stop reading data
	Buffer[0] = SPI_write(SDHC_DUMMY_BYTE);	//read the stuff byte
	Buffer[1] = FILLER_BYTE;
	while (Buffer[1] != SDHC_DUMMY_BYTE) Buffer[1] = SPI_write(SDHC_DUMMY_BYTE); //wait for card to finish internal processes
	SPICS(FALSE);
	SPIDisable();
	PortEx_OUTSET(BIT3_bm, PS_BANKB);	//pull SD cs high
}
Пример #2
0
//the following command reads one sector from the sdhc card
void SD_read_block(uint32_t sector,uint8_t* arrayOf512Bytes){
	PortEx_OUTCLR(BIT3_bm, PS_BANKB);	//pull SD cs low
	SPIInit(SPI_MODE_0_gc);
	SPICS(TRUE);
	
	for(int i=0;SD_command(SDHC_CMD_READ_SINGLE_BLOCK,sector,SDHC_DUMMY_BYTE,8) != SDHC_CMD_SUCCESS; i++) {	//send command to read data
		if (i >= 10) {
			//there was no response to the command
			while(1);
		}
	}		
	while(Buffer[0] != SDHC_DATA_TOKEN){
		Buffer[0] = SPI_write(SDHC_DUMMY_BYTE);
	}		
	for (int i=0;i<SDHC_SECTOR_SIZE;i++){
		arrayOf512Bytes[i] = SPI_write(SDHC_DUMMY_BYTE);	//read in the data
	}
	Buffer[12] = FILLER_BYTE;
	while (Buffer[12] != SDHC_DUMMY_BYTE){
		Buffer[12] = SPI_write(SDHC_DUMMY_BYTE);	
	}

	SPICS(FALSE);
	SPIDisable();
	PortEx_OUTSET(BIT3_bm, PS_BANKB);	//pull SD cs high
}
Пример #3
0
//the following command writes one sector to the sdhc card
void SD_write_block(uint32_t sector,uint8_t* data, int lengthOfData){
	PortEx_OUTCLR(BIT3_bm, PS_BANKB);	//pull SD cs low
	SPIInit(SPI_MODE_0_gc);
	SPICS(TRUE);
	int fillerBytes = SDHC_SECTOR_SIZE - lengthOfData;
	if (fillerBytes==SDHC_SECTOR_SIZE) fillerBytes = 0;
	for(int i=0;SD_command(SDHC_CMD_WRITE_SINGLE_BLOCK,sector,SDHC_DUMMY_BYTE,8) != SDHC_CMD_SUCCESS; i++){		//write to specified sector
	if (i >= 10) {
		//there was no response to the command
		while(1);
	}
}
Buffer[0] = SPI_write(SDHC_DUMMY_BYTE);	//send 1 dummy byte as spacer
SPI_write(SDHC_DATA_TOKEN);	//send data token
for (int i=0;i<lengthOfData;i++){	//write the data segment 1 byte at a time
Buffer[i%13] = SPI_write(data[i]);
	}
	for (int i=0;i<fillerBytes;i++){	//fill the rest of the sector with filler bytes
	Buffer[i%13] = SPI_write(FILLER_BYTE);
	} 
	Buffer[0] = SDHC_DUMMY_BYTE;
	for(int i=0; (i<2) || (Buffer[0] == SDHC_DUMMY_BYTE);i++){
		Buffer[0] = SPI_write(SDHC_DUMMY_BYTE);	//send 2 CRC dummy bytes and keep reading bytes until a response is seen 	
	}
	if ((Buffer[0] & SDHC_RESPONSE_STATUS_MASK) == 0x02){
		//data was written successfully
	}
	while(Buffer[0] != SDHC_DUMMY_BYTE) Buffer[0] = SPI_write(SDHC_DUMMY_BYTE);	//wait for card to finish internal processes
	SPICS(FALSE);
	SPIDisable();
	PortEx_OUTSET(BIT3_bm, PS_BANKB);	//pull SD cs high	
}
Пример #4
0
// Read from FRAM
// FRAM power (VDC-2) must be on with CS_FRAM pulled high to write protect
void readFRAM (uint16_t numBytes, uint16_t startAddress) {
	
	//save SPI registers
	uint8_t prev_SPI_settings;
	ADCPower(TRUE);
	
	prev_SPI_settings = SPIC.CTRL;
	SPIInit(SPI_MODE_0_gc);
	SPIC.CTRL = FR_SPI_CONFIG_gc;
	SPICS(TRUE);
	PORTB.OUTCLR = PIN3_bm;  // pull down CS_FRAM to write enable
	nop();
	
	SPIC.DATA = FR_READ;
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	SPIC.DATA = *(((uint8_t*)&startAddress) + 1);;
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	SPIC.DATA = *(((uint8_t*)&startAddress) + 0);;
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	
	for(uint16_t i = 0; i < numBytes; i++) {
		SPIC.DATA = 0xAA;
		while(!(SPIC.STATUS & SPI_IF_bm));
		FRAMReadBuffer[i] = SPIC.DATA;
	}

	PORTB.OUTSET = PIN3_bm;  // CS_FRAM write protect
	SPICS(FALSE);
	SPIC.CTRL = prev_SPI_settings;

}
Пример #5
0
//this function deselects the sd card and turns off power to the port expander and the sd card
void SD_disable(){
	PortEx_DIRSET(BIT3_bm, PS_BANKB);  //pull SD card CS high
	PortEx_OUTSET(BIT3_bm, PS_BANKB);
	SPIInit(SPI_MODE_0_gc);
	SPICS(TRUE);
	SPI_write(SDHC_DUMMY_BYTE);	//must write a byte to spi when cd card cs is high to have sd card release MISO line
	SPICS(FALSE);	//stop spi
	SPIDisable();
	
	ADCPower(FALSE);		//turn off portEX power
	Ext1Power(FALSE);			//power down SD card
}
Пример #6
0
void writeFRAM(uint8_t* buffer, uint16_t length) {
	
	uint8_t prev_SPI_settings;
	ADCPower(TRUE);
	
	prev_SPI_settings = SPIC.CTRL;
	SPIInit(SPI_MODE_0_gc);
	SPIC.CTRL = FR_SPI_CONFIG_gc;
	SPICS(TRUE);
	PORTB.OUTCLR = PIN3_bm;  // pull down CS_FRAM to write enable
	nop();
	SPIC.DATA = FR_WREN;
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	PORTB.OUTSET = PIN3_bm;  // latch opcode
	nop(); // time for CS_FRAM to accept high signal
	PORTB.OUTCLR = PIN3_bm;  // pull down CS_FRAM to write enable
	nop();
	SPIC.DATA = FR_WRITE;
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	//send address at which to start writing data
	SPIC.DATA = *(((uint8_t*)&FRAMAddress)+1);
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	SPIC.DATA = *((uint8_t*)&FRAMAddress);
	while(!(SPIC.STATUS & SPI_IF_bm));
	SPIBuffer[12] = SPIC.DATA;
	//write data to FRAM
	for(uint32_t i = 0; i< length; i++){
		SPIC.DATA = buffer[i];
		while(!(SPIC.STATUS & SPI_IF_bm));
		SPIBuffer[12] = SPIC.DATA;
	}
	
	PORTB.OUTSET = PIN3_bm;  // pull up CS_FRAM to write protect
	SPICS(FALSE);
	SPIC.CTRL = prev_SPI_settings;
	//SPIC.CTRL = ADC_SPI_CONFIG_gc;
	//PORTC.OUTCLR = PIN4_bm;  // enable SPI-SS
	
	//increment address by the written length
	FRAMAddress +=length;
}
Пример #7
0
//the following command writes multiple blocks/sectors to the sd card starting at a specified sector (in the sd card)
void SD_write_multiple_blocks(uint32_t sector,uint8_t* data,int lengthOfData){
	PortEx_OUTCLR(BIT3_bm, PS_BANKB);	//pull SD cs low
	SPIInit(SPI_MODE_0_gc);
	SPICS(TRUE);
	int numSectors = lengthOfData/SDHC_SECTOR_SIZE;
	int fillerBytes = SDHC_SECTOR_SIZE - lengthOfData%SDHC_SECTOR_SIZE;
	if (fillerBytes==SDHC_SECTOR_SIZE) fillerBytes = 0;
	else numSectors++;
	while(SD_command(SDHC_CMD_WRITE_MULTIPLE_BLOCKS,sector,SDHC_DUMMY_BYTE,8) != SDHC_CMD_SUCCESS);	//write starting at specified sector
	for (int j=0;j<numSectors;j++){
		Buffer[1] = SPI_write(SDHC_DUMMY_BYTE);	//send dummy byte
		Buffer[1] = SPI_write(SDHC_MULT_WRITE_DATA_TOKEN);	//send data token
		if(j == (numSectors-1)){
			for (int i=0;i<(SDHC_SECTOR_SIZE-fillerBytes);i++){
				Buffer[i%12] = SPI_write(data[(i+(j*SDHC_SECTOR_SIZE))]);
			}
			for (int i=0;i<fillerBytes;i++){
				Buffer[i%12] = SPI_write(FILLER_BYTE);
			}
		}
		else{
			for (int i=0;i<SDHC_SECTOR_SIZE;i++){
				Buffer[i%12] = SPI_write(data[(i+(j*SDHC_SECTOR_SIZE))]);
			}
		}
		for (int i=0;i<2;i++) Buffer[1] = SPI_write(SDHC_DUMMY_BYTE);	//write 2 CRC token
		Buffer[1] = FILLER_BYTE;
		while(Buffer[1] != SDHC_DUMMY_BYTE) Buffer[1] = SPI_write(SDHC_DUMMY_BYTE);	//wait for card to store the data it received
	}
	for(int i=0;i<4;i++){
		Buffer[1] = SPI_write(SDHC_DUMMY_BYTE);	//write dummy byte
	}
	Buffer[1] = SPI_write(SDHC_MULT_WRITE_STOP_TOKEN);	//write stop token
	for(int i=0;i<4;i++){
		Buffer[1] = SPI_write(SDHC_DUMMY_BYTE);	//write dummy byte
	}
	Buffer[1] = FILLER_BYTE;
	while (Buffer[1] != SDHC_DUMMY_BYTE) Buffer[1] = SPI_write(SDHC_DUMMY_BYTE); //wait for card to finish internal processes
	SPICS(FALSE);
	SPIDisable();
	PortEx_OUTSET(BIT3_bm, PS_BANKB);	//pull SD cs high
}
Пример #8
0
//the following function turns on power to the sd card and port expander and initializes the sdhc card in spi mode
//returns 0 if successful or 1 if not
uint8_t SD_init(void){
	ADCPower(TRUE);				//power up portEX
	Ext1Power(TRUE);			//power up SD card
	_delay_ms(100);				//wait for bootup
	uint8_t errorCode = 0;

	
	PortEx_DIRSET(BIT3_bm, PS_BANKB);  //SD card CS
	PortEx_OUTSET(BIT3_bm, PS_BANKB);	//pull SD cs high

	SPIInit2(SPI_MODE_0_gc,SPI_LOWEST_CLOCKRATE_PRESCALAR);
	SPICS(TRUE);
	
	for(int i=0; i<10; i++){		// idle for 10 bytes / 80 clocks
	SPIC.DATA=SDHC_DUMMY_BYTE;
	while(!(SPIC.STATUS & SPI_IF_bm)); //wait for byte to be sent
	Buffer[12] = SPIC.DATA; //read SPI data register to reset status flag
}

SPICS(FALSE);
SPIDisable();


PortEx_OUTCLR(BIT3_bm, PS_BANKB);	//pull SD cs low

SPIInit2(SPI_MODE_0_gc,SPI_LOWEST_CLOCKRATE_PRESCALAR);
SPICS(TRUE);
for(int i=0;SD_command(SDHC_CMD_RESET,SDHC_NO_ARGUMENTS,SDHC_CMD_RESET_CRC,8) != SDHC_IDLE_STATE; i++){		//send command 0 to put card in idle state and read 8 next bytes sent back or until response read
if (i >= 10) {												//try command 10 times before timing out
//there was no response to the first command
errorCode = 1;
break;
		}
	}
	_delay_ms(100);	
	
	for(int i=0;SD_command(SDHC_CHECK_VOLTAGE_CMD,SDHC_CHECK_VOLTAGE_ARGUMENT,SDHC_CHECK_VOLTAGE_CRC,8) != SDHC_IDLE_STATE; i++){		//check voltage range (used to indicate to sd card that we know it is an sdhc card)
		if (i >= 10) {
			//there was no response to the command
			errorCode = 1;
			break;
		}			
	}		
	for(int i=0;i<4;i++){
		Buffer[i+2] = SPI_write(SDHC_DUMMY_BYTE);
	}
	if((Buffer[4] != 0x01) || (Buffer[5] != 0xAA)){			//check that the response is the same as the argument sent in
		//broken card or voltage out of operating range bounds
		errorCode = 1;
	}
	//send second initialization command
	do{
		SD_command(SDHC_ADV_COMMAND,SDHC_NO_ARGUMENTS,SDHC_DUMMY_BYTE,8);	//next command will be advanced
		SD_command(SDHC_INITIALIZATION_CMD,SDHC_INITIALIZATION_CMD_ARGUMENT,SDHC_DUMMY_BYTE,8);	//initialize the SDHC card in SPI mode
	} while(Buffer[1]!= 0x00);
	
	for(int i=0;SD_command(SDHC_CMD_READ_OCR,SDHC_NO_ARGUMENTS,SDHC_DUMMY_BYTE,8) != SDHC_CMD_SUCCESS; i++){		//check OCR register
		if (i >= 10) {
			//there was no response to the command
			errorCode = 1;
			break;
		}
	}		
	for (int i=0;i<4;i++){
		Buffer[i] = SPI_write(SDHC_DUMMY_BYTE);
	}
	if (Buffer[0] & 0x40){
		//the card is addressed in 512 byte sectors
	}
	SPICS(FALSE);
	SPIDisable();
	PortEx_OUTSET(BIT3_bm, PS_BANKB);	//pull SD cs high
	return errorCode;	
}	
Пример #9
0
void SPIClass::setSS(uint8_t data) {
	SPICS(data);
}