zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.19k stars 6.25k forks source link

Add DALI driver to communicate with DALI equipment #71544

Open ChristianHirsch opened 3 months ago

ChristianHirsch commented 3 months ago

Implement the Digital Addressable Lighting Interface (DALI) to make DALI devices accessible with Zephyr.

DALI(-2) is used as a lighting communication bus, particularly in building lighting applications, and is specified in the IEC 62386 standard.

Motivation for or Use Case

Use Zephyr as a Control Device (sending and receiving control commands) or Control Gear (receiving control commands) within a DALI installation.

Design Details

Implement the DALI bus protocol, which is based on Manchester encoding, as a software-based GPIO bit-banging driver (similar to the I2C bit-banging driver). The driver only handles the reception and transmission of data on the DALI bus. The logic, whether it is a control gear or a control device, must be implemented in the application. Later a control device and a control gear can be added as a subsystem, similar to the Modbus client and server.

Alternatives

Add the software-based bit-banging DALI bus transceiver to the subsys section.

Test Strategy

Implement a simple example of a control device that switches a DALI LED driver on and off. Note that specific hardware is required for communication, e.g. schematics in Figure 14 at https://www.mouser.com/applications/lighting-digitally-addressable/.

Additional context I already implemented a working solution, see https://github.com/ChristianHirsch/zephyr/tree/dali_driver with a working sample. It, however, misses documentation, which will be added soon.

henrikbrixandersen commented 3 months ago

I already implemented a working solution, see https://github.com/ChristianHirsch/zephyr/tree/dali_driver with a working sample. It, however, misses documentation, which will be added soon.

Sounds great! Do you intend to submit this upstream once done? If yes, may I ask what is the purpose of this enhancement issue?

ChristianHirsch commented 3 months ago

Do you intend to submit this upstream once done?

Yes, of course.

If yes, may I ask what is the purpose of this enhancement issue?

Well, one point is that the Contribution Guidelines told me to do this, and I couldn't find out if this was still considered a small feature where a pull request would suffice. The other thing is this: I don't know if the drivers section is really the right place to put this, or if it would be better to move it somewhere else (e.g. subsys) and that's what I'd like to discuss. But if you prefer, we can close this and move the discussion also to a PR?

ChristianHirsch commented 2 months ago

@henrikbrixandersen Can I ask you who is responsible for that and how to proceed?

henrikbrixandersen commented 2 months ago

@henrikbrixandersen Can I ask you who is responsible for that and how to proceed?

Sorry, not sure what you are asking here?

pdgendt commented 2 months ago

@henrikbrixandersen Can I ask you who is responsible for that and how to proceed?

Anyone can create PRs, it's fine to have drivers/subsys/test/sample/... code in the same PR, just make sure to have separate commits for different changes. A new feature typically has:

I don't know if the drivers section is really the right place to put this, or if it would be better to move it somewhere else (e.g. subsys) and that's what I'd like to discuss.

drivers is where you want to put code that interacts with peripherals, maybe split the manchester encoding/decoding using a bus to allow re-using that?

ChristianHirsch commented 2 months ago

Sorry, not sure what you are asking here?

Sorry, @henrikbrixandersen for the confusion! Just wanted to know who will be responsible for discussing (and merging) this feature to finish the work.

henrikbrixandersen commented 2 months ago

Sorry, @henrikbrixandersen for the confusion! Just wanted to know who will be responsible for discussing (and merging) this feature to finish the work.

I'd suggest reading up on https://docs.zephyrproject.org/latest/contribute/index.html if not already read.

de-nordic commented 2 months ago

IMHO, bit-banging implementation of Manchester should not be considered part of DALI, it is general communication channel encoding (physical layer) that may be useful for other subsystems and purposes. I think it should be considered to be at the same level as SPI or I2C encoding, whether implemented with bit-banging or not.

ChristianHirsch commented 2 months ago

Thanks for the answers!

Well, I like the ideas of extracting the Manchester encoding and creating a driver with that. What about the following:

Manchester utility function A function that en- or decodes a uint8_t into a Manchester code uint16_t (consisting of "half"-bits) and which is placed in the utils section (e.g., lib/utils/manchester.c):

uint16_t manchester_encode(uint8_t data);
uint8_t manchester_decode(uint16_t data);

Manchester communication driver This is the driver which can be used to communicate with other devices using Manchester and resides in the drivers section and will for now be implemented with bit-banging.

DALI subsystem The DALI specific code uses the Manchester driver to communicate with DALI devices and will be placed in the subsys section.

Considerations Some microcontrollers have a DALI / Manchester communication interface already implemented in hardware (e.g., the TI MSPM0L130x series). Is there something that needs to be considered with the above-mentioned suggestion?

henrikbrixandersen commented 2 months ago

Manchester utility function

