Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BeautifulMemeProject by
i2c.cpp
00001 /* University of York Robotics Laboratory PsiSwarm Library: I2C Source File 00002 * 00003 * File: i2c.cpp 00004 * 00005 * (C) Dept. Electronics & Computer Science, University of York 00006 * James Hilder, Alan Millard, Homero Elizondo, Jon Timmis 00007 * 00008 * PsiSwarm Library Version: 0.3 00009 * 00010 * October 2015 00011 * 00012 */ 00013 00014 #include "psiswarm.h" 00015 00016 char gpio_byte0; 00017 char gpio_byte1; 00018 char user_id_set = 0; 00019 char wheel_enc_set = 0; 00020 char switch_set = 0; 00021 00022 char emitter_byte = 0x00; 00023 00024 Timeout update_timeout; 00025 00026 char test; 00027 00028 char get_dc_status() 00029 { 00030 IF_read_aux_ic_data(); 00031 return status_dc_in; 00032 } 00033 00034 void IF_set_IR_emitter_output(char emitter, char state) 00035 { 00036 if(emitter <3) { 00037 if(state == 0) { 00038 char shift = 1 << emitter; 00039 emitter_byte &= (0xFF - shift); 00040 } 00041 if(state == 1) { 00042 char shift = 1 << emitter; 00043 emitter_byte |= shift; 00044 } 00045 char data[2]; 00046 data [0] = 0x0A; //Write to OLAT register 00047 data [1] = emitter_byte; //GP0-3 are outputs on aux expansion IC 00048 //pc.printf("%c\n", emitter_byte); 00049 primary_i2c.write(AUX_IC_ADDRESS,data,2,false); 00050 } 00051 } 00052 00053 void IF_set_base_LED(char state) 00054 { 00055 if(state == 0) { 00056 emitter_byte &= 0xF7; 00057 } else emitter_byte |= 0x08; 00058 char data[2]; 00059 data [0] = 0x0A; //Write to OLAT register 00060 data [1] = emitter_byte; //GP0-3 are outputs on aux expansion IC 00061 primary_i2c.write(AUX_IC_ADDRESS,data,2,false); 00062 00063 } 00064 00065 unsigned short IF_read_IR_adc_value(char adc, char index) 00066 { 00067 char address = ADC1_ADDRESS; 00068 if(adc == 2) address=ADC2_ADDRESS; 00069 // Returns the raw sensor value for the IR sensor defined by index (range 0-7). 00070 short value = 0; 00071 // Read a single value from the ADC 00072 if(index<8) { 00073 char apb[1]; 00074 char data[2]; 00075 switch(index) { 00076 case 0: 00077 apb[0]=0x80; 00078 break; 00079 case 1: 00080 apb[0]=0x90; 00081 break; 00082 case 2: 00083 apb[0]=0xA0; 00084 break; 00085 case 3: 00086 apb[0]=0xB0; 00087 break; 00088 case 4: 00089 apb[0]=0xC0; 00090 break; 00091 case 5: 00092 apb[0]=0xD0; 00093 break; 00094 case 6: 00095 apb[0]=0xE0; 00096 break; 00097 case 7: 00098 apb[0]=0xF0; 00099 break; 00100 } 00101 primary_i2c.write(address,apb,1,false); 00102 primary_i2c.read(address,data,2,false); 00103 value=((data[0] % 16)<<8)+data[1]; 00104 if(value > 4096) value=4096; 00105 value=4096-value; 00106 } 00107 return value; 00108 } 00109 00110 char IF_setup_led_expansion_ic(void) 00111 { 00112 //LED expansion IC is PCA9555 00113 //Address is 0100 001x (0x42) {defined by LED_IC_ADDRESS} 00114 //All 16 entries are outputs as they drive LEDs; the relevant registers are 2&3 (output port registers) and 6&7 (config. registers: a 0=output) 00115 //Message structure: {Address-RW}{Command}{Port 0}{Port 1} 00116 //Command bytes: 00000010 (0x02) = Write to output port 00117 //Command bytes: 00000110 (0x06) = Write to config registers 00118 //Note that for the LEDs, 0 = on, 1 = off 00119 //Port 0 = LED 1:4 Red:Green 00120 //Port 1 = LED 5:8 Red:Green 00121 char data [3]; 00122 data [0] = 0x06; //Write config registers 00123 data [1] = 0x00; //All 8 pins in port 0 are outputs (0) 00124 data [2] = 0x00; //All 8 pins in port 1 are outputs (0) 00125 primary_i2c.write(LED_IC_ADDRESS,data,3,false); 00126 00127 //Turn all LEDs on 00128 data [0] = 0x02; //Write to output port 00129 data [1] = 0x00; //Enable LED1-4 (both colours) 00130 data [2] = 0x00; //Enable LED5-8 (both colours) 00131 primary_i2c.write(LED_IC_ADDRESS,data,3,false); 00132 00133 wait(0.05); 00134 //Turn all LEDs off 00135 data [0] = 0x02; //Write to output port 00136 data [1] = 0xFF; //Enable LED1-4 (both colours) 00137 data [2] = 0xFF; //Enable LED5-8 (both colours) 00138 return primary_i2c.write(LED_IC_ADDRESS,data,3,false); 00139 } 00140 00141 //Returns 0 if successful, 1 if test mode button pressed 00142 void IF_setup_gpio_expansion_ic(void) 00143 { 00144 //Main GPIO expansion IC is PCA9555 00145 //Address is 0100 000x (0x40) {defined by GPIO_IC_ADDRESS} 00146 //All 16 entries are inputs; the relevant registers are 0&1 (input port registers), 4&5 (polarity inv. registers) and 6&7 (config. registers: a 0=output) 00147 //Message structure: {Address-RW}{Command}{Port 0}{Port 1} 00148 //Command bytes: 00000010 (0x02) = Write to output port 00149 //Command bytes: 00000110 (0x06) = Write to config registers 00150 //Note that for the LEDs, 0 = on, 1 = off 00151 //Port 0 = PGDL; PGDR; PGDIR; UP; DOWN; LEFT; RIGHT; CENTER 00152 //Port 1 = ENC_LA; ENC_LB; ENC_RA; ENC_RB; ID0; ID1; ID2; ID3 00153 char data [3]; 00154 char okay = 1; 00155 data [0] = 0x06; //Write config registers 00156 data [1] = 0xFF; //All 8 pins in port 0 are inputs (1) 00157 data [2] = 0xFF; //All 8 pins in port 1 are inputs (1) 00158 if(primary_i2c.write(GPIO_IC_ADDRESS,data,3,false) != 0) { 00159 system_warnings += 2; 00160 okay = 0; 00161 debug("- WARNING: No I2C acknowledge for main GPIO IC\n"); 00162 if(HALT_ON_GPIO_ERROR){ 00163 debug("- PROGRAM HALTED. Check that robot is switched on!\n"); 00164 while(1){ 00165 mbed_led1=1; 00166 mbed_led2=1; 00167 mbed_led3=0; 00168 mbed_led4=0; 00169 wait(0.25); 00170 mbed_led1=0; 00171 mbed_led2=0; 00172 mbed_led3=1; 00173 mbed_led4=1; 00174 wait(0.25); 00175 } 00176 } 00177 } 00178 //Set all inputs to polarity-inverted (so a logic low = 1) 00179 data [0] = 0x04; //Write to polarity inversion ports 00180 data [1] = 0xF8; //Invert polarity of all switch input bits in input port 0 [but not power-good inputs] 00181 data [2] = 0xFF; //Invert polarity of all bits in input port 1 00182 primary_i2c.write(GPIO_IC_ADDRESS,data,3,false); 00183 00184 wait(0.01); 00185 00186 //Read data 00187 char read_data[2]; 00188 char command[1]; //Command to read from input port 0 00189 command[0]=0; 00190 primary_i2c.write(GPIO_IC_ADDRESS,command,1,false); 00191 primary_i2c.read(GPIO_IC_ADDRESS,read_data,2,false); 00192 gpio_byte0 = read_data[0]; 00193 //char ret_val = (gpio_byte0 & 0xF8) >> 3; //Returns a >0 value if a button is being pushed 00194 gpio_byte1 = read_data[1]; 00195 if(okay && testing_voltage_regulators_flag)debug("- Checking 3.3V voltage regulators\n"); 00196 IF_parse_gpio_byte0(gpio_byte0); 00197 IF_parse_gpio_byte1(gpio_byte1); 00198 testing_voltage_regulators_flag = 0; 00199 //Setup interrupt handler for GPIO interrupts 00200 gpio_interrupt.mode(PullUp); 00201 gpio_interrupt.rise(&IF_handle_gpio_interrupt); 00202 //pc.printf("%c %c",gpio_byte0,gpio_byte1); 00203 00204 //Secondary GPIO expansion IC is MCP23009 00205 //Address is 0100 111 (0x4E) {defined by AUX_IC_ADDRESS} 00206 //GP0,1,2,3 are outputs for driving infrared emitters and the base LED 00207 //IODIR register wants to be 0xF0 (1=input, 0=output) 00208 data [0] = 0x00; //Write to IODIR register 00209 data [1] = 0xF0; //Set GP0-3 as outputs 00210 primary_i2c.write(AUX_IC_ADDRESS,data,2,false); 00211 00212 if(primary_i2c.write(AUX_IC_ADDRESS,data,2,false) != 0) { 00213 system_warnings += 4; 00214 debug("- WARNING: No I2C acknowledge for aux GPIO IC\n"); 00215 } 00216 data [0] = 0x06; //Write to GPPU register 00217 data [1] = 0x3F; //Set GP0-3 as active pull-up outputs and P4,P5 as pull-up inputs 00218 primary_i2c.write(AUX_IC_ADDRESS,data,2,false); 00219 00220 //My interrupt is not so reliable: poll with a 50ms timeout in case interrupts aren't handled 00221 update_timeout.attach_us(&IF_update_gpio_inputs,50000); 00222 //return ret_val; 00223 } 00224 00225 void IF_read_aux_ic_data() 00226 { 00227 //Read the values of the input pins on the auxilliary GPIO expander 00228 char write_data [1]; 00229 char read_data [1]; 00230 write_data[0] = 0x09; 00231 primary_i2c.write(AUX_IC_ADDRESS,write_data,1,false); 00232 primary_i2c.read(AUX_IC_ADDRESS,read_data,1,false); 00233 char old_charging_state = status_dc_in; 00234 status_dc_in = 1-((read_data[0] & 0x10) >> 4); 00235 if(status_dc_in!=old_charging_state){ 00236 if(status_dc_in == 0)debug("No DC input\n"); 00237 else debug("DC input to charge pins\n"); 00238 } 00239 //pc.printf("Aux IC Data:%X Charge:%d\n",read_data[0],charge_in); 00240 } 00241 00242 void IF_parse_gpio_byte0(char byte) 00243 { 00244 gpio_byte0 = byte; 00245 //GPIO byte zero contains the power line traces and the switch states 00246 char current_switch = ((gpio_byte0 & 0xF8) >> 3); 00247 if(switch_set == 1) { 00248 if(current_switch != switch_byte) { 00249 previous_switch_byte = switch_byte; 00250 switch_byte = current_switch; 00251 event++; 00252 switch_event = 1; 00253 } 00254 } else { 00255 switch_byte = current_switch; 00256 switch_set = 1; 00257 } 00258 if(((gpio_byte0 & 0x01)) != power_good_motor_left){ 00259 power_good_motor_left = (gpio_byte0 & 0x01); 00260 if(!power_good_motor_left){ 00261 if(testing_voltage_regulators_flag || SHOW_VR_WARNINGS)debug("- WARNING: Voltage regulator left motor low\n"); 00262 } 00263 else if(testing_voltage_regulators_flag)debug("- Power good left motor v.reg\n"); 00264 } 00265 if(((gpio_byte0 & 0x02) >> 1) != power_good_motor_right){ 00266 power_good_motor_right = (gpio_byte0 & 0x02) >> 1; 00267 if(!power_good_motor_right){ 00268 if(testing_voltage_regulators_flag || SHOW_VR_WARNINGS)debug("- WARNING: Voltage regulator right motor low\n"); 00269 } 00270 else if(testing_voltage_regulators_flag)debug("- Power good right motor v.reg\n"); 00271 } 00272 if(((gpio_byte0 & 0x04) >> 2) != power_good_infrared){ 00273 power_good_infrared = (gpio_byte0 & 0x04) >> 2; 00274 if(!power_good_infrared){ 00275 if(testing_voltage_regulators_flag || SHOW_VR_WARNINGS)debug("- WARNING: Voltage regulator infrared low\n"); 00276 } 00277 else if(testing_voltage_regulators_flag)debug("- Power good infrared and aux v.reg\n"); 00278 } 00279 if(USE_LED4_FOR_VR_WARNINGS){ 00280 mbed_led4 = (!power_good_motor_left || !power_good_motor_right || !power_good_infrared); 00281 } 00282 //Halt the system if settings flag is set and all v-regs are bad [usually this means robot is switched off!] 00283 if(HALT_ON_ALL_VREGS_LOW && !power_good_motor_left && !power_good_motor_right && !power_good_infrared){ 00284 debug("- PROGRAM HALTED. Check that robot is switched on!\n"); 00285 while(1){ 00286 mbed_led1=1; 00287 mbed_led2=0; 00288 mbed_led3=1; 00289 mbed_led4=0; 00290 wait(0.25); 00291 mbed_led1=0; 00292 mbed_led2=1; 00293 mbed_led3=0; 00294 mbed_led4=1; 00295 wait(0.25); 00296 } 00297 } 00298 } 00299 00300 void IF_parse_gpio_byte1(char byte) 00301 { 00302 gpio_byte1 = byte; 00303 //GPIO byte one contains the wheel encoders and the ID switch 00304 char current_id = ((gpio_byte1 & 0xF0)>> 4); 00305 if(user_id_set == 1) { 00306 if(robot_id != current_id) { 00307 previous_robot_id = robot_id; 00308 robot_id = current_id; 00309 event++; 00310 change_id_event = 1; 00311 } 00312 } else { 00313 robot_id = current_id; 00314 user_id_set = 1; 00315 } 00316 char current_encoder = (gpio_byte1 & 0x0F); 00317 if(wheel_enc_set == 1) { 00318 if(wheel_encoder_byte != current_encoder) { 00319 previous_wheel_encoder_byte = wheel_encoder_byte; 00320 wheel_encoder_byte = current_encoder; 00321 event++; 00322 encoder_event = 1; 00323 } 00324 } else { 00325 wheel_encoder_byte = current_encoder; 00326 wheel_enc_set = 1; 00327 } 00328 } 00329 00330 void IF_handle_gpio_interrupt() 00331 { 00332 test = 1-test; 00333 if(USE_LED3_FOR_INTERRUPTS) mbed_led3 = test; 00334 IF_update_gpio_inputs(); 00335 } 00336 00337 char IF_is_switch_pressed() 00338 { 00339 //Read data 00340 char data[1]; 00341 char command[1] = {0}; //Command to read from input port 0 00342 primary_i2c.write(GPIO_IC_ADDRESS,command,1,false); 00343 primary_i2c.read(GPIO_IC_ADDRESS,data,1,false); 00344 return (data[0] & 0x80); //Returns a 1 if the center button is being pushed 00345 } 00346 00347 00348 char IF_get_switch_state() 00349 { 00350 //Read data 00351 char data[1]; 00352 char command[1] = {0}; //Command to read from input port 0 00353 primary_i2c.write(GPIO_IC_ADDRESS,command,1,false); 00354 primary_i2c.read(GPIO_IC_ADDRESS,data,1,false); 00355 return (data[0] & 0xF8) >> 3; //Returns the current switch state 00356 } 00357 00358 void IF_update_gpio_inputs() 00359 { 00360 update_timeout.detach(); 00361 //Read data 00362 char data[2]; 00363 char command[1] = {0}; //Command to read from input port 0 00364 primary_i2c.write(GPIO_IC_ADDRESS,command,1,false); 00365 primary_i2c.read(GPIO_IC_ADDRESS,data,2,false); 00366 if(data[0]!=gpio_byte0) { 00367 IF_parse_gpio_byte0(data[0]); 00368 } 00369 if(data[1]!=gpio_byte1) { 00370 IF_parse_gpio_byte1(data[1]); 00371 } 00372 update_timeout.attach_us(&IF_update_gpio_inputs,50000); 00373 } 00374 00375 00376 void IF_write_to_led_ic(char byte_0, char byte_1) 00377 { 00378 //Set LEDs 00379 char data[3]; 00380 data [0] = 0x02; //Write to output port 00381 data [1] = byte_0; 00382 data [2] = byte_1; 00383 primary_i2c.write(LED_IC_ADDRESS,data,3,false); 00384 } 00385 00386 00387 void IF_setup_temperature_sensor() 00388 { 00389 char data[3]; 00390 data[0] = 0x04; //Set critical temp limit 00391 data[1] = TEMPERATURE_CRITICAL_HI; 00392 data[2] = TEMPEARTURE_CRITICAL_LO; 00393 primary_i2c.write(TEMPERATURE_ADDRESS,data,3,false); 00394 data[0] = 0x02; //Set high temp limit 00395 data[1] = TEMPERATURE_HIGH_HI; 00396 data[2] = TEMPEARTURE_HIGH_LO; 00397 primary_i2c.write(TEMPERATURE_ADDRESS,data,3,false); 00398 data[0] = 0x03; //Set low temp limit 00399 data[1] = TEMPERATURE_LOW_HI; 00400 data[2] = TEMPEARTURE_LOW_LO; 00401 primary_i2c.write(TEMPERATURE_ADDRESS,data,3,false); 00402 } 00403 00404 float IF_read_from_temperature_sensor() 00405 { 00406 char command[1] = {0x05}; //Write to Ta Register 00407 char data[3]; 00408 signed int temp; 00409 float temperature; 00410 primary_i2c.write(TEMPERATURE_ADDRESS,command,1,false); 00411 primary_i2c.read(TEMPERATURE_ADDRESS,data,2,false); 00412 00413 //Convert the temperature data 00414 //First Check flag bits 00415 char UpperByte = data[0]; 00416 char LowerByte = data[1]; 00417 if ((UpperByte & 0x80) == 0x80) { 00418 debug("- WARNING: Temperature sensor reports critical temperature\n"); 00419 } 00420 if ((UpperByte & 0x40) == 0x40) { 00421 debug("- WARNING: Temperature sensor reports above upper limit\n"); 00422 } 00423 if ((UpperByte & 0x20) == 0x20) { 00424 debug("- WARNING: Temperature sensor reports below lower limit\n"); 00425 } 00426 UpperByte = UpperByte & 0x1F; //Clear flag bits 00427 if ((UpperByte & 0x10) == 0x10) { 00428 UpperByte = UpperByte & 0x0F; //Clear SIGN 00429 temp = (UpperByte * 256) + LowerByte; 00430 temperature = - (temp / 16.0f); 00431 } else { 00432 temp = (UpperByte * 256) + LowerByte; 00433 temperature = (temp / 16.0f); 00434 } 00435 return temperature; 00436 }
Generated on Fri Jul 15 2022 08:26:10 by
 1.7.2
 1.7.2 
    