Shop OBEX P1 Docs P2 Docs Learn Events
C4SX: Virtual Peripheral libraries and dynamic VP loading — Parallax Forums

C4SX: Virtual Peripheral libraries and dynamic VP loading

Peter VerkaikPeter Verkaik Posts: 3,956
edited 2007-08-26 02:38 in General Discussion
Hi,

Attached are some libraries for Uart (transmit and receive), Timer (16bits) and Queue.
They are almost working (hopefully this weekend) but I already share them so you
can study the mechanisms I applied.

The file vp_test.c is a showcase for the use of libraries. The supplied libraries show
how to use C macros. I use those macros to make it easy to manipulate variable
locations and to declare Virtual Peripheral parameters.

The receive uart macro for example,
vpUartRx(RX,PORTPIN_RA0,INPUT_INPUT,PORTPIN_RA1,HIGH_HIGH,19200,1,N81)
stores the parameters into rom.

The generic vpInstall() function, installs the uart, setting up the rambank used by the vp,
and initializing any pins that are used by the vp.
(Actually, this pin setting is the one thing·missing to make it all work).

The key issue is the mechanisms used. The overhead for having dynamic loadable VP's is
quite small, due to the generic setup. The libraries vpobjLib.h·(generic functions like vpInstall),
vpUart.h (receive and transmit uarts), objQueue (queue objects for within a rambank) and
vpTimer16.h (timer functions)·also show that CC1B can generate·1-to-1 translations
from C code to assembler. (Quite useful for the interrupt routines).

I make a distinction between objects and vp's. A queue for example is an object but no vp
because it has no installable parts. But it must be initialized and that is done by the generic
function objInitialize(), which is also used by vpInstall() to initialize vp's but vpInstall() does
also setup·the installable parts. It is possible to define more vp's than can run concurrently.
That's why there is also a vpUninstall() function.·So you can stop a vp, and run another vp.
This is quite useful for multiple transmit uarts as there usually is no need to have these running
simultaneously, but they could be. Note that having multiple vp's of the same type still only
includes the support code once. This is possible because the vp fields in different
rambanks are at the same offsets.

Just unzip the libraries in the cc1b folder.
The vp_test.c should go in the C4SX folder.
The vp_test.txt is identical as the .c but allows online reading.

Comments are welcome.

regards peter

Comments

  • James NewtonJames Newton Posts: 329
    edited 2007-08-17 18:35
    Peter, that appears to be freaking magical.

    Could the switching in the ISR also be generated automagically based on the VP's and objects used? E.g. if there are no timers being used, don't generate that·case of the switch? Probably not a big deal.

    Could you make a sort of "template" vp? In other words, code that has comments in place of the actual workings so that people could easily make a new VP for some other function such as SigDeltaA2D, or PWMOut, (FSK, I2C, SPI, 1Wire, stepper, keyboard LCD, LED, etc...) see:
    http://www.sxlist.com/techref/ubicom/virtperf.htm

    Is it just me or does anyone else find it amazing how much can be accomplished given a C compiler that actually works?



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ---
    James Newton, Host of SXList.com
    james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
    SX FAQ / Code / Tutorials / Documentation:
    http://www.sxlist.com Pick faster!



  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-08-17 19:02
    James,
    I can simply enclose each case with a #ifdef so a case is only included
    when a definition macro (like vpUartRx) is called. Automatically adding new
    cases is not possible, but the interrupt routine can be extended when new
    vp libraries come out.
    As for a template, I think you can best look at vpUart.h
    Basically you define the variables using shadowDef modifier which only
    ensures direct addressing is used for the generated assembly, and then add
    an interrupt part and support routines. If you look at the vpUartRx_isr()
    for example, you'll notice it looks just like the assembly interrupt uart code.
    (with some extra code to have a full featured uart).
    I was impressed myself, how easy it is to translate·existing assembly routines
    to C and to see how cc1b generated assembly from that C source
    that is almost identical to the assembly listing I started from.
    But thanks to RW Senser for creating the conversion program that enables
    the generated assembly to be loaded into the sxkey IDE.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2007-08-21 18:15
    The VP libraries are updated. I added pinSetup for the vpInstall() function
    so all elements for dynamic VP loading are in place.
    Had to redefine the PORTPIN values to make the code more compact.

    To prevent possible glitches on I/O pins when port direction registers
    are updated from both mainlevel code and interrupt code, I declared
    DDR copy registers in bank 0xF0. This also has the benefit that SX28
    code can read the direction registers (actually the copies), but more
    importantly, it offers an easy way to prevent glitches.

    The sequence to write to the DDR registers, once M is set, is:
    MOV W,DDRACOPY ;any DDR copy register
    MOV !RA,W

    If an interrupt occurs inbetween those 2 instructions, and the interrupt
    would update direction bits for port RA, then the interrupt update becomes
    undone.
    The function DDRupdate in library Portpin.h inserts an extra clockcycle
    when an RTCC rollover would occur inbetween those 2 instructions.
    As a result, the interrupt occurs before the MOV W,DDRACOPY instruction,
    so if the interrupt update the DDR registers, the change is maintained.

    Library Portpin.h contains a large number of small routines to make pins inputs
    or outputs, low or high and also a large number of small routines that operate
    on ports.

    The VP uarts have been updated and now include code for handshaking.
    With the port and pin functions available I can start to make a real demo
    program that actually runs.
    The attached vp_test.c compiles without error so you can checkout the
    generated code.

    In a couple of days I should have a working demo that demonstrates the
    loading and unloading of virtual peripherals.
    Unzip libraries.zip to the CC1B folder. Place vp_test.c into the C4SX folder.

    regards peter
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2007-08-26 02:38
    Peter Verkaik said...
    The sequence to write to the DDR registers, once M is set, is:
    MOV W,DDRACOPY ;any DDR copy register
    MOV !RA,W

    If an interrupt occurs inbetween those 2 instructions, and the interrupt
    would update direction bits for port RA, then the interrupt update becomes
    undone.
    The function DDRupdate in library Portpin.h inserts an extra clockcycle
    when an RTCC rollover would occur inbetween those 2 instructions.
    As a result, the interrupt occurs before the MOV W,DDRACOPY instruction,
    so if the interrupt update the DDR registers, the change is maintained.
    Edge triggered interrupts might still experience a problem.

    - Sparks
Sign In or Register to comment.