Hello,
I would like to know how I can sent data in a stream of up to 128 bits without interruption of the clock signal. Until now I got maximum 8 bits out. CLK should be 1MHz or above.
I use an Arduiono Zero and only MOSI(Pin4) and Clock(Pin3) on the SPI Header.
SPI.transfer16 works, but it makes me two transfers with 8 bits and a big gap in between.
SPI.transfer(buffer, size) does not work at all for me, it compiles and uploads, but no output on the pins. In this example I have expected the output to be the same as SPI.transfer16.
Can anyone point me in the right direction?
Here is my minimal code example:
#include<SPI.h>
void setup() {
SPI.begin();
SPI.beginTransaction(SPISettings(1000000,MSBFIRST,SPI_MODE0));
}
void loop() {
//SPI.transfer(0x00);
//SPI.transfer16(0x0000);
SPI.transfer(0x0000, 2);
delay(1);
}
SPI works by transmitting/receiving 8 bits (1byte) at a time.
SPI.transfer16 basically is a routine that send the 2 byte data (16 bits) 1 byte at a time. hence the space between the 2 byte.
If you want to transfer 128 bits in a single steam you may want to consider bit banging or the like.
SPI.transfer(0x0000, 2);
The function expects a pointer to a buffer (array) and the size of the buffer.
char buffer[] = "SPI COMm test: 1234567890";
// byte buffer[] = {1,2,3,4,5,67,8,9,222,111,34,89,56,100}; // works the same
SPI.transfer(buffer, sizeof(buffer));
The code that you posted is missing a chip select and you need to set pin 10 as an OUTPUT whether pin 10 is used for chip select or not.
Edit: you should get an output on mosi without any chip select.
Thank you for the fast response.
There is not something like this for the Arduino Zero?
CS I don't need, but thank you for the hint to set pin 10 as output.
Buffer works now, but still in 8 bit portions, not as a stream.
OK, I will lock for a different way to archive this.
not as a stream.
What does that mean. My logic analyzer shows less than a microsecond between bytes.
OK, I think that I understand. 128 bits in a stream. If that is so sherzaad's reply about bit banging is right on.
If you want to transfer 128 bits in a single steam you may want to consider bit banging or the like.
I have 1.8us in between @1MHz Clockrate. I want the clock (and data) running continuously.
I want the clock (and data) running continuously.
Then SPI is out. How is the 128 bits stored? An array of 16 bytes can hold the 128 bits.
Try this bit banging example. Tested on my Uno. If digitalWrite is too slow, consider direct port manipulation.
const byte clkPin = 13;
const byte mosiPin = 11;
byte bitArray[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
void setup()
{
Serial.begin(9600);
pinMode(clkPin, OUTPUT);
pinMode(mosiPin, OUTPUT);
digitalWrite(clkPin, LOW);
}
void loop()
{
for (int n = 0; n < 16; n++)
{
for (int m = 7; m >= 0; m--) // reverse byte for MSB first
{
digitalWrite(mosiPin, bitRead(bitArray[n], m));
digitalWrite(clkPin, HIGH);
digitalWrite(clkPin, LOW);
}
//delayMicroseconds(50); // just to separate bytes for testing
}
delay(10);
}
Thank you for the link with the port manipulation. This looks very interesting.
I have it working as I want, but with a library "fastLED". Very simple to use, but I want to understand how it is done "under the hood". 
I want to understand how it is done "under the hood"
You can read the library code to find out.
Markduino:
I have 1.8us in between @1MHz Clockrate. I want the clock (and data) running continuously.
Why? The big advantage of using a clocked communication method is that you don't need such tight timing requirements. Are you trying to hack SPI for some other use? Nothing wrong with that, I just want to understand your requirements.
I am much less familiar with ARM than I am with AVRs, but if the Zero has a DMA peripheral it might help you do what you want.
Hello Jiggy-Ninja,
here is a good description of what I am trying to do. I want to test the limit, so initially I thought SPI is faster.
Will have a look at the fastLED library how it is done.