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: MODSERIAL USBDevice_for_Rev_C_HW mbed
Fork of mbed_sv_firmware_with_init by
main.cpp@22:5707b236cbdb, 2015-06-05 (annotated)
- Committer:
- bob_tpc
- Date:
- Fri Jun 05 01:52:30 2015 +0000
- Revision:
- 22:5707b236cbdb
- Parent:
- 19:d3bef4fbab69
- Child:
- 23:52504c8f63c5
Full firmware for Rev C hardware
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| bob_tpc | 22:5707b236cbdb | 1 | /** |
| bob_tpc | 22:5707b236cbdb | 2 | * Copyright (c) 2015 The Positive Charge, LLC for Supervision, LLC |
| bob_tpc | 10:55e35536d493 | 3 | * @file main.cpp |
| bob_tpc | 22:5707b236cbdb | 4 | * @date 2015-06-04 |
| bob_tpc | 10:55e35536d493 | 5 | * @brief Freescale KL25Z firmware for USB-RFID adapter |
| bob_tpc | 10:55e35536d493 | 6 | * |
| bob_tpc | 22:5707b236cbdb | 7 | * This firmware provides communication from a PC's USB host port to the following peripherals: |
| bob_tpc | 10:55e35536d493 | 8 | * RFID-FE over UART - SuperVision RFID reader module |
| bob_tpc | 10:55e35536d493 | 9 | * VL6180X over I2C - ST Microelectronics proximity and ambient light sensor |
| bob_tpc | 10:55e35536d493 | 10 | * GPIO - two LEDs and several control signals for the RFID module |
| bob_tpc | 10:55e35536d493 | 11 | * EEPROM - over I2C - Generic 24LC16B (untested since first revision prototype hardware does not have an EEPROM) |
| bob_tpc | 22:5707b236cbdb | 12 | * |
| bob_tpc | 22:5707b236cbdb | 13 | * Revision History |
| bob_tpc | 22:5707b236cbdb | 14 | * 2014-11-01 |
| bob_tpc | 22:5707b236cbdb | 15 | * For Rev A Hardware - No EEPROM, single-byte GPIO |
| bob_tpc | 22:5707b236cbdb | 16 | * |
| bob_tpc | 22:5707b236cbdb | 17 | * 2015-03-01 |
| bob_tpc | 22:5707b236cbdb | 18 | * For Rev B and C Hardware - Includes EEPROM, single-byte GPIO |
| bob_tpc | 22:5707b236cbdb | 19 | * |
| bob_tpc | 22:5707b236cbdb | 20 | * 2015-06-04 |
| bob_tpc | 22:5707b236cbdb | 21 | * For Rev C Hardware - Includes EEPROM, 2-byte GPIO allows extra pins on LED connector to be used. |
| bob_tpc | 22:5707b236cbdb | 22 | * - Includes EEPROM storage of USB string descriptors and RFID command for Proximity interrupt |
| bob_tpc | 22:5707b236cbdb | 23 | * - Includes USB initialization update and added code to send RFID command on Proximity interrupt |
| bob_tpc | 22:5707b236cbdb | 24 | * |
| bob_tpc | 10:55e35536d493 | 25 | */ |
| bob_tpc | 10:55e35536d493 | 26 | |
| bob_tpc | 22:5707b236cbdb | 27 | // mbed.org headers |
| bob_tpc | 22:5707b236cbdb | 28 | #include "mbed.h" // main mbed.org libraries |
| bob_tpc | 22:5707b236cbdb | 29 | #include "USBDevice.h" |
| bob_tpc | 22:5707b236cbdb | 30 | #include "USBSerial.h" // USB CDC drivers |
| bob_tpc | 22:5707b236cbdb | 31 | #include "MODSERIAL.h" // UART drivers - MODSERIAL allows block writes compared to the mbed driver |
| bob_tpc | 10:55e35536d493 | 32 | |
| bob_tpc | 22:5707b236cbdb | 33 | // Supervision-specific headers |
| bob_tpc | 22:5707b236cbdb | 34 | #include "SV_USBConfig.h" // Default USB strings for initial power-up. |
| bob_tpc | 22:5707b236cbdb | 35 | #include "ProxInit.h" // VL6180X default initial values - *not* calibrated |
| bob_tpc | 0:8604e9cc07f2 | 36 | |
| bob_tpc | 0:8604e9cc07f2 | 37 | // Constants |
| bob_tpc | 15:713c26178a7d | 38 | #define LEDON 0 // Low active for LEDs - turns LED on |
| bob_tpc | 15:713c26178a7d | 39 | #define LEDOFF 1 // Low active for LEDs - turns LED off |
| bob_tpc | 22:5707b236cbdb | 40 | |
| bob_tpc | 22:5707b236cbdb | 41 | #define TRUE 1 // Boolean true and false |
| bob_tpc | 0:8604e9cc07f2 | 42 | #define FALSE 0 |
| bob_tpc | 0:8604e9cc07f2 | 43 | |
| bob_tpc | 0:8604e9cc07f2 | 44 | // Error return values |
| bob_tpc | 15:713c26178a7d | 45 | #define ERR_NONE 0x00 // Success |
| bob_tpc | 15:713c26178a7d | 46 | #define ERR_CDC_BAD_CMD 0x01 // First byte of PC to USB board needs to be 0xBB, 0xCC, 0xDD or 0xEE; |
| bob_tpc | 15:713c26178a7d | 47 | #define ERR_CDC_NO_TX_ENDMARK 0xA1 // message for no endmark on message to PC |
| bob_tpc | 15:713c26178a7d | 48 | #define ERR_UART_NOT_WRITEABLE 0xB1 // UART has no buffer space |
| bob_tpc | 15:713c26178a7d | 49 | #define ERR_UART_NOT_READABLE 0xB2 // UART has no buffer space |
| bob_tpc | 15:713c26178a7d | 50 | #define ERR_UART_NO_TX_ENDMARK 0xB3 // message for UART has no 0x7E end-mark |
| bob_tpc | 15:713c26178a7d | 51 | #define ERR_UART_NO_RX_ENDMARK 0xB4 // message received from UART has no end-mark |
| bob_tpc | 22:5707b236cbdb | 52 | #define ERR_I2C_NOT_WRITEABLE 0xC1 // I2C has no buffer space |
| bob_tpc | 22:5707b236cbdb | 53 | #define ERR_I2C_NO_TX_ENDMARK 0xC2 // message for I2C has no 0x7E end-mark |
| bob_tpc | 22:5707b236cbdb | 54 | #define ERR_I2C_NO_RX_ENDMARK 0xC3 // message received from I2C has no end-mark |
| bob_tpc | 22:5707b236cbdb | 55 | #define ERR_I2C_WRITE_TOO_LARGE 0x16 // message for I2C write is too large (16 bytes max) |
| bob_tpc | 15:713c26178a7d | 56 | #define ERR_NOT_IMPLEMENTED 0xFF // method has not yet been implemented |
| bob_tpc | 0:8604e9cc07f2 | 57 | |
| bob_tpc | 10:55e35536d493 | 58 | // I2C addresses and parameters |
| bob_tpc | 15:713c26178a7d | 59 | #define PROX (0x29 << 1) // default I2C address of VL6180X, shift into upper 7 bits |
| bob_tpc | 15:713c26178a7d | 60 | #define EEPROM (0xA0) // default I2C address of EEPROM, already shifted |
| bob_tpc | 15:713c26178a7d | 61 | #define I2CRATE 400000 // I2C speed |
| bob_tpc | 0:8604e9cc07f2 | 62 | |
| bob_tpc | 0:8604e9cc07f2 | 63 | // UART-RFID baud rate |
| bob_tpc | 15:713c26178a7d | 64 | #define RFIDBAUD 115200 // RFID-FE board default rate = 115.2Kbps |
| bob_tpc | 22:5707b236cbdb | 65 | #define BUFFERSIZE 128 // default buffer sizes |
| bob_tpc | 15:713c26178a7d | 66 | #define RFIDLENLOW 5 // RFID message length location (length is 2 bytes) |
| bob_tpc | 0:8604e9cc07f2 | 67 | |
| bob_tpc | 0:8604e9cc07f2 | 68 | // Peripherals |
| bob_tpc | 22:5707b236cbdb | 69 | USBSerial cdc; // CDC Class USB-Serial adapter. Needs custom INF, but uses existing Windows CDC drivers. |
| bob_tpc | 19:d3bef4fbab69 | 70 | MODSERIAL uart(PTA2, PTA1); // UART port connected to RFID-FE board |
| bob_tpc | 15:713c26178a7d | 71 | I2C i2c(PTB1, PTB0); // I2C port connected to VL6180X and EEPROM - note addresses above) |
| bob_tpc | 0:8604e9cc07f2 | 72 | |
| bob_tpc | 0:8604e9cc07f2 | 73 | // GPIO signals |
| bob_tpc | 15:713c26178a7d | 74 | DigitalOut led_err(PTC1); // Red LED shows error condition (active low) |
| bob_tpc | 15:713c26178a7d | 75 | DigitalOut led_com(PTC2); // Yellow LED shows communication activity (active low) |
| bob_tpc | 15:713c26178a7d | 76 | DigitalOut rfid_int(PTD4); // RFID FE power control (active high) |
| bob_tpc | 15:713c26178a7d | 77 | DigitalOut rfid_isp(PTD5); // RFID FE In-System Programming (active high) |
| bob_tpc | 15:713c26178a7d | 78 | DigitalOut rfid_rst(PTD6); // RFID FE Reset (active high) |
| bob_tpc | 15:713c26178a7d | 79 | DigitalOut rfid_pwr(PTE30); // RFID power switch on USB board (active high for prototype 1, low for all others) |
| bob_tpc | 15:713c26178a7d | 80 | DigitalIn rfid_hot(PTE0); // RFID over-current detection on USB board power switch (active low) |
| bob_tpc | 15:713c26178a7d | 81 | InterruptIn prox_int(PTD7); // Proximity sensor interrupt (active low) |
| bob_tpc | 22:5707b236cbdb | 82 | DigitalOut ee_wp(PTC5); // EEPROM Write Protect (active high) |
| bob_tpc | 0:8604e9cc07f2 | 83 | |
| bob_tpc | 19:d3bef4fbab69 | 84 | DigitalInOut gpio_0(PTC3); // Extra GPIO on LED connector, pin 6 |
| bob_tpc | 19:d3bef4fbab69 | 85 | DigitalInOut gpio_1(PTC4); // Extra GPIO on LED connector, pin 7 |
| bob_tpc | 19:d3bef4fbab69 | 86 | DigitalOut gpio_7(PTA4); // Extra GPIO output on LED connector, pin 3 - pin supports PWM for buzzer, not implemented here |
| bob_tpc | 19:d3bef4fbab69 | 87 | |
| bob_tpc | 22:5707b236cbdb | 88 | // global buffers & variables |
| bob_tpc | 22:5707b236cbdb | 89 | uint8_t led_com_state = LEDOFF; // initial LED state |
| bob_tpc | 22:5707b236cbdb | 90 | uint8_t prox_irq_state = 0; // interrupt state passed from service routine |
| bob_tpc | 22:5707b236cbdb | 91 | uint8_t usb_irq_state = 0; // interrupt state passed from service routine |
| bob_tpc | 15:713c26178a7d | 92 | uint8_t gpio_values = 0x00; // register to read GPIO values |
| bob_tpc | 22:5707b236cbdb | 93 | uint8_t cdc_buffer_rx[BUFFERSIZE]; // buffers for cdc (USB-Serial port on PC) |
| bob_tpc | 15:713c26178a7d | 94 | uint8_t cdc_buffer_tx[BUFFERSIZE]; |
| bob_tpc | 15:713c26178a7d | 95 | uint8_t uart_buffer_rx[BUFFERSIZE]; // buffers for uart (RFID-FE board) |
| bob_tpc | 15:713c26178a7d | 96 | uint8_t uart_buffer_tx[BUFFERSIZE]; |
| bob_tpc | 15:713c26178a7d | 97 | uint8_t gpio_buffer[BUFFERSIZE]; // buffer for GPIO messages |
| bob_tpc | 22:5707b236cbdb | 98 | |
| bob_tpc | 22:5707b236cbdb | 99 | char i2c_buffer[BUFFERSIZE]; // buffer for I2C devices - Proximity sensor and EEPROM - up to BUFFERSIZE bytes data payload for EEPROM, up to 4 for proximity |
| bob_tpc | 22:5707b236cbdb | 100 | char prox_irq_msg[BUFFERSIZE]; // buffer for automatic RFID message on proximity interrupt |
| bob_tpc | 22:5707b236cbdb | 101 | |
| bob_tpc | 22:5707b236cbdb | 102 | int i, j; // general index variables |
| bob_tpc | 15:713c26178a7d | 103 | int status = 0x00; // return value |
| bob_tpc | 22:5707b236cbdb | 104 | |
| bob_tpc | 22:5707b236cbdb | 105 | // USB config descriptor strings |
| bob_tpc | 22:5707b236cbdb | 106 | // These are held in SV_USBConfig.h, and only used during initial bring-up after manufacturing |
| bob_tpc | 22:5707b236cbdb | 107 | |
| bob_tpc | 22:5707b236cbdb | 108 | char mfg_str[0x2E] = {SV_MFG}; // Default USB strings - Manufacturer |
| bob_tpc | 22:5707b236cbdb | 109 | char mfg_str_cnt = SV_MFG_CNT; |
| bob_tpc | 22:5707b236cbdb | 110 | char ser_str[0x2E] = {SV_SER}; // Default USB strings - Serial Number |
| bob_tpc | 22:5707b236cbdb | 111 | char ser_str_cnt = SV_SER_CNT; |
| bob_tpc | 22:5707b236cbdb | 112 | char des_str[0x3E] = {SV_DES}; // Default USB strings - Product Description |
| bob_tpc | 22:5707b236cbdb | 113 | char des_str_cnt = SV_DES_CNT; |
| bob_tpc | 22:5707b236cbdb | 114 | |
| bob_tpc | 22:5707b236cbdb | 115 | // These next functions are modified from the original USBDevice.cpp and USBCDC.cpp mbed drivers |
| bob_tpc | 22:5707b236cbdb | 116 | // in order to allow custom USB descriptor strings. |
| bob_tpc | 22:5707b236cbdb | 117 | |
| bob_tpc | 22:5707b236cbdb | 118 | /** |
| bob_tpc | 22:5707b236cbdb | 119 | * @name USBDevice::stringImanufacturerDesc |
| bob_tpc | 22:5707b236cbdb | 120 | * @name USBDevice::stringIserialDesc |
| bob_tpc | 22:5707b236cbdb | 121 | * @name USBDevice::stringIproductDesc |
| bob_tpc | 22:5707b236cbdb | 122 | * @name USBCDC::stringIproductDesc |
| bob_tpc | 22:5707b236cbdb | 123 | * @brief Sets custom USB Config Descriptor Strings |
| bob_tpc | 22:5707b236cbdb | 124 | * |
| bob_tpc | 22:5707b236cbdb | 125 | * These methods are modified from the original to allow custom USB config descriptor strings. |
| bob_tpc | 22:5707b236cbdb | 126 | * The original (in USBDevice.cpp and USBCDC.cpp) are hard-coded for generic mbed.org values |
| bob_tpc | 22:5707b236cbdb | 127 | * The values used in these methods are read from the EEPROM. Especially important is allowing |
| bob_tpc | 22:5707b236cbdb | 128 | * a custom USB Serial Number, which will be written to the EEPROM during the factory test. |
| bob_tpc | 22:5707b236cbdb | 129 | * |
| bob_tpc | 22:5707b236cbdb | 130 | * @param [in] none |
| bob_tpc | 22:5707b236cbdb | 131 | * @retval stringImanufacturerDescriptor |
| bob_tpc | 22:5707b236cbdb | 132 | * @retval stringIserialDescriptor |
| bob_tpc | 22:5707b236cbdb | 133 | * @retval stringIproductDescriptor |
| bob_tpc | 22:5707b236cbdb | 134 | * @retval stringIproductDescriptor |
| bob_tpc | 22:5707b236cbdb | 135 | */ |
| bob_tpc | 22:5707b236cbdb | 136 | |
| bob_tpc | 9:046247707ffb | 137 | |
| bob_tpc | 22:5707b236cbdb | 138 | // MODIFIED to allow custom strings |
| bob_tpc | 22:5707b236cbdb | 139 | uint8_t * USBDevice::stringImanufacturerDesc() { |
| bob_tpc | 22:5707b236cbdb | 140 | static uint8_t stringImanufacturerDescriptor[0x30]; |
| bob_tpc | 22:5707b236cbdb | 141 | stringImanufacturerDescriptor[0] = mfg_str_cnt; |
| bob_tpc | 22:5707b236cbdb | 142 | stringImanufacturerDescriptor[1] = STRING_DESCRIPTOR; |
| bob_tpc | 22:5707b236cbdb | 143 | for (int i = 0; i < sizeof(mfg_str); i++){ |
| bob_tpc | 22:5707b236cbdb | 144 | stringImanufacturerDescriptor[i+2] = mfg_str[i]; |
| bob_tpc | 22:5707b236cbdb | 145 | } |
| bob_tpc | 22:5707b236cbdb | 146 | return stringImanufacturerDescriptor; |
| bob_tpc | 22:5707b236cbdb | 147 | } |
| bob_tpc | 22:5707b236cbdb | 148 | |
| bob_tpc | 22:5707b236cbdb | 149 | // MODIFIED to allow custom strings |
| bob_tpc | 22:5707b236cbdb | 150 | |
| bob_tpc | 22:5707b236cbdb | 151 | uint8_t * USBDevice::stringIserialDesc() { |
| bob_tpc | 22:5707b236cbdb | 152 | static uint8_t stringIserialDescriptor[0x30]; |
| bob_tpc | 22:5707b236cbdb | 153 | stringIserialDescriptor[0] = ser_str_cnt; |
| bob_tpc | 22:5707b236cbdb | 154 | stringIserialDescriptor[1] = STRING_DESCRIPTOR; |
| bob_tpc | 22:5707b236cbdb | 155 | for (int i = 0; i < sizeof(ser_str); i++){ |
| bob_tpc | 22:5707b236cbdb | 156 | stringIserialDescriptor[i+2] = ser_str[i]; |
| bob_tpc | 22:5707b236cbdb | 157 | } |
| bob_tpc | 22:5707b236cbdb | 158 | return stringIserialDescriptor; |
| bob_tpc | 22:5707b236cbdb | 159 | } |
| bob_tpc | 22:5707b236cbdb | 160 | |
| bob_tpc | 22:5707b236cbdb | 161 | // MODIFIED to allow custom strings |
| bob_tpc | 22:5707b236cbdb | 162 | uint8_t * USBDevice::stringIproductDesc() { |
| bob_tpc | 22:5707b236cbdb | 163 | static uint8_t stringIproductDescriptor[0x40]; |
| bob_tpc | 22:5707b236cbdb | 164 | stringIproductDescriptor[0] = des_str_cnt; |
| bob_tpc | 22:5707b236cbdb | 165 | stringIproductDescriptor[1] = STRING_DESCRIPTOR; |
| bob_tpc | 22:5707b236cbdb | 166 | for (int i = 0; i < sizeof(des_str); i++){ |
| bob_tpc | 22:5707b236cbdb | 167 | stringIproductDescriptor[i+2] = des_str[i]; |
| bob_tpc | 22:5707b236cbdb | 168 | } |
| bob_tpc | 22:5707b236cbdb | 169 | return stringIproductDescriptor; |
| bob_tpc | 22:5707b236cbdb | 170 | } |
| bob_tpc | 22:5707b236cbdb | 171 | |
| bob_tpc | 22:5707b236cbdb | 172 | |
| bob_tpc | 22:5707b236cbdb | 173 | // MODIFIED to allow custom strings |
| bob_tpc | 22:5707b236cbdb | 174 | uint8_t * USBCDC::stringIproductDesc() { |
| bob_tpc | 22:5707b236cbdb | 175 | static uint8_t stringIproductDescriptor[0x40]; |
| bob_tpc | 22:5707b236cbdb | 176 | stringIproductDescriptor[0] = des_str_cnt; |
| bob_tpc | 22:5707b236cbdb | 177 | stringIproductDescriptor[1] = STRING_DESCRIPTOR; |
| bob_tpc | 22:5707b236cbdb | 178 | for (int i = 0; i < sizeof(des_str); i++){ |
| bob_tpc | 22:5707b236cbdb | 179 | stringIproductDescriptor[i+2] = des_str[i]; |
| bob_tpc | 22:5707b236cbdb | 180 | } |
| bob_tpc | 22:5707b236cbdb | 181 | return stringIproductDescriptor; |
| bob_tpc | 22:5707b236cbdb | 182 | } |
| bob_tpc | 10:55e35536d493 | 183 | |
| bob_tpc | 10:55e35536d493 | 184 | /** |
| bob_tpc | 10:55e35536d493 | 185 | * @name prox_irq |
| bob_tpc | 10:55e35536d493 | 186 | * @brief Sets interrupt variable for use in the main loop. |
| bob_tpc | 10:55e35536d493 | 187 | * The interrupt is triggered by the VL6180X GPIO1 (IRQ output) |
| bob_tpc | 10:55e35536d493 | 188 | * |
| bob_tpc | 10:55e35536d493 | 189 | * @param [in] none |
| bob_tpc | 10:55e35536d493 | 190 | * @param [out] prox_irq_state = 1 indicates an interrupt occured. |
| bob_tpc | 10:55e35536d493 | 191 | */ |
| bob_tpc | 9:046247707ffb | 192 | void prox_irq(void) |
| bob_tpc | 0:8604e9cc07f2 | 193 | { |
| bob_tpc | 9:046247707ffb | 194 | prox_irq_state = 1; |
| bob_tpc | 22:5707b236cbdb | 195 | led_com.write(LEDON); // Turn on COM LED until interrupt is serviced |
| bob_tpc | 0:8604e9cc07f2 | 196 | } |
| bob_tpc | 0:8604e9cc07f2 | 197 | |
| bob_tpc | 22:5707b236cbdb | 198 | /** |
| bob_tpc | 22:5707b236cbdb | 199 | * @name usb_irq |
| bob_tpc | 22:5707b236cbdb | 200 | * @brief Sets interrupt variable for use in the main loop. |
| bob_tpc | 22:5707b236cbdb | 201 | * The interrupt is triggered when the host PC has sent data to the CDC port. |
| bob_tpc | 22:5707b236cbdb | 202 | * |
| bob_tpc | 22:5707b236cbdb | 203 | * @param [in] none |
| bob_tpc | 22:5707b236cbdb | 204 | * @param [out] usb_irq_state = 1 indicates an interrupt occured. |
| bob_tpc | 22:5707b236cbdb | 205 | */ |
| bob_tpc | 15:713c26178a7d | 206 | void usb_irq(void) |
| bob_tpc | 15:713c26178a7d | 207 | { |
| bob_tpc | 15:713c26178a7d | 208 | usb_irq_state = 1; |
| bob_tpc | 15:713c26178a7d | 209 | } |
| bob_tpc | 15:713c26178a7d | 210 | |
| bob_tpc | 10:55e35536d493 | 211 | /** |
| bob_tpc | 10:55e35536d493 | 212 | * @name init_periph |
| bob_tpc | 10:55e35536d493 | 213 | * @brief Initializes the KL25Z peripheal interfaces |
| bob_tpc | 10:55e35536d493 | 214 | * KL25Z interfaces: |
| bob_tpc | 22:5707b236cbdb | 215 | * USB - Initializes USB config descriptors |
| bob_tpc | 22:5707b236cbdb | 216 | * UART - Connects to SuperVision RFID-FE module |
| bob_tpc | 22:5707b236cbdb | 217 | * I2C - Configures to the ST VL6180X proximity/ambient light sensor device |
| bob_tpc | 22:5707b236cbdb | 218 | * I2C - Reads configuration data from EEPROM |
| bob_tpc | 22:5707b236cbdb | 219 | * GPIO - Includes two LEDs and signals to control RFID reader. |
| bob_tpc | 10:55e35536d493 | 220 | * |
| bob_tpc | 10:55e35536d493 | 221 | * @param [in] none |
| bob_tpc | 22:5707b236cbdb | 222 | * @param [out] error status (0 = no error) |
| bob_tpc | 22:5707b236cbdb | 223 | * |
| bob_tpc | 22:5707b236cbdb | 224 | * @retval error state |
| bob_tpc | 10:55e35536d493 | 225 | */ |
| bob_tpc | 22:5707b236cbdb | 226 | int init_periph(void) |
| bob_tpc | 0:8604e9cc07f2 | 227 | { |
| bob_tpc | 22:5707b236cbdb | 228 | int i2c_err; // return value |
| bob_tpc | 22:5707b236cbdb | 229 | char temploc = 0x00; // temporary values |
| bob_tpc | 22:5707b236cbdb | 230 | char temp[] = {0,0}; |
| bob_tpc | 22:5707b236cbdb | 231 | char i2c_page = 0; |
| bob_tpc | 22:5707b236cbdb | 232 | char prox_ee[254] = {0}; // buffer for Proximity initialization values stored |
| bob_tpc | 22:5707b236cbdb | 233 | // in EEPROM, especially the cover glass calibration |
| bob_tpc | 22:5707b236cbdb | 234 | // Set up peripherals on KL25Z |
| bob_tpc | 22:5707b236cbdb | 235 | |
| bob_tpc | 22:5707b236cbdb | 236 | led_err.write(LEDOFF); // Start with leds |
| bob_tpc | 22:5707b236cbdb | 237 | led_com.write(LEDOFF); |
| bob_tpc | 22:5707b236cbdb | 238 | |
| bob_tpc | 22:5707b236cbdb | 239 | // Check EEPROM for programmed USB string descriptors. These are held in BANK ZERO (I2C address = EEPROM | 0 << 1) |
| bob_tpc | 22:5707b236cbdb | 240 | // Factory test should initialize the EEPROM |
| bob_tpc | 22:5707b236cbdb | 241 | // |
| bob_tpc | 22:5707b236cbdb | 242 | // First two bytes of bank zero will be "SV" if programmed. |
| bob_tpc | 22:5707b236cbdb | 243 | // Bank 0x10 holds Manufacturer string |
| bob_tpc | 22:5707b236cbdb | 244 | // Bank 0x40 holds Serial Number string |
| bob_tpc | 22:5707b236cbdb | 245 | // Bank 0x70 holds Product Description string |
| bob_tpc | 22:5707b236cbdb | 246 | |
| bob_tpc | 22:5707b236cbdb | 247 | i2c_page = EEPROM | 0 << 1; // set EEPROM page = bank 0 |
| bob_tpc | 22:5707b236cbdb | 248 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte (just index), no stop at end. |
| bob_tpc | 22:5707b236cbdb | 249 | i2c.read(i2c_page, temp, 2, 0); // i2c address+bank 0, variable location, 2 bytes (just data), stop at end. |
| bob_tpc | 22:5707b236cbdb | 250 | |
| bob_tpc | 22:5707b236cbdb | 251 | if ((temp[0] == 'S') && (temp[1] == 'V')) { |
| bob_tpc | 22:5707b236cbdb | 252 | led_com.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 253 | |
| bob_tpc | 22:5707b236cbdb | 254 | // Read Manufacturer String |
| bob_tpc | 22:5707b236cbdb | 255 | temploc = 0x10; |
| bob_tpc | 22:5707b236cbdb | 256 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, count index, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 257 | i2c.read(i2c_page, &mfg_str_cnt, 1, 0); // i2c address+bank 0, mfg string size, 1 byte, stop at end |
| bob_tpc | 22:5707b236cbdb | 258 | temploc = 0x11; |
| bob_tpc | 22:5707b236cbdb | 259 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 260 | i2c.read(i2c_page, mfg_str, mfg_str_cnt, 0); // i2c address+bank 0, mfg string, string size, stop at end |
| bob_tpc | 22:5707b236cbdb | 261 | |
| bob_tpc | 22:5707b236cbdb | 262 | // Read Serial Number string |
| bob_tpc | 22:5707b236cbdb | 263 | temploc = 0x40; |
| bob_tpc | 22:5707b236cbdb | 264 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte no stop at end |
| bob_tpc | 22:5707b236cbdb | 265 | i2c.read(i2c_page, &ser_str_cnt, 1, 0); // i2c address+bank 0, serial number string size, 1 byte, stop at end |
| bob_tpc | 22:5707b236cbdb | 266 | temploc = 0x41; |
| bob_tpc | 22:5707b236cbdb | 267 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 268 | i2c.read(i2c_page, ser_str, ser_str_cnt, 0); // i2c address+bank 0, serial number string, string size, stop at end |
| bob_tpc | 22:5707b236cbdb | 269 | |
| bob_tpc | 22:5707b236cbdb | 270 | // Read Product Description String |
| bob_tpc | 22:5707b236cbdb | 271 | temploc = 0x70; |
| bob_tpc | 22:5707b236cbdb | 272 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 273 | i2c.read(i2c_page, &des_str_cnt, 1, 0); // i2c address+bank 0, description string size, 1 byte, stop at end |
| bob_tpc | 22:5707b236cbdb | 274 | temploc = 0x71; |
| bob_tpc | 22:5707b236cbdb | 275 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 276 | i2c.read(i2c_page, des_str, des_str_cnt, 0); // i2c address+bank 0, description string, string size, stop at end |
| bob_tpc | 22:5707b236cbdb | 277 | led_com.write(LEDOFF); |
| bob_tpc | 22:5707b236cbdb | 278 | |
| bob_tpc | 22:5707b236cbdb | 279 | } |
| bob_tpc | 22:5707b236cbdb | 280 | |
| bob_tpc | 22:5707b236cbdb | 281 | // Prox & EEPROM |
| bob_tpc | 22:5707b236cbdb | 282 | ee_wp.write(0); // no write protection on EEPROM |
| bob_tpc | 22:5707b236cbdb | 283 | i2c.frequency(I2CRATE); // I2C speed = 400Kbps |
| bob_tpc | 22:5707b236cbdb | 284 | |
| bob_tpc | 22:5707b236cbdb | 285 | // Get the VL6180X register values from the ProxInit.h header and program them to the Proximity Sensor (from VL6180X app notes) |
| bob_tpc | 22:5707b236cbdb | 286 | |
| bob_tpc | 22:5707b236cbdb | 287 | for (i = 0; i < sizeof(proxinit); i += 3){ // Initialize VL6180X with default values, calibration data sent later |
| bob_tpc | 22:5707b236cbdb | 288 | i2c_err = i2c.write(PROX, &proxinit[i], 3, 0); // I2C Address, pointer to buffer, number of bytes (for index + data), stop at end. |
| bob_tpc | 22:5707b236cbdb | 289 | // also includes taking off the "Fresh out of Reset" flag. |
| bob_tpc | 22:5707b236cbdb | 290 | if (i2c_err){ |
| bob_tpc | 22:5707b236cbdb | 291 | led_err.write(LEDON); // Turn on both LEDs |
| bob_tpc | 22:5707b236cbdb | 292 | led_com.write(LEDON); // We can't write to the proximity sensor |
| bob_tpc | 22:5707b236cbdb | 293 | return i2c_err; |
| bob_tpc | 22:5707b236cbdb | 294 | } |
| bob_tpc | 22:5707b236cbdb | 295 | } |
| bob_tpc | 22:5707b236cbdb | 296 | |
| bob_tpc | 22:5707b236cbdb | 297 | // Get Supervision-specific register values and program them to the Proximity Sensor (calibration, other operating features) |
| bob_tpc | 22:5707b236cbdb | 298 | |
| bob_tpc | 22:5707b236cbdb | 299 | i2c_page = EEPROM | 1 << 1; // set EEPROM page = bank 1 |
| bob_tpc | 22:5707b236cbdb | 300 | temploc = 0; |
| bob_tpc | 22:5707b236cbdb | 301 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 1, memory index, 1 byte (just index), no stop at end. |
| bob_tpc | 22:5707b236cbdb | 302 | i2c.read(i2c_page, temp, 2, 0); // i2c address+bank 1, variable location, 2 bytes (just data), stop at end. |
| bob_tpc | 22:5707b236cbdb | 303 | |
| bob_tpc | 22:5707b236cbdb | 304 | if ((temp[0] == 'S') && (temp[1] == 'V')) { |
| bob_tpc | 22:5707b236cbdb | 305 | led_com.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 306 | // Read values |
| bob_tpc | 22:5707b236cbdb | 307 | temploc = 0x02; // Values start here. Since this section is mostly one-byte values with two-byte |
| bob_tpc | 22:5707b236cbdb | 308 | // addresses, 2- and 4-byte registers are individually addressed |
| bob_tpc | 22:5707b236cbdb | 309 | i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 1, location 2, 1 byte, no stop at end - read the whole bank |
| bob_tpc | 22:5707b236cbdb | 310 | i2c.read(i2c_page, prox_ee, sizeof(prox_ee), 0); // i2c address+bank 1, buffer location, 1 byte, stop at end |
| bob_tpc | 22:5707b236cbdb | 311 | for (i = 0; i < sizeof(prox_ee); i += 3){ // Initialize VL6180X with default values, calibration data sent later |
| bob_tpc | 22:5707b236cbdb | 312 | if ((prox_ee[i] == 0xFF) && (prox_ee[i+1] == 0xFF)){ |
| bob_tpc | 22:5707b236cbdb | 313 | break; // No more values are in the EEPROM (blank / erased = 0xFF) |
| bob_tpc | 22:5707b236cbdb | 314 | } |
| bob_tpc | 22:5707b236cbdb | 315 | else { |
| bob_tpc | 22:5707b236cbdb | 316 | i2c_err = i2c.write(PROX, &prox_ee[i], 3, 0); // I2C Address, pointer to buffer, number of bytes (for index + data), stop at end. |
| bob_tpc | 22:5707b236cbdb | 317 | // also includes taking off the "Fresh out of Reset" flag. |
| bob_tpc | 22:5707b236cbdb | 318 | if (i2c_err){ |
| bob_tpc | 22:5707b236cbdb | 319 | led_err.write(LEDON); // Turn on both LEDs |
| bob_tpc | 22:5707b236cbdb | 320 | led_com.write(LEDON); // We can't write to the proximity sensor |
| bob_tpc | 22:5707b236cbdb | 321 | return i2c_err; |
| bob_tpc | 22:5707b236cbdb | 322 | } |
| bob_tpc | 22:5707b236cbdb | 323 | } |
| bob_tpc | 22:5707b236cbdb | 324 | } |
| bob_tpc | 22:5707b236cbdb | 325 | led_com.write(LEDOFF); |
| bob_tpc | 22:5707b236cbdb | 326 | } |
| bob_tpc | 22:5707b236cbdb | 327 | |
| bob_tpc | 22:5707b236cbdb | 328 | // Enable the Proximity interrupt |
| bob_tpc | 22:5707b236cbdb | 329 | prox_int.mode(PullUp); // pull up proximity sensor interrupt at MCU |
| bob_tpc | 22:5707b236cbdb | 330 | prox_int.fall(&prox_irq); // VL6180X interrupt is low active |
| bob_tpc | 22:5707b236cbdb | 331 | prox_int.enable_irq(); // Enable proximity interrupt inputs |
| bob_tpc | 22:5707b236cbdb | 332 | |
| bob_tpc | 22:5707b236cbdb | 333 | // "Fresh-out-of-reset" register was automatically set to 0x01 after boot |
| bob_tpc | 22:5707b236cbdb | 334 | prox_ee[0] = 0x00; |
| bob_tpc | 22:5707b236cbdb | 335 | prox_ee[1] = 0x16; |
| bob_tpc | 22:5707b236cbdb | 336 | prox_ee[2] = 0x00; |
| bob_tpc | 22:5707b236cbdb | 337 | i2c.write(PROX, prox_ee, 3, 0); // Remove "Fresh out of Reset" flag to allow normal operation |
| bob_tpc | 22:5707b236cbdb | 338 | |
| bob_tpc | 22:5707b236cbdb | 339 | cdc.attach(&usb_irq); // Attach USB interrupt |
| bob_tpc | 22:5707b236cbdb | 340 | usb_irq_state = 0; // Ensure interrupt flag is not set after setup |
| bob_tpc | 22:5707b236cbdb | 341 | |
| bob_tpc | 0:8604e9cc07f2 | 342 | // RFID |
| bob_tpc | 15:713c26178a7d | 343 | uart.baud(RFIDBAUD); // RFID-FE baud rate |
| bob_tpc | 22:5707b236cbdb | 344 | |
| bob_tpc | 15:713c26178a7d | 345 | rfid_int = 0; // RFID FE power control (active high) |
| bob_tpc | 15:713c26178a7d | 346 | rfid_isp = 0; // RFID FE In-System Programming (active high) |
| bob_tpc | 15:713c26178a7d | 347 | rfid_rst = 1; // RFID FE Reset (active high) |
| bob_tpc | 17:1e704604e1ac | 348 | rfid_pwr = 0; // RFID power switch on USB board (active low for all others) |
| bob_tpc | 19:d3bef4fbab69 | 349 | wait(0.25); // wait 250ms before... |
| bob_tpc | 15:713c26178a7d | 350 | rfid_rst = 0; // ... taking RFID out of reset |
| bob_tpc | 19:d3bef4fbab69 | 351 | wait(0.25); |
| bob_tpc | 22:5707b236cbdb | 352 | |
| bob_tpc | 22:5707b236cbdb | 353 | while(!uart.readable()) { // wait for RESET message from RFID |
| bob_tpc | 15:713c26178a7d | 354 | led_err.write(LEDON); // flash LED until it arrives |
| bob_tpc | 22:5707b236cbdb | 355 | wait(0.1); // This is a good way to see if the RFID cable is properly seated |
| bob_tpc | 15:713c26178a7d | 356 | led_err.write(LEDOFF); |
| bob_tpc | 15:713c26178a7d | 357 | wait(0.1); |
| bob_tpc | 22:5707b236cbdb | 358 | } |
| bob_tpc | 22:5707b236cbdb | 359 | |
| bob_tpc | 22:5707b236cbdb | 360 | uart.txBufferFlush(); // clear out UART buffers - we don't need the reset message |
| bob_tpc | 19:d3bef4fbab69 | 361 | uart.rxBufferFlush(); |
| bob_tpc | 22:5707b236cbdb | 362 | |
| bob_tpc | 15:713c26178a7d | 363 | // LEDs // Cycle through the LEDs. |
| bob_tpc | 5:e77529f7ede3 | 364 | led_err.write(LEDON); |
| bob_tpc | 5:e77529f7ede3 | 365 | led_com.write(LEDON); |
| bob_tpc | 5:e77529f7ede3 | 366 | wait(0.5); |
| bob_tpc | 5:e77529f7ede3 | 367 | led_err.write(LEDOFF); |
| bob_tpc | 5:e77529f7ede3 | 368 | wait(0.5); |
| bob_tpc | 5:e77529f7ede3 | 369 | led_com.write(LEDOFF); |
| bob_tpc | 22:5707b236cbdb | 370 | |
| bob_tpc | 10:55e35536d493 | 371 | return ERR_NONE; |
| bob_tpc | 0:8604e9cc07f2 | 372 | } |
| bob_tpc | 0:8604e9cc07f2 | 373 | |
| bob_tpc | 10:55e35536d493 | 374 | /** |
| bob_tpc | 15:713c26178a7d | 375 | * @name rfid_wr |
| bob_tpc | 22:5707b236cbdb | 376 | * @brief Forwards command to RFID reader |
| bob_tpc | 15:713c26178a7d | 377 | * |
| bob_tpc | 15:713c26178a7d | 378 | * RFID reader is connected to the KL25Z UART interface. The host PC will have a USB CDC class COM port device driver. |
| bob_tpc | 22:5707b236cbdb | 379 | * The host PC sends the RFID command over the COM port. Messages destined for the RFID reader (0xBB leading byte) are |
| bob_tpc | 15:713c26178a7d | 380 | * forwarded as-is to the RFID reader. The reader then responds in kind. All RFID commands are described in the |
| bob_tpc | 15:713c26178a7d | 381 | * RFID-FE module manual. |
| bob_tpc | 15:713c26178a7d | 382 | * |
| bob_tpc | 15:713c26178a7d | 383 | * @param [out] uart_buffer_tx - messages to the RFID reader |
| bob_tpc | 22:5707b236cbdb | 384 | * |
| bob_tpc | 15:713c26178a7d | 385 | * @retval ERR_NONE No error |
| bob_tpc | 15:713c26178a7d | 386 | * @retval ERR_UART_NOT_WRITEABLE UART has no buffer space |
| bob_tpc | 15:713c26178a7d | 387 | * @retval ERR_UART_NO_TX_ENDMARK message for UART has no 0x7E end-mark |
| bob_tpc | 15:713c26178a7d | 388 | * @example |
| bob_tpc | 22:5707b236cbdb | 389 | * BB 00 03 00 01 02 7E 2E C9 = read |
| bob_tpc | 15:713c26178a7d | 390 | */ |
| bob_tpc | 15:713c26178a7d | 391 | int rfid_wr(void) |
| bob_tpc | 15:713c26178a7d | 392 | { |
| bob_tpc | 15:713c26178a7d | 393 | int em_pos = 0; |
| bob_tpc | 22:5707b236cbdb | 394 | |
| bob_tpc | 22:5707b236cbdb | 395 | for (i = 0; i < sizeof(uart_buffer_tx); i++) { |
| bob_tpc | 15:713c26178a7d | 396 | if (uart_buffer_tx[i] == 0x7E) em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark |
| bob_tpc | 15:713c26178a7d | 397 | } |
| bob_tpc | 15:713c26178a7d | 398 | |
| bob_tpc | 22:5707b236cbdb | 399 | if (em_pos == 0) { |
| bob_tpc | 15:713c26178a7d | 400 | led_err.write(LEDON); // end mark never reached |
| bob_tpc | 15:713c26178a7d | 401 | return ERR_UART_NO_TX_ENDMARK; |
| bob_tpc | 15:713c26178a7d | 402 | } |
| bob_tpc | 15:713c26178a7d | 403 | |
| bob_tpc | 22:5707b236cbdb | 404 | if (!uart.writeable()) { |
| bob_tpc | 15:713c26178a7d | 405 | led_err.write(LEDON); |
| bob_tpc | 15:713c26178a7d | 406 | return ERR_UART_NOT_WRITEABLE; // if no space in uart, return error |
| bob_tpc | 15:713c26178a7d | 407 | } |
| bob_tpc | 15:713c26178a7d | 408 | |
| bob_tpc | 22:5707b236cbdb | 409 | for (i = 0; i < (em_pos + 2); i++) { |
| bob_tpc | 15:713c26178a7d | 410 | uart.putc(uart_buffer_tx[i]); // send uart message |
| bob_tpc | 15:713c26178a7d | 411 | } |
| bob_tpc | 22:5707b236cbdb | 412 | |
| bob_tpc | 15:713c26178a7d | 413 | return ERR_NONE; |
| bob_tpc | 22:5707b236cbdb | 414 | } |
| bob_tpc | 15:713c26178a7d | 415 | |
| bob_tpc | 15:713c26178a7d | 416 | /** |
| bob_tpc | 10:55e35536d493 | 417 | * @name prox_msg_wr |
| bob_tpc | 22:5707b236cbdb | 418 | * @brief Forwards command to VL6180X sensor |
| bob_tpc | 10:55e35536d493 | 419 | * |
| bob_tpc | 22:5707b236cbdb | 420 | * Proximity/ALS reader is connected to the KL25Z I2C interface. |
| bob_tpc | 22:5707b236cbdb | 421 | * The host PC sends the sensor command over the COM port. Messages destined for the proximity/ALS sensor (0xCC leading byte) are |
| bob_tpc | 22:5707b236cbdb | 422 | * forwarded to the proximity/ALS sensor after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes). |
| bob_tpc | 10:55e35536d493 | 423 | * The sensor then responds in kind. Firmware re-attaches the leading 0xCC and trailing bytes before sending the response over the |
| bob_tpc | 10:55e35536d493 | 424 | * CDC port to the host PC. |
| bob_tpc | 10:55e35536d493 | 425 | * |
| bob_tpc | 22:5707b236cbdb | 426 | * I2C-prox messages: |
| bob_tpc | 11:984631a6e373 | 427 | * - 0xCC (byte) leading value = 0xCC |
| bob_tpc | 11:984631a6e373 | 428 | * - r/w# (byte) 0 = write, 1 = read |
| bob_tpc | 11:984631a6e373 | 429 | * - number of data bytes(byte) 0 to 32 (size of declared buffers) |
| bob_tpc | 11:984631a6e373 | 430 | * - index (2 bytes) 12-bit VL6801X register offset, high byte first |
| bob_tpc | 11:984631a6e373 | 431 | * - data (n bytes) number of data bytes noted above |
| bob_tpc | 11:984631a6e373 | 432 | * - end_mark (byte) 0x7E |
| bob_tpc | 11:984631a6e373 | 433 | * - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes |
| bob_tpc | 10:55e35536d493 | 434 | * |
| bob_tpc | 10:55e35536d493 | 435 | * Multiple registers can be read or written with single prox_msg_rd() or prox_msg_wr(). Location address increments for each byte. |
| bob_tpc | 10:55e35536d493 | 436 | * VL6180X registers are defined in the sensor datasheet. |
| bob_tpc | 10:55e35536d493 | 437 | * |
| bob_tpc | 10:55e35536d493 | 438 | * @param [in] i2c_buffer - messages to and from the VL6180X and EEPROM |
| bob_tpc | 22:5707b236cbdb | 439 | * |
| bob_tpc | 10:55e35536d493 | 440 | * @retval 0 No error |
| bob_tpc | 10:55e35536d493 | 441 | * @retval 1 I2C bus has NAK'd / failure |
| bob_tpc | 10:55e35536d493 | 442 | * |
| bob_tpc | 10:55e35536d493 | 443 | * @param [in/out] i2c_buffer - messages to and from the i2c bus - see above |
| bob_tpc | 22:5707b236cbdb | 444 | * |
| bob_tpc | 4:13e3e375c0d3 | 445 | */ |
| bob_tpc | 15:713c26178a7d | 446 | int prox_msg_wr() // write proximity I2C register |
| bob_tpc | 0:8604e9cc07f2 | 447 | { |
| bob_tpc | 4:13e3e375c0d3 | 448 | int i2c_err; |
| bob_tpc | 4:13e3e375c0d3 | 449 | i2c_err = i2c.write(PROX, &i2c_buffer[3], i2c_buffer[2] + 2, 0);// I2C Address, pointer to buffer, number of bytes (for index + data), stop at end. |
| bob_tpc | 15:713c26178a7d | 450 | return i2c_err; // 0 = ACK received, 1 = NAK/failure |
| bob_tpc | 4:13e3e375c0d3 | 451 | } |
| bob_tpc | 22:5707b236cbdb | 452 | |
| bob_tpc | 10:55e35536d493 | 453 | /** |
| bob_tpc | 10:55e35536d493 | 454 | * @name prox_msg_rd |
| bob_tpc | 10:55e35536d493 | 455 | * @brief retrieves response from VL6180X sensor |
| bob_tpc | 10:55e35536d493 | 456 | * |
| bob_tpc | 22:5707b236cbdb | 457 | * Proximity/ALS reader is connected to the KL25Z I2C interface. |
| bob_tpc | 22:5707b236cbdb | 458 | * The host PC sends the sensor command over the COM port. Messages destined for the proximity/ALS sensor (0xCC leading byte) are |
| bob_tpc | 22:5707b236cbdb | 459 | * forwarded to the proximity/ALS sensor after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes). |
| bob_tpc | 10:55e35536d493 | 460 | * The sensor then responds in kind. Firmware re-attaches the leading 0xCC and trailing bytes before sending the response over the |
| bob_tpc | 10:55e35536d493 | 461 | * CDC port to the host PC. |
| bob_tpc | 10:55e35536d493 | 462 | * |
| bob_tpc | 22:5707b236cbdb | 463 | * I2C-prox messages: |
| bob_tpc | 11:984631a6e373 | 464 | * - 0xCC (byte) leading value = 0xCC |
| bob_tpc | 11:984631a6e373 | 465 | * - r/w# (byte) 0 = write, 1 = read |
| bob_tpc | 11:984631a6e373 | 466 | * - number of data bytes(byte) 0 to 32 (size of declared buffers) |
| bob_tpc | 11:984631a6e373 | 467 | * - index (2 bytes) 12-bit VL6801X register offset, high byte first |
| bob_tpc | 11:984631a6e373 | 468 | * - data (n bytes) number of data bytes noted above |
| bob_tpc | 11:984631a6e373 | 469 | * - end_mark (byte) 0x7E |
| bob_tpc | 11:984631a6e373 | 470 | * - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes |
| bob_tpc | 10:55e35536d493 | 471 | * |
| bob_tpc | 10:55e35536d493 | 472 | * Multiple registers can be read or written with single prox_msg_rd() or prox_msg_wr(). Location address increments for each byte. |
| bob_tpc | 10:55e35536d493 | 473 | * VL6180X registers are defined in the sensor datasheet. |
| bob_tpc | 10:55e35536d493 | 474 | * |
| bob_tpc | 10:55e35536d493 | 475 | * @param [in/out] i2c_buffer - messages to and from the i2c bus - see above |
| bob_tpc | 10:55e35536d493 | 476 | * |
| bob_tpc | 10:55e35536d493 | 477 | * @retval 0 No error |
| bob_tpc | 10:55e35536d493 | 478 | * @retval 1 I2C bus has NAK'd / failure |
| bob_tpc | 10:55e35536d493 | 479 | * |
| bob_tpc | 22:5707b236cbdb | 480 | * |
| bob_tpc | 10:55e35536d493 | 481 | */ |
| bob_tpc | 4:13e3e375c0d3 | 482 | int prox_msg_rd() |
| bob_tpc | 4:13e3e375c0d3 | 483 | { |
| bob_tpc | 4:13e3e375c0d3 | 484 | int i2c_err; |
| bob_tpc | 15:713c26178a7d | 485 | i2c_err = i2c.write(PROX, &i2c_buffer[3], 2, 1); // I2C Address, pointer to buffer (just the index), index, number of bytes (2 for index), no stop at end. |
| bob_tpc | 15:713c26178a7d | 486 | i2c_err |= i2c.read(PROX, &i2c_buffer[5], i2c_buffer[2], 0); // I2C Address, pointer to buffer (just the data), number of data bytes, stop at end. |
| bob_tpc | 15:713c26178a7d | 487 | return i2c_err; // 0 = ACK received, 1 = NAK/failure |
| bob_tpc | 4:13e3e375c0d3 | 488 | } |
| bob_tpc | 4:13e3e375c0d3 | 489 | |
| bob_tpc | 10:55e35536d493 | 490 | /** |
| bob_tpc | 10:55e35536d493 | 491 | * @name gpio_rd |
| bob_tpc | 10:55e35536d493 | 492 | * @brief retrieves instantaneous value of GPIO pins |
| bob_tpc | 10:55e35536d493 | 493 | * |
| bob_tpc | 22:5707b236cbdb | 494 | * GPIO signals are defined directly off of the KL25Z. |
| bob_tpc | 10:55e35536d493 | 495 | * The host PC sends the GPIO command over the COM port. With a 0xDD leading byte in the message, the state of the GPIO signals are read and returned. |
| bob_tpc | 10:55e35536d493 | 496 | * This allows a read-modify-write GPIO sequence. |
| bob_tpc | 10:55e35536d493 | 497 | * |
| bob_tpc | 22:5707b236cbdb | 498 | * GPIO messages: |
| bob_tpc | 11:984631a6e373 | 499 | * - 0xDD (byte) leading value = 0xDD |
| bob_tpc | 11:984631a6e373 | 500 | * - r/w# (byte) 0 = write, 1 = read |
| bob_tpc | 19:d3bef4fbab69 | 501 | * - data (2 bytes) see below |
| bob_tpc | 11:984631a6e373 | 502 | * - end_mark (byte) 0x7E |
| bob_tpc | 11:984631a6e373 | 503 | * - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes |
| bob_tpc | 10:55e35536d493 | 504 | * |
| bob_tpc | 19:d3bef4fbab69 | 505 | * GPIO data bits - First Byte |
| bob_tpc | 22:5707b236cbdb | 506 | * - 0 LED - Error 0 = on, 1 = off |
| bob_tpc | 13:a390c4798a0d | 507 | * - 1 LED - Comm state 0 = on, 1 = off |
| bob_tpc | 13:a390c4798a0d | 508 | * - 2 RFID interrupt input 0 = off, 1 = on (inverted in h/w) |
| bob_tpc | 13:a390c4798a0d | 509 | * - 3 RFID in-system-prog 0 = off, 1 = on (inverted in h/w) |
| bob_tpc | 13:a390c4798a0d | 510 | * - 4 RFID reset 0 = off, 1 = on (inverted in h/w) |
| bob_tpc | 13:a390c4798a0d | 511 | * - 5 RFID power enable for first prototype, 0 = off, 1 = on / for production, 0 = on, 1 = off |
| bob_tpc | 13:a390c4798a0d | 512 | * - 6 RFID over-current 0 = overcurrent detected, 1 = OK |
| bob_tpc | 13:a390c4798a0d | 513 | * - 7 Proximity interrupt 0 = interrupt, 1 = idle (This pin may not return anything meaningful here. The interrupt is edge triggered). |
| bob_tpc | 10:55e35536d493 | 514 | * |
| bob_tpc | 19:d3bef4fbab69 | 515 | * GPIO data bits - Second Byte |
| bob_tpc | 19:d3bef4fbab69 | 516 | * - 0 GPIO on pin 6 of LED connector - I/O |
| bob_tpc | 19:d3bef4fbab69 | 517 | * - 1 GPIO on pin 7 of LED connector - I/O |
| bob_tpc | 19:d3bef4fbab69 | 518 | * - 2-6 - unused bits, output don't care, input read as zero |
| bob_tpc | 19:d3bef4fbab69 | 519 | * - 7 GPIO on pin 3 of LED connector - OUTPUT only, inverted logic, open drain with 1K pull-up, read as zero |
| bob_tpc | 19:d3bef4fbab69 | 520 | * |
| bob_tpc | 10:55e35536d493 | 521 | * @param [in/out] gpio_buffer - GPIO states |
| bob_tpc | 10:55e35536d493 | 522 | * |
| bob_tpc | 10:55e35536d493 | 523 | * @retval 0 No error |
| bob_tpc | 22:5707b236cbdb | 524 | * |
| bob_tpc | 10:55e35536d493 | 525 | */ |
| bob_tpc | 9:046247707ffb | 526 | |
| bob_tpc | 5:e77529f7ede3 | 527 | int gpio_rd() |
| bob_tpc | 5:e77529f7ede3 | 528 | { |
| bob_tpc | 22:5707b236cbdb | 529 | gpio_buffer[2] = ( led_err.read() & 0x01); // read first byte of the GPIO pins |
| bob_tpc | 22:5707b236cbdb | 530 | gpio_buffer[2] |= ((led_com_state << 1) & 0x02); // use of led_com_state allows the LED to remain ON in the main loop if desired |
| bob_tpc | 9:046247707ffb | 531 | gpio_buffer[2] |= ((rfid_int.read() << 2) & 0x04); |
| bob_tpc | 9:046247707ffb | 532 | gpio_buffer[2] |= ((rfid_isp.read() << 3) & 0x08); |
| bob_tpc | 9:046247707ffb | 533 | gpio_buffer[2] |= ((rfid_rst.read() << 4) & 0x10); |
| bob_tpc | 9:046247707ffb | 534 | gpio_buffer[2] |= ((rfid_pwr.read() << 5) & 0x20); |
| bob_tpc | 10:55e35536d493 | 535 | gpio_buffer[2] |= ((rfid_hot.read() << 6) & 0x40); |
| bob_tpc | 10:55e35536d493 | 536 | gpio_buffer[2] |= ((prox_int.read() << 7) & 0x80); |
| bob_tpc | 19:d3bef4fbab69 | 537 | |
| bob_tpc | 22:5707b236cbdb | 538 | gpio_buffer[3] = ( gpio_0.read() & 0x01); // read second byte of the GPIO pins |
| bob_tpc | 22:5707b236cbdb | 539 | gpio_buffer[3] |= (( gpio_1.read() << 1) & 0x02); |
| bob_tpc | 22:5707b236cbdb | 540 | gpio_buffer[3] |= (( 0 << 2) & 0x04); // bits 2-7 always return zero |
| bob_tpc | 19:d3bef4fbab69 | 541 | gpio_buffer[3] |= (( 0 << 3) & 0x08); |
| bob_tpc | 19:d3bef4fbab69 | 542 | gpio_buffer[3] |= (( 0 << 4) & 0x10); |
| bob_tpc | 19:d3bef4fbab69 | 543 | gpio_buffer[3] |= (( 0 << 5) & 0x20); |
| bob_tpc | 19:d3bef4fbab69 | 544 | gpio_buffer[3] |= (( 0 << 6) & 0x40); |
| bob_tpc | 22:5707b236cbdb | 545 | gpio_buffer[3] |= (( 0 << 7) & 0x80); |
| bob_tpc | 5:e77529f7ede3 | 546 | return ERR_NONE; |
| bob_tpc | 5:e77529f7ede3 | 547 | } |
| bob_tpc | 4:13e3e375c0d3 | 548 | |
| bob_tpc | 10:55e35536d493 | 549 | |
| bob_tpc | 10:55e35536d493 | 550 | /** |
| bob_tpc | 10:55e35536d493 | 551 | * @name gpio_wr |
| bob_tpc | 10:55e35536d493 | 552 | * @brief sets value of GPIO pins |
| bob_tpc | 10:55e35536d493 | 553 | * |
| bob_tpc | 22:5707b236cbdb | 554 | * GPIO signals are defined directly off of the KL25Z. |
| bob_tpc | 10:55e35536d493 | 555 | * The host PC sends the GPIO command over the COM port. With a 0xDD leading byte in the message, the state of the GPIO signals are read and returned. |
| bob_tpc | 10:55e35536d493 | 556 | * This allows a read-modify-write GPIO sequence. |
| bob_tpc | 10:55e35536d493 | 557 | * |
| bob_tpc | 22:5707b236cbdb | 558 | * GPIO messages: |
| bob_tpc | 11:984631a6e373 | 559 | * - 0xDD (byte) leading value = 0xDD |
| bob_tpc | 11:984631a6e373 | 560 | * - r/w# (byte) 0 = write, 1 = read |
| bob_tpc | 22:5707b236cbdb | 561 | * - data (2 bytes) see below |
| bob_tpc | 11:984631a6e373 | 562 | * - end_mark (byte) 0x7E |
| bob_tpc | 11:984631a6e373 | 563 | * - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes |
| bob_tpc | 10:55e35536d493 | 564 | * |
| bob_tpc | 22:5707b236cbdb | 565 | * GPIO data bits - First Byte: |
| bob_tpc | 22:5707b236cbdb | 566 | * - 0 LED - Error 0 = on, 1 = off |
| bob_tpc | 13:a390c4798a0d | 567 | * - 1 LED - Comm state 0 = on, 1 = off |
| bob_tpc | 13:a390c4798a0d | 568 | * - 2 RFID interrupt input 0 = off, 1 = on (inverted in h/w) |
| bob_tpc | 13:a390c4798a0d | 569 | * - 3 RFID in-system-prog 0 = off, 1 = on (inverted in h/w) |
| bob_tpc | 13:a390c4798a0d | 570 | * - 4 RFID reset 0 = off, 1 = on (inverted in h/w) |
| bob_tpc | 13:a390c4798a0d | 571 | * - 5 RFID power enable for first prototype, 0 = off, 1 = on / for production, 0 = on, 1 = off |
| bob_tpc | 13:a390c4798a0d | 572 | * - 6 RFID over-current 0 = overcurrent detected, 1 = OK |
| bob_tpc | 13:a390c4798a0d | 573 | * - 7 Proximity interrupt 0 = interrupt, 1 = idle (This pin may not return anything meaningful here. The interrupt is edge triggered). |
| bob_tpc | 10:55e35536d493 | 574 | * |
| bob_tpc | 19:d3bef4fbab69 | 575 | * GPIO data bits - Second Byte |
| bob_tpc | 19:d3bef4fbab69 | 576 | * - 0 GPIO on pin 6 of LED connector - I/O |
| bob_tpc | 19:d3bef4fbab69 | 577 | * - 1 GPIO on pin 7 of LED connector - I/O |
| bob_tpc | 19:d3bef4fbab69 | 578 | * - 2-6 - unused bits, output don't care, input read as zero |
| bob_tpc | 19:d3bef4fbab69 | 579 | * - 7 GPIO on pin 3 of LED connector - OUTPUT only, inverted logic, open drain with 1K pull-up, read as zero |
| bob_tpc | 19:d3bef4fbab69 | 580 | * |
| bob_tpc | 10:55e35536d493 | 581 | * @param [in/out] gpio_buffer - GPIO states |
| bob_tpc | 10:55e35536d493 | 582 | * |
| bob_tpc | 10:55e35536d493 | 583 | * @retval 0 No error |
| bob_tpc | 22:5707b236cbdb | 584 | * |
| bob_tpc | 10:55e35536d493 | 585 | */ |
| bob_tpc | 5:e77529f7ede3 | 586 | int gpio_wr() |
| bob_tpc | 5:e77529f7ede3 | 587 | { |
| bob_tpc | 22:5707b236cbdb | 588 | if ((gpio_buffer[2] & 0x02) == 0x00) { // Set the desired state of the yellow LED |
| bob_tpc | 9:046247707ffb | 589 | led_com_state = LEDON; |
| bob_tpc | 22:5707b236cbdb | 590 | } else { |
| bob_tpc | 9:046247707ffb | 591 | led_com_state = LEDOFF; |
| bob_tpc | 9:046247707ffb | 592 | } |
| bob_tpc | 22:5707b236cbdb | 593 | led_err.write(gpio_buffer[2] & 0x01); // Write GPIO bits - first byte |
| bob_tpc | 22:5707b236cbdb | 594 | led_com.write(led_com_state); // use of led_com_state allows the LED to remain ON in the main loop if desired |
| bob_tpc | 22:5707b236cbdb | 595 | rfid_int.write(gpio_buffer[2] & 0x04); |
| bob_tpc | 22:5707b236cbdb | 596 | rfid_isp.write(gpio_buffer[2] & 0x08); |
| bob_tpc | 22:5707b236cbdb | 597 | rfid_rst.write(gpio_buffer[2] & 0x10); |
| bob_tpc | 22:5707b236cbdb | 598 | rfid_pwr.write(gpio_buffer[2] & 0x20); |
| bob_tpc | 19:d3bef4fbab69 | 599 | |
| bob_tpc | 22:5707b236cbdb | 600 | gpio_0.write(gpio_buffer[3] & 0x01); // Write GPIO bits - second byte |
| bob_tpc | 22:5707b236cbdb | 601 | gpio_1.write(gpio_buffer[3] & 0x02); // Write GPIO bits - second byte |
| bob_tpc | 22:5707b236cbdb | 602 | gpio_7.write(gpio_buffer[3] & 0x80); // Write GPIO bits - second byte |
| bob_tpc | 19:d3bef4fbab69 | 603 | |
| bob_tpc | 5:e77529f7ede3 | 604 | return ERR_NONE; |
| bob_tpc | 5:e77529f7ede3 | 605 | } |
| bob_tpc | 22:5707b236cbdb | 606 | |
| bob_tpc | 22:5707b236cbdb | 607 | |
| bob_tpc | 10:55e35536d493 | 608 | /** |
| bob_tpc | 10:55e35536d493 | 609 | * @name eeprom_msg_wr |
| bob_tpc | 10:55e35536d493 | 610 | * @brief writes data to the I2C EEPROM |
| bob_tpc | 10:55e35536d493 | 611 | * |
| bob_tpc | 22:5707b236cbdb | 612 | * The EEPROM is connected to the KL25Z I2C interface. |
| bob_tpc | 22:5707b236cbdb | 613 | * The host PC sends the sensor command over the COM port. Messages destined for the EERPOM (0xEE leading byte) are |
| bob_tpc | 22:5707b236cbdb | 614 | * forwarded to the EEPROM after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes). |
| bob_tpc | 22:5707b236cbdb | 615 | * Firmware re-attaches the leading 0xEE and trailing bytes before sending the response over the |
| bob_tpc | 10:55e35536d493 | 616 | * CDC port to the host PC. |
| bob_tpc | 10:55e35536d493 | 617 | * |
| bob_tpc | 22:5707b236cbdb | 618 | * I2C-EEPROM messages: |
| bob_tpc | 11:984631a6e373 | 619 | * - 0xEE (byte) leading value = 0xEE |
| bob_tpc | 11:984631a6e373 | 620 | * - r/w# (byte) 0 = write, 1 = read |
| bob_tpc | 22:5707b236cbdb | 621 | * - number of data bytes(byte) 0 to 16 bytes for write |
| bob_tpc | 11:984631a6e373 | 622 | * - block (byte) lower 3 bits are logically OR'd with the I2C address |
| bob_tpc | 11:984631a6e373 | 623 | * - address (byte) memory location within block |
| bob_tpc | 11:984631a6e373 | 624 | * - data (n bytes) number of data bytes noted above |
| bob_tpc | 11:984631a6e373 | 625 | * - end_mark (byte) 0x7E |
| bob_tpc | 11:984631a6e373 | 626 | * - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes |
| bob_tpc | 10:55e35536d493 | 627 | * |
| bob_tpc | 10:55e35536d493 | 628 | * Multiple memory locations can be read or written with single eeprom_msg_rd() or eeprom_msg_wr(). Location address increments for each byte. |
| bob_tpc | 10:55e35536d493 | 629 | * Read/Write sequences are defined in the 24LC16B datasheet. |
| bob_tpc | 10:55e35536d493 | 630 | * |
| bob_tpc | 10:55e35536d493 | 631 | * This practically the the same as the proximity calls, except the index/location is only one byte and the block select is part of the I2C address byte. |
| bob_tpc | 10:55e35536d493 | 632 | * |
| bob_tpc | 10:55e35536d493 | 633 | * @param [in] i2c_buffer - messages to and from the VL6180X and EEPROM |
| bob_tpc | 22:5707b236cbdb | 634 | * |
| bob_tpc | 10:55e35536d493 | 635 | * @retval 0 No error |
| bob_tpc | 10:55e35536d493 | 636 | * @retval 1 I2C bus has NAK'd / failure |
| bob_tpc | 22:5707b236cbdb | 637 | * @retval ERR_I2C_WRITE_TOO_LARGE buffer size too large |
| bob_tpc | 10:55e35536d493 | 638 | * |
| bob_tpc | 10:55e35536d493 | 639 | * @param [in/out] i2c_buffer - messages to and from the i2c bus - see above |
| bob_tpc | 22:5707b236cbdb | 640 | * |
| bob_tpc | 4:13e3e375c0d3 | 641 | */ |
| bob_tpc | 4:13e3e375c0d3 | 642 | |
| bob_tpc | 15:713c26178a7d | 643 | int eeprom_msg_wr() // write proximity I2C register |
| bob_tpc | 4:13e3e375c0d3 | 644 | { |
| bob_tpc | 22:5707b236cbdb | 645 | int i2c_err = ERR_NONE; |
| bob_tpc | 22:5707b236cbdb | 646 | char wr[2] = {0xFF, 0xFF}; |
| bob_tpc | 22:5707b236cbdb | 647 | |
| bob_tpc | 22:5707b236cbdb | 648 | for (i = 0; i < i2c_buffer[2]; i++){ // done with single-byte writes to avoid addressing wrap-around |
| bob_tpc | 22:5707b236cbdb | 649 | wr[0] = i2c_buffer[4]+i; |
| bob_tpc | 22:5707b236cbdb | 650 | wr[1] = i2c_buffer[5+i]; |
| bob_tpc | 22:5707b236cbdb | 651 | i2c_err |= i2c.write((EEPROM | (i2c_buffer[3] << 1 )), wr, 2, 0); |
| bob_tpc | 22:5707b236cbdb | 652 | while ( i2c.write(EEPROM | (i2c_buffer[3] << 1 ))); // wait until write is done (EEPROM will ACK = 0 for single byte i2c.write) |
| bob_tpc | 22:5707b236cbdb | 653 | // I2C Address & block select, pointer to buffer, 2 bytes (address + one data), stop at end. |
| bob_tpc | 22:5707b236cbdb | 654 | } |
| bob_tpc | 15:713c26178a7d | 655 | return i2c_err; // 0 = ACK received, 1 = NAK/failure |
| bob_tpc | 4:13e3e375c0d3 | 656 | } |
| bob_tpc | 22:5707b236cbdb | 657 | |
| bob_tpc | 10:55e35536d493 | 658 | /** |
| bob_tpc | 10:55e35536d493 | 659 | * @name eeprom_msg_rd |
| bob_tpc | 10:55e35536d493 | 660 | * @brief read data from the I2C EEPROM |
| bob_tpc | 22:5707b236cbdb | 661 | * @note EEPROM only availalbe on REV B and later |
| bob_tpc | 10:55e35536d493 | 662 | * |
| bob_tpc | 22:5707b236cbdb | 663 | * The EEPROM is connected to the KL25Z I2C interface. |
| bob_tpc | 22:5707b236cbdb | 664 | * The host PC sends the sensor command over the COM port. Messages destined for the EERPOM (0xEE leading byte) are |
| bob_tpc | 22:5707b236cbdb | 665 | * forwarded to the EEPROM after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes). |
| bob_tpc | 22:5707b236cbdb | 666 | * Firmware re-attaches the leading 0xEE and trailing bytes before sending the response over the |
| bob_tpc | 10:55e35536d493 | 667 | * CDC port to the host PC. |
| bob_tpc | 10:55e35536d493 | 668 | * |
| bob_tpc | 22:5707b236cbdb | 669 | * I2C-EEPROM messages: |
| bob_tpc | 11:984631a6e373 | 670 | * - 0xEE (byte) leading value = 0xEE |
| bob_tpc | 11:984631a6e373 | 671 | * - r/w# (byte) 0 = write, 1 = read |
| bob_tpc | 22:5707b236cbdb | 672 | * - number of data bytes(byte) 0 to 128 bytes for read (size of declared buffer) |
| bob_tpc | 11:984631a6e373 | 673 | * - block (byte) lower 3 bits are logically OR'd with the I2C address |
| bob_tpc | 11:984631a6e373 | 674 | * - address (byte) memory location within block |
| bob_tpc | 11:984631a6e373 | 675 | * - data (n bytes) number of data bytes noted above |
| bob_tpc | 11:984631a6e373 | 676 | * - end_mark (byte) 0x7E |
| bob_tpc | 11:984631a6e373 | 677 | * - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes |
| bob_tpc | 10:55e35536d493 | 678 | * |
| bob_tpc | 10:55e35536d493 | 679 | * Multiple memory locations can be read or written with single eeprom_msg_rd() or eeprom_msg_wr(). Location address increments for each byte. |
| bob_tpc | 10:55e35536d493 | 680 | * Read/Write sequences are defined in the 24LC16B datasheet. |
| bob_tpc | 10:55e35536d493 | 681 | * |
| bob_tpc | 10:55e35536d493 | 682 | * This practically the the same as the proximity calls, except the index/location is only one byte and the block select is part of the I2C address byte. |
| bob_tpc | 10:55e35536d493 | 683 | * |
| bob_tpc | 10:55e35536d493 | 684 | * @param [in/out] i2c_buffer - messages to and from the VL6180X and EEPROM |
| bob_tpc | 22:5707b236cbdb | 685 | * |
| bob_tpc | 10:55e35536d493 | 686 | * @retval [none]0 No error |
| bob_tpc | 10:55e35536d493 | 687 | * @retval 1 I2C bus has NAK'd / failure |
| bob_tpc | 10:55e35536d493 | 688 | * |
| bob_tpc | 10:55e35536d493 | 689 | * @param [in/out] i2c_buffer - messages to and from the i2c bus - see above |
| bob_tpc | 22:5707b236cbdb | 690 | * |
| bob_tpc | 10:55e35536d493 | 691 | */ |
| bob_tpc | 22:5707b236cbdb | 692 | int eeprom_msg_rd() |
| bob_tpc | 4:13e3e375c0d3 | 693 | { |
| bob_tpc | 4:13e3e375c0d3 | 694 | int i2c_err; |
| bob_tpc | 22:5707b236cbdb | 695 | i2c_err = i2c.write((EEPROM | (i2c_buffer[3] << 1)), &i2c_buffer[4], 1, 1); |
| bob_tpc | 22:5707b236cbdb | 696 | // I2C Address & block select, pointer to buffer (just the index), index, number of bytes (for address + data), no stop at end. |
| bob_tpc | 22:5707b236cbdb | 697 | i2c_err |= i2c.read((EEPROM | (i2c_buffer[3] << 1)), &i2c_buffer[5], i2c_buffer[2], 0); |
| bob_tpc | 22:5707b236cbdb | 698 | // I2C Address & block select, pointer to buffer (just the data), number of data bytes, stop at end. |
| bob_tpc | 15:713c26178a7d | 699 | return i2c_err; // 0 = ACK received, 1 = NAK/failure |
| bob_tpc | 0:8604e9cc07f2 | 700 | } |
| bob_tpc | 0:8604e9cc07f2 | 701 | |
| bob_tpc | 10:55e35536d493 | 702 | /** |
| bob_tpc | 10:55e35536d493 | 703 | * @name main |
| bob_tpc | 22:5707b236cbdb | 704 | * @brief Main firmware loop |
| bob_tpc | 10:55e35536d493 | 705 | * |
| bob_tpc | 10:55e35536d493 | 706 | * @returns [none] |
| bob_tpc | 10:55e35536d493 | 707 | */ |
| bob_tpc | 22:5707b236cbdb | 708 | int main(void) |
| bob_tpc | 0:8604e9cc07f2 | 709 | { |
| bob_tpc | 15:713c26178a7d | 710 | int em_pos = 0; // end of message count - allows multiple 0x7e in message. |
| bob_tpc | 22:5707b236cbdb | 711 | char msgcount; |
| bob_tpc | 22:5707b236cbdb | 712 | char temploc; |
| bob_tpc | 22:5707b236cbdb | 713 | char autorange[] = {0x00, 0x18, 0x00}; // Proximity sensor automatic measurement. Set last byte = 0x03 to start |
| bob_tpc | 22:5707b236cbdb | 714 | char proxintclr[] = {0x00, 0x15, 0x07}; // Clear proximity interrupt |
| bob_tpc | 9:046247707ffb | 715 | |
| bob_tpc | 22:5707b236cbdb | 716 | char i2c_addr = (EEPROM | (2 << 1)); // EEPROM base address is 0xA0 (already shifted). Bank 2 in use here, shifted for I2C addressing. |
| bob_tpc | 15:713c26178a7d | 717 | |
| bob_tpc | 15:713c26178a7d | 718 | init_periph(); // initialize everything |
| bob_tpc | 22:5707b236cbdb | 719 | |
| bob_tpc | 22:5707b236cbdb | 720 | while(1) { // main loop |
| bob_tpc | 15:713c26178a7d | 721 | led_com.write(led_com_state); // turn off communication LED unless it was specifically turned on by GPIO command |
| bob_tpc | 22:5707b236cbdb | 722 | if (prox_irq_state == 1) { // process the proximity interrupt |
| bob_tpc | 22:5707b236cbdb | 723 | if (prox_irq_msg[0] != 0xBB){ // no message to send to RFID |
| bob_tpc | 22:5707b236cbdb | 724 | cdc_buffer_tx[0] = 0xFF; // just send a dummy message back to the host |
| bob_tpc | 22:5707b236cbdb | 725 | cdc_buffer_tx[1] = 0x7E; |
| bob_tpc | 22:5707b236cbdb | 726 | cdc_buffer_tx[2] = 0x0F; |
| bob_tpc | 22:5707b236cbdb | 727 | cdc_buffer_tx[3] = 0xF0; |
| bob_tpc | 22:5707b236cbdb | 728 | cdc.writeBlock(cdc_buffer_tx, 4); |
| bob_tpc | 22:5707b236cbdb | 729 | led_err.write(LEDON); // we shouldn't get here |
| bob_tpc | 22:5707b236cbdb | 730 | } |
| bob_tpc | 22:5707b236cbdb | 731 | else{ |
| bob_tpc | 22:5707b236cbdb | 732 | msgcount = prox_irq_msg[2] + 6; // See RFID-FE manual for message construction |
| bob_tpc | 22:5707b236cbdb | 733 | for (i = 0; i < msgcount; i++) { |
| bob_tpc | 22:5707b236cbdb | 734 | uart.putc(prox_irq_msg[i]); // send message to RFID-FE module for a single read |
| bob_tpc | 22:5707b236cbdb | 735 | } |
| bob_tpc | 22:5707b236cbdb | 736 | } |
| bob_tpc | 22:5707b236cbdb | 737 | prox_irq_state = 0; // reset proximity interrupt state |
| bob_tpc | 22:5707b236cbdb | 738 | wait(0.5); // wait 1/2 sec so the COM LED can be seen |
| bob_tpc | 22:5707b236cbdb | 739 | led_com.write(led_com_state); // turn off COM LED if not on by GPIO (it was turned on in the ISR) |
| bob_tpc | 22:5707b236cbdb | 740 | i2c.write(PROX, proxintclr, 3, 0); // i2c prox sensor, interrupt clear message, 3 bytes, stop at end |
| bob_tpc | 22:5707b236cbdb | 741 | |
| bob_tpc | 15:713c26178a7d | 742 | } |
| bob_tpc | 22:5707b236cbdb | 743 | if (uart.readable()) { // message availalbe from rfid (all responses (0x01) and broadcast (0x02)) |
| bob_tpc | 19:d3bef4fbab69 | 744 | int rfid_len = 0; |
| bob_tpc | 19:d3bef4fbab69 | 745 | led_com.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 746 | for (i = 0; i < (RFIDLENLOW); i++) { // Get first part of message to find out total count |
| bob_tpc | 22:5707b236cbdb | 747 | uart_buffer_rx[i] = uart.getc(); // get a byte from rfid |
| bob_tpc | 19:d3bef4fbab69 | 748 | } |
| bob_tpc | 19:d3bef4fbab69 | 749 | rfid_len = ((uart_buffer_rx[i-2]<<8) + (uart_buffer_rx[i-1])); // location of message length for RFID |
| bob_tpc | 22:5707b236cbdb | 750 | for (i = RFIDLENLOW; i < (RFIDLENLOW + rfid_len + 3); i++) { // get the reset of the message |
| bob_tpc | 22:5707b236cbdb | 751 | uart_buffer_rx[i] = uart.getc(); // get a byte from rfid |
| bob_tpc | 9:046247707ffb | 752 | } |
| bob_tpc | 22:5707b236cbdb | 753 | for (i = 0; i < (RFIDLENLOW + rfid_len + 3); i++) { // copy the message to the USB buffer |
| bob_tpc | 19:d3bef4fbab69 | 754 | cdc_buffer_tx[i] = uart_buffer_rx[i]; |
| bob_tpc | 5:e77529f7ede3 | 755 | } |
| bob_tpc | 22:5707b236cbdb | 756 | cdc.writeBlock(cdc_buffer_tx, (RFIDLENLOW + rfid_len + 3)); // send the RFID message to the PC |
| bob_tpc | 22:5707b236cbdb | 757 | led_com.write(led_com_state); |
| bob_tpc | 22:5707b236cbdb | 758 | } |
| bob_tpc | 22:5707b236cbdb | 759 | if (usb_irq_state == 1) { // message available from PC |
| bob_tpc | 22:5707b236cbdb | 760 | usb_irq_state = 0; // allow another USB interrupt |
| bob_tpc | 15:713c26178a7d | 761 | |
| bob_tpc | 22:5707b236cbdb | 762 | for (i = 0; i < sizeof(cdc_buffer_rx); i++) { |
| bob_tpc | 15:713c26178a7d | 763 | if (cdc.readable()) cdc_buffer_rx[i] = cdc._getc(); // read data from USB side |
| bob_tpc | 15:713c26178a7d | 764 | } |
| bob_tpc | 22:5707b236cbdb | 765 | if ((cdc_buffer_rx[0] == 'A') && (cdc_buffer_rx[1] == 'T')) { // check for Hayes command and ignore it |
| bob_tpc | 22:5707b236cbdb | 766 | break; // Linux systems will enumerate as ttyACMx |
| bob_tpc | 22:5707b236cbdb | 767 | } // and attempt to initialize the non-existent modem |
| bob_tpc | 22:5707b236cbdb | 768 | for (i = 0; i < sizeof(cdc_buffer_rx); i++) { |
| bob_tpc | 22:5707b236cbdb | 769 | if (cdc_buffer_rx[i] == 0x7E) { // check for rfid end mark in outbound message |
| bob_tpc | 15:713c26178a7d | 770 | em_pos = (i + 1); |
| bob_tpc | 5:e77529f7ede3 | 771 | } |
| bob_tpc | 15:713c26178a7d | 772 | } |
| bob_tpc | 22:5707b236cbdb | 773 | led_com.write(LEDON); // Message received - turn on LED |
| bob_tpc | 22:5707b236cbdb | 774 | if (em_pos == 0) { // end mark never reached |
| bob_tpc | 15:713c26178a7d | 775 | led_err.write(LEDON); |
| bob_tpc | 15:713c26178a7d | 776 | break; |
| bob_tpc | 15:713c26178a7d | 777 | } |
| bob_tpc | 22:5707b236cbdb | 778 | |
| bob_tpc | 22:5707b236cbdb | 779 | switch(cdc_buffer_rx[0]) { // check first byte for "destination" |
| bob_tpc | 15:713c26178a7d | 780 | case 0xBB: // RFID-FE |
| bob_tpc | 22:5707b236cbdb | 781 | for (i = 0; i < sizeof(cdc_buffer_rx); i++) { |
| bob_tpc | 15:713c26178a7d | 782 | uart_buffer_tx[i] = cdc_buffer_rx[i]; // copy USB message to UART for RFID |
| bob_tpc | 15:713c26178a7d | 783 | } |
| bob_tpc | 22:5707b236cbdb | 784 | |
| bob_tpc | 15:713c26178a7d | 785 | status = rfid_wr(); // send buffer to RFID and get response according to RFID board |
| bob_tpc | 15:713c26178a7d | 786 | break; |
| bob_tpc | 22:5707b236cbdb | 787 | |
| bob_tpc | 15:713c26178a7d | 788 | case 0xCC: // Proximity Sensor |
| bob_tpc | 15:713c26178a7d | 789 | led_com.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 790 | for (i = 0; i < sizeof(cdc_buffer_rx); i++) { |
| bob_tpc | 15:713c26178a7d | 791 | i2c_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for I2C |
| bob_tpc | 5:e77529f7ede3 | 792 | } |
| bob_tpc | 15:713c26178a7d | 793 | |
| bob_tpc | 15:713c26178a7d | 794 | if (i2c_buffer[1] == 1) // I2C read = 1 |
| bob_tpc | 15:713c26178a7d | 795 | status = prox_msg_rd(); // read the requested data |
| bob_tpc | 15:713c26178a7d | 796 | else if (i2c_buffer[1] == 0) // I2C write = 0 |
| bob_tpc | 15:713c26178a7d | 797 | status = prox_msg_wr(); // send buffer to proximity sensor and get response |
| bob_tpc | 15:713c26178a7d | 798 | |
| bob_tpc | 22:5707b236cbdb | 799 | if (status) led_err.write(LEDON); // we shouldn't get here |
| bob_tpc | 22:5707b236cbdb | 800 | |
| bob_tpc | 15:713c26178a7d | 801 | em_pos = 0; |
| bob_tpc | 22:5707b236cbdb | 802 | for (i = 0; i < sizeof(cdc_buffer_tx); i++) { |
| bob_tpc | 15:713c26178a7d | 803 | cdc_buffer_tx[i] = i2c_buffer[i]; // copy RFID response back to USB buffer |
| bob_tpc | 22:5707b236cbdb | 804 | if (cdc_buffer_tx[i] == 0x7E) { |
| bob_tpc | 15:713c26178a7d | 805 | em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark |
| bob_tpc | 15:713c26178a7d | 806 | } |
| bob_tpc | 15:713c26178a7d | 807 | } |
| bob_tpc | 22:5707b236cbdb | 808 | if (em_pos == 0) { |
| bob_tpc | 15:713c26178a7d | 809 | led_err.write(LEDON); // end mark never reached |
| bob_tpc | 5:e77529f7ede3 | 810 | break; |
| bob_tpc | 5:e77529f7ede3 | 811 | } |
| bob_tpc | 15:713c26178a7d | 812 | |
| bob_tpc | 15:713c26178a7d | 813 | cdc.writeBlock(cdc_buffer_tx, (em_pos + 2)); |
| bob_tpc | 22:5707b236cbdb | 814 | led_com.write(led_com_state); |
| bob_tpc | 15:713c26178a7d | 815 | break; |
| bob_tpc | 22:5707b236cbdb | 816 | |
| bob_tpc | 15:713c26178a7d | 817 | case 0xDD: // GPIO (LEDs and RFID-FE control) |
| bob_tpc | 15:713c26178a7d | 818 | led_com.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 819 | for (i = 0; i < sizeof(cdc_buffer_rx); i++) { |
| bob_tpc | 22:5707b236cbdb | 820 | gpio_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for GPIO |
| bob_tpc | 15:713c26178a7d | 821 | } |
| bob_tpc | 22:5707b236cbdb | 822 | |
| bob_tpc | 15:713c26178a7d | 823 | if (gpio_buffer[1] == 1) // GPIO read = 1 |
| bob_tpc | 15:713c26178a7d | 824 | status = gpio_rd(); // read the requested data |
| bob_tpc | 15:713c26178a7d | 825 | else if (gpio_buffer[1] == 0) // GPIO write = 0 |
| bob_tpc | 15:713c26178a7d | 826 | status = gpio_wr(); // send GPIO pin data |
| bob_tpc | 22:5707b236cbdb | 827 | |
| bob_tpc | 15:713c26178a7d | 828 | em_pos = 0; |
| bob_tpc | 22:5707b236cbdb | 829 | for (i = 0; i < sizeof(cdc_buffer_tx); i++) { |
| bob_tpc | 15:713c26178a7d | 830 | cdc_buffer_tx[i] = gpio_buffer[i]; // copy RFID response back to USB buffer |
| bob_tpc | 22:5707b236cbdb | 831 | if (cdc_buffer_tx[i] == 0x7E) { |
| bob_tpc | 15:713c26178a7d | 832 | em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark |
| bob_tpc | 15:713c26178a7d | 833 | } |
| bob_tpc | 5:e77529f7ede3 | 834 | } |
| bob_tpc | 22:5707b236cbdb | 835 | if (em_pos == 0) { |
| bob_tpc | 15:713c26178a7d | 836 | led_err.write(LEDON); // end mark never reached |
| bob_tpc | 5:e77529f7ede3 | 837 | break; |
| bob_tpc | 5:e77529f7ede3 | 838 | } |
| bob_tpc | 15:713c26178a7d | 839 | |
| bob_tpc | 15:713c26178a7d | 840 | cdc.writeBlock(cdc_buffer_tx, (em_pos + 2)); |
| bob_tpc | 22:5707b236cbdb | 841 | led_com.write(led_com_state); |
| bob_tpc | 22:5707b236cbdb | 842 | |
| bob_tpc | 22:5707b236cbdb | 843 | break; |
| bob_tpc | 15:713c26178a7d | 844 | |
| bob_tpc | 15:713c26178a7d | 845 | case 0xEE: // Read/write EEPROM |
| bob_tpc | 22:5707b236cbdb | 846 | led_com.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 847 | for (i = 0; i < sizeof(cdc_buffer_rx); i++) { |
| bob_tpc | 15:713c26178a7d | 848 | i2c_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for I2C |
| bob_tpc | 15:713c26178a7d | 849 | } |
| bob_tpc | 15:713c26178a7d | 850 | |
| bob_tpc | 15:713c26178a7d | 851 | if (i2c_buffer[1] == 1) // I2C read = 1 |
| bob_tpc | 15:713c26178a7d | 852 | status = eeprom_msg_rd(); // read the requested data |
| bob_tpc | 15:713c26178a7d | 853 | else if (i2c_buffer[1] == 0) // I2C write = 0 |
| bob_tpc | 22:5707b236cbdb | 854 | status = eeprom_msg_wr(); // send buffer to EEPROM and get response |
| bob_tpc | 15:713c26178a7d | 855 | |
| bob_tpc | 17:1e704604e1ac | 856 | if (status) led_err.write(LEDON); |
| bob_tpc | 22:5707b236cbdb | 857 | |
| bob_tpc | 15:713c26178a7d | 858 | em_pos = 0; |
| bob_tpc | 22:5707b236cbdb | 859 | for (i = 0; i < sizeof(cdc_buffer_tx); i++) { |
| bob_tpc | 15:713c26178a7d | 860 | cdc_buffer_tx[i] = i2c_buffer[i]; // copy RFID response back to USB buffer |
| bob_tpc | 22:5707b236cbdb | 861 | if (cdc_buffer_tx[i] == 0x7E) { |
| bob_tpc | 15:713c26178a7d | 862 | em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark |
| bob_tpc | 15:713c26178a7d | 863 | } |
| bob_tpc | 5:e77529f7ede3 | 864 | } |
| bob_tpc | 22:5707b236cbdb | 865 | if (em_pos == 0) { |
| bob_tpc | 15:713c26178a7d | 866 | led_err.write(LEDON); // end mark never reached |
| bob_tpc | 5:e77529f7ede3 | 867 | break; |
| bob_tpc | 5:e77529f7ede3 | 868 | } |
| bob_tpc | 15:713c26178a7d | 869 | |
| bob_tpc | 15:713c26178a7d | 870 | cdc.writeBlock(cdc_buffer_tx, (em_pos + 2)); |
| bob_tpc | 22:5707b236cbdb | 871 | led_com.write(led_com_state); |
| bob_tpc | 15:713c26178a7d | 872 | break; |
| bob_tpc | 22:5707b236cbdb | 873 | |
| bob_tpc | 22:5707b236cbdb | 874 | case 0xFF: |
| bob_tpc | 22:5707b236cbdb | 875 | if (cdc_buffer_rx[1] > 0){ |
| bob_tpc | 22:5707b236cbdb | 876 | // read message sent to RFID on interrupt |
| bob_tpc | 22:5707b236cbdb | 877 | |
| bob_tpc | 22:5707b236cbdb | 878 | temploc = 0x12; |
| bob_tpc | 22:5707b236cbdb | 879 | i2c.write(i2c_addr, &temploc, 1, 1); // i2c address+bank 0, RFID message size location, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 880 | i2c.read(i2c_addr, &msgcount, 1, 0); // i2c address+bank 0, RFID message size, 1 byte, stop at end |
| bob_tpc | 22:5707b236cbdb | 881 | msgcount += 6; // get the real size |
| bob_tpc | 22:5707b236cbdb | 882 | temploc = 0x10; |
| bob_tpc | 22:5707b236cbdb | 883 | i2c.write(i2c_addr, &temploc, 1, 1); // i2c address+bank 0, RFID message location, 1 byte, no stop at end |
| bob_tpc | 22:5707b236cbdb | 884 | i2c.read(i2c_addr, prox_irq_msg, msgcount, 0); // i2c address+bank 0, description string, string size, stop at end |
| bob_tpc | 22:5707b236cbdb | 885 | |
| bob_tpc | 22:5707b236cbdb | 886 | autorange[2] = 0x03; |
| bob_tpc | 22:5707b236cbdb | 887 | i2c.write(PROX, autorange, 3, 0); // Start contonuous proximity range read |
| bob_tpc | 22:5707b236cbdb | 888 | } |
| bob_tpc | 22:5707b236cbdb | 889 | else { |
| bob_tpc | 22:5707b236cbdb | 890 | prox_irq_msg[0] = 0xFF; // clear first byte |
| bob_tpc | 22:5707b236cbdb | 891 | autorange[2] = 0x00; |
| bob_tpc | 22:5707b236cbdb | 892 | i2c.write(PROX, autorange, 3, 0); // Stop range read |
| bob_tpc | 22:5707b236cbdb | 893 | } |
| bob_tpc | 17:1e704604e1ac | 894 | |
| bob_tpc | 22:5707b236cbdb | 895 | break; |
| bob_tpc | 15:713c26178a7d | 896 | default: |
| bob_tpc | 22:5707b236cbdb | 897 | led_err.write(LEDON); // we should never get here |
| bob_tpc | 22:5707b236cbdb | 898 | while(1); // halt! |
| bob_tpc | 15:713c26178a7d | 899 | } |
| bob_tpc | 5:e77529f7ede3 | 900 | } |
| bob_tpc | 22:5707b236cbdb | 901 | led_com.write(led_com_state); |
| bob_tpc | 0:8604e9cc07f2 | 902 | } |
| bob_tpc | 0:8604e9cc07f2 | 903 | } |
| bob_tpc | 22:5707b236cbdb | 904 | //EOF main.cpp |
