16 bit word in SPI

643 views
Skip to first unread message

Tom Olenik

unread,
Apr 25, 2015, 10:08:36 PM4/25/15
to bcm...@googlegroups.com
Is it possible to set the SPI word size to 16 bits in the bcm2835 library?  The BCM2835 ARM Peripherals section 2.2.3 says the word size can be as much as 32 bits, but is there already a built in function somewhere in this library for changing it from 8 bits to says 16 bits.  I'm making due with sending byte arrays instead, but it would make things more tidy and easier to match up with my device datasheet if I could just use 16 bit words.


Mike McCauley

unread,
Apr 26, 2015, 2:27:53 AM4/26/15
to bcm...@googlegroups.com
Hi. The lib currently only supports 8 bits on SPI

Sent from my iPhone

On 26 Apr 2015, at 4:08 am, Tom Olenik <tol...@hotmail.com> wrote:

Is it possible to set the SPI word size to 16 bits in the bcm2835 library?  The BCM2835 ARM Peripherals section 2.2.3 says the word size can be as much as 32 bits, but is there already a built in function somewhere in this library for changing it from 8 bits to says 16 bits.  I'm making due with sending byte arrays instead, but it would make things more tidy and easier to match up with my device datasheet if I could just use 16 bit words.


--
You received this message because you are subscribed to the Google Groups "bcm2835" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bcm2835+u...@googlegroups.com.
To post to this group, send email to bcm...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bcm2835/a4d5e19a-9f90-46aa-a298-9e5490c282c7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Tom Olenik

unread,
Apr 26, 2015, 11:57:55 AM4/26/15
to bcm...@googlegroups.com
Thanks for the quick reply and thanks for the great library!  For anyone else who needs longer than an 8 bit word, the example below is working for communicating with an AD5592 8 channel 12 bit ADC/DAC on the RPi 2. I've seen questions about performance of the RPi 2 and the bcm2835 library. So here are my results. Pretty good I would say. This library kicks butt for performance.

//set up for MSB first

int l = 0;
int m = 0;
while(1)
{
l = m % 36; // This just allows me to step through the 36 element array holding the DAC counts for 10 degree increments of a sine wave
eightBitWord[0] = sixteenBitWord[l] >> 8; // Load the upper 8 bits to first element
eightBitWord[1] = sixteenBitWord[l] & 0x00FF; // Load lower 8 bits to second element
bcm2835_spi_transfern(eightBitWord, 2U);
m++;
}
With something similar to the above I am able to produce a sine wave at around 11 kHz with 10 degree increments on the DAC on the AD5592 with the RPi 2 and the awesome bcm2835 library in my C program.  Below is a scope plot with channel 2 on the CS line and channel 1 on my DAC output.  The timing wanders a little at that speed, but the signal still looks pretty good. I can probably give up a little signal quality to get faster speed depending on the application. I'm using a SPI clock divider of 16.  This makes my SPI clock 15 MHz.  According to the AD5592 datasheet, it can only handle up to 20 MHz. Although I also just tried it with a clock divider of 8 for 31 MHz clock and its still working with a sine wave at 14 kHz..... and this is over long (and cheap) jumper wires going to the chip.

Mike McCauley

unread,
Apr 26, 2015, 2:53:32 PM4/26/15
to bcm...@googlegroups.com
Thanks for the code and comments

Sent from my iPhone

Cyrille QUERON

unread,
Jul 27, 2015, 12:20:12 PM7/27/15
to bcm2835, mi...@airspayce.com
Hi,

I am currently developing using bcm2835_spi library with a DAC7311 16 bit digital to analog converter through SPI. I didn't succeed to find a way to do it working correctly, probably due to the fact i don't send the 16 bits correctly. 

Here is my code, does somebody could help me to solve my problem, i tried a lot of solutions, but i'm lost ? 


        bcm2835_spi_chipSelect(BCM2835_SPI_CS1);
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW);
char mosi[4]={0x00,0b1000000000000,0x00}; // Don't care bit, 4096 value (i want a 5v output) and config bits
bcm2835_spi_transfern(mosi,4);


My goal is to increment an integer, in a loop then output the voltage using bcm2835_spi_transfern(). Here is basically (and not in C++ of course) what i mean : 


        myVoltage=readFromSPI(channel1); // I read successfully from a MCP ADC.
        if(myVoltage<3.5) { increment++; }
        if(myVoltage>3.6) { increment--; }

        
bcm2835_spi_transfern(increment)


Does somebody can help me to translate it in C++ using bcm2835 library and explain how is done the communication (hex instructions) ?

Thanks !
Cyrille

Cyrille QUERON

