On 2/26/2019 7:24 AM, Damien.D wrote:
> Le lundi 25 février 2019 17:46:06 UTC+1, Charles Steinkuehler a écrit :
>>
>> Personally I don't really want to see hal_pru_generic code reading
>> from the fabric, it eats up too much time.  I'd rather see "slow" code
>> like this running on the other PRU, leaving the hal_pru_generic code
>> as-is.

Actually, implementing this as a "tasklet" would be fine, more below.

>> That said, you're free to do what you want.  If I was going to write
>> something like this, I'd probably create a "GPIO read" tasklet that
>> reads the input pins from the gpio bank(s) and stashes the data either
>> in the register bank or in one of the scratchpad banks.  Then you can
>> have other tasklets that process GPIO input pin data as needed.
>>
> That last suggestion seems like a good idea to me. I will look in that
> direction. Was it the intended purpose of the pru_read.p
> <https://github.com/machinekit/machinekit/blob/master/src/hal/drivers/hal_pru_generic/pru_read.p#L4-L6>
>  file?

Not really.  The read and write functions were intended to be similar
to the hm2 functions used when communicating with slow or remote
hardware (eg: EPP or Ethernet).  I had intended to make a proper
communication protocol between the PRU and the ARM to avoid issues
when reading multiple values, but wound up being lazy and using the
same hack as the software stepgen to do "atomic" reads:

https://github.com/cdsteinkuehler/machine-configs/blob/master/configs/CoreXZ/CoreXZ.hal#L168-L173

Ideally, the PRU should copy the required state details at the end of
a servo period and then interrupt the ARM.  With the PRU driving the
servo thread timing the motion calculations are all more accurate and
the PRU state read by the ARM will be completely consistent to a
single point in time (currently it's possible the PRU executes a few
cycles while the ARM is reading/processing the data on the servo
thread).  But I haven't had the time or inclination to get this coded
up and working.

Feel free to re-purpose the pru_read.p function shell or create a new one.

>> ...but really I think you'd be best off just using a PRU direct input
>> pin.  IIRC you said you're using a CRAMPS board.  If so, several of
>> the SPI signals function as direct PRU inputs and are already tied to
>> a connector via a FET bus level translator so they are bidirectional
>> and 5V tolerant:
>>
>> P9.28 SPI_CS0
>> P9.29 MISO
>> P9.30 MOSI
>> P9.31 SCK
>>
>> P503 on the CRAMPS board.
>>
> I'm not using a CRAMPS board, this does not fit my need. I made my own
> board (with opto-isolated "satellite" boards):
> https://youtu.be/bn6DsqG35MU?t=58
> 
> PRU direct inputs are indeed easy to use from software point of view.
> However from a practical point of view, in a real scale project it's
> another story.. In my case, with all hardware I have connected to the BBB,
> I don't have so much choice regarding the pinout/connections (which I have
> already been thinking&reflecting quite a lot when doing the electronic
> design). 35 IOs seems quite a lot at first but in my project they are
> already all used, and many have specific need that cannot be exchanged with
> others (encoders, UARTs, SPI). I could possibly free up 2IOs at max (by
> grouping some enable signals) but that's all. And most of those PRU input
> are shared with the hardware encoder which I'm using, and same thing for
> the SPI0 pins :/
> 
> Performance wise, there is no gain of using PRU inputs (in my case) since I
> read a few millisecond signal. I use a PRU period of 5000ns of which at the
> moment 4000ns are spent in the wait loop so that's only ~1000ns of active
> time to run the all PRU period... thanks to your well optimized code :) !
> If I ever had need to go down to ~1000ns PRU period, I would be more
> concerned about hardware limitations than the software ones :)

I typically use PRU periods around 2-3 uS, so the GPIO read is a
bigger chunk of the timing budget.

If you make the GPIO reads and timer processing individual "tasklets",
I have no issue with merging them into master.  Given the way the PRU
code works, there isn't much down-side to having the tasklets
available: just a bit more PRU program memory consumed (we're no where
near the limit at the moment) and they won't slow down the PRU
processing if they aren't being used.

I would recommend making the read tasklet configurable so that it will
optionally read any/all of the GPIO banks.  I'd probably use the task
state registers for the GPIO values (R4-11) and have the read tasklet
stash the GPIO values in the scratchpad, similar to what I did with
the GPIO address values:

Stash the values in the scratchpad:
https://github.com/machinekit/machinekit/blob/master/src/hal/drivers/hal_pru_generic/pru_generic.p#L209-L211

Get the values from the scratchpad:
https://github.com/machinekit/machinekit/blob/master/src/hal/drivers/hal_pru_generic/pru_wait.p#L87

Sadly, the Decamux code is using state register 6, or you could use
registers 4-7 for the GPIO values.  But you can do an offset when
performing the XIN/XOUT (set SHIFT_EN in the SPP register), so you can
use any other chunk of 4 registers in the scratchpad (maybe R0-3?).

Note the XIN/XOUT instructions only take a single clock, so this only
adds 2 cycles to your GPIO code vs. consuming 4 registers all the time.

-- 
Charles Steinkuehler
char...@steinkuehler.net

-- 
website: http://www.machinekit.io blog: http://blog.machinekit.io github: 
https://github.com/machinekit
--- 
You received this message because you are subscribed to the Google Groups 
"Machinekit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to machinekit+unsubscr...@googlegroups.com.
Visit this group at https://groups.google.com/group/machinekit.
For more options, visit https://groups.google.com/d/optout.

Reply via email to