Creating arrays in C based on data sheet

118 views Asked by At

I'm extremely new to the c language (obj-c, swift usually) and I'm working with some Cypress BLE boards. I'm trying to control a simple LED.

Per the documentation I should simply be writing to a SPI bus to control the LED.

Here is the relevant part: enter image description here

So I write 32 bits of 0's to start. Then the RGB array. Then 32 bits of all 1's. Here is what I'm currently trying:

static uint8 startFrame[32] = {0,0,0,0};
static uint8 colorFrame[32] = {1, 255, 0, 0};
static uint8 endFrame[32] = {1,1,1,1};


SPI_1_SpiUartPutArray(startFrame, 32);
SPI_1_SpiUartPutArray(colorFrame, 32);
SPI_1_SpiUartPutArray(endFrame,   32);

My thought is that an int is 8 bits so putting {1,1,1,1} should be of size 32. Again, I'm extremely new and hacking my way through this. Any help is very much appreciated!

Documentation for SPI_1_SpiUartPutArray:

/*******************************************************************************
* Function Name: SPI_1_SpiUartPutArray
****************************************************************************//**
*
*  Places an array of data into the transmit buffer to be sent.
*  This function is blocking and waits until there is a space available to put
*  all the requested data in the transmit buffer. The array size can be greater
*  than transmit buffer size.
*
* \param wrBuf: pointer to an array of data to be placed in transmit buffer. 
*  The width of the data to be transmitted depends on TX data width selection 
*  (the data bit counting starts from LSB for each array element).
* \param count: number of data elements to be placed in the transmit buffer.
*
* \globalvars
*  SPI_1_txBufferHead - the start index to put data into the 
*  software transmit buffer.
*  SPI_1_txBufferTail - start index to get data from the software
*  transmit buffer.
*
*******************************************************************************/
void SPI_1_SpiUartPutArray(const uint8 wrBuf[], uint32 count)
{
    uint32 i;

    for (i=0u; i < count; i++)
    {
        SPI_1_SpiUartWriteTxData((uint32) wrBuf[i]);
    }
}

Which I've also tried this:

 static uint8 startFrame[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    static uint8 colorFrame[32] = {1,1,1, 1,1,1,1,1 , 1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0};
    static uint8 endFrame[32] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};

and this:

static uint8 startFrame[4] = {0x00, 0x00, 0x00, 0x00};
static uint8 colorFrame[4] = {0xff, 0xff, 0xff, 0xff};
static uint8 endFrame[4]   = {0xff, 0xff, 0xff ,0xff};

SPI_1_SpiUartPutArray(startFrame, 4);
SPI_1_SpiUartPutArray(colorFrame, 4);
SPI_1_SpiUartPutArray(endFrame,   4);

and this:

static uint8 startFrame[4] = {0,0,0,0};
static uint8 colorFrame[4] = {255, <R>, <G>, <B>};
static uint8 endFrame[4] = {255,255,255,255};

SPI_1_SpiUartPutArray(startFrame, 4);
SPI_1_SpiUartPutArray(colorFrame, 4); // multiple of these for each LED
SPI_1_SpiUartPutArray(endFrame, 4);

If any of the above setups are correct then it must be an issue with how I'm writing to the SPI.

3

There are 3 answers

3
Brian McFarland On BEST ANSWER

You could have a couple problems here.

First of all... SPI is normally more or less transactional. Unlike UART (as a common counter example) you don't just write whatever you want whenever you want. You normally need to toggle a chip select (sometimes "slave select"), "clock out" words one at a time, then toggle the chip select the other way. Without documentation on SPI_1_SpiUartPutArray(), its hard to say whether or not you can call it multiple times in the same transfer (between chip select toggling).

EDIT: Never mind on the chip select thing. This LED driver does not appear to have a chip select/enable line. Just note for future reference this is unusual for SPI.

Second problem - I would assume SPI_1_SpiUartPutArray() puts out BYTES at a time, not bits. Again, you did not provide documentation of the function so its hard to say. If my assumption is correct, you would want startFrame to be static uint8 startFrame[4] = {0xff, 0xff, 0xff, 0xff}; as there are 8 bits in a byte giving you a 32-bit start-of-frame. Same idea applies to color & end of frame.

Third problem - If I'm wrong about how the SPI function works, you're not fully initializing those arrays. You declare arrays of 32 bytes and then only initialize 4 of those.

0
e.jahandar On

You have to declare startFrame a 4 element array of uint8, not 32 element of uint8 which is 256 bits long, accordingly if the second argument of SPI_1_SpiUartPutArray is number of Bytes to write on SPI, you have to put 4 (4bytes - 32bit), not 32 (which is 256 bit)

static uint8 startFrame[4];
SPI_1_SpiUartPutArray(startFrame, 4);
0
Leon Carlo Valencia On

You need to change your array size to 4 instead of 32. uint8 already has 8 bits and 4 of those means 32 bits. Now unless you use some non-standard library, you need a bit of math to say what bits to set to 1 and which ones to set to 0. For instance, putting a 31 = 00001111b in one byte means you are setting the first 4 bits to 0 and the last 4 bits to 1. So, in your case, the code would be:

static uint8 startFrame[4] = {0,0,0,0};
static uint8 colorFrame[4] = {255, <R>, <G>, <B>};
static uint8 endFrame[4] = {255,255,255,255};

SPI_1_SpiUartPutArray(startFrame, 4);
SPI_1_SpiUartPutArray(colorFrame, 4); // multiple of these for each LED
SPI_1_SpiUartPutArray(endFrame, 4);