MRAA and the UP board.

Kurt
Kurt New Member Posts: 146 ✭✭
As I mentioned in the forum thread: https://up-community.org/forum/announcements/866-up-board-4-4-linux-kernel-for-ubuntu-16-04-and-14-04-is-now-available#2333

I would continue the conversation in a new thread.

It has been awhile since I played around with MRAA. Earlier I used MRAA on the Edison, so I have a reasonable understanding of how it works.
From what I can tell, the UP board (up.c) code is pretty simple. There are no adv_func's defined. So the GPIO is using standard sysfs and luckily looks like it does not need to do lots of other special stuff to make IO pins like the Edison does with the Arduino shield.

So far with the expansion connector, I have tested that I can communicate using ttyS1 to talk to a Teensy 3.2 at 2mbs, which appears to work.

One question I have so far is, are there two UARTS on the 40 pin connector? As it looks like there are two defined in mraa_up_board (about line 131,140)
Pin13 is defined UART2_RX is RPI 27, likewise 22 is UART2_TX, RPI 25

Also defined in uart table (line 204) as /dev/ttyS2

Now back to experimenting

Comments

  • Dan O'Donovan
    Dan O'Donovan Administrator, Moderator, Emutex Posts: 241 admin
    Yep, the pin muxing and other configuration that was needed for Edison I/O is done at kernel driver level for UP, so its effectively hidden under the sysfs interface for pins 0-27.

    There's no UART2 on the 40-pin header unfortunately. It did exist on a pre-production version of the board but later got removed. I need to update MRAA for that, actually, thanks for the reminder!
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Thanks Dan,

    That is what I thought.

    Now starting to experiment, to get an idea of speeds.

    Took a few wrong steps as I needed to figure out that the pin number you pass into the mraa_gpio_init(iopin); is the physical pin number on the connector and not the Linux(RPI) pin number, which you use in the sysfs calls or when you do it from a Command Line interpreter, like what is shown in the Pinout GPIO example on the wiki. In the case of the wiki example: where you do something like: echo 26 > /sys/class/gpio/export
    (As SU), To use that pin in MRAA you would use pin number: 37

    I then updated the blink-io example and removed the delays as well as the printfs after each successful write to the GPIO pin. I then monitored it using my Saleae logic analyzer as you can see below:


    It appears to take about 5.85us to do an output...

    Maybe later I will see how long it take to change it from input to output... On Edison this was real slow and could not reliably use a ping sensor...

    Anyway having some fun
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Not sure if anyone else is interested, but I hacked up my PING sensor code that I did to try out some stuff on Edison, to get a general idea of timings, in this case I was interested on how long does it take to switch a pin from input to output and likewise back From my testing it looks like the calls to: mraa_gpio_dir are taking on average maybe something like: 1.6 or maybe 1.7ms per call.

    Note: I did this without adding the hardware so put stuff in to handle not getting the ping back...

    All of the code is in my Raspberry Pi project: https://github.com/KurtE/Raspberry_Pi/blob/master/TestMraaPing/TestMraaPing.cpp
  • Dan O'Donovan
    Dan O'Donovan Administrator, Moderator, Emutex Posts: 241 admin
    Nice, thanks for sharing, Kurt.

    Was it fast enough to make the PING sensor work?
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    edited September 2016
    I have not had a chance to test it with sensor as right now in middle of house projects and sensor is buried for now. but looking at the old Edison thread: https://communities.intel.com/message/265937#265937

    I am guessing it might be too slow to reliably do the ping sensor, especially if you look at the Edison stuff above with the Dec 3 AM posting that 1.3ms was still too slow.

    Edit: Looking more through the old thread, I believe the timing for the mraa_gpio_dir, would need to get down to about .71ms to work well with the ping sensor.
    But, not a high priority as I only used it as a test setup.
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    edited September 2016
    More interesting things to experiment with right now are I2C and SPI.

    Some things I am interested in trying out include:

    I2C: Would like to try out the BNO055 IMU, as I mentioned earlier in the thread: https://up-community.org/forum/search?query=BNO055&childforums=1
    The question will be, does the I2C of the UP board support clock stretching.

    Also software wise, I believe the Adafruit page: https://learn.adafruit.com/bno055-absolute-orientation-sensor-with-raspberry-pi-and-beaglebone-black
    Uses Python and RPI code, so will probably need to convert to MRAA as I believe from a very recent posting that the RPI library has not been ported to Ubuntu for the UP.

    SPI: Not much info info in Wiki on how SPI works here. Also hoping that SPI works a whole let better than Edison. The doc here says clock can be up to 25mhz, Don't remember what max said on Edison, but in reality it was really slow. Been awhile but maybe something like 400k...

    Couple of things to experiment with:

    Can I run simple ILI931 display like: https://www.adafruit.com/products/1770
    Work with UP using MRAA in user mode. The display uses SPI, plus a CS pin and a DC (Data/Command) pin, that both need to have their states timed carefully with the output SPI stream. That is for commands the DC needs to be asserted typically for the first byte of the command and then turned off for subsequent bytes. Also on many of these devices the CS needs to stay asserted during a command. If I remember SPIDEV has some control over this, which the Edison did not fully support, but I was able to work around by software control of these signals. This worked in some cases, but if some other device or software is running that does SPI, these could collide. Not sure if this will work here. Have one setup to try, but have doubts.

    Communications between UP and Teensy to control Servos and other things. Currently I am using USART or USB, but wondering about using SPI. The communications are semi bidirectional, but typically initiated by host. Was thinking host(UP) could issue commands and the like and when Teensy needs to give a response, maybe have it raise an IO pin, to signal host...

    Actually gives me something else to test. Interrupt handling of GPIO pins...

    Anyway lots to try out. Suggestions?

    Update: playing around with my MRAA version of the Adafruit_ILI9341 code I did for Edison. to see some simple SPI stuff. Don't have anything working yet, but can start to get some ideas of speed.

    In the Logic Analyzer output, you can see the start of timings of a basic fill screen

    The timings show the different outputs:
    first one is command byte(0x2a) - Around this we assert DC
    The next group is 4 byte write for start x, end X
    Then another command (0x2b)
    Again another 4 byte write for start y, end y
    then another command: 0x2c
    then a whole bunch of bytes, I have the code break it up into max writes of 256 bytes each...

    As you can see here in the gaps between bytes is in range of about .16-.25ms. My guess is the overhead in spidev is about the .16 and the others are due to probably toggling DC MRAA write state and the like.

    Now back to playing
  • Dan O'Donovan
    Dan O'Donovan Administrator, Moderator, Emutex Posts: 241 admin
    KurtE wrote:
    I2C: Would like to try out the BNO055 IMU, as I mentioned earlier in the thread: https://up-community.org/forum/search?query=BNO055&childforums=1
    The question will be, does the I2C of the UP board support clock stretching.
    I haven't explicitly test it myself. If it worked on Edison, I'd bet it will work on UP.
    KurtE wrote:
    Also software wise, I believe the Adafruit page: https://learn.adafruit.com/bno055-absolute-orientation-sensor-with-raspberry-pi-and-beaglebone-black
    Uses Python and RPI code, so will probably need to convert to MRAA as I believe from a very recent posting that the RPI library has not been ported to Ubuntu for the UP.
    I recommend checking out this page if you haven't already: https://up-community.org/wiki/Adafruit
    A lot of Adafruit's Python libraries use Adafruit_GPIO only to detect the underlying platform and choose the appropriate default I2C bus. We've published a fork of that library that uses MRAA to accomplish that, so RPi.GPIO isn't needed in that use case. From what I can see, the Adafruit_BNO055 follows this pattern so should hopefully "just work" if you install our fork of Adafruit_GPIO first (following the steps on that wiki page).
    KurtE wrote:
    SPI: Not much info info in Wiki on how SPI works here. Also hoping that SPI works a whole let better than Edison. The doc here says clock can be up to 25mhz, Don't remember what max said on Edison, but in reality it was really slow. Been awhile but maybe something like 400k...
    Bus frequencies up to 25MHz are supported, in steps which are less granular at higher speeds. E.g. Available speeds include:
    25MHz, 12.5MHz, 8.33MHz, 6.25MHz, 5MHz, 4.167MHz, 3.571MHz, 3.125MHz, et

    Also, I've noticed that the SPI driver from the latest v4.8 kernel runs significantly faster. I have it on my to-do list to find out which changes are making the difference there and hopefully get them back-ported to the UP kernels.

    KurtE wrote:
    Can I run simple ILI931 display like: https://www.adafruit.com/products/1770
    Work with UP using MRAA in user mode. The display uses SPI, plus a CS pin and a DC (Data/Command) pin, that both need to have their states timed carefully with the output SPI stream. That is for commands the DC needs to be asserted typically for the first byte of the command and then turned off for subsequent bytes. Also on many of these devices the CS needs to stay asserted during a command. If I remember SPIDEV has some control over this, which the Edison did not fully support, but I was able to work around by software control of these signals. This worked in some cases, but if some other device or software is running that does SPI, these could collide. Not sure if this will work here. Have one setup to try, but have doubts.
    I haven't tried to use them with user-space libraries, but we have some Adafruit TFTs working with kernel drivers: https://up-community.org/wiki/TFT_Display_HATs
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    dan wrote:
    KurtE wrote:
    I2C: Would like to try out the BNO055 IMU, as I mentioned earlier in the thread: https://up-community.org/forum/search?query=BNO055&childforums=1
    The question will be, does the I2C of the UP board support clock stretching.
    I haven't explicitly test it myself. If it worked on Edison, I'd bet it will work on UP.
    I have not tried it on the Edison either. I have not really used an Edison for maybe 1.5 years now, after Trossen added the option of using RPI2 on the HROS1 robot, I then converted over to using ODroids. I was sort of frustrated with Edison as for example SPI was busted and they kept saying they would fix it, but it got worse with each build... And then my Arduino board fried, still have some mini boards around... Hopefully it has gotten better since then. It worked on an Odroid, after I updated their library detection, and it looked like at least the one I tested for a bit was working. So hopefully soon I will give it a shot.
    dan wrote:
    I recommend checking out this page if you haven't already: https://up-community.org/wiki/Adafruit
    A lot of Adafruit's Python libraries use Adafruit_GPIO only to detect the underlying platform and choose the appropriate default I2C bus. We've published a fork of that library that uses MRAA to accomplish that, so RPi.GPIO isn't needed in that use case. From what I can see, the Adafruit_BNO055 follows this pattern so should hopefully "just work" if you install our fork of Adafruit_GPIO first (following the steps on that wiki page).
    Looks good, thanks. So far I have in many cases tried to avoid Python, at least on boards like RPI or Odroids, as it appears to eat far more cpu resources than I would expect. Example with a different IMU (https://www.sparkfun.com/products/10736), They have Python ROS code that simply reads in from IMU and publishes topic, and appeared to consume maybe 40% of one core of an Odroid, Will be interesting to see how it does on UP.
    dan wrote:
    Bus frequencies up to 25MHz are supported, in steps which are less granular at higher speeds. E.g. Available speeds include:
    25MHz, 12.5MHz, 8.33MHz, 6.25MHz, 5MHz, 4.167MHz, 3.571MHz, 3.125MHz, et

    Also, I've noticed that the SPI driver from the latest v4.8 kernel runs significantly faster. I have it on my to-do list to find out which changes are making the difference there and hopefully get them back-ported to the UP kernels.
    Sounds great! Again great to hear this level of feedback from ones involved with the development.
    dan wrote:
    I haven't tried to use them with user-space libraries, but we have some Adafruit TFTs working with kernel drivers: https://up-community.org/wiki/TFT_Display_HATs
    Thanks, I know that is the route I will take if I decide to have the display on the UP. I ported the Adafruit ILI9341/GFX code to MRAA a couple of years ago, as Edison did not support FBTFT driver (not sure if they do now or not), and thought I would try it out here to get an idea of capabilities.

    Things like: How the CS line is handled? On Edison I believe it toggled on/off for each byte even in a multiple byte transfer. Warning I am rusty on my SPIDEV stuff, but if memory serves me, It did not work, like spec where I believe there is a timeout, if no additional bytes come, then it deasserts CS. Also I believe there is an argument that is part of SPIDEV structure where you can tell it deassert at end, which I don't believe MRAA supports (just zeros out structure and fills in other stuff).

    As for timeout of CS, it looks like it will timeout before you can make any additional SPIDEV calls. At least for sure in cases that look something like:
    mraa_spi_write(SPI, ILI9341_CASET);
    mraa_gpio_write(DC, 1);
    mraa_gpio_transfer_buf(SPI, txData, NULL, 4);
    

    Note there are some helper functions in between these calls, but these are where I showed the delays of about .16-.25ms delays in the Logic analyzer. Note it was great to see that for the transfer_buf case, that the up board was fully utilizing the SPI buss, on the Edison they had not enabled DMA or other access, so it looked like they were outputting one byte at a time with probably interrupt handler between, so there were gaps!
    Again if anyone is interested in playing along, this code is up in my Rasperry Pi github project I mentioned earlier.

    And a lot of this experimentation is just me trying to understand how things work, and then I will decide how on a robot such as a Trossen Hexapod (PhantomX), decide what things I want controlled by the UP and which things I wish to be controlled by a secondary processor. Will probably be a PJRC Teensy 3.6 board which kickstarter project (https://www.kickstarter.com/projects/paulstoffregen/teensy-35-and-36/description) just shipped... Also again trying to figure out how I wish for these two boards to communicate. Obviously the easiest is USB, but I have verified I can use 2mbs Serial so far and will try push it up to see how fast it can go... Or maybe SPI at 25mhz...

    Thanks again!
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    edited October 2016
    Thought I would mention, I updated my AX Servo test program to allow Baud rate > 2mbs and tried communicating between UP and Teensy 3.2 (later will try new one) and it worked so far up to 4MBS.

    May try to figure out if it can go faster as largest value in TERMBITS is: B4000000

    Edit: Wondering about the 4mbs here, it appears to work, but the wiki says baud up to: 3686400? Wonder how high it can really go?

    Edit2: Since only B4000000 is max defined, I thought I would try setting custom speed, by first setting the serial port to 38400, by using tcsetattr call, then use the TIOCGSERIAL ioctl to get the current state and then update to set custom speed using TIOCSSERIAL ioctl. None of these calls failed, but did not communicate with Teensy... Looking at dmesg | tail I see the last line of:
    [  114.949548] dw-apb-uart 8086228A:00: AX12_Test sets custom speed on ttyS1. This is deprecated.
    
    And I see now output from Logic Analyzer... So that is not valid approach. Also my ctrl+c handler appears to hang for a long time before the program exits. The code does try to output to serial port. Went back to 4mbs and working again...

    Should mention, I am not using MRAA for UARTS. When I was doing MRAA stuff on Edison, the UART stuff more or less did nothing. I believe it had the Init method, which did very little. So I am doing all of the termios stuff myself.

    ...

    Having fun
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Another quick update for: I2C and BNO055, So far on the surface it looks like it is working :D

    Steps I took include:
    1) Install Adafruit_Python_GPIO, as Dan mentioned earlier in thread, instructions up at: https://up-community.org/wiki/Adafruit

    2) Went to the learning Adafruit BNO055 for RPI/BBBk site: https://learn.adafruit.com/bno055-absolute-orientation-sensor-with-raspberry-pi-and-beaglebone-black/overview and from the software page downloaded and installed the Python stuff.

    3) in the examples, I edited the simpletest.py script - and setup the configuration for the BNO055. My setup is:
    bno = BNO055.BNO055(rst=13)
    

    I then wired up the BNO055 like:
    VIN - 3.3v(Pin 1)
    GND - GND(9)
    SDA - SDA(3)
    SCL - SCL(5)
    RST - GPIO4(13
    
    )
    Note the 13 here matches the 13 in the simpletest.py script.

    I used this wiring as it looks like mraa gpio code is setup to default to I2C Bus 1... I have not tried modifying this to use I2C0 yet...

    But then running the python script now I see:
    kurt@kurt-UP-CHT01:~/Adafruit_Python_BNO055/examples$ sudo python simpletest.py
    [sudo] password for kurt:
    System status: 5
    Self test result (0x0F is normal): 0x0F
    Software version:   785
    Bootloader version: 21
    Accelerometer ID:   0xFB
    Magnetometer ID:    0x32
    Gyroscope ID:       0x0F
    
    Reading BNO055 data, press Ctrl-C to quit...
    Heading=0.00 Roll=0.00 Pitch=0.00       Sys_cal=0 Gyro_cal=0 Accel_cal=0 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=0 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=0
    Heading=240.38 Roll=10.62 Pitch=-161.06 Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=0
    Heading=298.44 Roll=70.38 Pitch=-90.06  Sys_cal=0 Gyro_cal=3 Accel_cal=1 Mag_cal=1
    Heading=323.50 Roll=58.62 Pitch=-10.88  Sys_cal=2 Gyro_cal=3 Accel_cal=1 Mag_cal=2
    Heading=24.19 Roll=21.75 Pitch=-30.31   Sys_cal=2 Gyro_cal=3 Accel_cal=1 Mag_cal=3
    Heading=353.69 Roll=28.69 Pitch=-3.44   Sys_cal=2 Gyro_cal=3 Accel_cal=1 Mag_cal=3
    Heading=316.94 Roll=15.81 Pitch=14.12   Sys_cal=3 Gyro_cal=3 Accel_cal=1 Mag_cal=3
    Heading=313.69 Roll=15.50 Pitch=9.81    Sys_cal=3 Gyro_cal=3 Accel_cal=1 Mag_cal=3
    Heading=351.38 Roll=29.19 Pitch=-7.75   Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=71.31 Roll=-7.38 Pitch=-21.50   Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=96.12 Roll=-11.00 Pitch=-1.06   Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=52.81 Roll=6.81 Pitch=-19.62    Sys_cal=2 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=16.69 Roll=-4.81 Pitch=16.81    Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=15.62 Roll=-6.50 Pitch=14.81    Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=20.81 Roll=-1.12 Pitch=11.88    Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=22.69 Roll=-0.44 Pitch=11.69    Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=17.69 Roll=5.19 Pitch=7.50      Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=86.56 Roll=7.38 Pitch=-23.81    Sys_cal=2 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=146.81 Roll=-23.25 Pitch=-47.31 Sys_cal=2 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=187.31 Roll=-41.19 Pitch=-26.06 Sys_cal=2 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=246.19 Roll=-27.62 Pitch=-10.81 Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=234.00 Roll=-31.31 Pitch=-13.94 Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=228.44 Roll=-32.62 Pitch=-13.25 Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=215.38 Roll=-36.00 Pitch=-20.44 Sys_cal=3 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=134.81 Roll=-17.94 Pitch=-106.12        Sys_cal=1 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=144.50 Roll=-23.88 Pitch=-124.69        Sys_cal=1 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    Heading=136.31 Roll=-21.62 Pitch=-124.81        Sys_cal=2 Gyro_cal=3 Accel_cal=0 Mag_cal=3
    

    Again I have not done much testing here yet, or looked at the I2C lines using Logic Analyzer yet to see if there was any clock stretching and if so what the UP did when it happened.
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Thought I would mention that today I was able to get some of the ILI9341 display working in user mode using MRAA gpio/SPI.

    This is using an old port of Adafruit_ILI9341 and Adafruit_GFX libraries that i ported in my Raspberry Pi project.

    Some of the issues I ran into include:

    Using the Reset line, If I close the gpio object I created for the reset pin, it appears to put the pin into output low mode, which leaves the display in reset mode. Wonder if there is a way to leave the pin in input mode as the display has a PU resistor on this pin...

    Also as with Edison and probably most boards using SPIDEV, you do not have enough control over the hardware CS pin. That is for concepts like fill rect, you set the X and Y bounds, then you output the RAMWR command followed by enough 16 bit color entries to fill that rect. During at least part of this time you need to keep the CS selected. However as I mentioned in previous posting, The hardware controlled CS appears to either gets asserted and deasserted for each SPIDEV call or, there may be a timeout, which times out before the next SPIDEV call can get there... So the fill rect looses the bounds information and starts at 0, 0... I can not do this all in one call as I need to toggle another IO pin (Data/Command) for some of these bytes.

    But using Software control for both CS and DC, I can now get the graphic test to Crawl along. Actually some of it is not too bad.
    Timings out of the graphic test program:
    kurt@kurt-UP-CHT01:~/Raspberry_pi/testAdafruit_ILI9341C$ sudo ./graphictest
    ILI9341 Test!
    Display Power Mode: 0x9C
    MADCTL Mode: 0x48
    Pixel Format: 0x5
    Image Format: 0x9C
    Self Diagnostic: 0xC0
    Benchmark                Time (microseconds)
    Screen fill              1019195
    Text                     648705
    Text 2                   169518
    Lines                    12902439
    Horiz/Vert Lines         130425
    Rectangles (outline)     131230
    Rectangles (filled)      2086884
    Circles (filled)         2941991
    Circles (outline)        5945632
    Triangles (outline)      4108084
    Triangles (filled)       1986525
    Rounded rects (outline)  1709393
    Rounded rects (filled)   3030917
    Done!
    

    As compared to Edison from my old thread: https://communities.intel.com/thread/55879?start=15&tstart=0
    root@Edison:~/Raspberry_Pi/testAdafruit_ILI9341C# ./graphictest
    
    ILI9341 Test!
    Display Power Mode: 0x9C
    MADCTL Mode: 0x48
    Pixel Format: 0x5
    Image Format: 0x9C
    Self Diagnostic: 0xC0
    Benchmark                Time (microseconds)
    Screen fill              2270161
    Text                     854178
    Text 2                   270466
    Lines                    17170298
    Horiz/Vert Lines         230718
    Rectangles (outline)     197715
    Rectangles (filled)      4707367
    Circles (filled)         3936498
    Circles (outline)        7516893
    Triangles (outline)      5478251
    Triangles (filled)       3085610
    Rounded rects (outline)  2326019
    Rounded rects (filled)   5949905
    Done!
    

    Which none of these come close to the speed using a Teensy. Earlier timings again from the Edison thread:
        Benchmark Time (microseconds)
        Screen fill 280093
        Text 16069
        Lines 93961
        Horiz/Vert Lines 22922
        Rectangles (outline) 14638
        Rectangles (filled) 581601
        Circles (filled) 84421
        Circles (outline) 74050
        Triangles (outline) 21293
        Triangles (filled) 191373
        Rounded rects (outline) 33327
        Rounded rects (filled) 634068
    

    But again probably not expecting blazing speed in user mode...
  • Dan O'Donovan
    Dan O'Donovan Administrator, Moderator, Emutex Posts: 241 admin
    KurtE wrote:
    Using the Reset line, If I close the gpio object I created for the reset pin, it appears to put the pin into output low mode, which leaves the display in reset mode. Wonder if there is a way to leave the pin in input mode as the display has a PU resistor on this pin...
    The "default" pin state is dictated by other non-GPIO functions which might be available on that pin. For example, if that GPIO pin can also used as a UART Tx pin, then it would be returned to output direction by default when not in GPIO mode. It is possible to influence that. Taking the UART Tx pin again as an example, if you disable the UART1 controller in the BIOS settings, then the UP board pin control driver will see that and should leave the pin in input mode by default.
    KurtE wrote:
    Also as with Edison and probably most boards using SPIDEV, you do not have enough control over the hardware CS pin. That is for concepts like fill rect, you set the X and Y bounds, then you output the RAMWR command followed by enough 16 bit color entries to fill that rect. During at least part of this time you need to keep the CS selected. However as I mentioned in previous posting, The hardware controlled CS appears to either gets asserted and deasserted for each SPIDEV call or, there may be a timeout, which times out before the next SPIDEV call can get there... So the fill rect looses the bounds information and starts at 0, 0... I can not do this all in one call as I need to toggle another IO pin (Data/Command) for some of these bytes.

    Probably worth opening an issue on github for MRAA (https://github.com/intel-iot-devkit/mraa/issues) to suggest it as a feature for their SPI API. The spidev kernel API allows the user to optionally specify that CS should not be de-asserted at the end of the transfer: http://lxr.free-electrons.com/source/include/uapi/linux/spi/spidev.h
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Thanks Dan,

    In this case I am using MRAA pin 31 for Reset, which at least by the pinout page does not look like it has any other functions. But I know looks can be deceiving.

    I will play around a little with the MRAA code and maybe add something like :
    mraa_spi_transfer_buf_ex

    Which allows me to pass in a time to fill in delay_usecs and maybe if value < 0 then instead set cs_change.

    I tried doing something like that earlier on Edison, but the Edison version of the kernel driver had not implemented these features.

    Also if I continue playing much with this (instead of simply using the FBTFT driver, may convert this code to instead of doing each change to the screen, instead write it to a memory black (sudo Frame buffer) and either have an explicit call like: Update, or have secondary thread, which sees that the page has been updated and so many times per second tries to update the display. Could either do full display or try to keep bounding rect on what changed...

    Another question will be, what is the largest size transfer I can do with spidev. That is can I do an output of:
    320x240x2 = 153,600 bytes in one spidev call? I guess there is one way to find out :D

    Also are the sources for the Kernel driver up somewhere to take a look at?

    Thanks again
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Quick updates:

    1) Don't think spidev likes 153K transfers, it appears to work with 4K transfers, have not tried more to find boundary yet, as timings did not improve much for fill screen over the 256 byte transfers I was doing.

    2) Setting the spidev member: delay_usecs does not help, in fact it hurts. What it appears to do, is simply hold the CS pin active for that additional amount of time, before it un-asserts the CS pin and returns. So before with a value of zero for one byte, the CS appeared to be asserted for about 54us and the time between the end of the last clock of first transfer and start of the clock for the next transfer was about 120us
    When I passed in cs_delay of 250 the cs was asserted about 316us and between clocks was something like 490...

    Note: all of these timings vary, but it appears that this is not an approach to try here. Not sure if this behavior is by design or bug...
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Another quick update: Again looks like 4K max SPI as tried with 3840 and it work, tried 5120 and it does not... May go back to 4096...

    Also playing around with changing code to write to memory and then have update function that you call to say update now, which currently does complete screen update. May try later to keep track of bounding rect of what was updated...

    First pass now doing real stupid and only implemented the drawPixel, and allow all of the functions to funnel there. With this timings was:
    ILI9341 Test!
    Display Power Mode: 0x9C
    MADCTL Mode: 0x48
    Pixel Format: 0x5
    Image Format: 0x9C
    Self Diagnostic: 0x0
    Benchmark                Time (microseconds)
    Screen fill              1011468
    Text                     202245
    Text 2                   203019
    Lines                    201590
    Horiz/Vert Lines         203446
    Rectangles (outline)     203495
    Rectangles (filled)      23809
    Circles (filled)         205594
    Circles (outline)        199702
    Triangles (outline)      200530
    Triangles (filled)       10733
    Rounded rects (outline)  203048
    Rounded rects (filled)   227873
    Done!
    
    I then did a few more quick and dirty versions of fillRect, fillScreen, horizontal line and vertical line....

    Sped up some:
    ILI9341 Test!
    Display Power Mode: 0x9C
    MADCTL Mode: 0x48
    Pixel Format: 0x5
    Image Format: 0x9C
    Self Diagnostic: 0x0
    Benchmark                Time (microseconds)
    Screen fill              997276
    Text                     202534
    Text 2                   204304
    Lines                    200203
    Horiz/Vert Lines         203717
    Rectangles (outline)     203278
    Rectangles (filled)      5017
    Circles (filled)         202883
    Circles (outline)        199153
    Triangles (outline)      200628
    Triangles (filled)       2373
    Rounded rects (outline)  198778
    Rounded rects (filled)   211493
    
    Probably all for now. Will probably push up alternative versions to my github project...
  • Mario
    Mario New Member Posts: 9
    Hello KurtE
    How did you manage to install the MRAA library on Ubuntu? I keep getting "Unable to correct problems, you have held broken packages" errors caused by unmet dependencies when installing python-mraa. I'm currently on Ubuntu 14.04 with the 4.4.0-1-upboard kernel. I followed the instructions at https://github.com/intel-iot-devkit/mraa.

    Regards
    Mario
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    edited October 2016
    I git cloned the project to my up board, and built and installed using the instructions in https://github.com/intel-iot-devkit/mraa/blob/master/docs/building.md
  • Mario
    Mario New Member Posts: 9
    Roger. I will give this a try. Thanks
  • Mario
    Mario New Member Posts: 9
    Hello KurtE
    It worked like a charm Thanks. However, I'm now trying to import the library in a python script but it is not finding it. I went back to the github instructions and did the symlink and still couldn’t get it to work. I'm sure I'm missing something simple, since I'm not that experienced in Linux. How did you do that last part?

    Regards
    Mario
  • Kurt
    Kurt New Member Posts: 146 ✭✭
    Sorry I am not a Python person... So maybe someone else knows