Shop OBEX P1 Docs P2 Docs Learn Events
Propeller Chip runs a mostly unmodified Arduino program (video) — Parallax Forums

Propeller Chip runs a mostly unmodified Arduino program (video)

Martin_HMartin_H Posts: 4,051
edited 2013-12-12 02:59 in Propeller 1
I wanted to see if it was possible to use the SimpleIDE and the Propeller chip to run Arduino programs. So I ported some of the Arduino.h, main.cpp, SPI (sort of), Adafruit_GFX, and Max72xxPanel. The port consisted of writing Propeller implementations of Arduino functions like digitalWrite, delay, and pinMode. But I also removed some Atmel concepts that aren't on the Propeller (e.g. pgm_read_byte).

The most challenging part was dealing with SPI because the Arduino uses fixed pins for MOSI and SCLK, while the Propeller doesn't. So I used Spin2cpp and ported the Propeller SPI to C++. I then rewrote a small section of code which calls the SPI functions. Not a big deal, but it means the port is a one way trip and the code won't run on the Arduino afterwards. However, the port was much less work than writing the whole mess from scratch.

Here's the photographic evidence before this gets chalked up as a Bigfoot sighting:

Here's the source code:

Ticker.zip
«134

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2013-06-05 19:56
    Hey Martin, that is really neat!
  • jazzedjazzed Posts: 11,803
    edited 2013-06-05 22:41
    Nice work Martin. Thanks for sharing.
  • TinkersALotTinkersALot Posts: 535
    edited 2013-06-05 22:53
    this sounds like a great idea for a "white paper" and a neat way to steal a bunch of code from the duino-camp :)
  • Heater.Heater. Posts: 21,230
    edited 2013-06-06 00:55
    Most excellent.
  • mindrobotsmindrobots Posts: 6,506
    edited 2013-06-06 05:09
    Wow! Well done!

    Yup, you got pictures, so it happened!!
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2013-06-06 05:52
    Much clever boffinry. Keep up the good work!
  • cavelambcavelamb Posts: 720
    edited 2013-06-06 07:37
    Wow, Martin.
    Just Wow!
    This could be a game changer.

    What other functions look like they might be a problem with Arduino code?
    ADC maybe?
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-06 08:11
    @All, thanks for the kudos.
    cavelamb wrote: »
    What other functions look like they might be a problem with Arduino code?
    ADC maybe?

    Yes, the ADC would be problematic, but only because there's no standard ADC used with the Propeller. If you assumed a specific board (e.g. Prop BOE, Propeller Backpack) or use conditional compilation, then that wouldn't be that hard at all. The hardest parts are the use of timers and interrupts as they don't exist on the Propeller. Now they're not needed because cogs are better and more general purpose, but that code won't port without a re-write. In practice most of their usage on the Arduino hides the ugly stuff behind a library, so the consuming code won't change. A good example is the servo library which uses timers. I could build a cog version and all code using the servo library would port unchanged. The same would be true for the analogWrite function.

    A lessor concern is the fact that the Harvard architecture is more in your face on the Arduino. So there's annotations like PROGMEM and pgm_read_byte which aren't needed in LMM or CMM. On the Propeller the cogs need to worry about separate data and code stores, so code written on the Propeller for a cog might use those annotations.
  • Bill HenningBill Henning Posts: 6,445
    edited 2013-06-06 09:02
    Nice work Martin!

    Hmm... maybe we need a "hit list" of library functions not done yet...
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-06 11:43
    A hit list is an interesting idea. The Arduino library is quite large, but it is often layered, so getting the core functions would allow for layered stuff to port as is.

    The core library is located in this directory \arduino-1.0.1\hardware\arduino\cores\arduino and consists of 36 files. Many of them aren't needed because either Propeller gcc has support for build in (e.g. new, delete), or don't apply (e.g. WInterrupts, HardwareSerial, USB support), or aren't core (e.g. IP Address). So I imagine we could limit it to the functions in Arduino.h, Print, and Serial. There commonly used libraries are in the directory \arduino-1.0.1\libraries and some like LiquidCrystal and Stepper look like they could compile with what I already have. But Servo will need work.

    What I can do is try a few more program ports and flesh out my implementation a bit more. That will give me a better idea how big a project this could be.
  • cavelambcavelamb Posts: 720
    edited 2013-06-06 18:09
    You really need to concentrate on a specific hardware platform, Martin.
    The ASC, with built-in A2D converter would make the most sense.
    All the other Propeller boards choke when that comes up.
    They may be ok for many applications, but the ASC is going to be\
    the closest match for the widest variety of apps.


    I've been looking at that Touch Screen shield at Radio Shack,
    wondering how to port the example programs from A to P.

    This might just be the trick.
    And it would be a very cool example too.

    Timely, Martin...
    Very timely.
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-06-07 04:49
    You could write your libraries to use a hardware abstraction layer. Each board would require it's own HAL code, which would be a device driver with a very simple interface. The higher level code would not need to be changed to support different boards.
  • prof_brainoprof_braino Posts: 4,313
    edited 2013-06-07 07:19
    This is a big deal. I was worried that using existing library would be much harder.

    Re: Concentrate on specific hardware - If only particular hardware is supported, that excludes everything else, and would obviously be a problem. Supported hardware should ideally include anything with a prop in it.

    Having a HAL for each board could be a reasonable approach. There already is a selection in simpleIDE for each memory model, if this also includes somewhere a HAL definition for each board...and users could at more definitions as new custom boards come out...
  • cavelambcavelamb Posts: 720
    edited 2013-06-07 08:50
    While being able to compile and run 'dino code might be handy, the real benefit, to my thinking,
    is to be able to use the 'dino hardware as well. That's not something that any old prop board
    will be able to do easily. The zillions of Aurdino shields that are out there, along with their
    drivers and application code...

    Martin has this niche pretty well nailed down.

    His ASC board (Aurdino Shield Compatible) is laid out on the Aurdino form factor, so shields
    will plug in just as they do on a Pic or Arm based Aurdino processor board.

    He also offers an adapter (ASA = Aurdino Shield Adapter) for Propeller Platform boards to allow Aurdino
    shields to be mounted.

    That's why I think he should concentrate on his ASC board.
    It has the required A2D converter that the Aurdino offers already.


    Altruism is all well and good, and all Propellerdom will benefit from this project.
    But business is business as well.

    Anyway, moving on...

    Hardware Abstraction Layer?
    Sounds like a no-brainer, but how would such a thing be implemented ?

    There are the normal suspects in the Propeller world -
    memory addressing and interrupts, delay timing - might be - uh - Interesting?

    The stuff that props often use; VGA, keyboard and mouse, TV, SD cards, EEPROM, RTC,
    LCD, touch screens, etc?

    All this hardware specific stuff...

    Makes a strong argument for GCC, doesn't it?
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-07 10:50
    cavelamb wrote: »
    Martin has this niche pretty well nailed down.

    That's why I think he should concentrate on his ASC board.
    It has the required A2D converter that the Aurdino offers already.

    There number of pronouns in that sentence might confuse people reading this who don't know the players.

    Martin Hodge is the creator of the Propeller ASC and the Propeller Platform DNA

    Martin Heermance (me) is the hobby robotics guy, plywood aficionado, and C++ programmer.

    The fact that we are both named Martin H, and like Propeller chips and Arduinos has caused confusion in the past.

    Anyway here's the list of functions left from Arduino.h that need to be nailed down:
    // These will be easy and I can work on them tonight.
    unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
    
    void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
    
    uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
    
    
    // These look easy on the surface, but are more complicated than you think.
    // The reason is the propeller's CNT register wraps once a minute. But a cog
    // could keep track of that and return correct values.
    
    unsigned long millis(void);
    
    unsigned long micros(void);
    
    // These are board specific and I'm going to hold off working on these
    
    int analogRead(uint8_t);
    
    void analogReference(uint8_t mode);
    
    void analogWrite(uint8_t, int);
    
  • cavelambcavelamb Posts: 720
    edited 2013-06-07 13:59
    Ok, ya got me there, Martin_H. I was one of the confused.
    I thought you were Martin Hodges, with a new avatar.
    Sorry 'bout that. :)


    There was a delay function posted somewhere fairly recently
    that may solve the millis() function.
    Dunno about the micros() tho.

    For the analog functions, Martin's (the other one) ASC board uses the MPC3008,
    a 10 bit, 8 channel chip. There is probably a driver for that somewhere that might
    supply code for analogRead().
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-10 08:18
    Well it was fun while it lasted. Over the weekend I ported analogWrite, pulseIn, shiftOut, and shiftIn which were all trivial. So I got ambitious and ported the Print, Printable, and WString classes and overflowed hub ram:
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c Adafruit_GFX.cpp -o cmm/Adafruit_GFX.opp
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c Arduino.cpp -o cmm/Arduino.opp
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c Max72xxPanel.cpp -o cmm/Max72xxPanel.opp
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c SPI.cpp -o cmm/SPI.opp
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c glcdfont.c -o cmm/glcdfont.o
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c Print.cpp -o cmm/Print.opp
    propeller-elf-c++ -I . -L . -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti -c WString.cpp -o cmm/WString.opp
    propeller-elf-c++ -I . -L . -o cmm/Ticker.elf -Os -mcmm -m32bit-doubles -fno-exceptions -fno-rtti cmm/Adafruit_GFX.opp cmm/Arduino.opp cmm/Max72xxPanel.opp cmm/SPI.opp cmm/glcdfont.o cmm/Print.opp cmm/WString.opp Ticker.cpp
    c:/users/a231861/propgcc/bin/../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/bin/ld.exe: region `hub' overflowed by 30404 bytes
    
    Done. Build Failed!
    
    Your program is too big for the memory model selected in the project.
    

    Those classes are used by the Serial object which is used for debugging purposes, so this is limiting. What interesting is that an AVR only has 32K of ram just like the Propeller's hub, so overflowing hub ram in CMM with so few classes seems a bit surprising. But I am using alpha software to cross compile code from another MCU, so trouble should be expected.
  • Heater.Heater. Posts: 21,230
    edited 2013-06-10 08:32
    On the Arduino an "int" is only 16 bits. That would account for a lot of "bloat" when moving to the 32 bit Propeller.

    Isn't Arduino code in 32K FLASH? So it has another 2K of RAM for data.

    I'm not sure that CMM is as compact as the AVR instruction set.
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-10 09:08
    Heater. wrote: »
    On the Arduino an "int" is only 16 bits. That would account for a lot of "bloat" when moving to the 32 bit Propeller.

    Isn't Arduino code in 32K FLASH? So it has another 2K of RAM for data.

    I'm not sure that CMM is as compact as the AVR instruction set.

    Yes, Arduino's have 16 bit ints. While the modern ones have a 32K flash and 2K RAM, the original was on a version that had 16K flash and 2K RAM, so it can fit in less. Since I'm not even calling most of these functions I suspect the linker isn't eliminating unused code which the AVR tools might be doing.
  • jazzedjazzed Posts: 11,803
    edited 2013-06-10 10:08
    Martin_H wrote: »
    Yes, Arduino's have 16 bit ints. While the modern ones have a 32K flash and 2K RAM, the original was on a version that had 16K flash and 2K RAM, so it can fit in less.

    AVR instruction packing is pretty amazing.
    Martin_H wrote: »
    Since I'm not even calling most of these functions I suspect the linker isn't eliminating unused code which the AVR tools might be doing.

    We have per-function dead-code removal ability now in a release but haven't posted it yet. Will get to it tonight.

    There is a way you can use dead-code removal now (with some limits). It requires using a special linker script.
    https://sites.google.com/site/propellergcc/documentation/faq#TOC-Q:-How-can-I-get-smaller-programs-


    Martin, could you post a .zip ?
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-10 10:14
    jazzed wrote: »
    Martin, could you post a .zip ?

    Sure thing I can do it when I get home tonight.
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2013-06-10 14:56
    Martin_H wrote: »
    In practice most of their usage on the Arduino hides the ugly stuff behind a library, so the consuming code won't change. A good example is the servo library which uses timers. I could build a cog version and all code using the servo library would port unchanged.

    Martin, A wonderful idea! I know such a library for Prop C would find its way into an article or two. In fact, I can see a series of pieces for basic robotics tasks with "cross-platform" code. Much of the basic functionality for a robot is fairly routine:

    * Servo
    * PWM out for DC motor control, LED dimming, or cranky sound making
    * digitalRead, of course
    * and just a scattering of others. Full string support isn't a must-have. The serial term stuff for debugging could be limited if there are memory concerns. Aren't there lighter weight versions for the string-handling routines?

    The PropBOE/Activity Board variant for analogRead looks like a safe bet.

    These and a plug-and-play equivalent to Ken Shirriff's remote IR library would just about cover 90+ percent of most people's robots.

    -- Gordon
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-10 18:30
    Martin, A wonderful idea!

    Thanks Gordon. I started working on the Servo lib port and that's going really smoothly. Using a cog boils it down to a for loop and some locks, which is much cleaner and smaller than the existing timer code.

    Last year I ported a bunch of PBasic to the Arduino to improve my programming chops on both platforms. This port is making me learn a ton about the Arduino library internals and the Propeller chip.
  • jazzedjazzed Posts: 11,803
    edited 2013-06-10 20:01
    Amazing. Down to only 9KB total bytes after pruning unused code.
    Propeller-gcc release candidate version 1.0.0 was posted here June 1st.
    https://code.google.com/p/propgcc/downloads/detail?name=propellergcc_v1_0_0-i686-windows.zip

    Download the package, rename your C:\propgcc to C:\propgcc_save.
    Extract the package contents as C:\propgcc

    The package will let you remove (prune) unused code at build time. To enable dead code pruning, add this to SimpleIDE's Project Manager -> Compiler -> Other Compiler Options:

    -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--print-gc-sections

    The -Wl,--print-gc-sections is optional and only allows seeing what was removed.
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-10 20:13
    This is great news. I'll update my propgcc and keep going. The thing about all those string and format routines is that you only use a few in any given program, but they're all handy to have around.
  • TinkersALotTinkersALot Posts: 535
    edited 2013-06-11 10:18
    so, if I were inclined to put one of these:

    http://docs.macetech.com/doku.php/centipede_shield

    on a prop asc -- how might I continue with your efforts? (as in how does what you are discovering enable us to use "any old shield we want to")
  • Martin_HMartin_H Posts: 4,051
    edited 2013-06-11 12:13
    so, if I were inclined to put one of these:

    http://docs.macetech.com/doku.php/centipede_shield

    on a prop asc -- how might I continue with your efforts? (as in how does what you are discovering enable us to use "any old shield we want to")

    I don't know enough about the Prop ASC to say for sure. Looking at the docs (http://mghdesigns.com/wiki/_media/asc:pasc-f.pdf) it looks like pins 14 and 15 are used for SDA and SCL for the A2D converter. So implementing analogRead under that assumption should work.


    BTW my interest in this project is code reuse, not shield reuse. My plan is to use this to port code from Arduino projects to Propeller projects, but I plan on using custom hardware.
  • Martin HodgeMartin Hodge Posts: 1,246
    edited 2013-06-11 23:40
    Martin_H wrote: »
    I don't know enough about the Prop ASC to say for sure. Looking at the docs (http://mghdesigns.com/wiki/_media/asc:pasc-f.pdf) it looks like pins 14 and 15 are used for SDA and SCL for the A2D converter. So implementing analogRead under that assumption should work.


    BTW my interest in this project is code reuse, not shield reuse. My plan is to use this to port code from Arduino projects to Propeller projects, but I plan on using custom hardware.

    If it would help you any with this project, I'd comp you an ASC. PM me your address.
  • cavelambcavelamb Posts: 720
    edited 2013-06-12 05:32
    so, if I were inclined to put one of these:

    http://docs.macetech.com/doku.php/centipede_shield

    on a prop asc -- how might I continue with your efforts? (as in how does what you are discovering enable us to use "any old shield we want to")

    Here is the thing I've been pondering...

    2.8" LCD Touch Screen - with full source code examples.

    Available from Lady Ada, Seed, And Radio Shack.
    https://github.com/adafruit/TFTLCD-Library
    http://www.radioshack.com/product/index.jsp?productId=12688460
    http://www.seeedstudio.com/depot/28-tft-touch-shield-v20-p-1286.html


    It's an Arduino form factor board, and would look perfect on an ASC.

    I'm just not confident enough of my coding skills to tackle it by myself.
Sign In or Register to comment.