DigitalChannelManager.h
1 /*
2  * DigitalStream.h
3  *
4  * Created on: 7 Jun 2016
5  * Author: giulio
6  */
7 
8 #ifndef DIGITALCHANNELMANAGER_H_
9 #define DIGITALCHANNELMANAGER_H_
10 #include <Bela.h>
11 
35 public:
37 
50  void setCallback(void (*newCallback)(bool, unsigned int, void*)){
51  stateChangedCallback = newCallback;
52  if(newCallback != NULL){
53  callbackEnabled = true;
54  } else {
55  callbackEnabled = false;
56  }
57  };
58 
68  void setCallbackArgument(unsigned int channel, void* arg){
69  callbackArguments[channel] = arg;
70  }
71 
82  void processInput(uint32_t* array, unsigned int length){
83  if(callbackEnabled == false){
84  return;
85  }
86  // DIGITAL_FORMAT_ASSUMPTION
87  static uint16_t lastDigitalInputValues = 0;
88  for (unsigned int frame = 0; frame < length; ++frame) {
89  uint32_t inWord = array[frame];
90  uint16_t direction = inWord & 0Xffff;
91  uint16_t inputValues = (inWord >> 16);
92  // note: even though INPUT == 0 and OUTPUT == 0, this is actually reversed in the binary word,
93  // so it actually is 1 for input and 0 for output
94 
95  // mask out outputValues from the half-word by setting them to zero
96  // if a bit of direction is 1, then it is an input.
97  // ANDing this with the inputValues gets rid of the output values
98  inputValues &= direction;
99  uint16_t changed = inputValues ^ lastDigitalInputValues;
100  //mask out channels that are not set at message rate
101  changed &= messageRate;
102  if(changed){
103 // rt_printf("changed: 0x%x, messageRate: 0x%x, ANDed: 0x%x\n", changed, messageRate, changed&messageRate);
104  for(int n = 0; n < 16; ++n){
105  if(changed & (1 << n)){ //if state for this channel has changed, invoke the callback
106  stateChangedCallback(inputValues & (1 << n), frame, callbackArguments[n]);
107  }
108  }
109  }
110  lastDigitalInputValues = inputValues;
111  }
112  }
113 
126  void processOutput(uint32_t* array, unsigned int length){
127  uint32_t orWord = ((setDataOut << 16) | modeInput);
128  uint32_t andWord = ~((clearDataOut << 16) | modeOutput);
129  uint32_t outWord;
130  for (unsigned int frame = 0; frame < length; ++frame) {
131  outWord = array[frame];
132  outWord = outWord | orWord;
133  outWord = outWord & andWord;
134  array[frame] = outWord;
135  }
136  }
137 
143  bool isSignalRate(unsigned int channel){
144  return (bool)((1 << channel) & signalRate);
145  }
146 
153  bool isMessageRate(unsigned int channel){
154  return (bool)((1 << channel) & messageRate);
155  }
156 
163  bool isInput(unsigned int channel){
164  return (bool)((1 << channel) & modeInput);
165  }
166 
173  bool isOutput(unsigned int channel){
174  return (bool)((1 << channel) & modeOutput);
175  }
176 
183  void setValue(unsigned int channel, bool value){
184  if(value == 0){
185  clearDataOut = setBit(clearDataOut, channel);
186  setDataOut = clearBit(setDataOut, channel);
187  } else {
188  setDataOut = setBit(setDataOut, channel);
189  clearDataOut = clearBit(clearDataOut, channel);
190  }
191  }
192 
198  void unmanage(unsigned int channel){
199  messageRate = clearBit(messageRate, channel);
200  signalRate = clearBit(signalRate, channel);
201  modeInput = clearBit(modeInput, channel);
202  modeOutput = clearBit(modeOutput, channel);
203  clearDataOut = clearBit(clearDataOut, channel);
204  setDataOut = clearBit(setDataOut, channel);
205  }
206 
217  void manage(unsigned int channel, bool direction, bool isMessageRate){
218  // direction is expected to be one of INPUT or OUTPUT
219  messageRate = changeBit(messageRate, channel, isMessageRate);
220  signalRate = changeBit(signalRate, channel, !isMessageRate);
221  if(direction == OUTPUT){
222  modeOutput = setBit(modeOutput, channel);
223  modeInput = clearBit(modeInput, channel);
224  } else { // direction == INPUT
225  modeInput = setBit(modeInput, channel);
226  modeOutput = clearBit(modeOutput, channel);
227  }
228  rt_printf("Bela digital: channel %d is set as %s at %s rate\n", channel,
229  isInput(channel) ? "input" : "output", isSignalRate(channel) ? "signal" : "message");
230  }
231 
232  virtual ~DigitalChannelManager();
233 private:
234  bool callbackEnabled;
235  void* callbackArguments[16];
236  void (*stateChangedCallback)(bool value, unsigned int delay, void* arg);
237  uint32_t clearDataOut;
238  uint32_t setDataOut;
239  uint16_t modeOutput;
240  uint16_t modeInput;
241  uint16_t messageRate;
242  uint16_t signalRate;
243 };
244 
245 #endif /* DIGITALCHANNELMANAGER_H_ */
void processOutput(uint32_t *array, unsigned int length)
Definition: DigitalChannelManager.h:126
Definition: DigitalChannelManager.h:34
bool isMessageRate(unsigned int channel)
Definition: DigitalChannelManager.h:153
bool isOutput(unsigned int channel)
Definition: DigitalChannelManager.h:173
bool isSignalRate(unsigned int channel)
Definition: DigitalChannelManager.h:143
bool isInput(unsigned int channel)
Definition: DigitalChannelManager.h:163
void setValue(unsigned int channel, bool value)
Definition: DigitalChannelManager.h:183
void manage(unsigned int channel, bool direction, bool isMessageRate)
Definition: DigitalChannelManager.h:217
void unmanage(unsigned int channel)
Definition: DigitalChannelManager.h:198
void processInput(uint32_t *array, unsigned int length)
Definition: DigitalChannelManager.h:82
Main Bela public API.
void setCallbackArgument(unsigned int channel, void *arg)
Definition: DigitalChannelManager.h:68
void setCallback(void(*newCallback)(bool, unsigned int, void *))
Definition: DigitalChannelManager.h:50