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.
Dependencies: mbed ESC mbed MODDMA
ButtonBoard.cpp
00001 // buttons.cpp 00002 00003 #include "ButtonBoard.h" 00004 00005 extern "C" void mbed_reset(); 00006 00007 ButtonBoard::ButtonBoard(PinName sda, PinName scl, PinName int1, PinName int2) : 00008 _i2c(sda, scl), 00009 _int1(int1), 00010 _int2(int2), 00011 _callbackFunction(NULL), 00012 _button_state(0) 00013 { 00014 // Initialize callback table 00015 for (int i=0; i < BTTN_COUNT; i++) 00016 { 00017 _callback_table_valid[i] = false; 00018 } 00019 00020 // Set I2C frequency to fast-mode 400KHz 00021 _i2c.frequency(400000L); 00022 00023 ///// Configuration 00024 bool bd1_failure = false; 00025 bool bd2_failure = false; 00026 00027 // Configure input latching 00028 out_buf[0] = 0x44; // Input latch register 00029 out_buf[1] = 0x00; // Don't need latching on output 00030 out_buf[1] = 0x00; // Latch them all 00031 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3); 00032 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3); 00033 00034 // Disable pull-ups 00035 out_buf[0] = 0x46; // Pull-up/down enable register 00036 out_buf[1] = 0x00; // Don't need on outputs 00037 out_buf[2] = 0x00; // Don't need 00038 out_buf[3] = 0xFF; // Select pull-ups 00039 out_buf[4] = 0xFF; 00040 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 5); 00041 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 5); 00042 00043 // Configure outputs as open-drain 00044 out_buf[0] = 0x4F; // Output port config register 00045 out_buf[1] = 0x02; // Port 1 to open drain 00046 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 2); 00047 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 2); 00048 00049 // Reset output register high 00050 _led_ports = 0xFFFF; // All LED's off 00051 out_buf[0] = 0x02; // Output register 00052 out_buf[1] = _led_ports & 0xFF; 00053 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 2); 00054 out_buf[2] = _led_ports>>8; 00055 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 2); 00056 00057 // Configure ports as input or outputs 00058 out_buf[0] = 0x06; // Configuration registers 00059 out_buf[1] = 0x00; // Port 1 -> Output 00060 out_buf[2] = 0xFF; // Port 2 <- Input 00061 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3); 00062 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3); 00063 00064 // Read input registers to clear interrupts 00065 out_buf[0] = 0x00; // Input registers 00066 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 1, true); 00067 bd1_failure |= _i2c.read(ADDR_BOARD_1, out_buf, 2); // Read registers 00068 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 1, true); 00069 bd2_failure |= _i2c.read(ADDR_BOARD_2, out_buf, 2); // Read registers 00070 00071 // Disable interrupt masking on inputs 00072 out_buf[0] = 0x4A; // Interrupt mask register 00073 out_buf[1] = 0xFF; // Mask outputs 00074 out_buf[2] = 0xFF; // Don't mask inputs 00075 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3); 00076 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3); 00077 00078 // Disable interrupt masking on inputs 00079 out_buf[0] = 0x4A; // Interrupt mask register 00080 out_buf[1] = 0xFF; // Mask outputs 00081 out_buf[2] = 0x00; // Don't mask inputs 00082 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3); 00083 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3); 00084 00085 if (bd1_failure) 00086 { 00087 // serial.printf("Nack recieved while configuring button board 1\n"); 00088 bd1_failure = false; 00089 } 00090 if (bd2_failure) 00091 { 00092 // serial.printf("Nack recieved while configuring button board 2\n"); 00093 bd2_failure = false; 00094 } 00095 00096 // Enable mbed interrupt lines 00097 _int1.fall(this, &ButtonBoard::_int1_handler); 00098 _int2.fall(this, &ButtonBoard::_int2_handler); 00099 _int1.mode(PullUp); 00100 _int2.mode(PullUp); 00101 00102 // Register callbacks 00103 //registerCallback(BTTN_RESET, &mbed_reset); 00104 00105 } 00106 00107 ButtonBoard::~ButtonBoard() 00108 { 00109 } 00110 00111 void ButtonBoard::_int1_handler() 00112 { 00113 _fall_handler(ADDR_BOARD_1); 00114 } 00115 00116 void ButtonBoard::_int2_handler() 00117 { 00118 _fall_handler(ADDR_BOARD_2); 00119 } 00120 00121 void ButtonBoard::_fall_handler(char board) 00122 { 00123 char int_status; 00124 char input_port; 00125 char masked_port; 00126 00127 int board_offset; 00128 if (board == ADDR_BOARD_1) 00129 { 00130 board_offset = 0; 00131 } 00132 else 00133 { 00134 board_offset = BTTN_COUNT_BOARD_1; 00135 } 00136 00137 // Poll board for interrupt source byte and input reg byte 00138 out_buf[0] = 0x4d; // Port 1 Interrupt status 00139 _i2c.write(board, out_buf, 1); 00140 _i2c.read(board, &int_status, 1); 00141 00142 out_buf[0] = 0x01; // Port 1 input register 00143 _i2c.write(board, out_buf, 1); 00144 _i2c.read(board, &input_port, 1); 00145 00146 // Use int status to mask input port (input goes low when button depressed) 00147 // int status will always indicate which button changed 00148 // masked_port will also indicate button if button is pressed, but will be 0 if button is released 00149 masked_port = int_status & (~input_port); 00150 if(masked_port) 00151 _button_state |= int_status; 00152 else 00153 _button_state &= ~int_status; 00154 00155 for (int i=0; i<8; i++) 00156 { 00157 // For every high bit in masked port 00158 if (masked_port & (1<<i)) 00159 { 00160 // Call corresponding callback 00161 int cb_i = i+board_offset; 00162 if (_callback_table_valid[cb_i] == true) 00163 { 00164 _callback_table[cb_i].call(); 00165 } 00166 } 00167 } 00168 // Call master callback 00169 if(_callbackFunction != NULL) 00170 _callbackFunction(int_status, masked_port, _button_state); 00171 } 00172 00173 00174 void ButtonBoard::registerCallback(uint32_t button, FunctionPointer p) 00175 { 00176 if (button < BTTN_COUNT) 00177 { 00178 _callback_table[button] = p; 00179 _callback_table_valid[button] = true; 00180 } 00181 } 00182 00183 void ButtonBoard::registerCallback(void (*p)(char buttonMask, bool pressed, char curState)) 00184 { 00185 _callbackFunction = p; 00186 } 00187 00188 //void ButtonBoard::setLED(uint32_t led, bool val) 00189 //{ 00190 // if (led > BTTN_COUNT) 00191 // { 00192 // // invalid, skip 00193 // return; 00194 // } 00195 // 00196 // char board; 00197 // 00198 // if (led < BTTN_COUNT_BOARD_1) 00199 // { 00200 // // Address first board 00201 // board = ADDR_BOARD_1; 00202 // } 00203 // else 00204 // { 00205 // // Address second board 00206 // board = ADDR_BOARD_2; 00207 // led = led - BTTN_COUNT_BOARD_1; 00208 // } 00209 // 00210 // bool fail = false; 00211 // 00212 // // Read port state 00213 // char port_state; 00214 // out_buf[0] = 0x02; // Port 0 output register 00215 // 00216 // fail |= _i2c.write(board, out_buf, 1, true); 00217 // fail |= _i2c.read(board, &port_state, 1); 00218 // 00219 // if (val == true) 00220 // { 00221 // // Turn LED on by clearing bit 00222 // port_state &= ~(1<<led); 00223 // } 00224 // else 00225 // { 00226 // // Turn LED off by raising bit 00227 // port_state |= (1<<led); 00228 // } 00229 // 00230 // // Now write to board 00231 // out_buf[0] = 0x02; // Port 0 output register 00232 // out_buf[1] = port_state; 00233 // 00234 // fail |= _i2c.write(board, out_buf, 2); 00235 // 00236 // if (fail) 00237 // { 00238 // // serial.printf("Nack recieved when writing LED %d on Board %d", led, board); 00239 // } 00240 // else 00241 // { 00242 // _led_ports = port_state<<(8*board) + _led_ports & (~(0xFF<<(8*board))); 00243 // } 00244 //} 00245 00246 void ButtonBoard::setLEDs(char mask, bool turnOn, char board /* = ADDR_BOARD_1 */) 00247 { 00248 bool fail = false; 00249 00250 // Read port state 00251 char port_state; 00252 out_buf[0] = 0x02; // Port 0 output register 00253 00254 fail |= _i2c.write(board, out_buf, 1, true); 00255 fail |= _i2c.read(board, &port_state, 1); 00256 00257 if(turnOn == true) 00258 { 00259 // Turn LEDs on by clearing bits 00260 port_state &= ~(mask); 00261 } 00262 else 00263 { 00264 // Turn LEDs off by raising bits 00265 port_state |= (mask); 00266 } 00267 00268 // Now write to board 00269 out_buf[0] = 0x02; // Port 0 output register 00270 out_buf[1] = port_state; 00271 00272 fail |= _i2c.write(board, out_buf, 2); 00273 00274 if(fail) 00275 { 00276 // serial.printf("Nack recieved when writing LED %d on Board %d", led, board); 00277 //printf("button board write failed\n"); 00278 } 00279 else 00280 { 00281 //_led_ports = port_state<<(8*board) + _led_ports & (~(0xFF<<(8*board))); 00282 _led_ports = port_state; 00283 } 00284 } 00285 00286 char ButtonBoard::getLEDs(char ledMask, char board /* = ADDR_BOARD_1 */) 00287 { 00288 return ~_led_ports & ledMask; 00289 // bool fail = false; 00290 // 00291 // // Read port state 00292 // char port_state; 00293 // out_buf[0] = 0x02; // Port 0 output register 00294 // 00295 // fail |= _i2c.write(board, out_buf, 1, true); 00296 // fail |= _i2c.read(board, &port_state, 1); 00297 // 00298 // return ~port_state & ledMask; 00299 } 00300 00301 char ButtonBoard::getButtons(char buttonMask, char board /* = ADDR_BOARD_1 */) 00302 { 00303 return _button_state & buttonMask; 00304 } 00305 00306 //uint16_t ButtonBoard::readInputs() 00307 //{ 00308 // char b1_p1; 00309 // char b2_p1; 00310 // 00311 // out_buf[0] = 0x01; 00312 // _i2c.write(ADDR_BOARD_1, out_buf, 1, true); 00313 // _i2c.read(ADDR_BOARD_1, &b1_p1, 1); 00314 // 00315 // _i2c.write(ADDR_BOARD_2, out_buf, 1, true); 00316 // _i2c.read(ADDR_BOARD_2, &b2_p1, 1); 00317 // 00318 // uint16_t out = (b2_p1<<8) | b1_p1; 00319 // 00320 // return out; 00321 //}
Generated on Wed Jul 13 2022 13:43:34 by
