Closed kripton closed 2 years ago
Code of method described above: https://github.com/jostlowe/Pico-DMX/compare/main...kripton:inputChannel512_try_A
I'd assume we might have the same problem with RDM responses: Depending on their length, we might currently not be able to get the last 1, 2 or 3 bytes.
Until now I haven't found a proper solution to that problem. Modifying the DMA to work with 8-bit-transfers (instead of 32 bit) didn't work for me since I only saw every 4th channel in my buffer then. ... Ideas are welcome :) Or a proper solution with DMA transfer size of 8, maybe?
Proper DMA_SIZE_8 has been implemented in #18. The problem why it was not working for me yesterday was that I needed to modify the PIO-program. I did that but the changes were not honored since the #include "DmxInput.pio.h"
-line always used the pre-compiled file in the src
-folder instead of the one generated on-the-fly from the .pio
-file I modified. Once I removed the pre-compiled .pio.h
, it was working for me. But since Android doesn't seem to be able to run pioasm
automatically during the build step, I re-added and updated the pre-compiled .pio.h
-file
Using
DmxInput::async_read
I'm not able to get the value of channel 512, it's always 0. Most probable cause after much debugging: The PIO pushes the channel values (byte-wise) from the input shift register to the state machine's RX FIFO. The DMA is configured to copy data from there to the user-provided buffer in 32-bit blocks. With the additional DMX start code, channel 511 ends such an 32-bit-block and the DMA copies over. Now when channel 512 is put into the RX FIFO, it won't trigger the DMA copy since the block will never be full. In this case, the DMA IRQ is not triggered as well right after the frame but only when the first bytes of the following frames came in (what I was and briefly mentioned in #13).Until now I haven't found a proper solution to that problem. Modifying the DMA to work with 8-bit-transfers (instead of 32 bit) didn't work for me since I only saw every 4th channel in my buffer then.
The best I could do was:
async_read
, ifnum_channels
is 512, request one transfer less than calculated so we get the IRQ fired after channel 511 came innum_channels
is 512. If so,busy_wait
40µs so we are sure that channel 512 has reached the state machine. Then, make the state machine execute aPULL
instruction (not sure why I needed to do so but otherwise the FIFO was empty?)However, that doesn't read channel 512 reliably, it just gives more or less random values :(
Ideas are welcome :) Or a proper solution with DMA transfer size of 8, maybe?