unread,
Jul 27, 2015, 1:12:41 PM7/27/15
to bcm2835, mi...@airspayce.com, cyrille...@gmail.com
Here is a partial solution i found :


                        char mosi[2]={0b00111111,0b11111100}; //
bcm2835_spi_transfern(mosi,2);


Now, i am looking for a simple way to transform a int value (example : 4095) into 2 binary values ?

Thanks !

Arjan

unread,
Jul 27, 2015, 1:28:42 PM7/27/15
to bcm2835, mi...@airspayce.com, cyrille...@gmail.com
Hi Cyrille,

According to the data-sheet, the DAC7311 has a 12-bit data input register with bit 15/14 for the power down mode. In normal mode they should be both zero.

I assume that you have connected RPI_V2_GPIO_P1_26 to /SYNC

The following code could work (the device is SPI compatible) :

uint16_t Voltage;
char DataIn[2];

DataIn[0] = ((uint8_t)(Voltage << 2) & 0xFF);
DataIn[1] = ((uint8_t)(Voltage >> 6) & 0xFF);

bcm2835_spi_transfern(DataIn,2);


Thanks, Arjan

Looking for RPI DMX512 - RDM open source solutions? Check http://www.raspberrypi-dmx.com/


Op maandag 27 juli 2015 18:20:12 UTC+2 schreef Cyrille QUERON:

Cyrille QUERON

unread,
Jul 27, 2015, 1:45:24 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com
Understood,

I just have a problem now : with your code, you build this :

111111111111

I need to get this result :

0011111111111100 // don't care bits at the beggining and config bits at the end

Thanks for your help !

Cyrille QUERON

unread,
Jul 27, 2015, 2:15:03 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com, cyrille...@gmail.com
I assume that you have connected RPI_V2_GPIO_P1_26 to /SYNC

Yes i did. 

Cyrille QUERON

unread,
Jul 27, 2015, 2:23:34 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com, cyrille...@gmail.com
Ok,

Found ! Thanks again for your help Arjan !

                DataIn[0] = 0x00;
DataIn[1] = ((uint8_t)(Voltage << 2) & 0xFF);
DataIn[2] = ((uint8_t)(Voltage >> 6) & 0xFF);
DataIn[3] = 0x00;

Cyrille QUERON

unread,
Jul 27, 2015, 2:27:56 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com, cyrille...@gmail.com
Hmm... 

No, not working finally...

Cyrille QUERON

unread,
Jul 27, 2015, 2:52:52 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com, cyrille...@gmail.com
Arjan,

The voltage goes to 0,0875v constantly (that is the maximum value recorded), then falls, and go up again, and loop restarts. 
Voltage value is 140 when all goes wrong the first time. I think the command i send isn't right.  

Any idea ? 
Thanks !

Arjan

unread,
Jul 27, 2015, 4:00:36 PM7/27/15
to bcm2835, mi...@airspayce.com, cyrille...@gmail.com
Hi Cyrille,

Just a quick check on my code provided earlier :

int main(void) {
    uint16_t Voltage = 0x0FFF;
    printf("%X %X %X\n", Voltage,((uint8_t)(Voltage >> 6) & 0xFF), ((uint8_t)(Voltage << 2) & 0xFF));
    return EXIT_SUCCESS;
}


Output
FFF 3F FC

And that is : 0b11111111111100

The DAC7311 expects 16-bit data when /SYNC is low. Sending DataIn[0] = 0b11111100 and DataIn[1] = 0b111111 (that is 0b00111111) should work.


Thanks, Arjan

Looking for RPI DMX512 - RDM open source solutions? Check http://www.raspberrypi-dmx.com/


Op maandag 27 juli 2015 20:52:52 UTC+2 schreef Cyrille QUERON:

Cyrille QUERON

unread,
Jul 27, 2015, 4:04:44 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com
Wow, i understand. 

I was giving a wrong value to Voltage (decimal not Hex).

uint16_t Voltage=1024 // The digital value

I would like to translate this digital value to hex, how should i do ? 

Thanks again for your time, i still have a lot of things to learn...

cyrille

Cyrille QUERON

unread,
Jul 27, 2015, 4:18:23 PM7/27/15
to bcm2835, mi...@airspayce.com, arjan.v...@gmail.com, cyrille...@gmail.com
That's OK now. 

I just checked the values was reversed. All's working like a charm now, with an int value too as voltage. 

    
    char DataIn[2];
    DataIn[0] = ((uint8_t)(Voltage >> 6) & 0xFF);
    DataIn[1] = ((uint8_t)(Voltage << 2) & 0xFF);
    bcm2835_spi_transfern(DataIn,2);


Thank you !
Reply all
Reply to author
Forward
0 new messages