libpruio (BB D/A - I/O fast and easy)

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
Post Reply
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

I have found and used the example of .gpio->raw(n) for input
but can't seem to find an example on how to use it for Output.

Regards
EDIT: Guess that's not possible as there will be a mixture of I/P's and O/P's
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: libpruio (BB D/A - I/O fast and easy)

Post by TJF »

Hi Dinosaur!
Dinosaur wrote:EDIT: Guess that's not possible as there will be a mixture of I/P's and O/P's
Not correct. You can also set output pins, up to 32 pins on one GPIO-SS at a time. Check out the source code at SUB GpioUdt::setGpio() (the WITH *Top block).

Meanwhile I found and fixed the DTOR bug (re-muxing pins). But I'm still debugging the problem with the hanging in the fast Gpio->setValue() sequence :-(

Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF
Check out the source code at SUB GpioUdt::setGpio() (the WITH *Top block).
One of my weaknesses, reading other peoples code.
I have no idea what you are doing there.
Will figure out a long hand way.

REgards
Edit: How do I Dim Share the line:
VAR io = NEW PruIo
so that I dont have to keep Deleting & Renewing it across multiple modules. ?
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: libpruio (BB D/A - I/O fast and easy)

Post by TJF »

Dinosaur wrote:I have no idea what you are doing there.
To understand that code you need to know the GPIO-SS hardware in the AM335x CPU, and the ASM code running in parallel on the PRU (that writes to the hardware registers).
Dinosaur wrote:Edit: How do I Dim Share the line:
VAR io = NEW PruIo
Nothing special here:

Code: Select all

DIM SHARED AS PruIo PTR io
io = NEW PruIo ' -> CTOR explicit
...
WITH *io
...
END WITH
...
DELETE io ' -> DTOR explicit
or

Code: Select all

DIM SHARED AS PruIo io ' CTOR implicit
...
WITH io
...
END WITH
...
' -> DTOR by fbc
In any case you should make sure that the DTOR gets called at the end, since it restores the hardware configurations. That's why I prefer the first solution during development: when the code hangs and I have to interrupt by <CRTL>-C, I can call the DTOR in a SIGINT signal handler.

Regards
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

libpruio (BB D/A - I/O fast and easy) - version 0.6.4b

Post by TJF »

Hi all!

I fixed two bugs (fast setValue sequence and DTOR re-muxing). New packages are uploaded. You can upgrade by

Code: Select all

sudo apt update
sudo apt --only-upgrade install libpruio*
Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

You have done well.
I have tested by turning all 20 outputs On, and in one sequence shut them all down at once.
Whilst running with my current setup, the loop time is about 35 micro Sec.(I have removed all usb coms)
During the period of shutting 20 outputs Off, it goes to about 65.

I can improve more by verifying if an O/P request has changed since last time I set it, and thus not set it again.
Have also put the Heartbeat led on my gui screen, had to guess at that pin Number (21).

The Graphics controller must be fairly slow on the BBB, as usually I refresh the gui screen every 100mSec.
This makes the operations look smoother, but with the BBB I have to do it about every 500 mSec, otherwise
the loop time goes up to much.

The only thing left now is to dream up a fixed number of pulse outputs.
Still waiting for my cape blanks so I can use it without stuffing up inputs. (which I have already done)
So not touching my new BBB until the cape is finished.

Below the code so far (except the .bi file)

Code: Select all

