Question

I have been facing a task to develop a software driver in C++ for a chip which makes available 8 digital inputs over the SPI bus. In the time being I have been thinking about the interface of the driver. The idea which I have is

class DigitalInputsDriver
{
public:
  
  enum class Input
  {
    Di_00,
    Di_01,
    Di_02,
    Di_03,
    Di_04,
    Di_05,
    Di_06,
    Di_07
  };

  enum class State 
  { 
    Low, 
    High 
  };

  DigitalInputsDriver(Spi *spiDriver);

  void initialize(void);
  State readInput(Input input);

private:

  Spi *spiDriver;
  
}; 

So the fact that the digital inputs are on the SPI is hidden for the client's code. The problem which I have is how to implement the readInput method.

First idea which I had was to implement the readInput method as a blocking i.e. client's code stucks in this method until the SPI transaction for reading the digital inputs finishes. This idea seems to me not appropriate due to the blocking nature.

Second idea was to use the interrupt and callback function mechanism. This solution seems to me better from the software timing point of view but I don't know how to precisely implement it. Because in that case the readInput can't return state of the digital input due to the fact that its call only starts the SPI transaction for reading the digital inputs.

Another idea which I had was to add some public method (let's say refresh()) into the driver's interface. This method will be called periodically and will invoke SPI transaction for reading the digital inputs and based on them will fill some internal variable of the driver (copy of the remote registers in the chip). The readInput will access to the internal variable.

Does anybody think that some of my ideas is usable or does anybody know better solution? Thanks in advance for any suggestions.

Was it helpful?

Solution

Your third option of caching the input states and having a function to refresh them is both workable and it has the least chance to bite you in the back later. It also has the advantage that it allows you to read all 8 inputs in one SPI transaction.

Having the readInput function block while the SPI transaction runs has the problem that the timing becomes unpredictable and if you are unlucky, you create a deadlock because the code calling readInput is in the middle of a different SPI transaction.

Using a callback both makes the calling code more complex (because the result of readOInput isn't available until some unspecified time in the future) and opens you up to all kinds of concurrency problems.

Licensed under: CC-BY-SA with attribution
scroll top