PICO I2C FW
Dependencies: USBDevice
main.cpp@28:c6fb76beb476, 2021-12-29 (annotated)
- Committer:
- walterluu
- Date:
- Wed Dec 29 07:00:48 2021 +0000
- Revision:
- 28:c6fb76beb476
- Parent:
- 27:72e40a8d3001
PICO I2C FW
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
switches | 0:60a522ae2e35 | 1 | #include "mbed.h" |
cyberjoey | 25:89979f4ccfa9 | 2 | #include "USBHID.h" |
cyberjoey | 27:72e40a8d3001 | 3 | #include "PicoCommands.h" |
cyberjoey | 9:36ba3626aab7 | 4 | |
cyberjoey | 23:9bcf097cbfc2 | 5 | // Virtual serial port over USB TODO NEW VID PID NEEDED!! |
cyberjoey | 25:89979f4ccfa9 | 6 | USBHID hid(64, 64); |
cyberjoey | 25:89979f4ccfa9 | 7 | |
cyberjoey | 25:89979f4ccfa9 | 8 | //This report will contain data to be sent |
cyberjoey | 25:89979f4ccfa9 | 9 | HID_REPORT send_report; |
cyberjoey | 25:89979f4ccfa9 | 10 | HID_REPORT recv_report; |
cyberjoey | 25:89979f4ccfa9 | 11 | |
cyberjoey | 25:89979f4ccfa9 | 12 | //debug port setup |
cyberjoey | 27:72e40a8d3001 | 13 | Serial db(P3_0, P3_1); |
cyberjoey | 9:36ba3626aab7 | 14 | |
cyberjoey | 9:36ba3626aab7 | 15 | // I2C setup |
cyberjoey | 23:9bcf097cbfc2 | 16 | I2C i2c(P1_6, P1_7); // P1_6 -> I2C1_SDA, P1_7-> I2C1_SCL |
cyberjoey | 9:36ba3626aab7 | 17 | |
cyberjoey | 9:36ba3626aab7 | 18 | //Timer setup |
cyberjoey | 9:36ba3626aab7 | 19 | Ticker timer_1; // timer for blinking led heartbeat |
cyberjoey | 9:36ba3626aab7 | 20 | bool led_toggle_flag = false; |
cyberjoey | 9:36ba3626aab7 | 21 | |
cyberjoey | 9:36ba3626aab7 | 22 | //LED blink setup |
switches | 1:90313362ec11 | 23 | DigitalOut rLED(LED1); |
switches | 1:90313362ec11 | 24 | DigitalOut gLED(LED2); |
cyberjoey | 9:36ba3626aab7 | 25 | DigitalOut bLED(LED3); |
switches | 0:60a522ae2e35 | 26 | |
cyberjoey | 23:9bcf097cbfc2 | 27 | //InterruptIn button(SW1); |
cyberjoey | 23:9bcf097cbfc2 | 28 | |
cyberjoey | 23:9bcf097cbfc2 | 29 | void LED_blink_callback() { // LED Heart beat |
cyberjoey | 9:36ba3626aab7 | 30 | |
cyberjoey | 9:36ba3626aab7 | 31 | led_toggle_flag = !led_toggle_flag; |
cyberjoey | 23:9bcf097cbfc2 | 32 | |
cyberjoey | 23:9bcf097cbfc2 | 33 | if (led_toggle_flag) |
cyberjoey | 9:36ba3626aab7 | 34 | { |
cyberjoey | 23:9bcf097cbfc2 | 35 | //toggle teal leds |
cyberjoey | 26:89920e2454f8 | 36 | gLED = LED_ON; |
cyberjoey | 23:9bcf097cbfc2 | 37 | bLED = LED_ON; |
cyberjoey | 9:36ba3626aab7 | 38 | } |
cyberjoey | 9:36ba3626aab7 | 39 | else |
cyberjoey | 9:36ba3626aab7 | 40 | { |
cyberjoey | 23:9bcf097cbfc2 | 41 | rLED = LED_OFF; |
cyberjoey | 23:9bcf097cbfc2 | 42 | gLED = LED_OFF; |
cyberjoey | 23:9bcf097cbfc2 | 43 | bLED = LED_OFF; |
cyberjoey | 9:36ba3626aab7 | 44 | } |
cyberjoey | 23:9bcf097cbfc2 | 45 | |
cyberjoey | 9:36ba3626aab7 | 46 | } |
cyberjoey | 9:36ba3626aab7 | 47 | |
cyberjoey | 9:36ba3626aab7 | 48 | // ***************************************************************************** |
cyberjoey | 22:ee0d36d534cd | 49 | // I2C_write_register(char, char, char) writes single byte to OT07 |
cyberjoey | 17:401a5bb8d403 | 50 | // char I2C address |
cyberjoey | 17:401a5bb8d403 | 51 | // char OT07 register address |
cyberjoey | 17:401a5bb8d403 | 52 | // char data byte to be writen |
cyberjoey | 17:401a5bb8d403 | 53 | // returns 0 on success ACK, 1 on NACK |
cyberjoey | 17:401a5bb8d403 | 54 | // ***************************************************************************** |
cyberjoey | 17:401a5bb8d403 | 55 | |
cyberjoey | 23:9bcf097cbfc2 | 56 | int I2C_write_register(char I2C_add, char reg_add, char byte) { |
cyberjoey | 17:401a5bb8d403 | 57 | char data[2]; |
cyberjoey | 17:401a5bb8d403 | 58 | int error; |
cyberjoey | 17:401a5bb8d403 | 59 | data[0] = reg_add; |
cyberjoey | 17:401a5bb8d403 | 60 | data[1] = byte; |
cyberjoey | 23:9bcf097cbfc2 | 61 | error = i2c.write(I2C_add, data, 2); |
cyberjoey | 23:9bcf097cbfc2 | 62 | return error; |
cyberjoey | 23:9bcf097cbfc2 | 63 | |
cyberjoey | 17:401a5bb8d403 | 64 | } |
cyberjoey | 17:401a5bb8d403 | 65 | |
cyberjoey | 17:401a5bb8d403 | 66 | /// **************************************************************************** |
cyberjoey | 22:ee0d36d534cd | 67 | // I2C_write_register(char, char, char *, int) writes multiple bytes to OT07 |
cyberjoey | 17:401a5bb8d403 | 68 | // char I2C address |
cyberjoey | 17:401a5bb8d403 | 69 | // char OT07 register address |
cyberjoey | 17:401a5bb8d403 | 70 | // char * data vector of bytes to be written |
cyberjoey | 17:401a5bb8d403 | 71 | // int number of bytes to write |
cyberjoey | 17:401a5bb8d403 | 72 | // returns 0 on success ACK, 1 on NACK |
cyberjoey | 17:401a5bb8d403 | 73 | // ***************************************************************************** |
cyberjoey | 17:401a5bb8d403 | 74 | |
cyberjoey | 23:9bcf097cbfc2 | 75 | int I2C_write_register(char I2C_add, char reg_add, char *bytes, int n) { |
cyberjoey | 23:9bcf097cbfc2 | 76 | int i; |
cyberjoey | 17:401a5bb8d403 | 77 | //set start address |
cyberjoey | 17:401a5bb8d403 | 78 | char data[16]; |
cyberjoey | 23:9bcf097cbfc2 | 79 | int error; |
cyberjoey | 23:9bcf097cbfc2 | 80 | data[0] = reg_add; |
cyberjoey | 23:9bcf097cbfc2 | 81 | for (i = 1; i <= n; i++) { |
cyberjoey | 23:9bcf097cbfc2 | 82 | data[i] = bytes[i - 1]; |
cyberjoey | 17:401a5bb8d403 | 83 | } |
cyberjoey | 23:9bcf097cbfc2 | 84 | error = i2c.write(I2C_add, data, n + 1); // send n bytes of data |
cyberjoey | 23:9bcf097cbfc2 | 85 | |
cyberjoey | 23:9bcf097cbfc2 | 86 | return error; |
cyberjoey | 17:401a5bb8d403 | 87 | } |
cyberjoey | 17:401a5bb8d403 | 88 | |
cyberjoey | 17:401a5bb8d403 | 89 | // ***************************************************************************** |
cyberjoey | 22:ee0d36d534cd | 90 | // I2C_read_register(char, char, char *, int) writes single byte to OT07 |
cyberjoey | 17:401a5bb8d403 | 91 | // char I2C address |
cyberjoey | 17:401a5bb8d403 | 92 | // char OT07 register address |
cyberjoey | 17:401a5bb8d403 | 93 | // char * data vector for read bytes to be stored in |
cyberjoey | 17:401a5bb8d403 | 94 | // int number of bytes to read |
cyberjoey | 17:401a5bb8d403 | 95 | // returns 0 on success, 1 on fail |
cyberjoey | 17:401a5bb8d403 | 96 | // ***************************************************************************** |
cyberjoey | 17:401a5bb8d403 | 97 | |
cyberjoey | 23:9bcf097cbfc2 | 98 | int I2C_read_register(char I2C_add, char reg_add, char *bytes, int n) { |
cyberjoey | 17:401a5bb8d403 | 99 | int error; |
cyberjoey | 23:9bcf097cbfc2 | 100 | error = i2c.write(I2C_add, ®_add, 1, 1); |
cyberjoey | 23:9bcf097cbfc2 | 101 | if (error)return error; |
cyberjoey | 23:9bcf097cbfc2 | 102 | error = i2c.read(I2C_add, bytes, n); |
cyberjoey | 23:9bcf097cbfc2 | 103 | return error; |
cyberjoey | 23:9bcf097cbfc2 | 104 | } |
cyberjoey | 23:9bcf097cbfc2 | 105 | |
cyberjoey | 27:72e40a8d3001 | 106 | void process_command(uint8_t command) |
cyberjoey | 27:72e40a8d3001 | 107 | { |
cyberjoey | 27:72e40a8d3001 | 108 | char data[130]; |
cyberjoey | 27:72e40a8d3001 | 109 | switch (command) |
cyberjoey | 27:72e40a8d3001 | 110 | { |
cyberjoey | 27:72e40a8d3001 | 111 | case I2CReadReg: |
cyberjoey | 27:72e40a8d3001 | 112 | { |
cyberjoey | 27:72e40a8d3001 | 113 | uint8_t slaveAddr = recv_report.data[2]; |
cyberjoey | 27:72e40a8d3001 | 114 | uint8_t regAddr = recv_report.data[3]; |
cyberjoey | 27:72e40a8d3001 | 115 | uint8_t numBytes = recv_report.data[4]; |
cyberjoey | 27:72e40a8d3001 | 116 | |
cyberjoey | 27:72e40a8d3001 | 117 | int error = I2C_read_register(slaveAddr, regAddr, data, numBytes); |
cyberjoey | 27:72e40a8d3001 | 118 | db.printf("slaveAddr = %02X regAddr = %02X data[0] = %02X numBytes = %d error = %d\r\n", slaveAddr, regAddr, data[0], numBytes, error); |
cyberjoey | 27:72e40a8d3001 | 119 | bool ack = !error; |
cyberjoey | 27:72e40a8d3001 | 120 | |
cyberjoey | 27:72e40a8d3001 | 121 | send_report.data[0] = I2CReadReg;//OpCode = I2CReadReg |
cyberjoey | 27:72e40a8d3001 | 122 | if(ack) |
cyberjoey | 27:72e40a8d3001 | 123 | send_report.data[1] = Success;//CmdStatus = Success |
cyberjoey | 27:72e40a8d3001 | 124 | else |
cyberjoey | 27:72e40a8d3001 | 125 | send_report.data[1] = Failure;//CmdStatus = Failure |
cyberjoey | 27:72e40a8d3001 | 126 | for(int i = 0; i < numBytes; i++) |
cyberjoey | 27:72e40a8d3001 | 127 | { |
cyberjoey | 27:72e40a8d3001 | 128 | send_report.data[2 + i] = data[i]; |
cyberjoey | 27:72e40a8d3001 | 129 | } |
cyberjoey | 27:72e40a8d3001 | 130 | |
cyberjoey | 27:72e40a8d3001 | 131 | //Send the report |
cyberjoey | 27:72e40a8d3001 | 132 | hid.send(&send_report); |
cyberjoey | 27:72e40a8d3001 | 133 | break; |
cyberjoey | 27:72e40a8d3001 | 134 | } |
cyberjoey | 27:72e40a8d3001 | 135 | case I2CWriteReg: |
cyberjoey | 27:72e40a8d3001 | 136 | { |
cyberjoey | 27:72e40a8d3001 | 137 | uint8_t slaveAddr = recv_report.data[2]; |
cyberjoey | 27:72e40a8d3001 | 138 | uint8_t regAddr = recv_report.data[3]; |
cyberjoey | 27:72e40a8d3001 | 139 | uint8_t numBytes = recv_report.data[4]; |
cyberjoey | 27:72e40a8d3001 | 140 | |
cyberjoey | 27:72e40a8d3001 | 141 | for(int i = 0; i < numBytes; i++) |
cyberjoey | 27:72e40a8d3001 | 142 | { |
cyberjoey | 27:72e40a8d3001 | 143 | data[i] = recv_report.data[5 + i]; |
cyberjoey | 27:72e40a8d3001 | 144 | } |
cyberjoey | 27:72e40a8d3001 | 145 | |
cyberjoey | 27:72e40a8d3001 | 146 | int error = I2C_write_register(slaveAddr, regAddr, data, numBytes); |
cyberjoey | 27:72e40a8d3001 | 147 | db.printf("slaveAddr = %02X regAddr = %02X data[0] = %02X numBytes = %d error = %d\r\n", slaveAddr, regAddr, data[0], numBytes, error); |
cyberjoey | 27:72e40a8d3001 | 148 | bool ack = !error; |
cyberjoey | 27:72e40a8d3001 | 149 | |
cyberjoey | 27:72e40a8d3001 | 150 | send_report.data[0] = I2CWriteReg;//OpCode = I2CWriteReg |
cyberjoey | 27:72e40a8d3001 | 151 | if(ack) |
cyberjoey | 27:72e40a8d3001 | 152 | send_report.data[1] = Success;//CmdStatus = Success |
cyberjoey | 27:72e40a8d3001 | 153 | else |
cyberjoey | 27:72e40a8d3001 | 154 | send_report.data[1] = Failure;//CmdStatus = Failure |
cyberjoey | 27:72e40a8d3001 | 155 | |
cyberjoey | 27:72e40a8d3001 | 156 | //Send the report |
cyberjoey | 27:72e40a8d3001 | 157 | hid.send(&send_report); |
cyberjoey | 27:72e40a8d3001 | 158 | break; |
cyberjoey | 27:72e40a8d3001 | 159 | } |
cyberjoey | 27:72e40a8d3001 | 160 | }//end switch(c) |
cyberjoey | 27:72e40a8d3001 | 161 | } |
cyberjoey | 27:72e40a8d3001 | 162 | |
cyberjoey | 9:36ba3626aab7 | 163 | //****************************************************************************** |
cyberjoey | 9:36ba3626aab7 | 164 | // main() |
cyberjoey | 9:36ba3626aab7 | 165 | //****************************************************************************** |
cyberjoey | 9:36ba3626aab7 | 166 | |
switches | 0:60a522ae2e35 | 167 | int main() |
switches | 0:60a522ae2e35 | 168 | { |
cyberjoey | 27:72e40a8d3001 | 169 | db.baud(9600); |
cyberjoey | 22:ee0d36d534cd | 170 | |
cyberjoey | 9:36ba3626aab7 | 171 | //************* init ticker timer callbacks **************** |
cyberjoey | 23:9bcf097cbfc2 | 172 | timer_1.attach(&LED_blink_callback, 0.5); //start ticker, once per sec. |
cyberjoey | 23:9bcf097cbfc2 | 173 | |
cyberjoey | 12:aa9fff0aec91 | 174 | i2c.frequency(400000); //set I2C clock to 400kHz |
cyberjoey | 23:9bcf097cbfc2 | 175 | |
cyberjoey | 9:36ba3626aab7 | 176 | rLED = LED_OFF; |
switches | 6:96d8d823e292 | 177 | gLED = LED_ON; |
cyberjoey | 9:36ba3626aab7 | 178 | bLED = LED_ON; |
cyberjoey | 23:9bcf097cbfc2 | 179 | |
cyberjoey | 26:89920e2454f8 | 180 | send_report.length = 64; |
cyberjoey | 25:89979f4ccfa9 | 181 | |
cyberjoey | 27:72e40a8d3001 | 182 | while (1) |
cyberjoey | 27:72e40a8d3001 | 183 | { |
cyberjoey | 25:89979f4ccfa9 | 184 | |
cyberjoey | 27:72e40a8d3001 | 185 | //if HID report is received... |
cyberjoey | 27:72e40a8d3001 | 186 | if(hid.readNB(&recv_report)) |
cyberjoey | 26:89920e2454f8 | 187 | { |
cyberjoey | 27:72e40a8d3001 | 188 | uint8_t command = recv_report.data[0]; |
cyberjoey | 27:72e40a8d3001 | 189 | process_command(command); |
cyberjoey | 25:89979f4ccfa9 | 190 | } |
cyberjoey | 25:89979f4ccfa9 | 191 | } |
switches | 0:60a522ae2e35 | 192 | } |