annotate include/Utilities.h @ 151:e9c9404e3d1f ClockSync

Pff partially working. No PID. When setting the audio clock on the bbb to 44098 the master and slave clock keep diverging instead of converging ...
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 22 Sep 2015 04:10:07 +0100
parents c529505203ee
children f1012082f142
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
andrewm@72 34 #define HIGH 0x1
andrewm@72 35 #define LOW 0x0
andrewm@72 36
andrewm@72 37 #define INPUT 0x0
andrewm@72 38 #define OUTPUT 0x1
andrewm@72 39
andrewm@95 40 /** @} */
andrewm@95 41
andrewm@95 42 /**
andrewm@95 43 * \ingroup wiring
andrewm@95 44 *
andrewm@95 45 * @{
andrewm@95 46 */
andrewm@95 47
andrewm@66 48 /// Set the given bit in \c word to 1.
andrewm@45 49 #define setBit(word,bit) ((word) | (1 << (bit)))
andrewm@66 50
andrewm@66 51 /// Clear the given bit in \c word to 0.
andrewm@45 52 #define clearBit(word,bit) ((word) &~ (1 << (bit)))
andrewm@66 53
andrewm@66 54 /// Check if the given bit in \c word is 1 (returns nonzero) or 0 (returns zero).
andrewm@45 55 #define getBit(word,bit) (((word) >> (bit)) & 1)
andrewm@66 56
andrewm@66 57 /// Set/clear the given bit in \c word to \c value.
andrewm@45 58 #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value) << (bit)))
andrewm@45 59
andrewm@95 60 /** @} */
andrewm@95 61
andrewm@95 62 /**
andrewm@95 63 * \ingroup iofunctions
andrewm@95 64 *
andrewm@95 65 * @{
andrewm@95 66 */
andrewm@95 67
andrewm@45 68 #if 1
andrewm@56 69 // Note: pinMode(), analogWrite() and digitalWrite() should be able to be called from setup()
andrewm@56 70 // Likewise, thread launch should be able to be called from setup()
andrewm@45 71 // Also, make volume change functions callable from render() thread -- as an aux task?
andrewm@45 72
andrewm@68 73 /**
andrewm@68 74 * \brief Read an analog input, specifying the frame number (when to read) and the channel.
andrewm@68 75 *
andrewm@68 76 * This function returns the value of an analog input, at the time indicated by \c frame.
andrewm@68 77 * The returned value ranges from 0 to 1, corresponding to a voltage range of 0 to 4.096V.
andrewm@68 78 *
andrewm@68 79 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 80 * \param frame Which frame (i.e. what time) to read the analog input. Valid values range
andrewm@68 81 * from 0 to (context->analogFrames - 1).
andrewm@68 82 * \param channel Which analog input to read. Valid values are between 0 and
andrewm@68 83 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 84 * \return Value of the analog input, range 0 to 1.
andrewm@68 85 */
andrewm@45 86 float analogReadFrame(BeagleRTContext *context, int frame, int channel);
andrewm@68 87
andrewm@68 88 /**
andrewm@68 89 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 90 *
andrewm@68 91 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 92 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 93 *
andrewm@68 94 * The value written will persist for all future frames if BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST
andrewm@68 95 * is set in context->flags. This is the default behaviour.
andrewm@68 96 *
andrewm@68 97 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 98 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 99 * from 0 to (context->analogFrames - 1).
andrewm@68 100 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 101 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 102 * \param value Value to write to the output, range 0 to 1.
andrewm@68 103 */
andrewm@45 104 void analogWriteFrame(BeagleRTContext *context, int frame, int channel, float value);
andrewm@68 105
andrewm@68 106 /**
andrewm@68 107 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 108 *
andrewm@68 109 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 110 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 111 *
andrewm@68 112 * Unlike analogWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@72 113 * future values unchanged. This is faster than analogWriteFrame() so is better suited
andrewm@68 114 * to applications where every frame will be written to a different value. If
andrewm@68 115 * BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST is not set within context->flags, then
andrewm@68 116 * analogWriteFrameOnce() and analogWriteFrame() are equivalent.
andrewm@68 117 *
andrewm@68 118 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 119 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 120 * from 0 to (context->analogFrames - 1).
andrewm@68 121 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 122 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 123 * \param value Value to write to the output, range 0 to 1.
andrewm@68 124 */
andrewm@45 125 void analogWriteFrameOnce(BeagleRTContext *context, int frame, int channel, float value);
andrewm@45 126
andrewm@72 127 /**
andrewm@72 128 * \brief Read a digital input, specifying the frame number (when to read) and the pin.
andrewm@72 129 *
andrewm@72 130 * This function returns the value of a digital input, at the time indicated by \c frame.
andrewm@72 131 * The value is 0 if the pin is low, and nonzero if the pin is high (3.3V).
andrewm@72 132 *
andrewm@72 133 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 134 * \param frame Which frame (i.e. what time) to read the digital input. Valid values range
andrewm@72 135 * from 0 to (context->digitalFrames - 1).
andrewm@72 136 * \param channel Which digital pin to read. 16 pins across the P8 and P9 headers of the
andrewm@72 137 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 138 * digital_gpio_mapping.h.
andrewm@72 139 * \return Value of the digital input.
andrewm@72 140 */
andrewm@45 141 int digitalReadFrame(BeagleRTContext *context, int frame, int channel);
andrewm@72 142
andrewm@72 143 /**
andrewm@72 144 * \brief Write a digital output, specifying the frame number (when to write) and the pin.
andrewm@72 145 *
andrewm@72 146 * This function sets the value of a digital output, at the time indicated by \c frame.
andrewm@72 147 * A value of 0 sets the pin low; any other value sets the pin high (3.3V).
andrewm@72 148 *
andrewm@72 149 * The value written will persist for all future frames.
andrewm@72 150 *
andrewm@72 151 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 152 * \param frame Which frame (i.e. what time) to write the digital output. Valid values range
andrewm@72 153 * from 0 to (context->digitalFrames - 1).
andrewm@72 154 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 155 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 156 * digital_gpio_mapping.h.
andrewm@72 157 * \param value Value to write to the output.
andrewm@72 158 */
andrewm@45 159 void digitalWriteFrame(BeagleRTContext *context, int frame, int channel, int value);
andrewm@72 160
andrewm@72 161 /**
andrewm@72 162 * \brief Write a digital output, specifying the frame number (when to write) and the pin.
andrewm@72 163 *
andrewm@72 164 * This function sets the value of a digital output, at the time indicated by \c frame.
andrewm@72 165 * A value of 0 sets the pin low; any other value sets the pin high (3.3V).
andrewm@72 166 *
andrewm@72 167 * Unlike digitalWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@72 168 * future values unchanged. This is faster than digitalWriteFrame() so is better suited
andrewm@72 169 * to applications where every frame will be written to a different value.
andrewm@72 170 *
andrewm@72 171 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 172 * \param frame Which frame (i.e. what time) to write the digital output. Valid values range
andrewm@72 173 * from 0 to (context->digitalFrames - 1).
andrewm@72 174 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 175 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 176 * digital_gpio_mapping.h.
andrewm@72 177 * \param value Value to write to the output.
andrewm@72 178 */
andrewm@45 179 void digitalWriteFrameOnce(BeagleRTContext *context, int frame, int channel, int value);
andrewm@45 180
andrewm@72 181 /**
andrewm@72 182 * \brief Set the direction of a digital pin to input or output.
andrewm@72 183 *
andrewm@72 184 * This function sets the direction of a digital pin, at the time indicated by \c frame.
andrewm@72 185 * Valid values are \c INPUT and \c OUTPUT. All pins begin as inputs by default.
andrewm@72 186 *
andrewm@72 187 * The value written will persist for all future frames.
andrewm@72 188 *
andrewm@72 189 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 190 * \param frame Which frame (i.e. what time) to set the pin direction. Valid values range
andrewm@72 191 * from 0 to (context->digitalFrames - 1).
andrewm@72 192 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 193 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 194 * digital_gpio_mapping.h.
andrewm@72 195 * \param value Direction of the pin (\c INPUT or \c OUTPUT).
andrewm@72 196 */
andrewm@45 197 void pinModeFrame(BeagleRTContext *context, int frame, int channel, int mode);
andrewm@72 198
andrewm@72 199 /**
andrewm@72 200 * \brief Set the direction of a digital pin to input or output.
andrewm@72 201 *
andrewm@72 202 * This function sets the direction of a digital pin, at the time indicated by \c frame.
andrewm@72 203 * Valid values are \c INPUT and \c OUTPUT. All pins begin as inputs by default.
andrewm@72 204 *
andrewm@72 205 * The value written will affect only the specified frame.
andrewm@72 206 *
andrewm@72 207 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@72 208 * \param frame Which frame (i.e. what time) to set the pin direction. Valid values range
andrewm@72 209 * from 0 to (context->digitalFrames - 1).
andrewm@72 210 * \param channel Which digital output to write. 16 pins across the P8 and P9 headers of the
andrewm@72 211 * BeagleBone Black are available. See the constants P8_xx and P9_xx defined in
andrewm@72 212 * digital_gpio_mapping.h.
andrewm@72 213 * \param value Direction of the pin (\c INPUT or \c OUTPUT).
andrewm@72 214 */
andrewm@45 215 void pinModeFrameOnce(BeagleRTContext *context, int frame, int channel, int mode);
andrewm@45 216
andrewm@95 217 /** @} */
andrewm@95 218
andrewm@45 219 #else
andrewm@13 220
giuliomoro@19 221 // Macros for accessing the analog values: usable _only_ within render()
andrewm@5 222
giuliomoro@19 223 // Read an Analog input from input pin p at frame f
giuliomoro@23 224 #define analogRead(p, f) (analogIn[(f)*gNumAnalogChannels + (p)])
giuliomoro@19 225 // Write an Analog output frame at output pin p, frame f, to value v
giuliomoro@23 226 #define analogWriteFrame(p, f, v) (analogOut[(f)*gNumAnalogChannels + (p)] = (v))
giuliomoro@23 227 #define analogWrite(pin, frame, value) \
giuliomoro@18 228 (({do {\
giuliomoro@19 229 for (int _privateI=(frame); _privateI<numAnalogFrames; _privateI++){ \
giuliomoro@23 230 analogWriteFrame(pin,_privateI,value); \
giuliomoro@18 231 }\
giuliomoro@18 232 } while (0);}),(void)0)\
andrewm@5 233
andrewm@45 234
giuliomoro@19 235 //digital API:
giuliomoro@33 236 #define setDigitalDirectionFrame(pin,frame,direction) digital[(frame)]=changeBit(digital[(frame)],(pin),(direction)),void(0)
giuliomoro@33 237 #define setDigitalDirection(pin,frame,direction)\
giuliomoro@33 238 (({do {\
giuliomoro@33 239 for(int _privateI=(frame); _privateI<numDigitalFrames; _privateI++)\
giuliomoro@33 240 setDigitalDirectionFrame(pin,_privateI,direction);\
giuliomoro@33 241 } while (0);}), (void)0)
giuliomoro@19 242 #define digitalWriteAll(frame,value) digital[(frame)]=0xffff0000*(!(!value));
giuliomoro@16 243 //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 244 #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 245 #define digitalWrite(pin, frame, value) \
giuliomoro@18 246 (({do {\
giuliomoro@33 247 for (int _privateI=(frame); _privateI<numDigitalFrames; _privateI++) \
giuliomoro@18 248 digitalWriteFrame(pin,_privateI,value); \
giuliomoro@18 249 } while (0);}),(void)0)\
giuliomoro@18 250
giuliomoro@19 251 #define digitalRead(pin, frame) ( getBit(digital[(frame)], pin+16) )
giuliomoro@16 252
andrewm@45 253 #endif
andrewm@45 254
andrewm@66 255 /**
andrewm@95 256 * \defgroup wiring Wiring language support
andrewm@95 257 *
andrewm@95 258 * These are functions found in the Wiring (Arduino) language which are not directly
andrewm@95 259 * related to I/O but are provided as a convenience.
andrewm@95 260 *
andrewm@95 261 * @{
andrewm@95 262 */
andrewm@95 263
andrewm@95 264 /**
andrewm@66 265 * \brief Linearly rescale a number from one range of values to another.
andrewm@66 266 *
andrewm@66 267 * This function linearly scales values of \c x such that the range in_min to
andrewm@66 268 * in_max at the input corresponds to the range out_min to out_max
andrewm@66 269 * at the output. Values outside this range are extrapolated.
andrewm@66 270 *
andrewm@66 271 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 272 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 273 * point values.
andrewm@66 274 *
andrewm@66 275 * \param x Input value to be mapped.
andrewm@66 276 * \param in_min Lower bound of the input range.
andrewm@66 277 * \param in_max Upper bound of the input range.
andrewm@66 278 * \param out_min Lower bound of the output range.
andrewm@66 279 * \param out_max Upper bound of the output range.
andrewm@66 280 * \return Rescaled value.
andrewm@66 281 */
andrewm@0 282 float map(float x, float in_min, float in_max, float out_min, float out_max);
andrewm@66 283
andrewm@66 284 /**
andrewm@66 285 * \brief Constrain a number to stay within a given range.
andrewm@66 286 *
andrewm@66 287 * This function constrains \c x to remain within the range min_val to
andrewm@66 288 * max_val. Values of \c x outside this range are clipped to the edges
andrewm@66 289 * of the range.
andrewm@66 290 *
andrewm@66 291 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 292 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 293 * point values.
andrewm@66 294 *
andrewm@66 295 * \param x Input value to be constrained.
andrewm@66 296 * \param min_val Minimum possible value.
andrewm@66 297 * \param max_val Maximum possible value.
andrewm@66 298 * \return Constrained value.
andrewm@66 299 */
andrewm@0 300 float constrain(float x, float min_val, float max_val);
andrewm@0 301
andrewm@95 302 /** @} */
andrewm@95 303
andrewm@0 304 #endif /* UTILITIES_H_ */