User avatar
Arjan
Posts: 265
Joined: Sat Sep 08, 2012 1:59 pm

RPi 2 : SPI : Not reliable? (SOLVED)

Sun Feb 28, 2016 9:13 am

Hi,

Please see the two SPI timing diagrams for Model A+ and Model 2 with the same data.
The Model A+ gives a nice SPI stream, where the stream for Model 2 has some gaps in the stream.
The code below is running on bare-metal.

Any thoughts why there a gaps in the SPI stream for the Model 2?

Many thanks in advance,
Arjan

RPi1.PNG
Model A+
RPi1.PNG (37.66 KiB) Viewed 1260 times
RPi2.PNG
Model 2
RPi2.PNG (40.11 KiB) Viewed 1260 times

Code: Select all

#define WS2812B_HIGH_CODE			0xF8		///< b11111000
#define WS2812B_LOW_CODE			0xC0		///< b11000000
#define WS2812B_SLOTS_PER_PIXEL		3			///< RGB

void ws2812b(const uint8_t *dmx_data) {
	int i;
	uint8_t mask = 0x80;
	uint16_t dmx_data_index = 0;

	bcm2835_spi_setClockDivider((uint16_t) ((uint32_t) BCM2835_CORE_CLK_HZ / (uint32_t) 6400000));
	bcm2835_spi_chipSelect(BCM2835_SPI_CS0);					// Just in case we have a multiplexer
	bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0 , LOW);	// Just in case we have a multiplexer

	// Clear TX and RX fifos
	BCM2835_PERI_SET_BITS(BCM2835_SPI0->CS, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
	// Set TA = 1
	BCM2835_PERI_SET_BITS(BCM2835_SPI0->CS, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA);

	for (i = 0; i < ((int)170 * (int)WS2812B_SLOTS_PER_PIXEL); i++) {

		mask = 0x80;

		while (mask != 0) {
			// Maybe wait for TXD
			while (!(BCM2835_SPI0->CS & BCM2835_SPI0_CS_TXD))
				;

			if (dmx_data[dmx_data_index] & mask) {
				BCM2835_SPI0->FIFO = (uint32_t) WS2812B_HIGH_CODE;
			} else {
				BCM2835_SPI0->FIFO = (uint32_t) WS2812B_LOW_CODE;
			}

			while ((BCM2835_SPI0->CS & BCM2835_SPI0_CS_RXD)) {
				(void) BCM2835_SPI0->FIFO;
			}

			mask >>= 1;
		}

		dmx_data_index++;
	}

	// Wait for DONE to be set
	while (!(BCM2835_SPI0->CS & BCM2835_SPI0_CS_DONE)) {
		while ((BCM2835_SPI0->CS & BCM2835_SPI0_CS_RXD)) {
			(void) BCM2835_SPI0->FIFO;
		}
	}

	// Set TA = 0
	BCM2835_PERI_SET_BITS(BCM2835_SPI0->CS, 0, BCM2835_SPI0_CS_TA);
}
Last edited by Arjan on Mon Mar 28, 2016 3:08 pm, edited 1 time in total.
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

User avatar
joan
Posts: 15124
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: RPi 2 : SPI : Not reliable?

Sun Feb 28, 2016 9:39 am

I can't see any indication of a time scale. What bps?

User avatar
Arjan
Posts: 265
Joined: Sat Sep 08, 2012 1:59 pm

Re: RPi 2 : SPI : Not reliable?

Sun Feb 28, 2016 9:55 am

Hi Joan,

I have set

Code: Select all

bcm2835_spi_setClockDivider((uint16_t) ((uint32_t) BCM2835_CORE_CLK_HZ / (uint32_t) 6400000));
and this results in a 6 MHz SPI clock.

The timing for each byte varies a lot on the Model 2. It is working fine on the Model A+.

Any pointers for what is happening here is much appreciated.

Thanks, Arjan
RPi2-detail.PNG
RPi2-detail.PNG (20.94 KiB) Viewed 1194 times
RPi2-details.PNG
RPi2-details.PNG (36.68 KiB) Viewed 1194 times
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

User avatar
Arjan
Posts: 265
Joined: Sat Sep 08, 2012 1:59 pm

RPi 2 : SPI : Not reliable? (SOLVED)

Mon Mar 28, 2016 3:10 pm

With many thanks to rst (https://github.com/rsta2/circle) I have found the issue.

The CPU cores 1-3 are continuously reading a local mailbox register to get a start address. They are competing for bus time with core 0 what slows it down. And it breaks the SPI output.

At startup I am putting the unused cores to sleep https://github.com/vanvught/rpidmx512/b ... are.c#L230

The SPI output is fine now.

- Arjan
RPi Open Source DMX/RDM : http://www.raspberrypi-dmx.com/
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

Return to “Interfacing (DSI, CSI, I2C, etc.)”