SPi comunication problem


#1

Hello,

Im trying for implement a SPI comunication and my code is the following:

#define WRITE_SIZE 5
#define READ_SIZE 5

u8 WriteBuffer[WRITE_SIZE], ReadBuffer[READ_SIZE];

static s32 HandleSPI; //SPI handler

adl_busAccess_t AccessConfig=
{
		0,0 //No Opcode, no Address
};

static adl_busSPISettings_t SPIconfig =
{
   1,                  //Master max freqclock = 13000/(1+127)~= 102 kHz
   ADL_BUS_SPI_CLK_MODE_0,      //rest state 0, data valid on rising edge.
   ADL_BUS_SPI_ADDR_CS_GPIO,   //cs_gio
   ADL_BUS_SPI_CS_POL_HIGH,      //Chip select signal is high level.
   ADL_BUS_SPI_MSB_FIRST,      //Send MSB bit first.
   ADL_IO_GPIO | 31,         //We use a gpio for chip select
   ADL_BUS_SPI_LOAD_UNUSED,   //The load signal is unused.
   ADL_BUS_SPI_DATA_BIDIR,   //3 wire mode miso, mosi and clk.
   ADL_BUS_SPI_MASTER_MODE,   //bus is used in master mode.
   ADL_BUS_SPI_BUSY_UNUSED      //The busy signal is not used.
};



/*********************** Headers Functions **********************/
void InitSPI(); //Initialize SPI

void SPI_Write(u8 *Data,int DataLenght); //Write Data in SPI Bus

void SPI_Read (u8 *Data,int DataLengh); //Read DAta from SPI Bus

void Function_Read(u8 ID, void * Context);//Function Read

void Function_Write(u8 ID, void * Context); //Function Write

void EchoSPI(); // All data received from SPI BUS is returned another time to SPI BUS

/***********************End Headers Functions*********************/

/**********************Functions**********************************/


void SPI_Write(u8 *Data,int DataLenght) //Write Data in SPI BUS
{
	adl_busWrite(HandleSPI,&AccessConfig,DataLenght,Data);
}

void SPI_Read (u8 *Data,int DataLengh) //Read data from the SPI BUS
{
	adl_busRead(HandleSPI,&AccessConfig,DataLengh,Data);
}

void Function_Read_Handler(u8 ID, void * Context) // Put read data in ReadBuffer
{
	SPI_Read(ReadBuffer,READ_SIZE);
	TRACE (( 7, "Reading" )); //Reading
	TRACE ((9,"%d%d%d%d%d",ReadBuffer[0],ReadBuffer[1],ReadBuffer[2],ReadBuffer[3],ReadBuffer[4])); //Trace read Buffer
}
void Function_Write_Handler(u8 ID, void * Context) // Put WriteBuffer in SPI bus
{
	TRACE (( 7, "Writing" )); //Reading
	wm_memset(WriteBuffer,1,WRITE_SIZE); //I set WriteBuffer to '1'
	//TRACE ((8,"%d%d%d%d%d",WriteBuffer[0],WriteBuffer[1],WriteBuffer[2],WriteBuffer[3],WriteBuffer[4]));
	SPI_Write(WriteBuffer,WRITE_SIZE); //I send WriteBuffer by the SPI bus


}

void InitSPI()
{
	HandleSPI = adl_busSubscribe(ADL_BUS_ID_SPI,1,&SPIconfig); //Subscribes to SPI bus
	if(HandleSPI>=0) //If subscription OK
	{
		TRACE (( 6, "suscribed BUS SPI" )); //Suscription to SPI BUS succesful
		t_write=adl_tmrSubscribe ( TRUE, 10, ADL_TMR_TYPE_100MS, Function_Write_Handler ); //I write from SPI BUS
		t_read=adl_tmrSubscribe ( TRUE, 10, ADL_TMR_TYPE_100MS, Function_Read_Handler ); // I read from SPI BUS
	}
	else
	{
		TRACE (( 6, " No suscribed BUS SPI" )); //Suscription failes to SPI BUS
	}
}

/************************end Functions ******************************/

/******************************Main******************************/
void main_task ( void )
{
	adl_InitType_e adl_InitType = adl_InitGetType ();

	InitSPI(); //Initialize SPI
}

The bus suscription is ok, the write process i think that is ok, but when i do the read function, i write in my ReadBuffer the same data that i have send in the write function.

For example:

if my WriteBuffer is ‘11111’ I read ’ 255 255 255 255 255’.
if my WriteBuffer is ‘00000’ I read ‘00000’.

Why that? Is my code correct for do a SPI communication? :question:
If i want do a protocol, this functions are well implemented??

Thank you


#2

Are you trying to write out the SPI bus and then read it on the same device (i.e. is your SPI_IO connected to your SPI_I), like a UART loopback test?

I do not think this is possible, as the SPI bus in OpenAT is only half-duplex (it can only send or recieve, not do both simultaneously). What is happening is you are writing out data to the SPI bus on the first set of clock cycles, and then you are reading from the bus on the second set of clock cycles. Obviously there will be no data to read, as the write operation has already completed.


#3

Which, in my opinion, is a major limitation:

https://forum.sierrawireless.com/t/can-open-at-do-full-duplex-spi-yet/4516/1


#4

Hello,

Im trying to read from the SPI bus a 200 bytes frame but when i read nothing (all zeros)

This is my code, whats wrong??

#define WRITE_SIZE 8
#define READ_SIZE 200

u8 WriteBuffer[WRITE_SIZE], ReadBuffer[READ_SIZE];

static s32 HandleSPI; //SPI handler

adl_busAccess_t AccessConfig=
{
      0,0 //No Opcode, no Address
};

