SPI CS issue on ATtiny816 (ATtiny1 family)

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've used the following code to setup SPI communication & send data commands:

void SPIInit(void)
{
    PORTMUX.CTRLB = PORTMUX_SPI0_bm;
    PORTC.DIRSET = PIN0_bm | PIN2_bm; // CLK & MOSI as outputs
    SPI0.CTRLA |= SPI_MASTER_bm;
    SPI0.CTRLB |= SPI_SSD_bm | SPI_BUFEN_bm | SPI_BUFWR_bm;
    SPI0.CTRLA |= SPI_ENABLE_bm;
}

void SPISendByte(uint8_t data)
{
    SPI0.DATA = data;
    while (!(SPI0.INTFLAGS & SPI_TXCIF_bm));
}

I'm calling this function from LCD communication functions like so:

void LCDWriteCommand(uint8_t command)
{
    LCD_DC_LO;
    LCD_CS_LO;
    _delay_us(5);
    SPISendByte(command);
    LCD_CS_HI;
}

void LCDWriteData(uint8_t data)
{
    LCD_DC_HI;
    LCD_CS_LO;
    _delay_us(5);
    SPISendByte(data);
    LCD_CS_HI;
}

The macros to toggle the CS & DC lines:

#define LCD_CS_HI	LCD_CS_PORT.OUTSET = LCD_CS
#define LCD_CS_LO	LCD_CS_PORT.OUTCLR = LCD_CS
#define LCD_DC_HI	LCD_DC_PORT.OUTSET = LCD_DC
#define LCD_DC_LO	LCD_DC_PORT.OUTCLR = LCD_DC

However when executing the following lines:

LCDWriteCommand(0x2A);
LCDWriteData(0x2A);

I see the following on the logic analyzer:

 

The 1st byte is sent OK, however the 2nd time the CS goes up it happens before the transfer is complete. I'm not sure what is wrong with the code. Can anyone spot a problem? 

Last Edited: Sat. Jan 20, 2018 - 07:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have not given us all definitions.  (in particular, LCD_CS_*)  Prefereably, past a complete test program that we all can compile, along with all the usual attendant information about the chip and the toolchain and the schematic/connections.

 

Are we to infer from the code snippet that the AVR is the master?  Where is /CS made an output?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe the second time, the flag you are monitoring is already set (from the first round), so its not really waiting? 

Not sure if you have to clear the flag yourself. Normally, most flags autoclear if using an IRQ (interrupt)....I didn't research this, just a thought.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Sat. Jan 20, 2018 - 09:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Looks like you are not clearing the TXCIF:

David

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Corrected SPI send code:

void SPISendByte(uint8_t data)
{
    SPI0.DATA = data;
    while (!(SPI0.INTFLAGS & SPI_TXCIF_bm));
    SPI0.INTFLAGS |= SPI_TXCIF_bm; // Clear flag
}

Thanks!