Juan Salazar / robotic_fish_7

Dependencies:   mbed ESC mbed MODDMA

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ButtonBoard.cpp Source File

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 //}