static adl_busSPISettings_t SPIconfig =
{
	  25,                  //Master max freq
	  ADL_BUS_SPI_CLK_MODE_2,      //rest state 0, data valid on rising edge.
	  ADL_BUS_SPI_ADDR_CS_GPIO,   //Chip select gio
	  ADL_BUS_SPI_CS_POL_HIGH,      //Chip select signal is high level.
	  ADL_BUS_SPI_MSB_FIRST,      //Send MSB bit first.
	  ADL_IO_GPIO | 45,         //We use a gpio for chip select
	  ADL_BUS_SPI_LOAD_UNUSED,   //The load signal is unused.
	  ADL_BUS_SPI_DATA_UNIDIR,   //3 wire mode miso, mosi and clk.
          ADL_BUS_SPI_MASTER_MODE,   //bus is used in master mode.
	  ADL_BUS_SPI_BUSY_UNUSED      //The busy signal is not used.
};


/**********************Functions**********************************/

//WRITE FUNCTION
void SPI_Write(u8 *Data,int DataLenght) //Write Data in SPI BUS
{
   adl_busWrite(HandleSPI,&AccessConfig,DataLenght,Data);
}

//Read data from the SPI BUS FUNCTION
void SPI_Read (u8 *Data,int DataLengh) //Read data from the SPI BUS
{
   adl_busRead(HandleSPI,&AccessConfig,DataLengh,Data);
}

//Read data from the SPI BUS CALL BACK
void Function_Read_Handler(u8 ID, void * Context) // Put read data in ReadBuffer
{
   SPI_Read(ReadBuffer,READ_SIZE);
   TRACE (( 7, "Reading" )); //Reading
   TRACE ((9,"%d%d%d%d%d%d%d%d",ReadBuffer[0],ReadBuffer[1],ReadBuffer[2],ReadBuffer[3],ReadBuffer[4],ReadBuffer[5],ReadBuffer[6],ReadBuffer[7])); //Trace read Buffer
}


//WRITE  AT THE SPI BUS CALL BACK
void Function_Write_Handler(u8 ID, void * Context) // Put WriteBuffer in SPI bus
{
   TRACE (( 7, "Writing" )); //Reading
   wm_memset(WriteBuffer,1,WRITE_SIZE); //I set WriteBuffer to '1'
   //TRACE ((8,"%d%d%d%d%d",WriteBuffer[0],WriteBuffer[1],WriteBuffer[2],WriteBuffer[3],WriteBuffer[4]));
   SPI_Write(WriteBuffer,WRITE_SIZE); //I send WriteBuffer by the SPI bus


}

s32 t_read,t_write;

//INITIALIZE SPI

void InitSPI()
{
   HandleSPI = adl_busSubscribe(ADL_BUS_ID_SPI,1,&SPIconfig); //Subscribes to SPI bus
   if(HandleSPI>=0) //If subscription OK
   {
      TRACE (( 6, "suscribed BUS SPI" )); //Suscription to SPI BUS succesful
     // t_write=adl_tmrSubscribe ( TRUE, 10, ADL_TMR_TYPE_100MS, Function_Write_Handler ); //I write from SPI BUS
      adl_tmrSubscribe ( TRUE, 10, ADL_TMR_TYPE_100MS, Function_Read_Handler ); // I read from SPI BUS
   }
   else
   {
      TRACE (( 6, " No suscribed BUS SPI" )); //Suscription failes to SPI BUS
   }
}

/************************end Functions ******************************/

/******************************Main******************************/
void main_task ( void )
{
   adl_InitType_e adl_InitType = adl_InitGetType ();

   InitSPI(); //Initialize SPI
}

tHANK YOU!!!


#5

What device are you reading from? Are you sure its working and connected up correctly? Can it handle the bus speed you have set? Is it set in slave mode?


#6

hELLO,

The device that i’m trying to comunicate is a Micro Controller. The Micro is working well because it was working with another software of other student (he is not in the school and any teacher can’t help me :confused: ) The speed is 500 kbps. The WMP is the Master and the Micro the slave.

When Micro want transmit, it raise Handshake line and he begin to transmit, if afther the WMP want send info, it raises Handshake line and Micro shall lower her handshake line and start to receive info. (WMP has priority in the communication)
I’m thinking that i could have a problem if my GPIO 45 is all the time in “1”, because the Micro will be always receiving and not in transmission mode.

I will try to solve it setting GPIO 45 to “0”

If u have any idea of my problem, please, tell me :wink:
Thank you :smiley:


#7

I’ve set the gpio45 to “0” and I try to read from the spi bus, but i continue with the problem. I’m don’t know where is the problem, i’m searching inthe examples of the ADL and I didn’t see any difference with my code :frowning:
Somebody knows my problem or has a sample of code?

Thank you 4 your help


#8

Hello,

I have new little problem with the SPI comunication. If I try to read X bytes of data, i have to do X+1 clocks because the first byte that i read is always ‘00000000’, the second byte that I read is my fisrt byte of info, the third read is the second byte of my info,… :exclamation: :exclamation: :exclamation:

Is it normal? How can I solve this problem? :question:

Thank you


#9

That depends on what you are reading from. If it is some sort of sensor or something like that, the byte that is sent is often a status byte or no data until the peripheral has received the command from the master.

If it is a microcontroller, are you sure you are loading the SPI output buffer before the clock is starting, and not when an SPI interrupt is generated?


#10

Hello,

An important note: If you want write and read from the SPI bus, you need to control with flags that when you are writing you will not read, and vice versa. If u don’t control it you can have resets in your telematic with the " ARM Data Abort " error. :exclamation: :exclamation: :exclamation: