Hi there!
I'm new to XMOS but I'm discovering the marvels every day...
anyway, I have a question related to the already mentioned issue of "driving a clock only if data is available" in some SPI code...
I'm working on a multichannel SPI-like "generator" where I have to generate CLK pulses while I have data to transmit and be quiet/idle otherwise.
So, my question is if it's possible to generate interrupts when the transfer buffer of the port gets empty/full?
I would then just stop the clock in the IRQ handler and start it again when I manage to fill the data buffers again.
Any other suggestion on how to generate the clock only when data is available? plain bit-banging is too slow
regards,
m.culibrk
Interrupts ports - transfer buffer empty/full
-
- Active Member
- Posts: 38
- Joined: Tue Jul 13, 2010 2:57 pm
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
What about writing 0xAAAAAAAA to the clock port, (the example creates 16 periods, but could be something else)
Check out the I2S examples.
Check out the I2S examples.
Probably not the most confused programmer anymore on the XCORE forum.
-
- XCore Addict
- Posts: 216
- Joined: Wed Feb 10, 2010 10:26 am
My SPI-like interface was relatively slow. So I was using the method proposed in this thre: https://www.xcore.com/forum/viewtopic.php?f=10&t=1116
There is a thread, which just pumps out the values and it read from a streaming channel. If there is something in the channel it writes out values with a proper clock. If not it halts. The thread calculating the data does not have to wait for the pumping thread to finish pumping. A simple and nice clean solution. Works astonishing fast due to the thread decoupling and is easy to programm, since each thread does not need to care what the other thread is doing.
If the protocol gets faster I think the method proposed in this thread is better: https://www.xcore.com/forum/viewtopic.php?f=7&t=1117
It drives a buffered output port according to a clock, generated by outputing clock values (e.g. 0xaaaaaa…) on another port. By that the buffered port reduces your encoding effort. This is especially usefull if you use only 1bit ports.
I hope I got it correct ;)
Marcus
There is a thread, which just pumps out the values and it read from a streaming channel. If there is something in the channel it writes out values with a proper clock. If not it halts. The thread calculating the data does not have to wait for the pumping thread to finish pumping. A simple and nice clean solution. Works astonishing fast due to the thread decoupling and is easy to programm, since each thread does not need to care what the other thread is doing.
If the protocol gets faster I think the method proposed in this thread is better: https://www.xcore.com/forum/viewtopic.php?f=7&t=1117
It drives a buffered output port according to a clock, generated by outputing clock values (e.g. 0xaaaaaa…) on another port. By that the buffered port reduces your encoding effort. This is especially usefull if you use only 1bit ports.
I hope I got it correct ;)
Marcus
-
- Active Member
- Posts: 38
- Joined: Tue Jul 13, 2010 2:57 pm
First of all, thanks for the help/comments!
Yes... I was working around this "double linked clocks" solution... but I tried to setup a "real" SPI mode 0 (idle = 0)... at the end I ended up needing "one bit/transaction more" for that... ie. the stream has a "unneeded" transition "before" data (first 0->1 transition) and then the required "data" bits.... the problem was again with the last "bit" missing the 0->1 transition. So a "9 bit clock for 8 bit data" is required... BUT this is a pain and ads additional code (= delay) so at the end I ended up using SPI mode 3 (clk idle = 1)... it should work... but its a little "ugly"...
I have another question regarding buffered ports (in context with the original buffer empty/full question)
I'm not sure I understood correctly the "buffered port" details...
is the "buffer port" always 32-bit "deep"? For example:
so I'm somehow asking again - is it possible to check if the (transfer) buffer has "room available" to store the next chunk?
so I could avoid thread blocking and try to output in the next loop.
regards,
m.culibrk
Yes... I was working around this "double linked clocks" solution... but I tried to setup a "real" SPI mode 0 (idle = 0)... at the end I ended up needing "one bit/transaction more" for that... ie. the stream has a "unneeded" transition "before" data (first 0->1 transition) and then the required "data" bits.... the problem was again with the last "bit" missing the 0->1 transition. So a "9 bit clock for 8 bit data" is required... BUT this is a pain and ads additional code (= delay) so at the end I ended up using SPI mode 3 (clk idle = 1)... it should work... but its a little "ugly"...
I have another question regarding buffered ports (in context with the original buffer empty/full question)
I'm not sure I understood correctly the "buffered port" details...
is the "buffer port" always 32-bit "deep"? For example:
Code: Select all
out buffered port:8 thePort = XS1_PORT_4A;
....
unsigned char chunk;
thePort <: chunk;
thePort <: chunk; // will the thread block here?
thePort <: chunk;
thePort <: chunk;
thePort <: chunk; // or here? assuming no data was actually removed from the transfer buffer.
so I could avoid thread blocking and try to output in the next loop.
regards,
m.culibrk