annotate include/Utilities.h @ 269:ac8eb07afcf5

Oxygen text added to each render.cpp file for the default projects. Text includes project explanation from Wiki, edited in places. Empty project added as a default project. Doxyfile updated. Each of the project locations added to INPUT configuration option. Consider just watching the whole project file so all new projects are automatically pulled through.
author Robert Jack <robert.h.jack@gmail.com>
date Tue, 17 May 2016 15:40:16 +0100
parents d7148d21aaa5
children e4392164b458
rev   line source
andrewm@66 1 /**
andrewm@66 2 * @file
andrewm@66 3 * @brief Wiring-inspired utility functions and macros
andrewm@0 4 *
andrewm@66 5 * Macros and functions for I/O and data processing taking after the Wiring
andrewm@66 6 * (Arduino) language. This code began as part of the Hackable Instruments
andrewm@66 7 * project (EPSRC) at Queen Mary University of London, 2013-14.
andrewm@66 8 *
andrewm@66 9 * (c) 2014-15 Andrew McPherson, Victor Zappi and Giulio Moro,
andrewm@66 10 * Queen Mary University of London
andrewm@0 11 */
andrewm@0 12
andrewm@0 13 #ifndef UTILITIES_H_
andrewm@0 14 #define UTILITIES_H_
andrewm@0 15
andrewm@45 16 #include "BeagleRT.h"
andrewm@45 17
andrewm@95 18 /**
andrewm@95 19 * \defgroup iofunctions I/O functions and constants
andrewm@95 20 *
andrewm@95 21 * These functions and macros are used for audio, analog and digital I/O. All the
andrewm@95 22 * I/O functions require the BeagleRTContext data structure from render() to be passed
andrewm@95 23 * in. This means that these functions are, by design, \b only usable from within
andrewm@95 24 * the rendering thread.
andrewm@95 25 *
andrewm@95 26 * The naming conventions are loosely derived from the Arduino environment, and the
andrewm@95 27 * syntax is similar. Unlike Arduino, the I/O functions require the frame number at which
andrewm@95 28 * the read or write should take place, since all I/O happens synchronously with the
andrewm@95 29 * audio clock.
andrewm@95 30 *
andrewm@95 31 * @{
andrewm@95 32 */
andrewm@95 33
giuliomoro@187 34 #ifndef INPUT
giuliomoro@187 35 #define INPUT 0x0
giuliomoro@187 36 #endif /* INPUT */
andrewm@72 37
giuliomoro@187 38 #ifndef OUTPUT
giuliomoro@187 39 #define OUTPUT 0x1
giuliomoro@187 40 #endif /* OUTPUT */
andrewm@72 41
andrewm@95 42 /** @} */
andrewm@95 43
andrewm@95 44 /**
andrewm@95 45 * \ingroup wiring
andrewm@95 46 *
andrewm@95 47 * @{
andrewm@95 48 */
andrewm@95 49
andrewm@66 50 /// Set the given bit in \c word to 1.
andrewm@45 51 #define setBit(word,bit) ((word) | (1 << (bit)))
andrewm@66 52
andrewm@66 53 /// Clear the given bit in \c word to 0.
andrewm@45 54 #define clearBit(word,bit) ((word) &~ (1 << (bit)))
andrewm@66 55
andrewm@66 56 /// Check if the given bit in \c word is 1 (returns nonzero) or 0 (returns zero).
andrewm@45 57 #define getBit(word,bit) (((word) >> (bit)) & 1)
andrewm@66 58
andrewm@66 59 /// Set/clear the given bit in \c word to \c value.
andrewm@45 60 #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value) << (bit)))
andrewm@45 61
andrewm@95 62 /** @} */
andrewm@95 63
andrewm@95 64 /**
andrewm@95 65 * \ingroup iofunctions
andrewm@95 66 *
andrewm@95 67 * @{
andrewm@95 68 */
andrewm@95 69
andrewm@45 70 #if 1
andrewm@56 71 // Note: pinMode(), analogWrite() and digitalWrite() should be able to be called from setup()
andrewm@56 72 // Likewise, thread launch should be able to be called from setup()
andrewm@45 73 // Also, make volume change functions callable from render() thread -- as an aux task?
andrewm@45 74
andrewm@68 75 /**
giuliomoro@179 76 * \brief Read an audio input, specifying the frame number (when to read) and the channel.
giuliomoro@179 77 *
giuliomoro@179 78 * This function returns the value of an audio input, at the time indicated by \c frame.
giuliomoro@179 79 * The returned value ranges from -1 to 1.
giuliomoro@179 80 *
giuliomoro@179 81 * \param context The I/O data structure which is passed by BeagleRT to render().
giuliomoro@179 82 * \param frame Which frame (i.e. what time) to read the audio input. Valid values range
giuliomoro@179 83 * from 0 to (context->audioFrames - 1).
giuliomoro@179 84 * \param channel Which audio input to read. Valid values are between 0 and
giuliomoro@179 85 * (context->audioChannels - 1), typically 0 to 1 by default.
giuliomoro@179 86 * \return Value of the analog input, range to 1.
giuliomoro@179 87 */
giuliomoro@187 88 static inline float audioReadFrame(BeagleRTContext *context, int frame, int channel);
giuliomoro@179 89
giuliomoro@179 90 /**
giuliomoro@179 91 * \brief Write an audio output, specifying the frame number (when to write) and the channel.
giuliomoro@179 92 *
giuliomoro@179 93 * This function sets the value of an audio output, at the time indicated by \c frame. Valid
giuliomoro@179 94 * values are between -1 and 1.
giuliomoro@179 95 *
giuliomoro@179 96 * \param context The I/O data structure which is passed by BeagleRT to render().
giuliomoro@179 97 * \param frame Which frame (i.e. what time) to write the audio output. Valid values range
giuliomoro@179 98 * from 0 to (context->audioFrames - 1).
giuliomoro@179 99 * \param channel Which analog output to write. Valid values are between 0 and
giuliomoro@179 100 * (context->audioChannels - 1), typically 0 to 1 by default.
giuliomoro@179 101 * \param value Value to write to the output, range -1 to 1.
giuliomoro@179 102 */
giuliomoro@187 103 static inline void audioWriteFrame(BeagleRTContext *context, int frame, int channel, float value);
giuliomoro@179 104
giuliomoro@179 105 /**
andrewm@68 106 * \brief Read an analog input, specifying the frame number (when to read) and the channel.
andrewm@68 107 *
andrewm@68 108 * This function returns the value of an analog input, at the time indicated by \c frame.
andrewm@68 109 * The returned value ranges from 0 to 1, corresponding to a voltage range of 0 to 4.096V.
andrewm@68 110 *
andrewm@68 111 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 112 * \param frame Which frame (i.e. what time) to read the analog input. Valid values range
andrewm@68 113 * from 0 to (context->analogFrames - 1).
andrewm@68 114 * \param channel Which analog input to read. Valid values are between 0 and
andrewm@68 115 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 116 * \return Value of the analog input, range 0 to 1.
andrewm@68 117 */
giuliomoro@187 118 static inline float analogReadFrame(BeagleRTContext *context, int frame, int channel);
andrewm@68 119
andrewm@68 120 /**
andrewm@68 121 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 122 *
andrewm@68 123 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 124 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 125 *
andrewm@68 126 * The value written will persist for all future frames if BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST
andrewm@68 127 * is set in context->flags. This is the default behaviour.
andrewm@68 128 *
andrewm@68 129 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 130 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 131 * from 0 to (context->analogFrames - 1).
andrewm@68 132 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 133 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 134 * \param value Value to write to the output, range 0 to 1.
andrewm@68 135 */
giuliomoro@187 136 static inline void analogWriteFrame(BeagleRTContext *context, int frame, int channel, float value);
andrewm@68 137
andrewm@68 138 /**
andrewm@68 139 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 140 *
andrewm@68 141 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 142 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 143 *
andrewm@68 144 * Unlike analogWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@72 145 * future values unchanged. This is faster than analogWriteFrame() so is better suited
andrewm@68 146 * to applications where every frame will be written to a different value. If
andrewm@68 147 * BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST is not set within context->flags, then
andrewm@68 148 * analogWriteFrameOnce() and analogWriteFrame() are equivalent.
andrewm@68 149 *
andrewm@68 150 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 151 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 152 * from 0 to (context->analogFrames - 1).
andrewm@68 153 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 154 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 155 * \param value Value to write to the output, range 0 to 1.
andrewm@68 156 */
giuliomoro@187 157 static inline void analogWriteFrameOnce(BeagleRTContext *context, int frame, int channel, float value);
andrewm@45 158
andrewm@72 159 /**
andrewm@72 160 * \brief Read a digital input, specifying the frame number (when to read) and the pin.
andrewm@72 161 *
andrewm@72 162 * This function returns the value of a digital input, at the time indicated by \c frame.
andrewm@72 163 * The value is 0 if the pin is low, and nonzero if the pin is high (3.3V).
andrewm@72 164 *
andrewm@72 165 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 166 * \param frame Which frame (i.e. what time) to read the digital input. Valid values range
andrewm@72 167 * from 0 to (context->digitalFrames - 1).
andrewm@72 168 * \param channel Which digital pin to read. 16 pins across the P8 and P9 headers of the
andrewm@72 169 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 170 * digital_gpio_mapping.h.
andrewm@72 171 * \return Value of the digital input.
andrewm@72 172 */
giuliomoro@187 173 static inline int digitalReadFrame(BeagleRTContext *context, int frame, int channel);
andrewm@72 174
andrewm@72 175 /**
andrewm@72 176 * \brief Write a digital output, specifying the frame number (when to write) and the pin.
andrewm@72 177 *
andrewm@72 178 * This function sets the value of a digital output, at the time indicated by \c frame.
andrewm@72 179 * A value of 0 sets the pin low; any other value sets the pin high (3.3V).
andrewm@72 180 *
andrewm@72 181 * The value written will persist for all future frames.
andrewm@72 182 *
andrewm@72 183 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 184 * \param frame Which frame (i.e. what time) to write the digital output. Valid values range
andrewm@72 185 * from 0 to (context->digitalFrames - 1).
andrewm@72 186 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 187 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 188 * digital_gpio_mapping.h.
andrewm@72 189 * \param value Value to write to the output.
andrewm@72 190 */
giuliomoro@187 191 static inline void digitalWriteFrame(BeagleRTContext *context, int frame, int channel, int value);
andrewm@72 192
andrewm@72 193 /**
andrewm@72 194 * \brief Write a digital output, specifying the frame number (when to write) and the pin.
andrewm@72 195 *
andrewm@72 196 * This function sets the value of a digital output, at the time indicated by \c frame.
andrewm@72 197 * A value of 0 sets the pin low; any other value sets the pin high (3.3V).
andrewm@72 198 *
andrewm@72 199 * Unlike digitalWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@72 200 * future values unchanged. This is faster than digitalWriteFrame() so is better suited
andrewm@72 201 * to applications where every frame will be written to a different value.
andrewm@72 202 *
andrewm@72 203 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 204 * \param frame Which frame (i.e. what time) to write the digital output. Valid values range
andrewm@72 205 * from 0 to (context->digitalFrames - 1).
andrewm@72 206 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 207 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 208 * digital_gpio_mapping.h.
andrewm@72 209 * \param value Value to write to the output.
andrewm@72 210 */
giuliomoro@187 211 static inline void digitalWriteFrameOnce(BeagleRTContext *context, int frame, int channel, int value);
andrewm@45 212
andrewm@72 213 /**
andrewm@72 214 * \brief Set the direction of a digital pin to input or output.
andrewm@72 215 *
andrewm@72 216 * This function sets the direction of a digital pin, at the time indicated by \c frame.
andrewm@72 217 * Valid values are \c INPUT and \c OUTPUT. All pins begin as inputs by default.
andrewm@72 218 *
andrewm@72 219 * The value written will persist for all future frames.
andrewm@72 220 *
andrewm@72 221 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 222 * \param frame Which frame (i.e. what time) to set the pin direction. Valid values range
andrewm@72 223 * from 0 to (context->digitalFrames - 1).
andrewm@72 224 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 225 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 226 * digital_gpio_mapping.h.
andrewm@72 227 * \param value Direction of the pin (\c INPUT or \c OUTPUT).
andrewm@72 228 */
giuliomoro@187 229 static inline void pinModeFrame(BeagleRTContext *context, int frame, int channel, int mode);
andrewm@72 230
andrewm@72 231 /**
andrewm@72 232 * \brief Set the direction of a digital pin to input or output.
andrewm@72 233 *
andrewm@72 234 * This function sets the direction of a digital pin, at the time indicated by \c frame.
andrewm@72 235 * Valid values are \c INPUT and \c OUTPUT. All pins begin as inputs by default.
andrewm@72 236 *
andrewm@72 237 * The value written will affect only the specified frame.
andrewm@72 238 *
andrewm@72 239 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 240 * \param frame Which frame (i.e. what time) to set the pin direction. Valid values range
andrewm@72 241 * from 0 to (context->digitalFrames - 1).
andrewm@72 242 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 243 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 244 * digital_gpio_mapping.h.
andrewm@72 245 * \param value Direction of the pin (\c INPUT or \c OUTPUT).
andrewm@72 246 */
giuliomoro@187 247 static inline void pinModeFrameOnce(BeagleRTContext *context, int frame, int channel, int mode);
andrewm@45 248
andrewm@95 249 /** @} */
andrewm@95 250
andrewm@45 251 #else
andrewm@13 252
giuliomoro@19 253 // Macros for accessing the analog values: usable _only_ within render()
andrewm@5 254
giuliomoro@19 255 // Read an Analog input from input pin p at frame f
giuliomoro@23 256 #define analogRead(p, f) (analogIn[(f)*gNumAnalogChannels + (p)])
giuliomoro@19 257 // Write an Analog output frame at output pin p, frame f, to value v
giuliomoro@23 258 #define analogWriteFrame(p, f, v) (analogOut[(f)*gNumAnalogChannels + (p)] = (v))
giuliomoro@23 259 #define analogWrite(pin, frame, value) \
giuliomoro@18 260 (({do {\
giuliomoro@19 261 for (int _privateI=(frame); _privateI<numAnalogFrames; _privateI++){ \
giuliomoro@23 262 analogWriteFrame(pin,_privateI,value); \
giuliomoro@18 263 }\
giuliomoro@18 264 } while (0);}),(void)0)\
andrewm@5 265
andrewm@45 266
giuliomoro@19 267 //digital API:
giuliomoro@33 268 #define setDigitalDirectionFrame(pin,frame,direction) digital[(frame)]=changeBit(digital[(frame)],(pin),(direction)),void(0)
giuliomoro@33 269 #define setDigitalDirection(pin,frame,direction)\
giuliomoro@33 270 (({do {\
giuliomoro@33 271 for(int _privateI=(frame); _privateI<numDigitalFrames; _privateI++)\
giuliomoro@33 272 setDigitalDirectionFrame(pin,_privateI,direction);\
giuliomoro@33 273 } while (0);}), (void)0)
giuliomoro@19 274 #define digitalWriteAll(frame,value) digital[(frame)]=0xffff0000*(!(!value));
giuliomoro@16 275 //sets the bit in the high word, clears the bit in the low word (just in case the direction was not previously set)
giuliomoro@19 276 #define digitalWriteFrame(pin, frame, value) digital[(frame)]=( changeBit(digital[(frame)], (pin+16), (value)) & (0xffffffff-(1<<(pin))) ) //could have been done with two subsequent assignments
giuliomoro@18 277 #define digitalWrite(pin, frame, value) \
giuliomoro@18 278 (({do {\
giuliomoro@33 279 for (int _privateI=(frame); _privateI<numDigitalFrames; _privateI++) \
giuliomoro@18 280 digitalWriteFrame(pin,_privateI,value); \
giuliomoro@18 281 } while (0);}),(void)0)\
giuliomoro@18 282
giuliomoro@19 283 #define digitalRead(pin, frame) ( getBit(digital[(frame)], pin+16) )
giuliomoro@16 284
andrewm@45 285 #endif
andrewm@45 286
andrewm@66 287 /**
andrewm@95 288 * \defgroup wiring Wiring language support
andrewm@95 289 *
andrewm@95 290 * These are functions found in the Wiring (Arduino) language which are not directly
andrewm@95 291 * related to I/O but are provided as a convenience.
andrewm@95 292 *
andrewm@95 293 * @{
andrewm@95 294 */
andrewm@95 295
andrewm@95 296 /**
andrewm@66 297 * \brief Linearly rescale a number from one range of values to another.
andrewm@66 298 *
andrewm@66 299 * This function linearly scales values of \c x such that the range in_min to
andrewm@66 300 * in_max at the input corresponds to the range out_min to out_max
andrewm@66 301 * at the output. Values outside this range are extrapolated.
andrewm@66 302 *
andrewm@66 303 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 304 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 305 * point values.
andrewm@66 306 *
andrewm@66 307 * \param x Input value to be mapped.
andrewm@66 308 * \param in_min Lower bound of the input range.
andrewm@66 309 * \param in_max Upper bound of the input range.
andrewm@66 310 * \param out_min Lower bound of the output range.
andrewm@66 311 * \param out_max Upper bound of the output range.
andrewm@66 312 * \return Rescaled value.
andrewm@66 313 */
giuliomoro@187 314 static inline float map(float x, float in_min, float in_max, float out_min, float out_max);
andrewm@66 315
andrewm@66 316 /**
andrewm@66 317 * \brief Constrain a number to stay within a given range.
andrewm@66 318 *
andrewm@66 319 * This function constrains \c x to remain within the range min_val to
andrewm@66 320 * max_val. Values of \c x outside this range are clipped to the edges
andrewm@66 321 * of the range.
andrewm@66 322 *
andrewm@66 323 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 324 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 325 * point values.
andrewm@66 326 *
andrewm@66 327 * \param x Input value to be constrained.
andrewm@66 328 * \param min_val Minimum possible value.
andrewm@66 329 * \param max_val Maximum possible value.
andrewm@66 330 * \return Constrained value.
andrewm@66 331 */
giuliomoro@187 332 static inline float constrain(float x, float min_val, float max_val);
andrewm@0 333
andrewm@95 334 /** @} */
giuliomoro@187 335 // audioReadFrame()
giuliomoro@187 336 //
giuliomoro@187 337 // Returns the value of the given audio input at the given frame number.
giuliomoro@187 338 static inline float audioReadFrame(BeagleRTContext *context, int frame, int channel) {
giuliomoro@187 339 return context->audioIn[frame * context->audioChannels + channel];
giuliomoro@187 340 }
giuliomoro@187 341
giuliomoro@187 342 // audioWriteFrame()
giuliomoro@187 343 //
giuliomoro@187 344 // Sets a given audio output channel to a value for the current frame
giuliomoro@187 345 static inline void audioWriteFrame(BeagleRTContext *context, int frame, int channel, float value) {
giuliomoro@187 346 context->audioOut[frame * context->audioChannels + channel] = value;
giuliomoro@187 347 }
giuliomoro@187 348
giuliomoro@187 349 // analogReadFrame()
giuliomoro@187 350 //
giuliomoro@187 351 // Returns the value of the given analog input at the given frame number.
giuliomoro@187 352 static inline float analogReadFrame(BeagleRTContext *context, int frame, int channel) {
giuliomoro@187 353 return context->analogIn[frame * context->analogChannels + channel];
giuliomoro@187 354 }
giuliomoro@187 355
giuliomoro@187 356 // analogWriteFrame()
giuliomoro@187 357 //
giuliomoro@187 358 // Sets a given analog output channel to a value for the current frame and, if persistent outputs are
giuliomoro@187 359 // enabled, for all subsequent frames
giuliomoro@187 360 static inline void analogWriteFrame(BeagleRTContext *context, int frame, int channel, float value) {
giuliomoro@187 361 if(context->flags & BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST) {
giuliomoro@187 362 for(unsigned int f = frame; f < context->analogFrames; f++)
giuliomoro@187 363 context->analogOut[frame * context->analogChannels + channel] = value;
giuliomoro@187 364 }
giuliomoro@187 365 else
giuliomoro@187 366 context->analogOut[frame * context->analogChannels + channel] = value;
giuliomoro@187 367 }
giuliomoro@187 368
giuliomoro@187 369 // analogWriteFrameOnce()
giuliomoro@187 370 //
giuliomoro@187 371 // Sets a given channel to a value for only the current frame
giuliomoro@187 372 static inline void analogWriteFrameOnce(BeagleRTContext *context, int frame, int channel, float value) {
giuliomoro@187 373 context->analogOut[frame * context->analogChannels + channel] = value;
giuliomoro@187 374 }
giuliomoro@187 375
giuliomoro@187 376 // digitalReadFrame()
giuliomoro@187 377 //
giuliomoro@187 378 // Returns the value of a given digital input at the given frame number
giuliomoro@187 379 static inline int digitalReadFrame(BeagleRTContext *context, int frame, int channel) {
giuliomoro@187 380 return getBit(context->digital[frame], channel + 16);
giuliomoro@187 381 }
giuliomoro@187 382
giuliomoro@187 383 // digitalWriteFrame()
giuliomoro@187 384 //
giuliomoro@187 385 // Sets a given digital output channel to a value for the current frame and all subsequent frames
giuliomoro@187 386 static inline void digitalWriteFrame(BeagleRTContext *context, int frame, int channel, int value) {
giuliomoro@187 387 for(unsigned int f = frame; f < context->digitalFrames; f++) {
giuliomoro@187 388 if(value)
giuliomoro@187 389 context->digital[f] |= 1 << (channel + 16);
giuliomoro@187 390 else
giuliomoro@187 391 context->digital[f] &= ~(1 << (channel + 16));
giuliomoro@187 392 }
giuliomoro@187 393 }
giuliomoro@187 394
giuliomoro@187 395 // digitalWriteFrameOnce()
giuliomoro@187 396 //
giuliomoro@187 397 // Sets a given digital output channel to a value for the current frame only
giuliomoro@187 398 static inline void digitalWriteFrameOnce(BeagleRTContext *context, int frame, int channel, int value) {
giuliomoro@187 399 if(value)
giuliomoro@187 400 context->digital[frame] |= 1 << (channel + 16);
giuliomoro@187 401 else
giuliomoro@187 402 context->digital[frame] &= ~(1 << (channel + 16));
giuliomoro@187 403 }
giuliomoro@187 404
giuliomoro@187 405 // pinModeFrame()
giuliomoro@187 406 //
giuliomoro@187 407 // Sets the direction of a digital pin for the current frame and all subsequent frames
giuliomoro@187 408 static inline void pinModeFrame(BeagleRTContext *context, int frame, int channel, int mode) {
giuliomoro@187 409 for(unsigned int f = frame; f < context->digitalFrames; f++) {
giuliomoro@187 410 if(mode == INPUT)
giuliomoro@187 411 context->digital[f] |= (1 << channel);
giuliomoro@187 412 else
giuliomoro@187 413 context->digital[f] &= ~(1 << channel);
giuliomoro@187 414 }
giuliomoro@187 415 }
giuliomoro@187 416
giuliomoro@187 417 // pinModeFrameOnce()
giuliomoro@187 418 //
giuliomoro@187 419 // Sets the direction of a digital pin for the current frame only
giuliomoro@187 420 static inline void pinModeFrameOnce(BeagleRTContext *context, int frame, int channel, int mode) {
giuliomoro@187 421 if(mode == INPUT)
giuliomoro@187 422 context->digital[frame] |= (1 << channel);
giuliomoro@187 423 else
giuliomoro@187 424 context->digital[frame] &= ~(1 << channel);
giuliomoro@187 425 }
giuliomoro@187 426
giuliomoro@187 427
giuliomoro@187 428
giuliomoro@187 429 // map()
giuliomoro@187 430 //
giuliomoro@187 431 // Scale an input value from one range to another. Works like its Wiring language equivalent.
giuliomoro@187 432 // x is the value to scale; in_min and in_max are the input range; out_min and out_max
giuliomoro@187 433 // are the output range.
giuliomoro@187 434
giuliomoro@187 435 static inline float map(float x, float in_min, float in_max, float out_min, float out_max)
giuliomoro@187 436 {
giuliomoro@187 437 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
giuliomoro@187 438 }
giuliomoro@187 439
giuliomoro@187 440 // constrain()
giuliomoro@187 441 //
giuliomoro@187 442 // Clips an input value to be between two end points
giuliomoro@187 443 // x is the value to constrain; min_val and max_val are the range
giuliomoro@187 444
giuliomoro@187 445 static inline float constrain(float x, float min_val, float max_val)
giuliomoro@187 446 {
giuliomoro@187 447 if(x < min_val) return min_val;
giuliomoro@187 448 if(x > max_val) return max_val;
giuliomoro@187 449 return x;
giuliomoro@187 450 }
andrewm@95 451
andrewm@0 452 #endif /* UTILITIES_H_ */