Sub InitBBB
   WITH io
      IF .Gpio->config(P0 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P1 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P2 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P3 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P4 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P5 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P6 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P7 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P8 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P9 , PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P10, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P11, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P12, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P13, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P14, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P15, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P16, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P17, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P18, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .Gpio->config(P19, PRUIO_GPIO_OUT0) THEN ErrControl.Errer = 1
      IF .config() THEN ?"config failed (" & *.Errr & ")" : End

      IF .Gpio->config(P24, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P25, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P26, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P27, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P28, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P29, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P30, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .Gpio->config(P31, PRUIO_GPIO_IN_1) THEN ErrControl.Errer = 1
      IF .config() THEN ?"config failed (" & *.Errr & ")" : End
   End With
   BBBInit.InitOK = 1
End Sub
Sub BBBController
    ''----------------------------------------------------------------------
    ''Called from TaskScan
    ''This routine does all comms to BBB
    ''All Inputs are Read and Outputs are set.
    ''First Set Output Bits , then Read I/O bits
    ''-----------------------------------------------------------------------
    Dim as Integer PinValue,Xq
    BBBTimer.mSec = (Timer - BBBTimer.CalTime) * 1000
    With BBBControl
        .Handle = BBBInit.Handle
        Select Case .StepNbr
            Case -1
                If BBBInit.InitOK > 0 Then
                    .StepNbr = 1
                EndIf
            Case 0
                .StepNbr = -1
            Case 1
                .OPValue = 0
                With io
                    ''---------WRITE OUTPUT BITS----------
                    .Gpio->SetValue(P0, IOCtrl.PortBit(0))
                    .Gpio->SetValue(P1, IOCtrl.PortBit(1))
                    .Gpio->SetValue(P2, IOCtrl.PortBit(2))
                    .Gpio->SetValue(P3, IOCtrl.PortBit(3))
                    .Gpio->SetValue(P4, IOCtrl.PortBit(4))
                    .Gpio->SetValue(P5, IOCtrl.PortBit(5))
                    .Gpio->SetValue(P6, IOCtrl.PortBit(6))
                    .Gpio->SetValue(P7, IOCtrl.PortBit(7))
                    .Gpio->SetValue(P8, IOCtrl.PortBit(8))
                    .Gpio->SetValue(P9, IOCtrl.PortBit(9))
                    .Gpio->SetValue(P10,IOCtrl.PortBit(10))
                    .Gpio->SetValue(P11,IOCtrl.PortBit(11))
                    .Gpio->SetValue(P12,IOCtrl.PortBit(12))
                    .Gpio->SetValue(P13,IOCtrl.PortBit(13))
                    .Gpio->SetValue(P14,IOCtrl.PortBit(14))
                    .Gpio->SetValue(P15,IOCtrl.PortBit(15))
                    .Gpio->SetValue(P16,IOCtrl.PortBit(16))
                    .Gpio->SetValue(P17,IOCtrl.PortBit(17))
                    .Gpio->SetValue(P18,IOCtrl.PortBit(18))
                    .Gpio->SetValue(P19,IOCtrl.PortBit(19))
                End With
                .StepNbr = 2
            Case 2    ''Ask for Inputs
                'Read Raw registers and assign to I/P Pin numbers and invert them so 1 = I/P'
                With io
                    PinValue = .Gpio->Raw(0)->Mix
                    If Bit(PinValue,2)  Then IOCtrl.PortBit(29) = 0 Else IOCtrl.PortBit(29) = 1
                    If Bit(PinValue,30) Then IOCtrl.PortBit(27) = 0 Else IOCtrl.PortBit(27) = 1
                    '---------------------------------------'
                    PinValue = .Gpio->Raw(1)->Mix
                    If Bit(PinValue,12) Then IOCtrl.PortBit(25) = 0 Else IOCtrl.PortBit(25) = 1
                    If Bit(PinValue,13) Then IOCtrl.PortBit(24) = 0 Else IOCtrl.PortBit(24) = 1
                    If Bit(PinValue,16) Then IOCtrl.PortBit(28) = 0 Else IOCtrl.PortBit(28) = 1
                    If Bit(PinValue,29) Then IOCtrl.PortBit(26) = 0 Else IOCtrl.PortBit(26) = 1
                    '----------------------------------------'
                    PinValue = .Gpio->Raw(3)->Mix
                    If Bit(PinValue,16) Then IOCtrl.PortBit(31) = 0 Else IOCtrl.PortBit(31) = 1
                    If Bit(PinValue,19) Then IOCtrl.PortBit(30) = 0 Else IOCtrl.PortBit(30) = 1
                    '-----------------------------------------'
                    IOCtrl.HeartBeat = .Gpio->Value(21)
                End With
                .StepNbr = -1
        End Select
    End With
End Sub
I have to improve error handling as well.
EDIT: Turning 20 O/P's ON takes 9 micro Sec's
Improving the code has taken the Loop time down to 20 micro Sec's.
REgards
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: libpruio (BB D/A - I/O fast and easy)

Post by TJF »

Dinosaur wrote:You have done well.
Thanks for the feedback!
Dinosaur wrote:I have tested by turning all 20 outputs On, and in one sequence shut them all down at once.
Whilst running with my current setup, the loop time is about 35 micro Sec.(I have removed all usb coms)
During the period of shutting 20 outputs Off, it goes to about 65.
You could set all outputs at one GPIO-SS by a single operation, as discussed above.
Dinosaur wrote:The Graphics controller must be fairly slow on the BBB, as usually I refresh the gui screen every 100mSec.
This makes the operations look smoother, but with the BBB I have to do it about every 500 mSec, otherwise
the loop time goes up to much.
There's a SGX530 graphics controller on the ARM CPU, but no driver jet (the manufacturer doesn't privde his sources). So currently all graphics are computed by the main CPU. But in last days a user closed this gap. His drivers should be available soon as main stream packages. Find details here and here. The Wayland driver should work with GDK/GTK (untested).
Dinosaur wrote:Below the code so far (except the .bi file)
Again, you're starting the main loop twice. Drop the first

Code: Select all

IF .config() THEN ?"config failed (" & *.Errr & ")" : End
Dinosaur wrote:I have to improve error handling as well.
Sure. You're loosing all information on which error occurs where. And perhaps you should stop in case of an error?

Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

Powered up the new BBB and had errors running examples. (Memory Error)
So figured I need to erase the on board mmcblk1 as a first step.

Made the mistake of doing
sudo dd if=/dev/zero bs=512 count=1024 of=/dev/mmcblk0
and wiped my disk.
OK, a few hours lost, no big deal.

Did
sudo dd if=/dev/zero bs=512 count=1024 of=/dev/mmcblk1
and tried to reboot onto a backup uSD.

The only light that comes on is the 5vdc power nothing else.
Pressing power button for 8 sec's will turn that light off, then pressing it briefly
will bring it back on, but no disk activity.

Is there a button combination trick to overcome this, or do I have dud ?

Regards
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: libpruio (BB D/A - I/O fast and easy)

Post by TJF »

Dinosaur wrote:... and tried to reboot onto a backup uSD.

The only light that comes on is the 5vdc power nothing else.
It seems that the backup wasn't made by dd command (you just copied the files). In this case the kernel boot loader doesn't find a bootable partition (neither eMMC nor uSD).

Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

Since the update I am having the following error even on running SOS.
Malloc(): Memory corruption: 0x1685f68

This only happens when using your examples as you wrote them
If I convert them to

Code: Select all

Dim Shared io as PruIo
With io
End With
Then no errors, as with my GUI application, it all runs very well.

Regards
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: libpruio (BB D/A - I/O fast and easy)

Post by TJF »

Dinosaur wrote:Since the update I am having the following error even on running SOS.
Malloc(): Memory corruption: 0x1685f68
This sounds like header miss-match. You updated the binary (package libpruio). Did you also update the header files (packages libpruio-dev and libpruio-bas)?

Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

Only did what you suggested.
sudo apt update
sudo apt --only-upgrade install libpruio*
Regards
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: libpruio (BB D/A - I/O fast and easy)

Post by TJF »

Dinosaur wrote:Only did what you suggested.
I may be wrong some times. The output of dpkg -l libpruio* may help.

Regards
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

libpruio = Version 0.6.4b
all the others are 0.6.4a

Regards
Edit: Reinstalling the -dev & -bas & -doc solved the problem.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Re: libpruio (BB D/A - I/O fast and easy)

Post by Dinosaur »

Hi TJF

Do you have any Timer examples where you use it to stop/start an event.
The normal FB Timer call is just not cutting it on the BBB.
Obviously in the code below I am calling the Timer far to often, but I am getting variations of 400 uSec.

Code: Select all

#INCLUDE ONCE "BBB/pruio.bi"
#INCLUDE ONCE "BBB/pruio_pins.bi"
Type Timing
    CalTime     As  Double
    uSec        AS  UInteger
    StartTime   As  UInteger
    Elapsed     As  UInteger
End TYPE
Common Shared Times As Timing
Dim Shared io as PruIo
    Times.CalTime = Timer
    WITH io
        IF .Errr THEN Goto Err_End
        IF .config(1, 0) THEN Goto Err_End
        .Pwm->setValue(P9_14, 500, .5)
        Times.StartTime = (Timer - Times.CalTime) * 1000000
        Times.uSec = Times.StartTime
        '-------------------------------------------------------------'
        DO
            Times.uSec = (Timer - Times.CalTime) * 1000000
            If Times.uSec - Times.StartTime >= 1000 Then
                .Pwm->setValue(P9_14, 0, 0.0)
                Exit Do
            EndIf
            If Inkey <> "" Then Exit Do
        LOOP
        Print "StartTime = "; Times.StartTime
        Print "End Time  = "; Times.uSec
        Print "Elapsed   = "; Times.uSec - Times.StartTime
        '-------------------------------------------------------------'
    END WITH
    End
Err_End:
    Print "Error End"
    End
I tried reading the TI manual, but my eyes glaze over after the first page.
It is not exactly written to quickly draw examples from. That would have made your library creation
all the more remarkable.

Regards
EDIT: The other option is to use the rb_file concept, but having difficulty understanding that.
So basically I want to start the pwm and check for an elapsed time which then updates .DRAM[0] to allow me to stop the pwm.

EDIT2: Some confusion over Timer values.
Parameter Dur1 specifies the time period of the starting state in seconds. Parameter Dur2 specifies the time period of the state change (= pulse) in seconds.
Dur1 The total period duration in [ms] (or 0 to stop timer).
Dur2 The duration in [ms] for the state change (or 0 for minimal duration)
In either case I cannot get better then a negative pulse at about 0.02 mSec with the below code.

Code: Select all

Dim Shared io as PruIo
    WITH io
        IF .Errr THEN Goto Err_End
        IF .config(1, 0) THEN Goto Err_End
        .Tim->setValue(P8_07, 0, 20,0)
    END WITH
    End
Err_End:
    Print "Error End"
    End
 
So whether it is mSec or Sec I translate the description as meaning that if Dur1 = 0 and Dur2 = n , then it will produce 1 pulse at (n) duration.
Post Reply