Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DmxInput: start_channel is not honored #15

Open
kripton opened this issue Dec 14, 2021 · 15 comments
Open

DmxInput: start_channel is not honored #15

kripton opened this issue Dec 14, 2021 · 15 comments

Comments

@kripton
Copy link
Contributor

kripton commented Dec 14, 2021

DmxInput::begin has a parameter called start_channel. It's meant to ignore the first X channels and only read input values from that value on.
However, the value is not actually used as expected. It is however (incorrectly) used to calculate the buffer size here:

DMXINPUT_BUFFER_SIZE(_start_channel, _num_channels)/4, // transfer count,

I wouldn't know a proper solution to tell the PIO state machine OR the DMA to ignore the first X bytes. Of course, we could let the DMX write into an intermediary buffer and then copy only the requested channels to the buffer provided by the library user. But in the worst case, that would mean copying 511 byte in an IRQ handler. Not what I would call ideal.

As such I would propose to remove the start_channel functionality

@kripton
Copy link
Contributor Author

kripton commented Dec 15, 2021

It looks like the start_channel feature was in and working (only when using read) before #8, but was removed when read was re-written to use read_async to do its job:
https://github.com/jostlowe/Pico-DMX/pull/8/files#diff-42a9a8ae12afd6562fa620becac01e3c263d29fd4cbcd832a35abbca6cd76fa6L84

@Gavin-Perry
Copy link

Gavin-Perry commented Mar 24, 2022

I can't get DMX channel one to be read properly from my Chauvet Light board.
IF I use DMXOutput and DMXInput then it works "right?". Or are both off by one?
How is start byte (normally 0) handled? Does the returned buffer put channel 1 at index 0 or 1?
I think it would be clear if the entire DMX packet were read in including the Start byte so that channel 1 is indexed as [1]
This would let one use RDM as well as avoiding confusion between index of array and channel number.

Is the problem here?
in .cpp we have &_pio->rxf[_sm], // src
DMXINPUT_BUFFER_SIZE(_start_channel, _num_channels), // transfer count,
(is it src, dest, count?)
the .h file defines
#define DMXINPUT_BUFFER_SIZE (start_channel, num_channels) (num_channels+1)
in the version I have, though it is different in the one referenced by kripton in the previous comment
#define DMXINPUT_BUFFER_SIZE(start_channel, num_channels) ((start_channel+num_channels+1)+((4-(start_channel+num_channels+1)%4)%4))
Presumably this was before the 32 bit transfer not doing 513 bytes issue was resolved by doing 8 bit transfers

@kripton
Copy link
Contributor Author

kripton commented Mar 27, 2022

How is start byte (normally 0) handled? Does the returned buffer put channel 1 at index 0 or 1? I think it would be clear if the entire DMX packet were read in including the Start byte so that channel 1 is indexed as [1] This would let one use RDM as well as avoiding confusion between index of array and channel number.

I didn't try it out lately but according to the Readme any my memory, the 0th byte in the buffer is the start code, the byte indexed 1 is the value of the 1st channel in the universe

@Gavin-Perry
Copy link

Gavin-Perry commented Apr 3, 2022 via email

@kripton
Copy link
Contributor Author

kripton commented Apr 16, 2022

If it's not working right (= as expected), I would assume that the DMX sender sends "short frames" with fewer than 513 slots.This is perfectly fine according to the standard but the library currently cannot cope with it.
As you said, it would be helpful to have an IRQ on BREAK or MAB but it'S currently just not implemented.

@Gavin-Perry
Copy link

Gavin-Perry commented Apr 17, 2022 via email

@queekusme
Copy link

@Gavin-Perry i've used 26-28 on my Pi Pico (non arduino) without any issues so I presume that the issues you're referencing are arduino specific

I haven't tried the ADC specifically however if adc_init is called from somewhere in the arduino source it may block the default GPIO functions... I had this issue with I2C

I can't confirm this just yet as I'm currently afk for a few days but suspect it may be the case

I also don't have an arduino pico setup so can't confirm that way however from what I do know, this is most likely the reason...

@Gavin-Perry
Copy link

Thanks for the idea. I don't use adc_init, and I explicitly did call gpio_set_dir(i,GPIO_OUT) and then gpio_pull {up or down}
The pull worked for setting my defaults.
I'd call gpio_set_function() but the choices don't include simple gpio input as far as I can tell.
All the fancy uses are documented, not the simplest which should be (and claimed to be) default.

@queekusme
Copy link

@Gavin-Perry you shouldn't need to set the function,

The enum is defined here (https://raspberrypi.github.io/pico-sdk-doxygen/group__hardware__gpio.html) as gpio_function,

If you're just reading digital inputs then you can ignore function, that's for connecting the hardware spi/i2c/pwm modules to the pins, heck you shouldn't even need to call that for adc, as that's handled by adc_init

@Gavin-Perry
Copy link

I now realize that now. Just flailing at options to figure out the problem with digital input which should be the default. And learning some of the cool things that this baby can do.

@Gavin-Perry
Copy link

Gavin-Perry commented Apr 21, 2022 via email

@MarcusGarfunkel
Copy link

I'd like to mention that this issue is affecting my use of this library.

@jostlowe
Copy link
Owner

I'm a bit short on time these days! @kripton would it be possible for you to author a pull request to remove/fix the feature?

@kripton
Copy link
Contributor Author

kripton commented Oct 13, 2022

Unfortunately, I currently also don't have much spare time to donate to this project. So please don't expect a PR for this, soon.

However, I don't see why this is a big blocker: As long as there are "full packets" = start code + 512 channels on the wire, the reception should be fine. Yes, you will need to provide a 513 byte large buffer, receive the complete packet and then use only the parts you are interested in. In the worst case, it's a 512 byte large memcpy/memmove operation.

@MarcusGarfunkel: Any point I missed? Is that workaround not working for you?

@MarcusGarfunkel
Copy link

@kripton, @jostlowe Hi, thanks for the response. The work around is fine, I just believe most people assume the behavior to work as expected, and it results in unexpected behavior. I appreciate the effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants