Robot Arm Controller Library

Dependents:   PR_RobotArm lighthouse_2

Committer:
jah128
Date:
Thu Feb 16 23:57:45 2017 +0000
Revision:
0:9f7b70e0186e
First commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jah128 0:9f7b70e0186e 1 /* University of York Robotics Laboratory Robot Arm Controller Board
jah128 0:9f7b70e0186e 2 *
jah128 0:9f7b70e0186e 3 * Dynamixel Servo Library for AX-12 and MX-28
jah128 0:9f7b70e0186e 4 *
jah128 0:9f7b70e0186e 5 * Based on library by Chris Styles (see copyright notice at end of file)
jah128 0:9f7b70e0186e 6 *
jah128 0:9f7b70e0186e 7 * File: servo.cpp
jah128 0:9f7b70e0186e 8 *
jah128 0:9f7b70e0186e 9 * (C) Dept. Electronics & Computer Science, University of York
jah128 0:9f7b70e0186e 10 * James Hilder, Alan Millard, Shuhei Miyashita, Homero Elizondo, Jon Timmis
jah128 0:9f7b70e0186e 11 *
jah128 0:9f7b70e0186e 12 * February 2017, Version 1.0
jah128 0:9f7b70e0186e 13 */
jah128 0:9f7b70e0186e 14
jah128 0:9f7b70e0186e 15 // NOTE:
jah128 0:9f7b70e0186e 16 // When communicating with 'new' servos the are defaulted to ID 1
jah128 0:9f7b70e0186e 17 // Make sure only one such servo is connected at one time
jah128 0:9f7b70e0186e 18 // Also note that this library defaults to 57600 serial comms
jah128 0:9f7b70e0186e 19 // The MX-28s are defaulted to communicate at this speed but the AX-12s are not (1Mbaud)
jah128 0:9f7b70e0186e 20 // Use SetInitBaud(57600) to override the default and then change baud rate when setting up MX-28s
jah128 0:9f7b70e0186e 21
jah128 0:9f7b70e0186e 22 #ifndef SERVO_H
jah128 0:9f7b70e0186e 23 #define SERVO_H
jah128 0:9f7b70e0186e 24
jah128 0:9f7b70e0186e 25 #include "mbed.h"
jah128 0:9f7b70e0186e 26 #include "SerialHalfDuplex.h"
jah128 0:9f7b70e0186e 27
jah128 0:9f7b70e0186e 28 #define WRITE_DEBUG 0
jah128 0:9f7b70e0186e 29 #define READ_DEBUG 0
jah128 0:9f7b70e0186e 30 #define TRIGGER_DEBUG 0
jah128 0:9f7b70e0186e 31 #define DEBUG 0
jah128 0:9f7b70e0186e 32
jah128 0:9f7b70e0186e 33 // Number of times to retry a read\write operation if read times out
jah128 0:9f7b70e0186e 34 #define READ_TIMEOUT_LIMIT 3
jah128 0:9f7b70e0186e 35
jah128 0:9f7b70e0186e 36 #define LOW_VOLTAGE_LIMIT 90
jah128 0:9f7b70e0186e 37 #define HIGH_VOLTAGE_LIMIT 140
jah128 0:9f7b70e0186e 38 #define HIGH_TEMPERATURE_LIMIT 70
jah128 0:9f7b70e0186e 39
jah128 0:9f7b70e0186e 40 #define AX12_MODEL 0x0C
jah128 0:9f7b70e0186e 41 #define MX28_MODEL 0x1D
jah128 0:9f7b70e0186e 42
jah128 0:9f7b70e0186e 43 #define RETURN_DELAY 250
jah128 0:9f7b70e0186e 44
jah128 0:9f7b70e0186e 45 #define REG_MODEL_NUMBER 0x00
jah128 0:9f7b70e0186e 46 #define REG_FIRMWARE_VERSION 0x02
jah128 0:9f7b70e0186e 47 #define REG_ID 0x03
jah128 0:9f7b70e0186e 48 #define REG_BAUDRATE 0x04
jah128 0:9f7b70e0186e 49 #define REG_RETURN_DELAY 0x05
jah128 0:9f7b70e0186e 50 #define REG_CW_LIMIT 0x06
jah128 0:9f7b70e0186e 51 #define REG_CCW_LIMIT 0x08
jah128 0:9f7b70e0186e 52 #define REG_HIGHTEMP_LIMIT 0x0B
jah128 0:9f7b70e0186e 53 #define REG_LOW_VOLTAGE_LIMIT 0x0C
jah128 0:9f7b70e0186e 54 #define REG_HIGH_VOLTAGE_LIMIT 0x0D
jah128 0:9f7b70e0186e 55 #define REG_MAX_TORQUE 0x0E
jah128 0:9f7b70e0186e 56 #define REG_TORQUE_ENABLE 0x18
jah128 0:9f7b70e0186e 57 #define REG_GOAL_POSITION 0x1E
jah128 0:9f7b70e0186e 58 #define REG_MOVING_SPEED 0x20
jah128 0:9f7b70e0186e 59 #define REG_VOLTS 0x2A
jah128 0:9f7b70e0186e 60 #define REG_TEMP 0x2B
jah128 0:9f7b70e0186e 61 #define REG_SPEED 0x26
jah128 0:9f7b70e0186e 62 #define REG_LOAD 0x28
jah128 0:9f7b70e0186e 63 #define REG_MOVING 0x2E
jah128 0:9f7b70e0186e 64 #define REG_POSITION 0x24
jah128 0:9f7b70e0186e 65 #define REG_EEPROM_LOCK 0x2F
jah128 0:9f7b70e0186e 66
jah128 0:9f7b70e0186e 67 #define MODE_POSITION 0
jah128 0:9f7b70e0186e 68 #define MODE_ROTATION 1
jah128 0:9f7b70e0186e 69
jah128 0:9f7b70e0186e 70 #define CW 1
jah128 0:9f7b70e0186e 71 #define CCW 0
jah128 0:9f7b70e0186e 72
jah128 0:9f7b70e0186e 73 extern Serial data;
jah128 0:9f7b70e0186e 74
jah128 0:9f7b70e0186e 75 /** Servo Class
jah128 0:9f7b70e0186e 76 * Class with functions to control a Dynamixel single-wire TTL Serial Servo
jah128 0:9f7b70e0186e 77 *
jah128 0:9f7b70e0186e 78 * Example code for main.cpp:
jah128 0:9f7b70e0186e 79 * @code
jah128 0:9f7b70e0186e 80 * #include "servo.h"
jah128 0:9f7b70e0186e 81 * Servo servo(p9,p10)
jah128 0:9f7b70e0186e 82 * int main(){
jah128 0:9f7b70e0186e 83 * arm.init();
jah128 0:9f7b70e0186e 84 * while(1) { //Do something!
jah128 0:9f7b70e0186e 85 * }
jah128 0:9f7b70e0186e 86 * }
jah128 0:9f7b70e0186e 87 * @endcode
jah128 0:9f7b70e0186e 88 */
jah128 0:9f7b70e0186e 89 class Servo {
jah128 0:9f7b70e0186e 90
jah128 0:9f7b70e0186e 91 public:
jah128 0:9f7b70e0186e 92
jah128 0:9f7b70e0186e 93 /** Create a Dynamixel servo controller object connected to the specified serial port, with the specified ID
jah128 0:9f7b70e0186e 94 *
jah128 0:9f7b70e0186e 95 * @param pin tx pin
jah128 0:9f7b70e0186e 96 * @param pin rx pin
jah128 0:9f7b70e0186e 97 */
jah128 0:9f7b70e0186e 98 Servo(PinName tx, PinName rx);
jah128 0:9f7b70e0186e 99
jah128 0:9f7b70e0186e 100 void ClearBuffer(void);
jah128 0:9f7b70e0186e 101
jah128 0:9f7b70e0186e 102 void ScanForServos(void);
jah128 0:9f7b70e0186e 103
jah128 0:9f7b70e0186e 104
jah128 0:9f7b70e0186e 105 /** Prints (over PC serial) a detailed set of data for the servo
jah128 0:9f7b70e0186e 106 *
jah128 0:9f7b70e0186e 107 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 108 */
jah128 0:9f7b70e0186e 109 void DebugData(int ID);
jah128 0:9f7b70e0186e 110
jah128 0:9f7b70e0186e 111 /** Set the mode of the servo
jah128 0:9f7b70e0186e 112 *
jah128 0:9f7b70e0186e 113 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 114 * @param mode
jah128 0:9f7b70e0186e 115 * 0 = Positional, default
jah128 0:9f7b70e0186e 116 * 1 = Continuous rotation
jah128 0:9f7b70e0186e 117 */
jah128 0:9f7b70e0186e 118 int SetMode(int ID, int mode);
jah128 0:9f7b70e0186e 119
jah128 0:9f7b70e0186e 120 /** Set goal angle, in positional mode
jah128 0:9f7b70e0186e 121 *
jah128 0:9f7b70e0186e 122 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 123 * @param goal 0-4095
jah128 0:9f7b70e0186e 124 * @param flags, defaults to 0
jah128 0:9f7b70e0186e 125 * flags[0] = blocking, return when goal position reached
jah128 0:9f7b70e0186e 126 * flags[1] = register, activate with a broadcast trigger
jah128 0:9f7b70e0186e 127 *
jah128 0:9f7b70e0186e 128 */
jah128 0:9f7b70e0186e 129 int SetGoal(int ID, short goal, int flags = 0);
jah128 0:9f7b70e0186e 130
jah128 0:9f7b70e0186e 131 /** Set goal angle in integer degrees, in positional mode
jah128 0:9f7b70e0186e 132 *
jah128 0:9f7b70e0186e 133 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 134 * @param degrees 0-300
jah128 0:9f7b70e0186e 135 * @param flags, defaults to 0
jah128 0:9f7b70e0186e 136 * flags[0] = blocking, return when goal position reached
jah128 0:9f7b70e0186e 137 * flags[1] = register, activate with a broadcast trigger
jah128 0:9f7b70e0186e 138 *
jah128 0:9f7b70e0186e 139 */
jah128 0:9f7b70e0186e 140 int SetGoalDegrees(int ID, int degrees, int flags = 0);
jah128 0:9f7b70e0186e 141
jah128 0:9f7b70e0186e 142
jah128 0:9f7b70e0186e 143 /** Set the speed of the servo in continuous rotation mode
jah128 0:9f7b70e0186e 144 *
jah128 0:9f7b70e0186e 145 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 146 * @param speed, -1.0 to 1.0
jah128 0:9f7b70e0186e 147 * -1.0 = full speed counter clock wise
jah128 0:9f7b70e0186e 148 * 1.0 = full speed clock wise
jah128 0:9f7b70e0186e 149 */
jah128 0:9f7b70e0186e 150 int SetCRSpeed(int ID, float speed);
jah128 0:9f7b70e0186e 151
jah128 0:9f7b70e0186e 152
jah128 0:9f7b70e0186e 153 /** Set the clockwise limit of the servo
jah128 0:9f7b70e0186e 154 *
jah128 0:9f7b70e0186e 155 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 156 * @param degrees, 0-300
jah128 0:9f7b70e0186e 157 */
jah128 0:9f7b70e0186e 158 int SetCWLimit(int ID, int degrees);
jah128 0:9f7b70e0186e 159
jah128 0:9f7b70e0186e 160 /** Set the counter-clockwise limit of the servo
jah128 0:9f7b70e0186e 161 *
jah128 0:9f7b70e0186e 162 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 163 * @param degrees, 0-300
jah128 0:9f7b70e0186e 164 */
jah128 0:9f7b70e0186e 165 int SetCCWLimit(int ID, int degrees);
jah128 0:9f7b70e0186e 166
jah128 0:9f7b70e0186e 167 /** Enable or disable the torque hold of the servo
jah128 0:9f7b70e0186e 168 *
jah128 0:9f7b70e0186e 169 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 170 * @param enable, 0=disable (floppy) 1=enable (hold)
jah128 0:9f7b70e0186e 171 */
jah128 0:9f7b70e0186e 172 int SetTorqueEnable (int ID, int enable);
jah128 0:9f7b70e0186e 173
jah128 0:9f7b70e0186e 174
jah128 0:9f7b70e0186e 175 /** Change the low voltage limit of a servo
jah128 0:9f7b70e0186e 176 *
jah128 0:9f7b70e0186e 177 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 178 * @param lv_limit, 0-254
jah128 0:9f7b70e0186e 179 *
jah128 0:9f7b70e0186e 180 * voltage = lv_limit / 10
jah128 0:9f7b70e0186e 181 */
jah128 0:9f7b70e0186e 182 int SetLowVoltageLimit (int ID, char lv_limit);
jah128 0:9f7b70e0186e 183
jah128 0:9f7b70e0186e 184 /** Lock the EEPROM area of a servo
jah128 0:9f7b70e0186e 185 *
jah128 0:9f7b70e0186e 186 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 187 */
jah128 0:9f7b70e0186e 188 int LockEeprom(int ID);
jah128 0:9f7b70e0186e 189
jah128 0:9f7b70e0186e 190 /** Change the high voltage limit of a servo
jah128 0:9f7b70e0186e 191 *
jah128 0:9f7b70e0186e 192 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 193 * @param hv_limit, 0-254
jah128 0:9f7b70e0186e 194 *
jah128 0:9f7b70e0186e 195 * voltage = hv_limit / 10
jah128 0:9f7b70e0186e 196 */
jah128 0:9f7b70e0186e 197 int SetHighVoltageLimit (int ID, char hv_limit);
jah128 0:9f7b70e0186e 198
jah128 0:9f7b70e0186e 199 /** Change the delay time of a servo
jah128 0:9f7b70e0186e 200 *
jah128 0:9f7b70e0186e 201 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 202 * @param delay, 0-254 C
jah128 0:9f7b70e0186e 203 *
jah128 0:9f7b70e0186e 204 */
jah128 0:9f7b70e0186e 205 int SetDelayTime (int ID, char delay);
jah128 0:9f7b70e0186e 206
jah128 0:9f7b70e0186e 207 /** Change the high temperature limit of a servo
jah128 0:9f7b70e0186e 208 *
jah128 0:9f7b70e0186e 209 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 210 * @param temp_limit, 0-254 C
jah128 0:9f7b70e0186e 211 *
jah128 0:9f7b70e0186e 212 */
jah128 0:9f7b70e0186e 213 int SetTemperatureLimit (int ID, char temp_limit);
jah128 0:9f7b70e0186e 214
jah128 0:9f7b70e0186e 215 /** Change the ID of a servo
jah128 0:9f7b70e0186e 216 *
jah128 0:9f7b70e0186e 217 * @param CurentID 1-255
jah128 0:9f7b70e0186e 218 * @param NewID 1-255
jah128 0:9f7b70e0186e 219 *
jah128 0:9f7b70e0186e 220 * If a servo ID is not know, the broadcast address of 0 can be used for CurrentID.
jah128 0:9f7b70e0186e 221 * In this situation, only one servo should be connected to the bus
jah128 0:9f7b70e0186e 222 */
jah128 0:9f7b70e0186e 223 int SetID(int CurrentID, int NewID);
jah128 0:9f7b70e0186e 224
jah128 0:9f7b70e0186e 225 /** Change the baud of a servo
jah128 0:9f7b70e0186e 226 *
jah128 0:9f7b70e0186e 227 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 228 * @param baud, 0-252
jah128 0:9f7b70e0186e 229 *
jah128 0:9f7b70e0186e 230 * baudrate = 2000000/baud (with special cases 250=2.25Mbps, 251=2.5Mbps and 252=3Mbps on MX-28 only)
jah128 0:9f7b70e0186e 231 */
jah128 0:9f7b70e0186e 232 int SetBaud (int ID, int baud);
jah128 0:9f7b70e0186e 233
jah128 0:9f7b70e0186e 234 /** Poll to see if the servo is moving
jah128 0:9f7b70e0186e 235 *
jah128 0:9f7b70e0186e 236 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 237 * @returns true is the servo is moving
jah128 0:9f7b70e0186e 238 */
jah128 0:9f7b70e0186e 239 int isMoving(int ID);
jah128 0:9f7b70e0186e 240
jah128 0:9f7b70e0186e 241 /** Send the broadcast "trigger" command, to activate any outstanding registered commands
jah128 0:9f7b70e0186e 242 */
jah128 0:9f7b70e0186e 243 void trigger(void);
jah128 0:9f7b70e0186e 244
jah128 0:9f7b70e0186e 245 /** Read the model number of the servo
jah128 0:9f7b70e0186e 246 *
jah128 0:9f7b70e0186e 247 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 248 * @returns int matching defined model number
jah128 0:9f7b70e0186e 249 */
jah128 0:9f7b70e0186e 250 int GetModelNumber(int ID);
jah128 0:9f7b70e0186e 251
jah128 0:9f7b70e0186e 252 /** Read the current angle of the servo
jah128 0:9f7b70e0186e 253 *
jah128 0:9f7b70e0186e 254 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 255 * @returns float in the range 0.0-300.0
jah128 0:9f7b70e0186e 256 */
jah128 0:9f7b70e0186e 257 float GetPositionDegrees(int ID);
jah128 0:9f7b70e0186e 258
jah128 0:9f7b70e0186e 259
jah128 0:9f7b70e0186e 260 /** Read the raw angle reading of the servo
jah128 0:9f7b70e0186e 261 *
jah128 0:9f7b70e0186e 262 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 263 * @returns short in the range 0 - 4095 for MX-28
jah128 0:9f7b70e0186e 264 */
jah128 0:9f7b70e0186e 265 short GetPosition(int ID);
jah128 0:9f7b70e0186e 266
jah128 0:9f7b70e0186e 267
jah128 0:9f7b70e0186e 268 /** Read the temperature of the servo
jah128 0:9f7b70e0186e 269 *
jah128 0:9f7b70e0186e 270 * @returns float temperature
jah128 0:9f7b70e0186e 271 */
jah128 0:9f7b70e0186e 272 float GetTemp(int ID);
jah128 0:9f7b70e0186e 273
jah128 0:9f7b70e0186e 274 /** Read the supply voltage of the servo
jah128 0:9f7b70e0186e 275 *
jah128 0:9f7b70e0186e 276 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 277 * @returns short voltage * 10
jah128 0:9f7b70e0186e 278 */
jah128 0:9f7b70e0186e 279 short GetVoltage(int ID) ;
jah128 0:9f7b70e0186e 280
jah128 0:9f7b70e0186e 281 /** Read the supply voltage of the servo
jah128 0:9f7b70e0186e 282 *
jah128 0:9f7b70e0186e 283 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 284 * @returns float voltage
jah128 0:9f7b70e0186e 285 */
jah128 0:9f7b70e0186e 286 float GetVolts(int ID);
jah128 0:9f7b70e0186e 287
jah128 0:9f7b70e0186e 288 /** Read the temperature of the servo
jah128 0:9f7b70e0186e 289 *
jah128 0:9f7b70e0186e 290 * @returns short temperature
jah128 0:9f7b70e0186e 291 */
jah128 0:9f7b70e0186e 292 short GetTemperature(int ID);
jah128 0:9f7b70e0186e 293
jah128 0:9f7b70e0186e 294 /** Read the torque load of the servo
jah128 0:9f7b70e0186e 295 *
jah128 0:9f7b70e0186e 296 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 297 * @returns short load, range 0-2048, 0 is 100% CCW, 1024 is zero and 2048 is 100% CW
jah128 0:9f7b70e0186e 298 */
jah128 0:9f7b70e0186e 299 short GetLoad(int ID) ;
jah128 0:9f7b70e0186e 300
jah128 0:9f7b70e0186e 301 /** Read the speed of the servo
jah128 0:9f7b70e0186e 302 *
jah128 0:9f7b70e0186e 303 * @param ID, the Bus ID of the servo 1-255
jah128 0:9f7b70e0186e 304 * @returns short speed
jah128 0:9f7b70e0186e 305 */
jah128 0:9f7b70e0186e 306 short GetSpeed(int ID) ;
jah128 0:9f7b70e0186e 307
jah128 0:9f7b70e0186e 308 /** Change the internal baud rate to something other than 1000000 (note MX-28s default to 57600)
jah128 0:9f7b70e0186e 309 *
jah128 0:9f7b70e0186e 310 * @param baud, the baud rate to set
jah128 0:9f7b70e0186e 311 * @param delaytime, the delay time to set (x2 us)
jah128 0:9f7b70e0186e 312 */
jah128 0:9f7b70e0186e 313 void SetInitBaud(int baud, int delaytime);
jah128 0:9f7b70e0186e 314
jah128 0:9f7b70e0186e 315 /** Returns the software lower limit for the given servo
jah128 0:9f7b70e0186e 316 *
jah128 0:9f7b70e0186e 317 * @param ID, the servo ID to return the limit for
jah128 0:9f7b70e0186e 318 * @returns short limit (either preset value or 0)
jah128 0:9f7b70e0186e 319 */
jah128 0:9f7b70e0186e 320 short GetLowerLimit(int ID);
jah128 0:9f7b70e0186e 321
jah128 0:9f7b70e0186e 322 /** Returns the software upper limit for the given servo
jah128 0:9f7b70e0186e 323 *
jah128 0:9f7b70e0186e 324 * @param ID, the servo ID to return the limit for
jah128 0:9f7b70e0186e 325 * @returns short limit (either preset value or 4095)
jah128 0:9f7b70e0186e 326 */
jah128 0:9f7b70e0186e 327 short GetUpperLimit(int ID);
jah128 0:9f7b70e0186e 328
jah128 0:9f7b70e0186e 329
jah128 0:9f7b70e0186e 330 private :
jah128 0:9f7b70e0186e 331 SerialHalfDuplex _servo;
jah128 0:9f7b70e0186e 332 int read(int ID, int start, int length, char* data);
jah128 0:9f7b70e0186e 333 int write(int ID, int start, int length, char* data, int flag=0);
jah128 0:9f7b70e0186e 334
jah128 0:9f7b70e0186e 335 };
jah128 0:9f7b70e0186e 336
jah128 0:9f7b70e0186e 337
jah128 0:9f7b70e0186e 338
jah128 0:9f7b70e0186e 339 #endif
jah128 0:9f7b70e0186e 340
jah128 0:9f7b70e0186e 341 /*
jah128 0:9f7b70e0186e 342 * Copyright 2017 University of York
jah128 0:9f7b70e0186e 343 *
jah128 0:9f7b70e0186e 344 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
jah128 0:9f7b70e0186e 345 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
jah128 0:9f7b70e0186e 346 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS
jah128 0:9f7b70e0186e 347 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
jah128 0:9f7b70e0186e 348 * See the License for the specific language governing permissions and limitations under the License.
jah128 0:9f7b70e0186e 349 *
jah128 0:9f7b70e0186e 350 */
jah128 0:9f7b70e0186e 351
jah128 0:9f7b70e0186e 352 /*
jah128 0:9f7b70e0186e 353 * Copyright (c) 2010, Chris Styles (http://mbed.org)
jah128 0:9f7b70e0186e 354 *
jah128 0:9f7b70e0186e 355 * Permission is hereby granted, free of charge, to any person obtaining a copy
jah128 0:9f7b70e0186e 356 * of this software and associated documentation files (the "Software"), to deal
jah128 0:9f7b70e0186e 357 * in the Software without restriction, including without limitation the rights
jah128 0:9f7b70e0186e 358 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
jah128 0:9f7b70e0186e 359 * copies of the Software, and to permit persons to whom the Software is
jah128 0:9f7b70e0186e 360 * furnished to do so, subject to the following conditions:
jah128 0:9f7b70e0186e 361 *
jah128 0:9f7b70e0186e 362 * The above copyright notice and this permission notice shall be included in
jah128 0:9f7b70e0186e 363 * all copies or substantial portions of the Software.
jah128 0:9f7b70e0186e 364 *
jah128 0:9f7b70e0186e 365 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jah128 0:9f7b70e0186e 366 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jah128 0:9f7b70e0186e 367 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
jah128 0:9f7b70e0186e 368 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jah128 0:9f7b70e0186e 369 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
jah128 0:9f7b70e0186e 370 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
jah128 0:9f7b70e0186e 371 * THE SOFTWARE.
jah128 0:9f7b70e0186e 372 */