All mbed code for control over dive planes, pump motor, valve motor, BCUs, UART interface, etc.

Dependencies:   mbed ESC mbed MODDMA

Committer:
juansal12
Date:
Tue Jan 14 19:17:05 2020 +0000
Revision:
0:c3a329a5b05d
Sofi7 mbed code;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
juansal12 0:c3a329a5b05d 1 // buttons.cpp
juansal12 0:c3a329a5b05d 2
juansal12 0:c3a329a5b05d 3 #include "ButtonBoard.h"
juansal12 0:c3a329a5b05d 4
juansal12 0:c3a329a5b05d 5 extern "C" void mbed_reset();
juansal12 0:c3a329a5b05d 6
juansal12 0:c3a329a5b05d 7 ButtonBoard::ButtonBoard(PinName sda, PinName scl, PinName int1, PinName int2) :
juansal12 0:c3a329a5b05d 8 _i2c(sda, scl),
juansal12 0:c3a329a5b05d 9 _int1(int1),
juansal12 0:c3a329a5b05d 10 _int2(int2),
juansal12 0:c3a329a5b05d 11 _callbackFunction(NULL),
juansal12 0:c3a329a5b05d 12 _button_state(0)
juansal12 0:c3a329a5b05d 13 {
juansal12 0:c3a329a5b05d 14 // Initialize callback table
juansal12 0:c3a329a5b05d 15 for (int i=0; i < BTTN_COUNT; i++)
juansal12 0:c3a329a5b05d 16 {
juansal12 0:c3a329a5b05d 17 _callback_table_valid[i] = false;
juansal12 0:c3a329a5b05d 18 }
juansal12 0:c3a329a5b05d 19
juansal12 0:c3a329a5b05d 20 // Set I2C frequency to fast-mode 400KHz
juansal12 0:c3a329a5b05d 21 _i2c.frequency(400000L);
juansal12 0:c3a329a5b05d 22
juansal12 0:c3a329a5b05d 23 ///// Configuration
juansal12 0:c3a329a5b05d 24 bool bd1_failure = false;
juansal12 0:c3a329a5b05d 25 bool bd2_failure = false;
juansal12 0:c3a329a5b05d 26
juansal12 0:c3a329a5b05d 27 // Configure input latching
juansal12 0:c3a329a5b05d 28 out_buf[0] = 0x44; // Input latch register
juansal12 0:c3a329a5b05d 29 out_buf[1] = 0x00; // Don't need latching on output
juansal12 0:c3a329a5b05d 30 out_buf[1] = 0x00; // Latch them all
juansal12 0:c3a329a5b05d 31 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3);
juansal12 0:c3a329a5b05d 32 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3);
juansal12 0:c3a329a5b05d 33
juansal12 0:c3a329a5b05d 34 // Disable pull-ups
juansal12 0:c3a329a5b05d 35 out_buf[0] = 0x46; // Pull-up/down enable register
juansal12 0:c3a329a5b05d 36 out_buf[1] = 0x00; // Don't need on outputs
juansal12 0:c3a329a5b05d 37 out_buf[2] = 0x00; // Don't need
juansal12 0:c3a329a5b05d 38 out_buf[3] = 0xFF; // Select pull-ups
juansal12 0:c3a329a5b05d 39 out_buf[4] = 0xFF;
juansal12 0:c3a329a5b05d 40 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 5);
juansal12 0:c3a329a5b05d 41 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 5);
juansal12 0:c3a329a5b05d 42
juansal12 0:c3a329a5b05d 43 // Configure outputs as open-drain
juansal12 0:c3a329a5b05d 44 out_buf[0] = 0x4F; // Output port config register
juansal12 0:c3a329a5b05d 45 out_buf[1] = 0x02; // Port 1 to open drain
juansal12 0:c3a329a5b05d 46 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 2);
juansal12 0:c3a329a5b05d 47 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 2);
juansal12 0:c3a329a5b05d 48
juansal12 0:c3a329a5b05d 49 // Reset output register high
juansal12 0:c3a329a5b05d 50 _led_ports = 0xFFFF; // All LED's off
juansal12 0:c3a329a5b05d 51 out_buf[0] = 0x02; // Output register
juansal12 0:c3a329a5b05d 52 out_buf[1] = _led_ports & 0xFF;
juansal12 0:c3a329a5b05d 53 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 2);
juansal12 0:c3a329a5b05d 54 out_buf[2] = _led_ports>>8;
juansal12 0:c3a329a5b05d 55 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 2);
juansal12 0:c3a329a5b05d 56
juansal12 0:c3a329a5b05d 57 // Configure ports as input or outputs
juansal12 0:c3a329a5b05d 58 out_buf[0] = 0x06; // Configuration registers
juansal12 0:c3a329a5b05d 59 out_buf[1] = 0x00; // Port 1 -> Output
juansal12 0:c3a329a5b05d 60 out_buf[2] = 0xFF; // Port 2 <- Input
juansal12 0:c3a329a5b05d 61 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3);
juansal12 0:c3a329a5b05d 62 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3);
juansal12 0:c3a329a5b05d 63
juansal12 0:c3a329a5b05d 64 // Read input registers to clear interrupts
juansal12 0:c3a329a5b05d 65 out_buf[0] = 0x00; // Input registers
juansal12 0:c3a329a5b05d 66 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 1, true);
juansal12 0:c3a329a5b05d 67 bd1_failure |= _i2c.read(ADDR_BOARD_1, out_buf, 2); // Read registers
juansal12 0:c3a329a5b05d 68 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 1, true);
juansal12 0:c3a329a5b05d 69 bd2_failure |= _i2c.read(ADDR_BOARD_2, out_buf, 2); // Read registers
juansal12 0:c3a329a5b05d 70
juansal12 0:c3a329a5b05d 71 // Disable interrupt masking on inputs
juansal12 0:c3a329a5b05d 72 out_buf[0] = 0x4A; // Interrupt mask register
juansal12 0:c3a329a5b05d 73 out_buf[1] = 0xFF; // Mask outputs
juansal12 0:c3a329a5b05d 74 out_buf[2] = 0xFF; // Don't mask inputs
juansal12 0:c3a329a5b05d 75 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3);
juansal12 0:c3a329a5b05d 76 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3);
juansal12 0:c3a329a5b05d 77
juansal12 0:c3a329a5b05d 78 // Disable interrupt masking on inputs
juansal12 0:c3a329a5b05d 79 out_buf[0] = 0x4A; // Interrupt mask register
juansal12 0:c3a329a5b05d 80 out_buf[1] = 0xFF; // Mask outputs
juansal12 0:c3a329a5b05d 81 out_buf[2] = 0x00; // Don't mask inputs
juansal12 0:c3a329a5b05d 82 bd1_failure |= _i2c.write(ADDR_BOARD_1, out_buf, 3);
juansal12 0:c3a329a5b05d 83 bd2_failure |= _i2c.write(ADDR_BOARD_2, out_buf, 3);
juansal12 0:c3a329a5b05d 84
juansal12 0:c3a329a5b05d 85 if (bd1_failure)
juansal12 0:c3a329a5b05d 86 {
juansal12 0:c3a329a5b05d 87 // serial.printf("Nack recieved while configuring button board 1\n");
juansal12 0:c3a329a5b05d 88 bd1_failure = false;
juansal12 0:c3a329a5b05d 89 }
juansal12 0:c3a329a5b05d 90 if (bd2_failure)
juansal12 0:c3a329a5b05d 91 {
juansal12 0:c3a329a5b05d 92 // serial.printf("Nack recieved while configuring button board 2\n");
juansal12 0:c3a329a5b05d 93 bd2_failure = false;
juansal12 0:c3a329a5b05d 94 }
juansal12 0:c3a329a5b05d 95
juansal12 0:c3a329a5b05d 96 // Enable mbed interrupt lines
juansal12 0:c3a329a5b05d 97 _int1.fall(this, &ButtonBoard::_int1_handler);
juansal12 0:c3a329a5b05d 98 _int2.fall(this, &ButtonBoard::_int2_handler);
juansal12 0:c3a329a5b05d 99 _int1.mode(PullUp);
juansal12 0:c3a329a5b05d 100 _int2.mode(PullUp);
juansal12 0:c3a329a5b05d 101
juansal12 0:c3a329a5b05d 102 // Register callbacks
juansal12 0:c3a329a5b05d 103 //registerCallback(BTTN_RESET, &mbed_reset);
juansal12 0:c3a329a5b05d 104
juansal12 0:c3a329a5b05d 105 }
juansal12 0:c3a329a5b05d 106
juansal12 0:c3a329a5b05d 107 ButtonBoard::~ButtonBoard()
juansal12 0:c3a329a5b05d 108 {
juansal12 0:c3a329a5b05d 109 }
juansal12 0:c3a329a5b05d 110
juansal12 0:c3a329a5b05d 111 void ButtonBoard::_int1_handler()
juansal12 0:c3a329a5b05d 112 {
juansal12 0:c3a329a5b05d 113 _fall_handler(ADDR_BOARD_1);
juansal12 0:c3a329a5b05d 114 }
juansal12 0:c3a329a5b05d 115
juansal12 0:c3a329a5b05d 116 void ButtonBoard::_int2_handler()
juansal12 0:c3a329a5b05d 117 {
juansal12 0:c3a329a5b05d 118 _fall_handler(ADDR_BOARD_2);
juansal12 0:c3a329a5b05d 119 }
juansal12 0:c3a329a5b05d 120
juansal12 0:c3a329a5b05d 121 void ButtonBoard::_fall_handler(char board)
juansal12 0:c3a329a5b05d 122 {
juansal12 0:c3a329a5b05d 123 char int_status;
juansal12 0:c3a329a5b05d 124 char input_port;
juansal12 0:c3a329a5b05d 125 char masked_port;
juansal12 0:c3a329a5b05d 126
juansal12 0:c3a329a5b05d 127 int board_offset;
juansal12 0:c3a329a5b05d 128 if (board == ADDR_BOARD_1)
juansal12 0:c3a329a5b05d 129 {
juansal12 0:c3a329a5b05d 130 board_offset = 0;
juansal12 0:c3a329a5b05d 131 }
juansal12 0:c3a329a5b05d 132 else
juansal12 0:c3a329a5b05d 133 {
juansal12 0:c3a329a5b05d 134 board_offset = BTTN_COUNT_BOARD_1;
juansal12 0:c3a329a5b05d 135 }
juansal12 0:c3a329a5b05d 136
juansal12 0:c3a329a5b05d 137 // Poll board for interrupt source byte and input reg byte
juansal12 0:c3a329a5b05d 138 out_buf[0] = 0x4d; // Port 1 Interrupt status
juansal12 0:c3a329a5b05d 139 _i2c.write(board, out_buf, 1);
juansal12 0:c3a329a5b05d 140 _i2c.read(board, &int_status, 1);
juansal12 0:c3a329a5b05d 141
juansal12 0:c3a329a5b05d 142 out_buf[0] = 0x01; // Port 1 input register
juansal12 0:c3a329a5b05d 143 _i2c.write(board, out_buf, 1);
juansal12 0:c3a329a5b05d 144 _i2c.read(board, &input_port, 1);
juansal12 0:c3a329a5b05d 145
juansal12 0:c3a329a5b05d 146 // Use int status to mask input port (input goes low when button depressed)
juansal12 0:c3a329a5b05d 147 // int status will always indicate which button changed
juansal12 0:c3a329a5b05d 148 // masked_port will also indicate button if button is pressed, but will be 0 if button is released
juansal12 0:c3a329a5b05d 149 masked_port = int_status & (~input_port);
juansal12 0:c3a329a5b05d 150 if(masked_port)
juansal12 0:c3a329a5b05d 151 _button_state |= int_status;
juansal12 0:c3a329a5b05d 152 else
juansal12 0:c3a329a5b05d 153 _button_state &= ~int_status;
juansal12 0:c3a329a5b05d 154
juansal12 0:c3a329a5b05d 155 for (int i=0; i<8; i++)
juansal12 0:c3a329a5b05d 156 {
juansal12 0:c3a329a5b05d 157 // For every high bit in masked port
juansal12 0:c3a329a5b05d 158 if (masked_port & (1<<i))
juansal12 0:c3a329a5b05d 159 {
juansal12 0:c3a329a5b05d 160 // Call corresponding callback
juansal12 0:c3a329a5b05d 161 int cb_i = i+board_offset;
juansal12 0:c3a329a5b05d 162 if (_callback_table_valid[cb_i] == true)
juansal12 0:c3a329a5b05d 163 {
juansal12 0:c3a329a5b05d 164 _callback_table[cb_i].call();
juansal12 0:c3a329a5b05d 165 }
juansal12 0:c3a329a5b05d 166 }
juansal12 0:c3a329a5b05d 167 }
juansal12 0:c3a329a5b05d 168 // Call master callback
juansal12 0:c3a329a5b05d 169 if(_callbackFunction != NULL)
juansal12 0:c3a329a5b05d 170 _callbackFunction(int_status, masked_port, _button_state);
juansal12 0:c3a329a5b05d 171 }
juansal12 0:c3a329a5b05d 172
juansal12 0:c3a329a5b05d 173
juansal12 0:c3a329a5b05d 174 void ButtonBoard::registerCallback(uint32_t button, FunctionPointer p)
juansal12 0:c3a329a5b05d 175 {
juansal12 0:c3a329a5b05d 176 if (button < BTTN_COUNT)
juansal12 0:c3a329a5b05d 177 {
juansal12 0:c3a329a5b05d 178 _callback_table[button] = p;
juansal12 0:c3a329a5b05d 179 _callback_table_valid[button] = true;
juansal12 0:c3a329a5b05d 180 }
juansal12 0:c3a329a5b05d 181 }
juansal12 0:c3a329a5b05d 182
juansal12 0:c3a329a5b05d 183 void ButtonBoard::registerCallback(void (*p)(char buttonMask, bool pressed, char curState))
juansal12 0:c3a329a5b05d 184 {
juansal12 0:c3a329a5b05d 185 _callbackFunction = p;
juansal12 0:c3a329a5b05d 186 }
juansal12 0:c3a329a5b05d 187
juansal12 0:c3a329a5b05d 188 //void ButtonBoard::setLED(uint32_t led, bool val)
juansal12 0:c3a329a5b05d 189 //{
juansal12 0:c3a329a5b05d 190 // if (led > BTTN_COUNT)
juansal12 0:c3a329a5b05d 191 // {
juansal12 0:c3a329a5b05d 192 // // invalid, skip
juansal12 0:c3a329a5b05d 193 // return;
juansal12 0:c3a329a5b05d 194 // }
juansal12 0:c3a329a5b05d 195 //
juansal12 0:c3a329a5b05d 196 // char board;
juansal12 0:c3a329a5b05d 197 //
juansal12 0:c3a329a5b05d 198 // if (led < BTTN_COUNT_BOARD_1)
juansal12 0:c3a329a5b05d 199 // {
juansal12 0:c3a329a5b05d 200 // // Address first board
juansal12 0:c3a329a5b05d 201 // board = ADDR_BOARD_1;
juansal12 0:c3a329a5b05d 202 // }
juansal12 0:c3a329a5b05d 203 // else
juansal12 0:c3a329a5b05d 204 // {
juansal12 0:c3a329a5b05d 205 // // Address second board
juansal12 0:c3a329a5b05d 206 // board = ADDR_BOARD_2;
juansal12 0:c3a329a5b05d 207 // led = led - BTTN_COUNT_BOARD_1;
juansal12 0:c3a329a5b05d 208 // }
juansal12 0:c3a329a5b05d 209 //
juansal12 0:c3a329a5b05d 210 // bool fail = false;
juansal12 0:c3a329a5b05d 211 //
juansal12 0:c3a329a5b05d 212 // // Read port state
juansal12 0:c3a329a5b05d 213 // char port_state;
juansal12 0:c3a329a5b05d 214 // out_buf[0] = 0x02; // Port 0 output register
juansal12 0:c3a329a5b05d 215 //
juansal12 0:c3a329a5b05d 216 // fail |= _i2c.write(board, out_buf, 1, true);
juansal12 0:c3a329a5b05d 217 // fail |= _i2c.read(board, &port_state, 1);
juansal12 0:c3a329a5b05d 218 //
juansal12 0:c3a329a5b05d 219 // if (val == true)
juansal12 0:c3a329a5b05d 220 // {
juansal12 0:c3a329a5b05d 221 // // Turn LED on by clearing bit
juansal12 0:c3a329a5b05d 222 // port_state &= ~(1<<led);
juansal12 0:c3a329a5b05d 223 // }
juansal12 0:c3a329a5b05d 224 // else
juansal12 0:c3a329a5b05d 225 // {
juansal12 0:c3a329a5b05d 226 // // Turn LED off by raising bit
juansal12 0:c3a329a5b05d 227 // port_state |= (1<<led);
juansal12 0:c3a329a5b05d 228 // }
juansal12 0:c3a329a5b05d 229 //
juansal12 0:c3a329a5b05d 230 // // Now write to board
juansal12 0:c3a329a5b05d 231 // out_buf[0] = 0x02; // Port 0 output register
juansal12 0:c3a329a5b05d 232 // out_buf[1] = port_state;
juansal12 0:c3a329a5b05d 233 //
juansal12 0:c3a329a5b05d 234 // fail |= _i2c.write(board, out_buf, 2);
juansal12 0:c3a329a5b05d 235 //
juansal12 0:c3a329a5b05d 236 // if (fail)
juansal12 0:c3a329a5b05d 237 // {
juansal12 0:c3a329a5b05d 238 // // serial.printf("Nack recieved when writing LED %d on Board %d", led, board);
juansal12 0:c3a329a5b05d 239 // }
juansal12 0:c3a329a5b05d 240 // else
juansal12 0:c3a329a5b05d 241 // {
juansal12 0:c3a329a5b05d 242 // _led_ports = port_state<<(8*board) + _led_ports & (~(0xFF<<(8*board)));
juansal12 0:c3a329a5b05d 243 // }
juansal12 0:c3a329a5b05d 244 //}
juansal12 0:c3a329a5b05d 245
juansal12 0:c3a329a5b05d 246 void ButtonBoard::setLEDs(char mask, bool turnOn, char board /* = ADDR_BOARD_1 */)
juansal12 0:c3a329a5b05d 247 {
juansal12 0:c3a329a5b05d 248 bool fail = false;
juansal12 0:c3a329a5b05d 249
juansal12 0:c3a329a5b05d 250 // Read port state
juansal12 0:c3a329a5b05d 251 char port_state;
juansal12 0:c3a329a5b05d 252 out_buf[0] = 0x02; // Port 0 output register
juansal12 0:c3a329a5b05d 253
juansal12 0:c3a329a5b05d 254 fail |= _i2c.write(board, out_buf, 1, true);
juansal12 0:c3a329a5b05d 255 fail |= _i2c.read(board, &port_state, 1);
juansal12 0:c3a329a5b05d 256
juansal12 0:c3a329a5b05d 257 if(turnOn == true)
juansal12 0:c3a329a5b05d 258 {
juansal12 0:c3a329a5b05d 259 // Turn LEDs on by clearing bits
juansal12 0:c3a329a5b05d 260 port_state &= ~(mask);
juansal12 0:c3a329a5b05d 261 }
juansal12 0:c3a329a5b05d 262 else
juansal12 0:c3a329a5b05d 263 {
juansal12 0:c3a329a5b05d 264 // Turn LEDs off by raising bits
juansal12 0:c3a329a5b05d 265 port_state |= (mask);
juansal12 0:c3a329a5b05d 266 }
juansal12 0:c3a329a5b05d 267
juansal12 0:c3a329a5b05d 268 // Now write to board
juansal12 0:c3a329a5b05d 269 out_buf[0] = 0x02; // Port 0 output register
juansal12 0:c3a329a5b05d 270 out_buf[1] = port_state;
juansal12 0:c3a329a5b05d 271
juansal12 0:c3a329a5b05d 272 fail |= _i2c.write(board, out_buf, 2);
juansal12 0:c3a329a5b05d 273
juansal12 0:c3a329a5b05d 274 if(fail)
juansal12 0:c3a329a5b05d 275 {
juansal12 0:c3a329a5b05d 276 // serial.printf("Nack recieved when writing LED %d on Board %d", led, board);
juansal12 0:c3a329a5b05d 277 //printf("button board write failed\n");
juansal12 0:c3a329a5b05d 278 }
juansal12 0:c3a329a5b05d 279 else
juansal12 0:c3a329a5b05d 280 {
juansal12 0:c3a329a5b05d 281 //_led_ports = port_state<<(8*board) + _led_ports & (~(0xFF<<(8*board)));
juansal12 0:c3a329a5b05d 282 _led_ports = port_state;
juansal12 0:c3a329a5b05d 283 }
juansal12 0:c3a329a5b05d 284 }
juansal12 0:c3a329a5b05d 285
juansal12 0:c3a329a5b05d 286 char ButtonBoard::getLEDs(char ledMask, char board /* = ADDR_BOARD_1 */)
juansal12 0:c3a329a5b05d 287 {
juansal12 0:c3a329a5b05d 288 return ~_led_ports & ledMask;
juansal12 0:c3a329a5b05d 289 // bool fail = false;
juansal12 0:c3a329a5b05d 290 //
juansal12 0:c3a329a5b05d 291 // // Read port state
juansal12 0:c3a329a5b05d 292 // char port_state;
juansal12 0:c3a329a5b05d 293 // out_buf[0] = 0x02; // Port 0 output register
juansal12 0:c3a329a5b05d 294 //
juansal12 0:c3a329a5b05d 295 // fail |= _i2c.write(board, out_buf, 1, true);
juansal12 0:c3a329a5b05d 296 // fail |= _i2c.read(board, &port_state, 1);
juansal12 0:c3a329a5b05d 297 //
juansal12 0:c3a329a5b05d 298 // return ~port_state & ledMask;
juansal12 0:c3a329a5b05d 299 }
juansal12 0:c3a329a5b05d 300
juansal12 0:c3a329a5b05d 301 char ButtonBoard::getButtons(char buttonMask, char board /* = ADDR_BOARD_1 */)
juansal12 0:c3a329a5b05d 302 {
juansal12 0:c3a329a5b05d 303 return _button_state & buttonMask;
juansal12 0:c3a329a5b05d 304 }
juansal12 0:c3a329a5b05d 305
juansal12 0:c3a329a5b05d 306 //uint16_t ButtonBoard::readInputs()
juansal12 0:c3a329a5b05d 307 //{
juansal12 0:c3a329a5b05d 308 // char b1_p1;
juansal12 0:c3a329a5b05d 309 // char b2_p1;
juansal12 0:c3a329a5b05d 310 //
juansal12 0:c3a329a5b05d 311 // out_buf[0] = 0x01;
juansal12 0:c3a329a5b05d 312 // _i2c.write(ADDR_BOARD_1, out_buf, 1, true);
juansal12 0:c3a329a5b05d 313 // _i2c.read(ADDR_BOARD_1, &b1_p1, 1);
juansal12 0:c3a329a5b05d 314 //
juansal12 0:c3a329a5b05d 315 // _i2c.write(ADDR_BOARD_2, out_buf, 1, true);
juansal12 0:c3a329a5b05d 316 // _i2c.read(ADDR_BOARD_2, &b2_p1, 1);
juansal12 0:c3a329a5b05d 317 //
juansal12 0:c3a329a5b05d 318 // uint16_t out = (b2_p1<<8) | b1_p1;
juansal12 0:c3a329a5b05d 319 //
juansal12 0:c3a329a5b05d 320 // return out;
juansal12 0:c3a329a5b05d 321 //}