CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

controlling a neopixel with spi
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
temtronic



Joined: 01 Jul 2010
Posts: 9073
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 08, 2018 2:36 pm     Reply with quote

Can't answer directly as I don't use that PIC but.....
There are 2 modes for SPI.
Hardware SPI, uses the HW spi perihperal in PIC.
Software SPI, emulates spi via software.

If you use the I/O pins the HW SPI is attached to, the compiler should use HW SPI. If you dump the listing it'll be obvious. HW SPI acceses SPI registers, code is small compared to SW SPI.
perhaps MR T will respond on the 'math' and 'SPI 'option' selections.

I'm stuck getting snowblower ready for another 4" of 'wet white'...sigh, 40 days until Spring.

You probably need to use one PIC for the 'LED controller' and a 'master PIC' to do the rest....

just ideas....
Jay
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Thu Feb 08, 2018 3:11 pm     Reply with quote

In the 16F18326 the SPI pins (SDO/SCK) are not attached to pins by default. They all need to be set using #pin_select.

I'd say the hardware SPI is used; a spi_write(x) translates to 6 instructions that select bank 4 and write out x to register 11, SSP1BUF.

I surmise that Mr T used a much faster PIC. Apart from that I need to take another look at the quick and dirty way I created the half-nibbles; that might account for part of the slowdown.

Take care with the snowblower! And cherish the snow :-) Our winter started the day before yesterday (-6C in the night) and will be over this Saturday when the night temperature is expected to be above 0C.

Paul
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Fri Feb 09, 2018 1:07 am     Reply with quote

On timings, I tend to forget the 'limitations' of the 8bit PIC's.
Embarassed

Over 60% of the stuff I do now uses the DsPIC's, and on these I also have some 'specials' from MicroChip, that implement faster clocks for SPI than they officially support (these will probably appear in a few months on 'release' chips). I've actually got SPI running now at over 20MHz from some of these...
This though is also why when designing a project I always type out the clock timings, and usually incorporate this into a header file for the particular project. It's too easy to get a timing wrong.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Fri Feb 09, 2018 2:19 am     Reply with quote

That clears it up. I really liked your idea of misusing the SPI to generate the bitstream for the LED's but alas this is slower than bit banging. Fortunately fast clocks seem to trickle down to the 8 bit family so maybe I can get away eventually without resorting to using dsPIC's :-)

I came across an application note (AN1606) that explains how one could use SPI in combination with PWM and CLC to generate the precise timing for these LED's. As the 16F18326 has plenty of these peripherals I'll give that a go and see how that compares.

I find PIC timing rather complex. Although in the habit of over commenting what I do I still get bitten by it every now and then.
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Fri Feb 09, 2018 2:42 am     Reply with quote

'Slower than bit banging'?.

Shouldn't be.

The 'fast' way to generate this, is to pre-store the data patterns that have to be SPI sent, as an array. I do it by the nibble. So one nibble of the source selects a line in the array, which is four bytes to send. The array has 16*4 entries. The PIC has a 'swap' instruction that switches the high and low nibbles, so you can just re-use the same array for the high nibble.
You've already got the timing working, but I suspect you are wasting a lot of time on generating the patterns. The point is that with the SPI you can be loading the next byte while the first is sending, and if you just pull the data from the array like this, you can send the data really fast. Smile
You can also use a divider of 0 with the Timer2, which doubles the clock rate from what you show.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Fri Feb 09, 2018 3:50 am     Reply with quote

Yep, I spend 5us to translate the data from byte to half-nibble and into the SPI buffer and another 9us to get the next byte out of the LED array. So 24us / byte or 17ms out of the 26ms of the total transfer time it takes for 720 bytes (240 LED's / 3 colors). There certainly is a lot to gain there.

Use Timer 2 with divide by 0? How do I do that? AFAIK I can prescale with DIV_BY_1 as a minimum (also in the DS), which gives me Fosc /4.

The T2 period goes as low as 0x01. 0x00 gives me no output. What am I missing?

Paul
Ttelmah



Joined: 11 Mar 2010
Posts: 19186

View user's profile Send private message

PostPosted: Fri Feb 09, 2018 6:53 am     Reply with quote

It is the division, not the prescaler. It sounds as if chips differ on this. I found on another chip a while ago, that it would accept 0. It gives a match on the very first clock cycle, and resets on the next, so gave division by 1.

The way to do the translation is with an array as already mentioned. You just have a two dimensional array with 4 elements per line, and use val & 0xF as the row index, then 0, 1, 2, 3 for the column index to send the bytes. Then swap(val), and repeat to handle the high nibble.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Tue Feb 13, 2018 11:33 am     Reply with quote

Ha! I spend the best part of today understanding the @!!$@& CLC in the 16F18326 and finally wrestled it into submission Very Happy

Now when I send a byte to the SPI device this results in 8 bits out of the CLC magic that are 340ns high/780ns low for a 0 and 680ns high/560ns low for a 1. All neatly within the limits of the WS2812b.

A byte takes around 9.5us depending on the number of 1's and 0's it contains. A complete led word (3 bytes + getting the data out of the array) takes a little over 39us. A 240 led string takes under 10 ms to write from the 720 byes long buffer.

The important bits:

Code:

// Setup clock
#use delay(internal=32000000)

// Setup output pin for WS2812b data in
#pin_select CLC1OUT = PIN_C0

// Setup timer2
setup_timer_2(T2_DIV_BY_1,0x04,1);

// setup pwm
setup_pwm5(PWM_ENABLED|PWM_TIMER2);
set_pwm5_duty(0x0009);

// Setup CLC
setup_clc1(CLC_ENABLED|CLC_MODE_AND_OR);
setup_clc2(CLC_DISABLED);
setup_clc3(CLC_DISABLED);
setup_clc4(CLC_DISABLED);

clc1_setup_input(1,CLC_INPUT_SCL1);
clc1_setup_input(2,CLC_INPUT_SDA1);
clc1_setup_input(3,CLC_INPUT_PWM5);
clc1_setup_input(4,CLC_INPUT_CLCIN0);

clc1_setup_gate(1, CLC_GATE_NON_INVERTED_INPUT_1);
clc1_setup_gate(2, CLC_GATE_NON_INVERTED_INPUT_2);
clc1_setup_gate(3, CLC_GATE_NON_INVERTED_INPUT_1);
clc1_setup_gate(4, CLC_GATE_NON_INVERTED_INPUT_3);



I have some questions left as I took a slightly different approach than laid out in AN1606. There two CLC units are used and nSDO is ANDed with SCK and PWM to make the 0 bits, where I use SDA (SDO) AND PWM only. This means I always generate a 0 bit with the width of the PWM signal in the middle of a 1 bit. But as the 1 bit is wider that does not show in the output signal. But I have no idea if I wreak havoc with this approach. So far it works great.

Paul
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group