A function that en- or decodes a uint8_t into a Manchester code uint16_t (consisting of "half"-bits) and which is placed in the utils section (e.g., lib/utils/manchester.c):


uint16_t manchester_encode(uint8_t data);

uint8_t manchester_decode(uint16_t data);

Where do you foresee these utility functions to be used? Solely in the Manchester communication driver? Or other places as well?

Manchester communication driver

This is the driver which can be used to communicate with other devices using Manchester and resides in the drivers section and will for now be implemented with bit-banging.

Sounds reasonable.

DALI subsystem

The DALI specific code uses the Manchester driver to communicate with DALI devices and will be placed in the subsys section.

Sounds reasonable.

Considerations

Some microcontrollers have a DALI / Manchester communication interface already implemented in hardware (e.g., the TI MSPM0L130x series). Is there something that needs to be considered with the above-mentioned suggestion?

Are these types of peripherals typically tied to DALI or more low-level Manchester encoding communication devices?

If they are tied to DALI, the architecture described above will be hard to fit to these.

ChristianHirsch commented 2 months ago

Manchester utility function A function that en- or decodes a uint8_t into a Manchester code uint16_t (consisting of "half"-bits) and which is placed in the utils section (e.g., lib/utils/manchester.c):


uint16_t manchester_encode(uint8_t data);

uint8_t manchester_decode(uint16_t data);

Where do you foresee these utility functions to be used? Solely in the Manchester communication driver? Or other places as well?

Good question. I will only use it in the communication driver. IDK if there is the need to also use it somewhere else. TBH, I can't think of any other good use case right now.

Considerations Some microcontrollers have a DALI / Manchester communication interface already implemented in hardware (e.g., the TI MSPM0L130x series). Is there something that needs to be considered with the above-mentioned suggestion?

Are these types of peripherals typically tied to DALI or more low-level Manchester encoding communication devices?

If they are tied to DALI, the architecture described above will be hard to fit to these.

Well, I think it depends on the hardware. From the ones I've seen (but I did not use them) it seems that they can configure the UART in a way that the UART does all the physical handling (setting the BAUD, being able to send more bytes than traditional UART and also does the Manchester encoding). All the DALI specific code needs to be implemented by the user / software. I.e., I see them more tied to the low-level encoded communication.

henrikbrixandersen commented 2 months ago

Good question. I will only use it in the communication driver. IDK if there is the need to also use it somewhere else. TBH, I can't think of any other good use case right now.

Another option could be to have them as utility function in the include/zephyr/drivers/manchester.h driver header. It is fine for a driver subsystem to provide utility functions, if those are tightly related to that subsystem.

Well, I think it depends on the hardware. From the ones I've seen (but I did not use them) it seems that they can configure the UART in a way that the UART does all the physical handling (setting the BAUD, being able to send more bytes than traditional UART and also does the Manchester encoding). All the DALI specific code needs to be implemented by the user / software. I.e., I see them more tied to the low-level encoded communication.

In that case, I think your proposed architecture sounds sane.

A driver for the aforementioned devices can probably be made to fit into the Manchester communication driver API later on, but I would advice at least surveying those device types and their design before designing the driver API in order not to end up with a "bit-banging" centric API. There may also be some terminology to be picked up from the documentation of these devices, that can be used in the design and documentation of the driver API.

de-nordic commented 2 months ago

A driver for the aforementioned devices can probably be made to fit into the Manchester communication driver API later on, but I would advice at least surveying those device types and their design before designing the driver API in order not to end up with a "bit-banging" centric API. There may also be some terminology to be picked up from the documentation of these devices, that can be used in the design and documentation of the driver API.

This is really worth taking into account.

de-nordic commented 2 months ago

Good question. I will only use it in the communication driver. IDK if there is the need to also use it somewhere else. TBH, I can't think of any other good use case right now.

In the past I was working on DALI devices and had the light ballast devices built using bit-banging on Microchip 8bit MCUs. To test those I have built UART<->Manchester encoding device with voltage level shifter to get 18V (to fit into that hi-level 22V of DALI); the control device did not understood DALI at all, it was just converting whatever it got on UART to/from Manchester and was used with PC for testing the DALI net.

Having separate NRZ encoding allows you to not only communicate with DALI, but also use it to connect between two devices, running Zephyr, and communicate using that method.

henrikbrixandersen commented 2 months ago

Having separate NRZ encoding allows you to not only communicate with DALI, but also use it to connect between two devices, running Zephyr, and communicate using that method.

Right, but wouldn't this happen through the Manchester communication driver?

de-nordic commented 2 months ago

Having separate NRZ encoding allows you to not only communicate with DALI, but also use it to connect between two devices, running Zephyr, and communicate using that method.

Right, but wouldn't this happen through the Manchester communication driver?

Yes. What I mean that once you have the comm driver (the manchester), you can use it for whatever you want; you can put DALI on top of it or just send some user defined frame.