Super Vision / Mbed 2 deprecated sv_usb_firmware

Dependencies:   MODSERIAL USBDevice_for_Rev_C_HW mbed

Fork of mbed_sv_firmware_with_init by Bob Recny

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?

UserRevisionLine numberNew 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