Shop OBEX P1 Docs P2 Docs Learn Events
8 PWM and a serial... — Parallax Forums

8 PWM and a serial...

Scott MScott M Posts: 43
edited 2005-06-09 00:12 in General Discussion
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?

Comments

  • pjvpjv Posts: 1,903
    edited 2005-06-02 05:02
    Hi Scott;

    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)
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-02 05:14
    Bean just realeased code for a serial driven 16 channel PWM for the SX in the project forum. To see the different SX packages go here. I strongly suggest getting the Plus kit, Gunther's book is a·very valuable reference. It may seem steep, but its all up front cost, buying new chips is pretty cheap and you use the same SX-Key to program them.
  • PJMontyPJMonty Posts: 983
    edited 2005-06-02 07:21
    Scott,

    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
  • Scott MScott M Posts: 43
    edited 2005-06-07 02:10
    OK, I'm looking at the code for the serial driven, 16 channel PWM code. Before I put dowm money on a dev environment, I have questions.

    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. smile.gif

    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?
  • pjvpjv Posts: 1,903
    edited 2005-06-07 04:46
    Hi Scott;

    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)
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-07 05:46
    Also there is a prescaler you can set for the RTCC so that it is incremented every Nth cycle, where N is a power of 2. This combined with the RETIW permits you to set your inturrupt rate with extreme accuracy.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2005-06-07 06:12
    Scott, I presume you want to use the Javelin's ShiftOut (not serout) since you mentioned a clock.

    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
  • BeanBean Posts: 8,129
    edited 2005-06-07 12:38
    Scott,
    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."
    ·
  • Scott MScott M Posts: 43
    edited 2005-06-07 13:44
    >Scott, Can you explain why you need to send data so fast ?

    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.



    ·
  • BeanBean Posts: 8,129
    edited 2005-06-07 14:47
    Scott,
    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
  • Scott MScott M Posts: 43
    edited 2005-06-07 15:30
    >I can help you if you want to try it after you get your programming tools.

    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.
    ·
  • BeanBean Posts: 8,129
    edited 2005-06-07 17:37
    I would work in stages. First get the SX to do the PWM, then after that is working, get the SX to handle the ramping, then move on to the next step. Another limitation you might have is the limited amount of RAM in the SX (only 136 bytes).
    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."
    ·
  • Scott MScott M Posts: 43
    edited 2005-06-07 18:05
    Bean (Hitt Consulting) said...
    I would work in stages. First get the SX to do the PWM, then after that is working, get the SX to handle the ramping, then move on to the next step. Another limitation you might have is the limited amount of RAM in the SX (only 136 bytes).
    Bean.

    136... ouch. I'd missed that. Ok, it's definitely not a candidate for the complex command parser - it's not uncommon to load in 10-30 commands at a time (at 7 bytes each).

    Does anyone make a fast, realtime kind of chip with, say, 2k of memory onboard?

    ·
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-07 18:18
    The most versatile memory you can couple with the SX is Ramtron's FRAM series, the FM25C160 is a 2K serial 8-SOIC availible from www.newarkinone.com for $2.07. Its bus speed is 20MHz (newark states its 5MHz but Ramtron states its a 20MHz part) It takes 4 bytes for each read or write so you can obtain a·byte of data each ·32/(2x107) or every 1.6 uS.

    Post Edited (Paul Baker) : 6/7/2005 6:36:32 PM GMT
  • Scott MScott M Posts: 43
    edited 2005-06-07 20:57
    OK, this is lame, but before I plunk down $200 I'd like to make sure I have some idea what I'm doing. This is not complete code (hey, I just started reading the mauals today), but will it do what it claims it does, more or less? I've marked stuff that I know is incomplete.

    Since I don't need rock-steady PWM, I'm avoiding using interrupts.

    Comments and laughter welcome. smile.gif

    ---

    ;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
  • BeanBean Posts: 8,129
    edited 2005-06-08 11:27
    Scott,
    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
  • James NewtonJames Newton Posts: 329
    edited 2005-06-09 00:12
    http://www.sxlist.com/techref/ubicom/lib/math/bit/swap_sx.htm "Swap w and f without a temp register "

    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!



Sign In or Register to comment.