8 PWM and a serial...
Scott M
Posts: 43
I need a chip that can simultaneously handle driving 8 PWM lines and reading one serial data line. Someone suggested the SX chip, which I've never used. I'm reasonably comfortable with interrupt programming and assemblers (and C coding), but not at all with this particular chip.
Has anyone done anything like this? The idea is to receive a rapid series of serial commands (from a Javelin) that set (and frequently change) 8 channels of PWM output (which will be stepped up to 0-10v and used to drive dimmers.)
What's cost of entry with this chip? Is there a PDIP version, or do I get to learn how to solder SMD devices?
Has anyone done anything like this? The idea is to receive a rapid series of serial commands (from a Javelin) that set (and frequently change) 8 channels of PWM output (which will be stepped up to 0-10v and used to drive dimmers.)
What's cost of entry with this chip? Is there a PDIP version, or do I get to learn how to solder SMD devices?
Comments
Well, the SX28 is your animal. If you're new to that chip, purchase an appropriately priced starter kit from Parallax (personally I like their brand new professional development board), and you're away.
Running 8 PWM's and a serial link in software is a piece of cake for this device, and you'll have a lot of fun doing it right on the solderless plugboard on the Professional set. I'm unsure is they sell a combination set of development board and programmer/debugger.
A programmer (burner) is required, and it's real-time debug capability is just awesome.
If you are somewhat price sensitive, you can reduce costs by purchasing the smaller development combo's.
SX; the only way to go.
Have fun,
Peter (pjv)
As Peter V mentioned, 8 PWMs and a serial line are a piece of cake for the SX chips. It can run any clock from DC to 50 Mhz. Pretty much every instruction except jumps and skips use only a single clock cycle, so at 50 MHz it's a 50 MIPs machine. Interrupts have a fixed latency period which means zero jitter. I have a project which uses an interrupt rate of 250 Khz (yes, 250,000 interrupts per second), and even that is not pushing the chip to the limit. It's a screaming fast chip, and the dev kits are well under $200 (and that includes the IDE, as well as full GUI based programming and debugging).
Thanks, PeterM
I'd like to slam commands from a Javelin to the SX as fast as possible, so 2400 baud isn't going to cut it. I'd like to use the Javelin's serout command, because the commands I need to send only need to be 12 bits long, but I need to send lots of them.
Is there any reason I can't sample the command bitstream and clock at interrupt level, in effect writing my own serin, and do the PWM in the same interrupt function? I see an advantage: No need to count the instructions or cycles used in the interrupt code, because the main execution loop is just going to be an infinite loop anyway. All the work happens in the interrupts.
Of course, this assumes the SX can generate interrupts at least twice as fast as the Javelin will emit clock and data pulses on a serout instruction, but I'm pretty sure that's not an issue. (Actually, I have no idea at what rate the Javelin writes data during serout...)
But then... hm. Interrupts happen on RTCC rollover, I understand, and that happens every 256 clock cycles. So is it *BAD* if an interrupt routine costs more than 256 cycles?
Walk me through this please.
Also, for a light dimmer, am I better off doing a more even distribution of On pulses in my PWM? This code seems to generate a PWM of 2:256 by doing on * 2, off * 254, but am I better off doing on * 1, off * 127, on * 1, off * 127?
I also don't know the speed of the Javelin's serial routine, but I do know that the SX can successfully run a conventional VP UART at 345Kbits/sec, and under special circumstances I run a 50Mhz SX at 10 Megabits/second, so I suppose that is speed enough. Admittedly, at the 10 Mbit rate, there is nothing else the SX can do while pumping or receiving data at that clip, but at 345K bits and below, there is ample speed to do 16 channels of PWM.
All this can only be effectively performed under control of a high speed interrupt, probably at 1 Usec.
Interrupts do occur at RTCC rollover, but not neccessarily at 256. Using a 50 Mhz clock, the interrupt will be 50 clocks if the RTCC register is preloaded with minus 50, being 256-50 = 206. Each clock tick increments the RTCC, and at rollover from 256 (FF) to zero the interrupt fires. Simply exit the interrupt with RETIW holding the 206 in W, and the RTCC is adjusted to fire again 50 cycles from the previous time.
The simplest PWM is the add-watch-for-rollover routine. The value you wish for a duty cycle (out of 256) is simply added at each interrupt to an 8 bit accumulator, and when that rolls over, the carry is set. So watch for carry, and set the PWM output when carry is high, and clear the PWM bit when carry is low.
For a code example where PWM is used to generate dual sine waves, see my contest entry. It is in line with what you describe.
That example also shows a very simple yet effective Real Time Operating System which can be used to schedule actions at various times.
Holler if you need more direction,
Peter (pjv)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The Javelin shiftout method operates at approx. 100 kHz I believe and is a SPI master.
So you need to run a SPI slave on the SX.
Here is a source for SPI slave with detailed explanation.
http://www.sxlist.com/techref/ubicom/spis.src
regards peter
Can you explain why you need to send data so fast ?
PWM does not update quickly, so there is no sense changing the values any faster than the PWM update rate. If you ISR runs at 1MHz for an 8-bit PWM the update rate is 3906.25 Hz. And if you have an RC circuit to average the PWM, the rate is many times slower yet.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module" Now available from Parallax for only $28.95
http://www.parallax.com/detail.asp?product_id=30012
Product web site: www.sxvm.com
"It's not getting what you want, it's wanting what you've got."
·
I've probably overspecifed the need for speed - I'm so used to working with Javelins, which are always just a little slower than I want, that I've become paranoid.
Basically, I want to control 5 or 6 channels (or more...)·of dimming with very tight control over the exact brightness at any given time, on all channels - and the channels typically vary simultaneously. Right now, I revisit the Javelin's 4 PWMs about 13 times a second to respecify them. I still find the dimmer's brightness changes in visible steps - the human eye is good at noticing changes slower than about 20-30Hz. (I'm using a small value for the smoothing cap, because I don't want it to end up extending the dimming period much).
I'm hoping that by using a smoother and much faster PWM design, I can get smoother light control AND more channels than the Javelin can give me. But this means shovelling instructions between the Javelin and the SX, for 6 channels, 12 bits a command, upwards of 30 times a second. 9600 baud would probably do nicely for that - unless next week I go to 16 channels, and larger commands, and a 50Hz update rate. Basically, I want tons of wiggle room so I can extend the design without concern. 19.2k might be a safe minimum (and it's about all the Javelin can send, anyway). 2400 baud definitely squeezy.
By 1) putting the serial input function in the interrupt routine and 2) having the interrupts go really, really fast - the SX won't need to do anything at all *except* service interrupts, so I don't care how much·is left over for non-interrupts·- I free myself from worrying about data rates and PWM speed for good. The Javelin's ability to send commands·will be the only limiting factor. I like the idea of only have one chip's speed to worry about.
·
I would work it this way:
Set prescaler to 1:2
Use reload value 217
This will give you an interrupt rate of 115207 or about 6x 19200
Your PWM update rate will be 450 Hz (115207 / 256)
You will be able to have about 430 cycles to use in the ISR (should be do-able).
My PWM16 program requires only 20 bytes to update ALL the outputs, you that would be 1920/20 = 96 times a second. Of course that is the maximum you could every get, but even half of that is good enough to avoid seeing the steps.
I can help you if you want to try it after you get your programming tools.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module" Now available from Parallax for only $28.95
http://www.parallax.com/detail.asp?product_id=30012
Product web site: www.sxvm.com
"It's not getting what you want, it's wanting what you've got."
Post Edited (Bean (Hitt Consulting)) : 6/7/2005 2:50:08 PM GMT
Gee, with a willing victim to help, I can get a lot more ambitious. :-)
My current controller is made up of 2 Javelins (J1, J2), and it talks to a lot more than dimmers. J1 takes input from a bunch of sources (RS232 lines, 12v signal lines, etc) and makes a bunch of complicated decisions based on them. That part works fine and is typically fast enough for my purposes. It turns the decisions into a series of commands, which it ships to J2. The commands are complex; an example is "after the previously sent command finishes, wait 6 ticks and then ramp the dimmer on pin 12 at a rate of +1 per tick until it reaches 230." There's options for interrupting previous commands, sending blink patterns and so on - moderately intricate stuff.
J2 takes those and shuffles the commands into time order (often, commands will end up scheduled for the same tick), and then, on ticks,·execute them. It runs 4 PWMs and a bunch of digital outputs. The problem is, even running at 1 tick = 1/13th of a second - slower than I really want to go - J2 doesn't always keep up. This results in tiny, irritating delays in scenes. Basically, J2 is maxed out of both processing speed and PWM availability, and I want to go higher on both. I've been considering having J2 break the commands down into individual "PWM set operations" and handing them to the SX as it came time to execute them - but maybe I can just make J2 an SX. All that speed...
Maybe that's feasible, though it would be more than 430 cycles of instructions. Maybe I could live with a lower interrupt rate - J1 only feeds J2 at 19.2k and that's been more or less adaquate for that part. (The commands are complex enough that I don't have to ship many over at a time.)
And a $4 processor is a little more appealing than the $89 Javelin. The Javelin was a breeze to code, though - I'll miss that.
·
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module" Now available from Parallax for only $28.95
http://www.parallax.com/detail.asp?product_id=30012
Product web site: www.sxvm.com
"It's not getting what you want, it's wanting what you've got."
·
Does anyone make a fast, realtime kind of chip with, say, 2k of memory onboard?
·
Post Edited (Paul Baker) : 6/7/2005 6:36:32 PM GMT
Since I don't need rock-steady PWM, I'm avoiding using interrupts.
Comments and laughter welcome.
---
;fisrt time coding an SX.
; ;;; marks stuff I think is wrong
; Do PWM on 13 channels. Chose 13 because this way the data fits in 32 bytes
;;; - which hopefully means no bank switches
; take in 8 bits (a PWM value) followed by 4 bits (which channel to load it into)
;;;declare SX28, no interrupts needed, and all the drivel I don't understand
;;get some variables
HOLDER DS 1 ;storage for value being reassembled
INDEX DS 1 ;which bit are we about to read in?
NEWV DS 1 ;storage, next PWM value to set
LASTCLK DS 1 ;last clock bit value we saw
V DS 13 ;current value of each channel
RATE DS 13 ;what to add to each channel, each time through
MAIN: ;here on power up ;;;;look up how to declare that
;out go the lights, to start
mov rb, #0
mov rc, #0
mov !rb, #0 ;get those outputs out there
mov !rc, #0
;clear out the rates
clr RATE+0
clr RATE+1
...
clr RATE+12
;don't bother clearing out V, as it matters very little
clr HOLDER ;clear temp byte
clr INDEX ;clear count of received bits
clr LASTCLK ;no clock seen yet
;ok, ready to run
jmp GETINP ;start with the input routine
;waste a bunch of time. Used when we have no input, to keep
; things a little more even in timing.
DELAY1: mov w, #8
DELAY2: dec w
jnz w, DELAY2 ;loop to 0, wasting time
GOGOGO:
;do basic PWM on our channels
mov w, rate+0 ;get rate of change
add w, v+0 ;add to current value
sc ; carry bit -> rb.0 is a bit messy...
jmp $+3
setb rb.0
skip
clrb rb.0
;;;...repeat 12 times more for rb1..rc.3 and rate+1, v+1 though +12
;PWM done, now it's time to look at the input clock and data
;if we get clock change, we do some work
;if we don't, we go do some time wasting to roughly match the work we
; didn't do here
GETINP: mov w, ra ;get clock input (ra.1)
and w, #2 ; isolate the clock bit
swap w, LASTCLK ;store new bit, fetch previous
xor w, LASTCLK ;are they different?
jz DELAY1 ;no, no clock change, go do more PWM after a wait
;clock changed. Did it go high?
test LASTCLK
jz DELAY1 ;no, low. No new data, skip out of here
;clock just went high - grab a data bit
rl HOLDER ;make room for bit
mov w, ra ;get data input (ra.0)
and w, #1 ; isolate the data bit
or HOLDER, w ;store newly arrived bit
mov w,INDEX ; which bit did we get?
inc INDEX ; (for next time)
jmp $+w ;;;is this off by 1?
;jump table, 12 cases
jmp GOGOGO ; bit 0, not enough data, go do PWM
jmp GOGOGO ; bit 1, not enough data, go do PWM
jmp GOGOGO ;..
jmp GOGOGO
jmp GOGOGO
jmp GOGOGO
jmp GOGOGO
jmp GOTV ;got bits 0-7, we have full value, go store
jmp GOGOGO
jmp GOGOGO
jmp GOGOGO
jmp GOTINDX ;got bits 0-11, we have full index (and value)
;;yeah, I know, I could remove the last jmp in that table and just fall into
;; this case, but yuck.
GOTINDX:
;finally got both new value (NEWV) and index to put it in (HOLDER)
mov w, NEWV
;;;ok, how to move w into V[noparse][[/noparse]HOLDER] ?!?!
clr INDEX ;done counting bits
clr HOLDER ;start collecting a new value
jmp GOGOGO ;go back to PWM work
GOTV: ;HOLDER has assembled value - tuck it into NEWV
mov w, HOLDER
mov NEWV, w
clr HOLDER ;start collecting a new value
jmp GOGOGO ;go back to PWM work
END
SWAP doesn't work the way you are using it. It swaps the high and low nibble of a single byte.
";;;ok, how to move w into V[noparse][[/noparse]HOLDER] ?!?!"
MOV FSR,#V ; NOTE "#"
ADD FSR,HOLDER
MOV IND,NEWV
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"SX-Video·Module" Now available from Parallax for only $28.95
http://www.parallax.com/detail.asp?product_id=30012
Product web site: www.sxvm.com
"It's not getting what you want, it's wanting what you've got."
Post Edited (Bean (Hitt Consulting)) : 6/8/2005 11:30:06 AM GMT
xor F, W
xor W, F
xor F, W
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!