示例#1
0
/*!
    \brief closes an opened spi communication port

	\param	 		fd			-	file descriptor of an opened SPI channel

	\return			upon successful completion, the function shall return 0.
					Otherwise, -1 shall be returned

    \sa             spi_Open
	\note
    \warning
*/
int spi_Close(Fd_t fd)
{
    unsigned long ulBase = LSPI_BASE;

    g_SpiFd = 0;
if(g_ucDMAEnabled)
{
    //Simplelink_UDMADeInit();
    #ifdef SL_PLATFORM_MULTI_THREADED
      osi_InterruptDeRegister(INT_LSPI);
      osi_MsgQDelete(&DMAMsgQ);
    #else
      SPIIntUnregister(ulBase);
      g_cDummy = 0;
    #endif
    SPIFIFODisable(ulBase,SPI_RX_FIFO);
    SPIFIFODisable(ulBase,SPI_TX_FIFO);
    SPIDmaDisable(ulBase,SPI_RX_DMA);
    SPIDmaDisable(ulBase,SPI_TX_DMA);
}
    //Disable Chip Select
    SPICSDisable(LSPI_BASE);


    //Disable SPI Channel
    SPIDisable(ulBase);

    // Reset SPI
    SPIReset(ulBase);

    // Enable SPI Peripheral
    PRCMPeripheralClkDisable(PRCM_LSPI,PRCM_RUN_MODE_CLK|PRCM_SLP_MODE_CLK);

    return 0;
}
示例#2
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
}
示例#3
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
}
示例#4
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	
}
示例#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
//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
}
示例#7
0
/*!
    \brief open spi communication port to be used for communicating with a SimpleLink device

	Given an interface name and option flags, this function opens the spi communication port
	and creates a file descriptor. This file descriptor can be used afterwards to read and
	write data from and to this specific spi channel.
	The SPI speed, clock polarity, clock phase, chip select and all other attributes are all
	set to hardcoded values in this function.

	\param	 		ifName		-	points to the interface name/path. The interface name is an
									optional attributes that the simple link driver receives
									on opening the device. in systems that the spi channel is
									not implemented as part of the os device drivers, this
									parameter could be NULL.
	\param			flags		-	option flags

	\return			upon successful completion, the function shall open the spi channel and return
					a non-negative integer representing the file descriptor.
					Otherwise, -1 shall be returned

    \sa             spi_Close , spi_Read , spi_Write
	\note
    \warning
*/
Fd_t spi_Open(char *ifName, unsigned long flags)
{
    unsigned long ulBase;

    //NWP master interface
    ulBase = LSPI_BASE;

    //Enable MCSPIA2
    PRCMPeripheralClkEnable(PRCM_LSPI,PRCM_RUN_MODE_CLK|PRCM_SLP_MODE_CLK);

    //Disable Chip Select
    SPICSDisable(ulBase);

    //Disable SPI Channel
    SPIDisable(ulBase);

    // Reset SPI
    SPIReset(ulBase);

    //
  // Configure SPI interface
  //
  SPIConfigSetExpClk(ulBase,PRCMPeripheralClockGet(PRCM_LSPI),
                     SPI_IF_BIT_RATE,SPI_MODE_MASTER,SPI_SUB_MODE_0,
                     (SPI_SW_CTRL_CS |
                     SPI_4PIN_MODE |
                     SPI_TURBO_OFF |
                     SPI_CS_ACTIVEHIGH |
                     SPI_WL_32));

if(PRCMPeripheralStatusGet(PRCM_UDMA))
{
  g_ucDMAEnabled = (HWREG(UDMA_BASE + UDMA_O_CTLBASE) != 0x0) ? 1 : 0;
}
else
{
	g_ucDMAEnabled = 0;
}
#ifdef SL_CPU_MODE
g_ucDMAEnabled = 0;
#endif
if(g_ucDMAEnabled)
{
    memset(g_ucDinDout,0xFF,sizeof(g_ucDinDout));
    //g_ucDout[0]=0xFF;
    //Simplelink_UDMAInit();
    // Set DMA channel
    cc_UDMAChannelSelect(UDMA_CH12_LSPI_RX);
    cc_UDMAChannelSelect(UDMA_CH13_LSPI_TX);


    SPIFIFOEnable(ulBase,SPI_RX_FIFO);
    SPIFIFOEnable(ulBase,SPI_TX_FIFO);
    SPIDmaEnable(ulBase,SPI_RX_DMA);
    SPIDmaEnable(ulBase,SPI_TX_DMA);

    SPIFIFOLevelSet(ulBase,1,1);
#if defined(SL_PLATFORM_MULTI_THREADED)
    osi_InterruptRegister(INT_LSPI, (P_OSI_INTR_ENTRY)DmaSpiSwIntHandler,INT_PRIORITY_LVL_1);
    SPIIntEnable(ulBase,SPI_INT_EOW);


    osi_MsgQCreate(&DMAMsgQ,"DMAQueue",sizeof(int),1);
#else

    IntRegister(INT_LSPI,(void(*)(void))DmaSpiSwIntHandler);
    IntPrioritySet(INT_LSPI, INT_PRIORITY_LVL_1);
    IntEnable(INT_LSPI);

    SPIIntEnable(ulBase,SPI_INT_EOW);


    g_cDummy = 0x0;
#endif

}
    SPIEnable(ulBase);

    g_SpiFd = 1;
    return g_SpiFd;

}
示例#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;	
}