laith-dosinfection / lwIOlinkMaster

This repository is a work in progress with the intent to create a IO-link master stack which can extract data from IO-link Devices
GNU General Public License v3.0
1 stars 0 forks source link

PHY abstraction in Master Class #7

Open unref-ptr opened 1 year ago

unref-ptr commented 1 year ago

I was checking the class IOLink::Master and was thinking about some suggestions that could help keep the software flexible and extensible in the future if a new driver is added.

Based on this characterization I can suggest something as follows

example implementation in C++

classDiagram
    class fault_e{
        <<enumeration>>
        OverCurrent
        OverTemp
    }
  class PhyDriver {
    - Fault_cb m_fault_cb
    - PLTransferInd_cb m_transferInd_cb
    - uint8_t m_total_ports
    - Hw_cfg_t m_hw_cfg
    # PhyDriver(hw_cfg: const Hw_cfg_t * ,port_count: uint8_t)
    + set_fault_cb(cb: Fault_cb): void
    + set_transferInd_cb(cb: PLTransferInd_cb): void
    + wakeup(port_no: uint8_t): bool
    + PLTransferReq(port_no: uint8_t, pBuf: uint8_t*, len: uint8_t): void
  }

  class Port {
    +Port(phy_driver:PhyDriver*,phy_port:uint8_t)
    -m_phyDriver: PhyDriver*
    -m_phy_port:const uint8_t
  }

  class Master {
    #Master(port_list:Port*)
    -m_port_list: Port*
  }

  class Fault_cb
  class PLTransferInd_cb

  PhyDriver --> fault_e
  PhyDriver --> Fault_cb
  PhyDriver --> PLTransferInd_cb

  Port --> PhyDriver
  Master --> Port
laith-dosinfection commented 1 year ago

The PHYS which report faults like over current and temp are those sent digitally? Could you send me a reference part number so I can research and consider ways of abstracting.

Another factor to consider around the ports and handling of the ports would be the other IC's involved in the port. There could be up to 3 ICs with enables, faults and possibly additional diagnostic data (a smart high side switch with current monitoring). A fully defined port would extend a few items: the PHY (TIOL112), a DI/DO chip (like the TIOS102x), and a high side switch (like the TPS27S100). Every IO-Link port becomes pin hungry quickly being able to implement GPIO expanders should be considered. Thanks for the detailed diagram and sample code.

unref-ptr commented 1 year ago

The PHYS which report faults like over current and temp are those sent digitally? Could you send me a reference part number so I can research and consider ways of abstracting.

Thanks for the detailed diagram and sample code.

No problem! I think diagrams always help and the PHY architecture should be clearly defined as to not have headaches when the code grows.

unref-ptr commented 1 year ago

Another factor to consider around the ports and handling of the ports would be the other IC's involved in the port.

I see. I havent compared all the PHYs in respect to high-side switching and current monitor. For example I think the LTC2874 includes a current monitor. This means that some PHYs may or may not have these functions included in the IC.

In this case I think that these port functions (are there more?) should be part of the IOLink::Port class and if the functionality is available by the PHY IC then it should call the phy driver if not a secondary driver for the High side functionality or current monitor should be called. Then the port could have an optional constructor parameter to indicate a High Side driver IC or a current monitor driver.

Example code

So my suggestion is dependency injection, and a sort of strategy design pattern.

Note: that the driver interface for high side switch and current monitor are improvised and just to show the idea of how to call other drivers in case they are not available in the phy.

classDiagram

class PhyResult_e{
    sucess,
    hw_fail,
    incorrect_mode,
    not_available
}

class CurrentDriver{
    -getCurrent(val:float *) bool
}

class HighSideDriver{
    -SetDO(val:float *) bool
}

class PhyDriver{
    -SetDO(val:bool) PhyResult_e
}

class Port {
    -m_phy_driver:PhyDriver
    -m_current_driver:CurrentDriver
    -m_highside_driver:HighSideDriver
    +Port(phy_driver:PhyDriver, highside_driver:HighSideDriver, current_driver:CurrentDriver)
    -getCurrent(val:float *) bool
    -setDO(val:bool) bool
}

PhyDriver --> PhyResult_e
Port --> PhyDriver
Port --> CurrentDriver
Port --> HighSideDriver