1 /* 2 OrangutanX2.h - Library of functions for controlling the auxiliary 3 processor on the Orangutan X2. 4 */ 5 6 /* 7 * Written by Ben Schmidel, Mar 2, 2010. 8 * Copyright (c) 2010-2012 Pololu Corporation. For more information, see 9 * 10 * http://www.pololu.com 11 * http://forum.pololu.com 12 * http://www.pololu.com/docs/0J18 13 * 14 * You may freely modify and share this code, as long as you keep this 15 * notice intact (including the three links above). Licensed under the 16 * Creative Commons BY-SA 3.0 license: 17 * 18 * http://creativecommons.org/licenses/by-sa/3.0/ 19 * 20 * Disclaimer: To the extent permitted by law, Pololu provides this work 21 * without any warranty. It might be defective, in which case you agree 22 * to be responsible for all resulting costs and damages. 23 */ 24 25 #ifndef OrangutanX2_h 26 #define OrangutanX2_h 27 28 #include "../OrangutanResources/include/OrangutanModel.h" 29 30 #ifdef _ORANGUTAN_X2 31 32 #include "../OrangutanBuzzer/OrangutanBuzzer.h" // for note macros 33 34 35 // COMMANDS 36 #define CMD_MOTOR1_BRAKE_LOW 128 37 #define CMD_MOTOR1_BRAKE_HIGH 130 38 #define CMD_MOTOR2_BRAKE_LOW 132 39 #define CMD_MOTOR2_BRAKE_HIGH 134 40 #define CMD_MOTOR1_FORWARD 136 41 #define CMD_MOTOR1_REVERSE 138 42 #define CMD_MOTOR2_FORWARD 140 43 #define CMD_MOTOR2_REVERSE 142 44 #define CMD_JOINT_BRAKE 144 // 150 will also joint-brake low 45 #define CMD_JOINT_FORWARD 146 46 #define CMD_JOINT_REVERSE 148 47 #define CMD_JOINT_ACCEL_FORWARD 228 48 #define CMD_JOINT_ACCEL_REVERSE 230 49 #define CMD_MOTOR1_ACCEL_FORWARD 232 50 #define CMD_MOTOR1_ACCEL_REVERSE 234 51 #define CMD_MOTOR2_ACCEL_FORWARD 236 52 #define CMD_MOTOR2_ACCEL_REVERSE 238 53 54 #define CMD_DISABLE_JOINT_MOTOR_MODE 214 55 #define CMD_ENABLE_JOINT_MOTOR_MODE 215 56 #define CMD_SET_M1_ACCELERATION 208 57 #define CMD_SET_M2_ACCELERATION 209 58 #define CMD_SET_M1_BRAKE_DURATION 188 59 #define CMD_SET_M2_BRAKE_DURATION 190 60 #define CMD_SET_PWM_FREQUENCIES 210 61 #define CMD_SET_NUM_CURRENT_SAMPLES 212 62 #define CMD_SET_M1_CURRENT_LIMIT 192 63 #define CMD_SET_M2_CURRENT_LIMIT 194 64 65 #define CMD_GET_M1_CURRENT 216 66 #define CMD_GET_M2_CURRENT 217 67 68 69 #define CMD_BUZZER_OFF 225 70 #define CMD_PLAY_NOTE 152 71 #define CMD_PLAY_FREQUENCY 160 72 73 #define CMD_PLAY_MELODY 176 74 #define CMD_STORE_NOTE 168 75 #define CMD_END_MELODY 224 76 #define CMD_ERASE_MELODIES 186 77 78 #define CMD_SET_VOLUME 226 79 #define CMD_SET_NOTE_GAP 187 80 81 82 #define CMD_SEND_SERIAL 220 83 #define CMD_READ_SERIAL 219 84 85 #define CMD_SET_SERIAL 200 86 #define CMD_SET_AND_SAVE_SERIAL 201 87 #define CMD_SET_READ_READY_SIZE 227 88 89 #define CMD_GET_SEND_BUFF_FREE_SPACE 222 90 #define CMD_GET_READ_BUFF_NUM_BYTES 223 91 #define CMD_GET_UART_ERROR 252 92 93 94 #define CMD_WRITE_EEPROM 240 95 #define CMD_READ_EEPROM 248 96 #define CMD_GET_EEPROM_BUSY 254 97 98 99 #define CMD_GET_STATUS 218 100 #define CMD_GET_FIRMWARE_VERSION 253 101 102 103 // Arguments for the setMotor() method 104 #define MOTOR1 0 105 #define MOTOR2 1 106 #define JOINT_MOTOR 0xFF 107 108 #define IMMEDIATE_DRIVE 0 109 #define ACCEL_DRIVE 1 110 #define BRAKE_LOW 0xFF 111 112 // argument options for setMotorPWM() function 113 // PWM frequency = 20MHz / prescaler / 2^(bit-resolution) 114 // e.g. PRESCALER_8 with RESOLUTION_7BIT = freq. of 19.5 kHz 115 #define RESOLUTION_7BIT 0 // pwm ranges from 0 - 127 116 #define RESOLUTION_8BIT 1 // pwm ranges from 0 - 255 117 #define PRESCALER_8 0 // 20MHz / 8 118 #define PRESCALER_64 1 // 20MHz / 64 119 #define PRESCALER_256 2 // 20MHz / 256 120 #define PRESCALER_1024 3 // 20MHz / 1024 121 122 // argument options for the setSerial() function 123 #define UART_READ_BUFF_SZ 32 // UART read buffer can hold 32 bytes 124 #define UART_SEND_BUFF_SZ 32 // UART send buffer can hold 32 bytes 125 126 #define UART_NO_PARITY 0 127 #define UART_EVEN_PARITY 2 128 #define UART_ODD_PARITY 3 129 130 #define UART_ONE_STOP_BIT 0 131 #define UART_TWO_STOP_BITS 1 132 133 #define UART_NORMAL_SPEED 0 134 #define UART_DOUBLE_SPEED 1 135 136 // UBRR values that achieve various bauds at normal speed 137 #define UBRR_115200_BAUD 10 // -1.4% error 138 #define UBRR_76800_BAUD 15 // 1.7% error 139 #define UBRR_57600_BAUD 21 // -1.4% error 140 #define UBRR_38400_BAUD 32 // -1.4% error 141 #define UBRR_28800_BAUD 42 // .9% error 142 #define UBRR_19200_BAUD 64 // .2% error 143 #define UBRR_14400_BAUD 86 // -.2% error 144 #define UBRR_9600_BAUD 129 // .2% error 145 #define UBRR_4800_BAUD 259 // .2% error 146 #define UBRR_2400_BAUD 520 // 0% error 147 148 // UART error byte bits 149 #define UART_SEND_BUFF_OVERRUN 1 // UART send buffer overflow 150 #define UART_READ_BUFF_OVERRUN 2 // UART read buffer overflow 151 #define UART_FRAME_ERROR 4 152 #define UART_DATA_OVERRUN 8 153 #define UART_PARITY_ERROR 16 154 #define UART_READ_BUFF_UNDERRUN 32 // tried reading from empty buffer 155 156 // status byte bits 157 #define STATUS_UART_ERROR 1 // cleared only on status byte read 158 #define STATUS_UART_READ_READY 2 // value always reflects current state 159 #define STATUS_UART_SEND_FULL 4 // value always reflects current state 160 #define STATUS_BUZZER_FINISHED 8 // value always reflects current state 161 #define STATUS_M1_FAULT 16 // cleared only on status byte read 162 #define STATUS_M1_CURRENT_HIGH 32 // cleared only on status byte read 163 #define STATUS_M2_FAULT 64 // cleared only on status byte read 164 #define STATUS_M2_CURRENT_HIGH 128 // cleared only on status byte read 165 166 167 // mega168's EEPROM addresses for settings 168 #define ADDR_INIT_CHECK 0 // check to see if EEPROM initialized 169 #define ADDR_M1_PWM_FREQUENCY 1 // freq + resolution of PWM1 (timer0) 170 #define ADDR_M2_PWM_FREQUENCY 2 // freq + resolution of PWM2 (timer2) 171 #define ADDR_M1_CURRENT_SAMPLES 3 // number of M1 ADC samples to avg 172 // must be a power of 2 <= 128 173 #define ADDR_M2_CURRENT_SAMPLES 4 // number of M2 ADC samples to avg 174 // must be a power of 2 <= 128 175 #define ADDR_M1_CURRENT_LIMIT 5 // 0 = no limit 176 #define ADDR_M1_CL_P_CONST 6 // 7-bit P val: pwm += P * (CL - cur) 177 // 0 = shutdown motor on overlimit 178 #define ADDR_M2_CURRENT_LIMIT 7 // 0 = no limit 179 #define ADDR_M2_CL_P_CONST 8 // 7-bit P val: pwm += P * (CL - cur) 180 // 0 = shutdowm motor on overlimit 181 #define ADDR_M1_ACCELERATION 9 // M1 acceleration; 0 = instantaneous 182 #define ADDR_M2_ACCELERATION 10 // M2 acceleration; 0 = instantaneous 183 #define ADDR_M1_BRAKE_DURATION 11 // M1 time to spend hard braking (ms) 184 #define ADDR_M2_BRAKE_DURATION 12 // M2 time to spend hard braking (ms) 185 #define ADDR_SERIAL_SETTINGS 13 // parity, stop bits, 2x speed, p. mode 186 #define ADDR_SERIAL_UBRRH 14 // UBRRH register (determines baud) 187 #define ADDR_SERIAL_UBRRL 15 // UBRRL register (determines baud) 188 #define ADDR_SERIAL_READ_READY 16 // UART read buffer ready for reading 189 #define ADDR_BUZZER_VOLUME 17 // buzzer volume 190 #define ADDR_STARTUP_MELODY 18 // melody that plays on startup 191 // 0 - 7 = melody, 8 = silence 192 // else chirp 193 #define ADDR_NOTE_GAP 19 // default duration in ms of silent 194 // pause inserted after each note 195 #define ADDR_SCK_DURATION 20 // programmer SPI SCK setting 196 #define ADDR_ISP_STATE 21 // 168 ISP state (in progmode or not) 197 #define ADDR_ISP_SW_MINOR 22 // ISP version major byte 198 #define ADDR_ISP_SW_MAJOR 23 // ISP version minor byte 199 200 201 // no pointer to the start of melody0 is needed as location never changes 202 #define ADDR_MELODY_START_PTR_MSBS 24 // bit i is MSB of melody i+1 pointer 203 #define ADDR_MELODY1_START_PTR 25 // address of pointer to melody1 start 204 #define ADDR_MELODY2_START_PTR 26 // melody 2 205 #define ADDR_MELODY3_START_PTR 27 // melody 3 206 #define ADDR_MELODY4_START_PTR 28 // melody 4 207 #define ADDR_MELODY5_START_PTR 29 // melody 5 208 #define ADDR_MELODY6_START_PTR 30 // melody 6 209 #define ADDR_MELODY7_START_PTR 31 // melody 7 210 #define ADDR_MELODY7_END_PTR 32 // ptr to end of melody 7 211 212 // address of 1st note of melody 0 213 #define ADDR_MELODY0_START 33 214 215 // there is room in EEPROM for 159 notes, distributed in any way amongst the 216 // eight melodies. The mega168's EEPROM is 512 bytes in size. 217 218 #ifdef __cplusplus 219 220 // C++ Function Declarations 221 222 class OrangutanX2 223 { 224 private: 225 static void writeToEEPROM(unsigned int address, unsigned char data); 226 static unsigned char isEEPROMBusy(); 227 228 // Delays execution until the EEPROM on the auxiliary MCU is available for 229 // writing or reading. This is a PRIVATE method. waitForEEPROM()230 static inline void waitForEEPROM() 231 { 232 while (isEEPROMBusy()); 233 } 234 235 236 public: 237 static unsigned char getStatus(); 238 static void getFirmwareVersion(unsigned char &majorVersion, unsigned char &minorVersion); 239 240 // After this function is called, the mega168 must be manually reset for the 241 // changes to take effect. After the reset the settings will all be restored 242 // to their factory default values. restoreDefaultSettings()243 static inline void restoreDefaultSettings() 244 { 245 writeToEEPROM(ADDR_INIT_CHECK, 0xFF); 246 } 247 248 static void saveAVRISPVersion(unsigned char vMajor, unsigned char vMinor); 249 250 // This method writes a byte to EEPROM if the specified address is outside 251 // the parameter address space. It can be safely used for general non-volatile 252 // data storage using the auxiliary MCU's EEPROM. If the specified address is 253 // inside the parameter address space (i.e. address <= 23), the method 254 // does nothing and the data is not stored. saveEEPROMByte(unsigned int address,unsigned char data)255 static inline void saveEEPROMByte(unsigned int address, unsigned char data) 256 { 257 if (address > 23) 258 writeToEEPROM(address, data); 259 } 260 261 // This method provides public access to the private writeToEEPROM() method. 262 // It is intended to be used for saving X2 parameters, but it can be used to write 263 // bytes to any address in the auxiliary MCU's EEPROM (0 - 511). For saving bytes 264 // that are not parameters, the saveEEPROMByte() method should be used so that 265 // parameter data cannot be accidentally corrupted. Parameter addresses are defined 266 // in OrangutanX2.h. saveParameter(unsigned int paramAddress,unsigned char paramValue)267 static inline void saveParameter(unsigned int paramAddress, unsigned char paramValue) 268 { 269 writeToEEPROM(paramAddress, paramValue); 270 } 271 272 static unsigned char readEEPROMByte(unsigned int address); 273 readParameter(unsigned int paramAddress)274 static inline unsigned char readParameter(unsigned int paramAddress) 275 { 276 return readEEPROMByte(paramAddress); 277 } 278 279 static void setMotor(unsigned char motor, unsigned char operationMode, int speed); 280 static void setPWMFrequencies(unsigned char M1Resolution, unsigned char M1Prescaler, 281 unsigned char M2Resolution, unsigned char M2Prescaler, unsigned char save); 282 static void setAcceleration(unsigned char motor, unsigned char accel, 283 unsigned char save); 284 static void setBrakeDuration(unsigned char motor, unsigned char brakeDur, 285 unsigned char save); 286 static void setNumCurrentSamples( unsigned char M1Exponent, unsigned char M2Exponent, 287 unsigned char save); 288 static void setCurrentLimit(unsigned char motor, unsigned char limit, 289 unsigned char P, unsigned char save); 290 static unsigned char getMotorCurrent(unsigned char motor); 291 292 static void playNote(unsigned char note, unsigned int duration); 293 static void playFrequency(unsigned int frequency, unsigned int duration); 294 static void buzzerOff(); 295 static void setVolume(unsigned char volume, unsigned char save = 0); 296 static void setNoteGap(unsigned char noteGap, unsigned char save = 0); 297 298 static void setSerial(unsigned char parity, unsigned char stopBits, 299 unsigned char speedMode, unsigned int baud_UBRR, unsigned char save); 300 static void enablePermanentProgMode(unsigned char save); 301 static void setReadReadySize(unsigned char rrSize, unsigned char save); 302 static unsigned char getTXBufferSpace(); 303 static unsigned char getNumRXBytes(); 304 static unsigned char getSerialError(); 305 static unsigned char sendSerialByteIfReady(unsigned char data); 306 static unsigned char readSerialByte(); 307 }; 308 309 extern "C" { 310 #endif // __cplusplus 311 312 // C Function Declarations 313 314 void x2_get_firmware_version(unsigned char *vmajor, unsigned char *vminor); 315 unsigned char x2_get_status(void); 316 void x2_restore_default_settings(void); 317 void x2_save_avrisp_version(unsigned char vmajor, unsigned char vminor); 318 void x2_save_eeprom_byte(unsigned int address, unsigned char data); 319 void x2_save_parameter(unsigned int param_address, unsigned char param_value); 320 unsigned char x2_read_eeprom_byte(unsigned int address); 321 unsigned char x2_read_parameter(unsigned int param_address); 322 323 void x2_set_motor(unsigned char motor, unsigned char operation_mode, int speed); 324 void x2_set_pwm_frequencies(unsigned char m1_resolution, unsigned char m1_prescaler, 325 unsigned char m2_resolution, unsigned char m2_prescaler, unsigned char save); 326 void x2_set_acceleration(unsigned char motor, unsigned char accel, unsigned char save); 327 void x2_set_brake_duration(unsigned char motor, unsigned char brake_dur, unsigned char save); 328 void x2_set_num_current_samples(unsigned char m1_exp, unsigned char m2_exp, unsigned char save); 329 void x2_set_current_limit(unsigned char motor, unsigned char limit, unsigned char p, 330 unsigned char save); 331 unsigned char x2_get_motor_current(unsigned char motor); 332 333 void x2_play_note(unsigned char note, unsigned int duration); 334 void x2_play_frequency(unsigned int frequency, unsigned int duration); 335 void x2_buzzer_off(void); 336 void x2_set_volume(unsigned char volume, unsigned char save); 337 void x2_set_note_gap(unsigned char note_gap, unsigned char save); 338 339 void x2_set_serial(unsigned char parity, unsigned char stop_bits, unsigned char speed_mode, 340 unsigned int baud_ubrr, unsigned char save); 341 void x2_enable_permanent_programming_mode(unsigned char save); 342 void x2_set_read_ready_size(unsigned char rrsize, unsigned char save); 343 unsigned char x2_get_tx_buffer_space(void); 344 unsigned char x2_get_num_rx_bytes(void); 345 unsigned char x2_get_serial_error(void); 346 unsigned char x2_send_serial_byte_if_ready(unsigned char data); 347 unsigned char x2_read_serial_byte(void); 348 349 #ifdef __cplusplus 350 } 351 #endif 352 353 #endif // _ORANGUTAN_X2 354 355 #endif // OrangutanX2_h 356