annotate include/Utilities.h @ 68:59edd5780fef

Changed d-box code to run cleanly when built on board. Updated Makefile to add ne10 include path on board. Some extra docs in Utilities.h
author andrewm
date Fri, 17 Jul 2015 16:57:08 +0100
parents 74a44c3d91f0
children d837fb676977
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@66 18 /// Set the given bit in \c word to 1.
andrewm@45 19 #define setBit(word,bit) ((word) | (1 << (bit)))
andrewm@66 20
andrewm@66 21 /// Clear the given bit in \c word to 0.
andrewm@45 22 #define clearBit(word,bit) ((word) &~ (1 << (bit)))
andrewm@66 23
andrewm@66 24 /// Check if the given bit in \c word is 1 (returns nonzero) or 0 (returns zero).
andrewm@45 25 #define getBit(word,bit) (((word) >> (bit)) & 1)
andrewm@66 26
andrewm@66 27 /// Set/clear the given bit in \c word to \c value.
andrewm@45 28 #define changeBit(word,bit,value) ((clearBit((word),(bit))) | ((value) << (bit)))
andrewm@45 29
andrewm@45 30 #if 1
andrewm@56 31 // Note: pinMode(), analogWrite() and digitalWrite() should be able to be called from setup()
andrewm@56 32 // Likewise, thread launch should be able to be called from setup()
andrewm@45 33 // Also, make volume change functions callable from render() thread -- as an aux task?
andrewm@45 34
andrewm@68 35 /**
andrewm@68 36 * \brief Read an analog input, specifying the frame number (when to read) and the channel.
andrewm@68 37 *
andrewm@68 38 * This function returns the value of an analog input, at the time indicated by \c frame.
andrewm@68 39 * The returned value ranges from 0 to 1, corresponding to a voltage range of 0 to 4.096V.
andrewm@68 40 *
andrewm@68 41 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 42 * \param frame Which frame (i.e. what time) to read the analog input. Valid values range
andrewm@68 43 * from 0 to (context->analogFrames - 1).
andrewm@68 44 * \param channel Which analog input to read. Valid values are between 0 and
andrewm@68 45 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 46 * \return Value of the analog input, range 0 to 1.
andrewm@68 47 */
andrewm@45 48 float analogReadFrame(BeagleRTContext *context, int frame, int channel);
andrewm@68 49
andrewm@68 50 /**
andrewm@68 51 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 52 *
andrewm@68 53 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 54 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 55 *
andrewm@68 56 * The value written will persist for all future frames if BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST
andrewm@68 57 * is set in context->flags. This is the default behaviour.
andrewm@68 58 *
andrewm@68 59 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 60 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 61 * from 0 to (context->analogFrames - 1).
andrewm@68 62 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 63 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 64 * \param value Value to write to the output, range 0 to 1.
andrewm@68 65 */
andrewm@45 66 void analogWriteFrame(BeagleRTContext *context, int frame, int channel, float value);
andrewm@68 67
andrewm@68 68 /**
andrewm@68 69 * \brief Write an analog output, specifying the frame number (when to write) and the channel.
andrewm@68 70 *
andrewm@68 71 * This function sets the value of an analog output, at the time indicated by \c frame. Valid
andrewm@68 72 * values are between 0 and 1, corresponding to the range 0 to 5V.
andrewm@68 73 *
andrewm@68 74 * Unlike analogWriteFrame(), the value written will affect \b only the frame specified, with
andrewm@68 75 * future values unchanged. This is more efficient than analogWriteFrame() so is better suited
andrewm@68 76 * to applications where every frame will be written to a different value. If
andrewm@68 77 * BEAGLERT_FLAG_ANALOG_OUTPUTS_PERSIST is not set within context->flags, then
andrewm@68 78 * analogWriteFrameOnce() and analogWriteFrame() are equivalent.
andrewm@68 79 *
andrewm@68 80 * \param context The I/O data structure which is passed by BeagleRT to render().
andrewm@68 81 * \param frame Which frame (i.e. what time) to write the analog output. Valid values range
andrewm@68 82 * from 0 to (context->analogFrames - 1).
andrewm@68 83 * \param channel Which analog output to write. Valid values are between 0 and
andrewm@68 84 * (context->analogChannels - 1), typically 0 to 7 by default.
andrewm@68 85 * \param value Value to write to the output, range 0 to 1.
andrewm@68 86 */
andrewm@45 87 void analogWriteFrameOnce(BeagleRTContext *context, int frame, int channel, float value);
andrewm@45 88
andrewm@45 89 int digitalReadFrame(BeagleRTContext *context, int frame, int channel);
andrewm@45 90 void digitalWriteFrame(BeagleRTContext *context, int frame, int channel, int value);
andrewm@45 91 void digitalWriteFrameOnce(BeagleRTContext *context, int frame, int channel, int value);
andrewm@45 92
andrewm@45 93 void pinModeFrame(BeagleRTContext *context, int frame, int channel, int mode);
andrewm@45 94 void pinModeFrameOnce(BeagleRTContext *context, int frame, int channel, int mode);
andrewm@45 95
andrewm@45 96 #else
andrewm@13 97
giuliomoro@19 98 // Macros for accessing the analog values: usable _only_ within render()
andrewm@5 99
giuliomoro@19 100 // Read an Analog input from input pin p at frame f
giuliomoro@23 101 #define analogRead(p, f) (analogIn[(f)*gNumAnalogChannels + (p)])
giuliomoro@19 102 // Write an Analog output frame at output pin p, frame f, to value v
giuliomoro@23 103 #define analogWriteFrame(p, f, v) (analogOut[(f)*gNumAnalogChannels + (p)] = (v))
giuliomoro@23 104 #define analogWrite(pin, frame, value) \
giuliomoro@18 105 (({do {\
giuliomoro@19 106 for (int _privateI=(frame); _privateI<numAnalogFrames; _privateI++){ \
giuliomoro@23 107 analogWriteFrame(pin,_privateI,value); \
giuliomoro@18 108 }\
giuliomoro@18 109 } while (0);}),(void)0)\
andrewm@5 110
andrewm@45 111
giuliomoro@19 112 //digital API:
giuliomoro@33 113 #define setDigitalDirectionFrame(pin,frame,direction) digital[(frame)]=changeBit(digital[(frame)],(pin),(direction)),void(0)
giuliomoro@33 114 #define setDigitalDirection(pin,frame,direction)\
giuliomoro@33 115 (({do {\
giuliomoro@33 116 for(int _privateI=(frame); _privateI<numDigitalFrames; _privateI++)\
giuliomoro@33 117 setDigitalDirectionFrame(pin,_privateI,direction);\
giuliomoro@33 118 } while (0);}), (void)0)
giuliomoro@19 119 #define digitalWriteAll(frame,value) digital[(frame)]=0xffff0000*(!(!value));
giuliomoro@16 120 //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 121 #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 122 #define digitalWrite(pin, frame, value) \
giuliomoro@18 123 (({do {\
giuliomoro@33 124 for (int _privateI=(frame); _privateI<numDigitalFrames; _privateI++) \
giuliomoro@18 125 digitalWriteFrame(pin,_privateI,value); \
giuliomoro@18 126 } while (0);}),(void)0)\
giuliomoro@18 127
giuliomoro@19 128 #define digitalRead(pin, frame) ( getBit(digital[(frame)], pin+16) )
giuliomoro@16 129
andrewm@45 130 #endif
andrewm@45 131
andrewm@66 132 /**
andrewm@66 133 * \brief Linearly rescale a number from one range of values to another.
andrewm@66 134 *
andrewm@66 135 * This function linearly scales values of \c x such that the range in_min to
andrewm@66 136 * in_max at the input corresponds to the range out_min to out_max
andrewm@66 137 * at the output. Values outside this range are extrapolated.
andrewm@66 138 *
andrewm@66 139 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 140 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 141 * point values.
andrewm@66 142 *
andrewm@66 143 * \param x Input value to be mapped.
andrewm@66 144 * \param in_min Lower bound of the input range.
andrewm@66 145 * \param in_max Upper bound of the input range.
andrewm@66 146 * \param out_min Lower bound of the output range.
andrewm@66 147 * \param out_max Upper bound of the output range.
andrewm@66 148 * \return Rescaled value.
andrewm@66 149 */
andrewm@0 150 float map(float x, float in_min, float in_max, float out_min, float out_max);
andrewm@66 151
andrewm@66 152 /**
andrewm@66 153 * \brief Constrain a number to stay within a given range.
andrewm@66 154 *
andrewm@66 155 * This function constrains \c x to remain within the range min_val to
andrewm@66 156 * max_val. Values of \c x outside this range are clipped to the edges
andrewm@66 157 * of the range.
andrewm@66 158 *
andrewm@66 159 * This function behaves identically to the function of the same name in Processing. It
andrewm@66 160 * is also similar to the corresponding function in Arduino, except that it supports floating
andrewm@66 161 * point values.
andrewm@66 162 *
andrewm@66 163 * \param x Input value to be constrained.
andrewm@66 164 * \param min_val Minimum possible value.
andrewm@66 165 * \param max_val Maximum possible value.
andrewm@66 166 * \return Constrained value.
andrewm@66 167 */
andrewm@0 168 float constrain(float x, float min_val, float max_val);
andrewm@0 169
andrewm@0 170 #endif /* UTILITIES_H_ */