SPI code locks attempting to write byte

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

Hi Guys,

   

I am having some trouble with the SPI. I have looked through the site and found some documents but not a worked example.

   

The code is ported across from a Microchip project. The Devie is PSOC 5LP and the memory is FM25W256-G.

   

The code runs until the second line in the ReadByte routine and appears to hang. I have the SPI component set to Mode 0 and 4MHz using internal clock source. Does my code below look correct? Or is there something I need to enable or initialise? Thanks in advance for your help.

   

 

   

#define WREN 0x06

   

#define MEMWRITE 0x02

   

#define MEMREAD 0x03

   

 

   

unsigned char Muted;

   

unsigned char testbyte;

   

 

   

void SendByte(unsigned short MemAddress, unsigned char MemData)  //FM25W256-G Device

   

{

   

  MEM_EN_Write(false);    //Enable Write function

   

  SPI_WriteByte(WREN);   

   

  MEM_EN_Write(true);

   

  MEM_EN_Write(false);   //Send Write command

   

  SPI_WriteByte(MEMWRITE);  

   

  SPI_WriteByte(MemAddress >> 8);  //Send 16-bit Address, MSB first

   

  SPI_WriteByte(MemAddress);

   

  SPI_WriteByte(MemData);  //Send Data byte

   

  MEM_EN_Write(true);

   

}

   

 

   

unsigned char ReadByte(unsigned short MemAddress)

   

{

   

  unsigned char i;

   

  

   

  MEM_EN_Write(false);   //Send Read Command

   

  SPI_WriteByte(MEMREAD);   //************************ LOCKS UP on this line ********************

   

  SPI_WriteByte(MemAddress >> 8);  //Read Address, MSB fist

   

  SPI_WriteByte(MemAddress);

   

  i = SPI_ReadByte();   //Read the byte ????

   

  MEM_EN_Write(true);

   

  return i;

   

}

   

 

   

void init(void)

   

{

   

    CyGlobalIntEnable; 

   

    PWM_Start();

   

    SPI_Init();

   

}

   

 

   

int main()

   

   

  init();

   

    SendByte(0x01, 0x33);

   

    testbyte = ReadByte(0x01);  //Test byte should = 0x33

   

   for(;;) {}

0 Likes
2 Replies
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 I have played around a bit more, read a couple of documents but still having trouble understanding how to get this working.

   

My changed code ensures that the last byte was sent from the buffer before attempting to send the next one. This time the code does not hang anywhere but I keep reading back "0" on the RX buffer.

   

I am assuming that I put a byte into the TX buf and it sends it, while sending it shifts any received data into RX buf and once done the SPI_DONE flag is set and I can go to next byte???

   

There seem to be very few worked example of how to use the component in this manner. Tomorrow I will put a logic analyser on the pins and see what the hardware is doing to help narrow it doen to hardware or software issue.

   

I am hoping someone would not mind taking a quick look at the code below and let me know if there is anything glaringly obvious (stupid) I have done or grossly misunderstood. Thanks again

   

unsigned char Send_SPI(unsigned char sData)

   

{

   

   SPI_WriteTxData(sData); 

   

   while(!(SPI_ReadTxStatus() & SPI_STS_SPI_DONE));

   

   return SPI_ReadRxData();

   

}

   

 

   

void PutMemByte(unsigned short MemAddress, unsigned char MemData)  //FM25W256-G Device

   

{

   

  MEM_EN_Write(false);      //Enable Write

   

  Send_SPI(WREN);  

   

  MEM_EN_Write(true);

   

 

   

  MEM_EN_Write(false);

   

  Send_SPI(MEMWRITE);  

   

  Send_SPI(MemAddress >> 8);

   

  Send_SPI(MemAddress);

   

  Send_SPI(MemData);

   

  MEM_EN_Write(true);

   

}

   

 

   

unsigned char GetMemByte(unsigned short MemAddress)

   

{

   

  unsigned char i;

   

  

   

  MEM_EN_Write(false);

   

  Send_SPI(MEMREAD);   //0x03

   

  Send_SPI(MemAddress >> 8);

   

  Send_SPI(MemAddress);

   

  i = Send_SPI(0);

   

  MEM_EN_Write(true);

   

  return i;

   

}

   

 

   

void init(void)

   

{

   

    CyGlobalIntEnable; 

   

    PWM_Start();

   

    SPI_Start();

   

    SPI_ClearRxBuffer();

   

    SPI_ClearTxBuffer();

   

 }

   

 

   

int main()

   

   

  init();

   

  for(;;)

   

  {

   

    PutMemByte(0x01, 0x33);

   

    testbyte = GetMemByte(0x01);  //Returns 0, expecting 0x33

0 Likes
lock attach
Attachments are accessible only for community members.
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

 It seems there is so much information on this site but when I attempt to do something specific, I have trouble finding the exact information I need. Today I checked the hardware and can see the write signal is working correctly but not reply fromt he IC, I tried a second hardware target and exactly the same thing. If I set the MISO pin to pull up resistor, I get nothing at all returned, If I leave high impedance then I see glitches in the MISO line. The MOSI line, clock and CS are all ok (I software select CS).

   

It is as if the PSOC is pulling the MISO up strong when the IC wants to send data.The datasheet talks about API functions Write_TXData() but any examples I found use WriteByte (which I used as I assume it writes directly to the SPI register instead of the buffer? Not sure what this does really. The module should be shifting bits out MOSI and back into MISO.

   

Attached is copy of my current code, waveforms attached.

   

 

   

void PutMemByte(unsigned short MemAddress, unsigned char MemData)  //FM25W256-G Device

   

{

   

  MEM_EN_Write(false);      //Enable Write

   

  SPI_WriteByte(WREN);  

   

  while(!(SPI_ReadTxStatus() & SPI_STS_SPI_DONE));

   

  MEM_EN_Write(true);

   

 

   

  MEM_EN_Write(false);

   

  SPI_WriteByte(MEMWRITE);  

   

  SPI_WriteByte(MemAddress >> 8);

   

  SPI_WriteByte(MemAddress);

   

  SPI_WriteByte(MemData);

   

  while(!(SPI_ReadTxStatus() & SPI_STS_SPI_DONE));

   

  MEM_EN_Write(true);

   

}

   

 

   

unsigned char GetMemByte(unsigned short MemAddress)

   

{

   

  unsigned char i;

   

    

   

  MEM_EN_Write(false);

   

  SPI_WriteByte(MEMREAD);   //0x03

   

  SPI_WriteByte(MemAddress >> 8);

   

  SPI_WriteByte(MemAddress);

   

  while(!(SPI_ReadTxStatus() & SPI_STS_SPI_DONE));

   

  i = SPI_ReadByte();

   

  MEM_EN_Write(true);

   

  return i;

   

}

   

 

   

void init(void)

   

{

   

    RTC_EN_Write(true);

   

    MEM_EN_Write(true);

   

    CyGlobalIntEnable; 

   

    PWM_Start();

   

    SPI_Start();

   

    SPI_ClearRxBuffer();

   

    SPI_ClearTxBuffer();

   

    CyDelay(100);

   

 }

   

 

   

int main()

   

   

  init();

   

  for(;;)

   

  {

   

    PutMemByte(0x01,0x33);

   

    testbyte = GetMemByte(0x01);

   

    CyDelay(1); 

   

  }

   

}

0 Likes