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
Diff: main.cpp
- Revision:
- 22:5707b236cbdb
- Parent:
- 19:d3bef4fbab69
- Child:
- 23:52504c8f63c5
--- a/main.cpp Thu Apr 02 20:17:21 2015 +0000
+++ b/main.cpp Fri Jun 05 01:52:30 2015 +0000
@@ -1,24 +1,44 @@
-/**
+ /**
+ * Copyright (c) 2015 The Positive Charge, LLC for Supervision, LLC
* @file main.cpp
- * @date January 2015
+ * @date 2015-06-04
* @brief Freescale KL25Z firmware for USB-RFID adapter
*
- * This firmware provided communication from a PC's USB host port to the following peripherals:
+ * This firmware provides communication from a PC's USB host port to the following peripherals:
* RFID-FE over UART - SuperVision RFID reader module
* VL6180X over I2C - ST Microelectronics proximity and ambient light sensor
* GPIO - two LEDs and several control signals for the RFID module
* EEPROM - over I2C - Generic 24LC16B (untested since first revision prototype hardware does not have an EEPROM)
+ *
+ * Revision History
+ * 2014-11-01
+ * For Rev A Hardware - No EEPROM, single-byte GPIO
+ *
+ * 2015-03-01
+ * For Rev B and C Hardware - Includes EEPROM, single-byte GPIO
+ *
+ * 2015-06-04
+ * For Rev C Hardware - Includes EEPROM, 2-byte GPIO allows extra pins on LED connector to be used.
+ * - Includes EEPROM storage of USB string descriptors and RFID command for Proximity interrupt
+ * - Includes USB initialization update and added code to send RFID command on Proximity interrupt
+ *
*/
+// mbed.org headers
+#include "mbed.h" // main mbed.org libraries
+#include "USBDevice.h"
+#include "USBSerial.h" // USB CDC drivers
+#include "MODSERIAL.h" // UART drivers - MODSERIAL allows block writes compared to the mbed driver
-#include "mbed.h"
-#include "USBSerial.h"
-#include "MODSERIAL.h"
+// Supervision-specific headers
+#include "SV_USBConfig.h" // Default USB strings for initial power-up.
+#include "ProxInit.h" // VL6180X default initial values - *not* calibrated
// Constants
#define LEDON 0 // Low active for LEDs - turns LED on
#define LEDOFF 1 // Low active for LEDs - turns LED off
-#define TRUE 1
+
+#define TRUE 1 // Boolean true and false
#define FALSE 0
// Error return values
@@ -29,9 +49,10 @@
#define ERR_UART_NOT_READABLE 0xB2 // UART has no buffer space
#define ERR_UART_NO_TX_ENDMARK 0xB3 // message for UART has no 0x7E end-mark
#define ERR_UART_NO_RX_ENDMARK 0xB4 // message received from UART has no end-mark
-#define ERR_I2C_NOT_WRITEABLE 0xC1 // UART has no buffer space
-#define ERR_I2C_NO_TX_ENDMARK 0xC2 // message for UART has no 0x7E end-mark
-#define ERR_I2C_NO_RX_ENDMARK 0xC3 // message received from UART has no end-mark
+#define ERR_I2C_NOT_WRITEABLE 0xC1 // I2C has no buffer space
+#define ERR_I2C_NO_TX_ENDMARK 0xC2 // message for I2C has no 0x7E end-mark
+#define ERR_I2C_NO_RX_ENDMARK 0xC3 // message received from I2C has no end-mark
+#define ERR_I2C_WRITE_TOO_LARGE 0x16 // message for I2C write is too large (16 bytes max)
#define ERR_NOT_IMPLEMENTED 0xFF // method has not yet been implemented
// I2C addresses and parameters
@@ -41,11 +62,11 @@
// UART-RFID baud rate
#define RFIDBAUD 115200 // RFID-FE board default rate = 115.2Kbps
-#define BUFFERSIZE 128 // default buffer sizes
+#define BUFFERSIZE 128 // default buffer sizes
#define RFIDLENLOW 5 // RFID message length location (length is 2 bytes)
// Peripherals
-USBSerial cdc; // CDC Class USB<>Serial adapter. Needs custom INF, but uses existing Windows drivers.
+USBSerial cdc; // CDC Class USB-Serial adapter. Needs custom INF, but uses existing Windows CDC drivers.
MODSERIAL uart(PTA2, PTA1); // UART port connected to RFID-FE board
I2C i2c(PTB1, PTB0); // I2C port connected to VL6180X and EEPROM - note addresses above)
@@ -58,25 +79,107 @@
DigitalOut rfid_pwr(PTE30); // RFID power switch on USB board (active high for prototype 1, low for all others)
DigitalIn rfid_hot(PTE0); // RFID over-current detection on USB board power switch (active low)
InterruptIn prox_int(PTD7); // Proximity sensor interrupt (active low)
+DigitalOut ee_wp(PTC5); // EEPROM Write Protect (active high)
DigitalInOut gpio_0(PTC3); // Extra GPIO on LED connector, pin 6
DigitalInOut gpio_1(PTC4); // Extra GPIO on LED connector, pin 7
DigitalOut gpio_7(PTA4); // Extra GPIO output on LED connector, pin 3 - pin supports PWM for buzzer, not implemented here
-// buffers & variables
+// global buffers & variables
+uint8_t led_com_state = LEDOFF; // initial LED state
+uint8_t prox_irq_state = 0; // interrupt state passed from service routine
+uint8_t usb_irq_state = 0; // interrupt state passed from service routine
uint8_t gpio_values = 0x00; // register to read GPIO values
-uint8_t cdc_buffer_rx[BUFFERSIZE]; // buffers for cdc (USB-Serial port on PC)
+uint8_t cdc_buffer_rx[BUFFERSIZE]; // buffers for cdc (USB-Serial port on PC)
uint8_t cdc_buffer_tx[BUFFERSIZE];
uint8_t uart_buffer_rx[BUFFERSIZE]; // buffers for uart (RFID-FE board)
uint8_t uart_buffer_tx[BUFFERSIZE];
uint8_t gpio_buffer[BUFFERSIZE]; // buffer for GPIO messages
-char i2c_buffer[BUFFERSIZE]; // buffer for I2C devices - Proximity sensor and EEPROM - up to 256 bytes data payload for EEPROM, up to 4 for proximity
-int i, j; // index variables
+
+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
+char prox_irq_msg[BUFFERSIZE]; // buffer for automatic RFID message on proximity interrupt
+
+int i, j; // general index variables
int status = 0x00; // return value
-uint8_t led_com_state = LEDOFF; // initial LED state
-uint8_t prox_irq_state = 0; // interrupt state passed from service routine
-uint8_t usb_irq_state = 0; // interrupt state passed from service routine
+
+// USB config descriptor strings
+// These are held in SV_USBConfig.h, and only used during initial bring-up after manufacturing
+
+char mfg_str[0x2E] = {SV_MFG}; // Default USB strings - Manufacturer
+char mfg_str_cnt = SV_MFG_CNT;
+char ser_str[0x2E] = {SV_SER}; // Default USB strings - Serial Number
+char ser_str_cnt = SV_SER_CNT;
+char des_str[0x3E] = {SV_DES}; // Default USB strings - Product Description
+char des_str_cnt = SV_DES_CNT;
+
+// These next functions are modified from the original USBDevice.cpp and USBCDC.cpp mbed drivers
+// in order to allow custom USB descriptor strings.
+
+/**
+ * @name USBDevice::stringImanufacturerDesc
+ * @name USBDevice::stringIserialDesc
+ * @name USBDevice::stringIproductDesc
+ * @name USBCDC::stringIproductDesc
+ * @brief Sets custom USB Config Descriptor Strings
+ *
+ * These methods are modified from the original to allow custom USB config descriptor strings.
+ * The original (in USBDevice.cpp and USBCDC.cpp) are hard-coded for generic mbed.org values
+ * The values used in these methods are read from the EEPROM. Especially important is allowing
+ * a custom USB Serial Number, which will be written to the EEPROM during the factory test.
+ *
+ * @param [in] none
+ * @retval stringImanufacturerDescriptor
+ * @retval stringIserialDescriptor
+ * @retval stringIproductDescriptor
+ * @retval stringIproductDescriptor
+ */
+
+// MODIFIED to allow custom strings
+uint8_t * USBDevice::stringImanufacturerDesc() {
+ static uint8_t stringImanufacturerDescriptor[0x30];
+ stringImanufacturerDescriptor[0] = mfg_str_cnt;
+ stringImanufacturerDescriptor[1] = STRING_DESCRIPTOR;
+ for (int i = 0; i < sizeof(mfg_str); i++){
+ stringImanufacturerDescriptor[i+2] = mfg_str[i];
+ }
+ return stringImanufacturerDescriptor;
+}
+
+// MODIFIED to allow custom strings
+
+uint8_t * USBDevice::stringIserialDesc() {
+ static uint8_t stringIserialDescriptor[0x30];
+ stringIserialDescriptor[0] = ser_str_cnt;
+ stringIserialDescriptor[1] = STRING_DESCRIPTOR;
+ for (int i = 0; i < sizeof(ser_str); i++){
+ stringIserialDescriptor[i+2] = ser_str[i];
+ }
+ return stringIserialDescriptor;
+}
+
+// MODIFIED to allow custom strings
+uint8_t * USBDevice::stringIproductDesc() {
+ static uint8_t stringIproductDescriptor[0x40];
+ stringIproductDescriptor[0] = des_str_cnt;
+ stringIproductDescriptor[1] = STRING_DESCRIPTOR;
+ for (int i = 0; i < sizeof(des_str); i++){
+ stringIproductDescriptor[i+2] = des_str[i];
+ }
+ return stringIproductDescriptor;
+}
+
+
+// MODIFIED to allow custom strings
+uint8_t * USBCDC::stringIproductDesc() {
+ static uint8_t stringIproductDescriptor[0x40];
+ stringIproductDescriptor[0] = des_str_cnt;
+ stringIproductDescriptor[1] = STRING_DESCRIPTOR;
+ for (int i = 0; i < sizeof(des_str); i++){
+ stringIproductDescriptor[i+2] = des_str[i];
+ }
+ return stringIproductDescriptor;
+}
/**
* @name prox_irq
@@ -89,8 +192,17 @@
void prox_irq(void)
{
prox_irq_state = 1;
+ led_com.write(LEDON); // Turn on COM LED until interrupt is serviced
}
+/**
+ * @name usb_irq
+ * @brief Sets interrupt variable for use in the main loop.
+ * The interrupt is triggered when the host PC has sent data to the CDC port.
+ *
+ * @param [in] none
+ * @param [out] usb_irq_state = 1 indicates an interrupt occured.
+ */
void usb_irq(void)
{
usb_irq_state = 1;
@@ -100,51 +212,154 @@
* @name init_periph
* @brief Initializes the KL25Z peripheal interfaces
* KL25Z interfaces:
- * UART - connects to SuperVision RFID-FE module
- * I2C - connects to the ST VL6180X proximity/ambient light sensor device and a 24LC16B EEPROM (future)
- * GPIO - includes two LEDs and signals to control RFID reader.
+ * USB - Initializes USB config descriptors
+ * UART - Connects to SuperVision RFID-FE module
+ * I2C - Configures to the ST VL6180X proximity/ambient light sensor device
+ * I2C - Reads configuration data from EEPROM
+ * GPIO - Includes two LEDs and signals to control RFID reader.
*
* @param [in] none
- * @param [out] none
- *
- * @retval ERR_NONE No error
+ * @param [out] error status (0 = no error)
+ *
+ * @retval error state
*/
- int init_periph(void)
+int init_periph(void)
{
- // Set up peripherals
+ int i2c_err; // return value
+ char temploc = 0x00; // temporary values
+ char temp[] = {0,0};
+ char i2c_page = 0;
+ char prox_ee[254] = {0}; // buffer for Proximity initialization values stored
+ // in EEPROM, especially the cover glass calibration
+ // Set up peripherals on KL25Z
+
+ led_err.write(LEDOFF); // Start with leds
+ led_com.write(LEDOFF);
+
+ // Check EEPROM for programmed USB string descriptors. These are held in BANK ZERO (I2C address = EEPROM | 0 << 1)
+ // Factory test should initialize the EEPROM
+ //
+ // First two bytes of bank zero will be "SV" if programmed.
+ // Bank 0x10 holds Manufacturer string
+ // Bank 0x40 holds Serial Number string
+ // Bank 0x70 holds Product Description string
+
+ i2c_page = EEPROM | 0 << 1; // set EEPROM page = bank 0
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte (just index), no stop at end.
+ i2c.read(i2c_page, temp, 2, 0); // i2c address+bank 0, variable location, 2 bytes (just data), stop at end.
+
+ if ((temp[0] == 'S') && (temp[1] == 'V')) {
+ led_com.write(LEDON);
+
+ // Read Manufacturer String
+ temploc = 0x10;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, count index, 1 byte, no stop at end
+ i2c.read(i2c_page, &mfg_str_cnt, 1, 0); // i2c address+bank 0, mfg string size, 1 byte, stop at end
+ temploc = 0x11;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end
+ i2c.read(i2c_page, mfg_str, mfg_str_cnt, 0); // i2c address+bank 0, mfg string, string size, stop at end
+
+ // Read Serial Number string
+ temploc = 0x40;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte no stop at end
+ i2c.read(i2c_page, &ser_str_cnt, 1, 0); // i2c address+bank 0, serial number string size, 1 byte, stop at end
+ temploc = 0x41;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end
+ i2c.read(i2c_page, ser_str, ser_str_cnt, 0); // i2c address+bank 0, serial number string, string size, stop at end
+
+ // Read Product Description String
+ temploc = 0x70;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end
+ i2c.read(i2c_page, &des_str_cnt, 1, 0); // i2c address+bank 0, description string size, 1 byte, stop at end
+ temploc = 0x71;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 0, memory index, 1 byte, no stop at end
+ i2c.read(i2c_page, des_str, des_str_cnt, 0); // i2c address+bank 0, description string, string size, stop at end
+ led_com.write(LEDOFF);
+
+ }
+
+ // Prox & EEPROM
+ ee_wp.write(0); // no write protection on EEPROM
+ i2c.frequency(I2CRATE); // I2C speed = 400Kbps
+
+ // Get the VL6180X register values from the ProxInit.h header and program them to the Proximity Sensor (from VL6180X app notes)
+
+ for (i = 0; i < sizeof(proxinit); i += 3){ // Initialize VL6180X with default values, calibration data sent later
+ i2c_err = i2c.write(PROX, &proxinit[i], 3, 0); // I2C Address, pointer to buffer, number of bytes (for index + data), stop at end.
+ // also includes taking off the "Fresh out of Reset" flag.
+ if (i2c_err){
+ led_err.write(LEDON); // Turn on both LEDs
+ led_com.write(LEDON); // We can't write to the proximity sensor
+ return i2c_err;
+ }
+ }
+
+ // Get Supervision-specific register values and program them to the Proximity Sensor (calibration, other operating features)
+
+ i2c_page = EEPROM | 1 << 1; // set EEPROM page = bank 1
+ temploc = 0;
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 1, memory index, 1 byte (just index), no stop at end.
+ i2c.read(i2c_page, temp, 2, 0); // i2c address+bank 1, variable location, 2 bytes (just data), stop at end.
+
+ if ((temp[0] == 'S') && (temp[1] == 'V')) {
+ led_com.write(LEDON);
+ // Read values
+ temploc = 0x02; // Values start here. Since this section is mostly one-byte values with two-byte
+ // addresses, 2- and 4-byte registers are individually addressed
+ i2c.write(i2c_page, &temploc, 1, 1); // i2c address+bank 1, location 2, 1 byte, no stop at end - read the whole bank
+ i2c.read(i2c_page, prox_ee, sizeof(prox_ee), 0); // i2c address+bank 1, buffer location, 1 byte, stop at end
+ for (i = 0; i < sizeof(prox_ee); i += 3){ // Initialize VL6180X with default values, calibration data sent later
+ if ((prox_ee[i] == 0xFF) && (prox_ee[i+1] == 0xFF)){
+ break; // No more values are in the EEPROM (blank / erased = 0xFF)
+ }
+ else {
+ i2c_err = i2c.write(PROX, &prox_ee[i], 3, 0); // I2C Address, pointer to buffer, number of bytes (for index + data), stop at end.
+ // also includes taking off the "Fresh out of Reset" flag.
+ if (i2c_err){
+ led_err.write(LEDON); // Turn on both LEDs
+ led_com.write(LEDON); // We can't write to the proximity sensor
+ return i2c_err;
+ }
+ }
+ }
+ led_com.write(LEDOFF);
+ }
+
+ // Enable the Proximity interrupt
+ prox_int.mode(PullUp); // pull up proximity sensor interrupt at MCU
+ prox_int.fall(&prox_irq); // VL6180X interrupt is low active
+ prox_int.enable_irq(); // Enable proximity interrupt inputs
+
+ // "Fresh-out-of-reset" register was automatically set to 0x01 after boot
+ prox_ee[0] = 0x00;
+ prox_ee[1] = 0x16;
+ prox_ee[2] = 0x00;
+ i2c.write(PROX, prox_ee, 3, 0); // Remove "Fresh out of Reset" flag to allow normal operation
+
+ cdc.attach(&usb_irq); // Attach USB interrupt
+ usb_irq_state = 0; // Ensure interrupt flag is not set after setup
+
// RFID
uart.baud(RFIDBAUD); // RFID-FE baud rate
-
- cdc.attach(&usb_irq);
-
+
rfid_int = 0; // RFID FE power control (active high)
rfid_isp = 0; // RFID FE In-System Programming (active high)
rfid_rst = 1; // RFID FE Reset (active high)
-// rfid_pwr = 1; // RFID power switch on USB board (active high for prototype 1)
rfid_pwr = 0; // RFID power switch on USB board (active low for all others)
wait(0.25); // wait 250ms before...
rfid_rst = 0; // ... taking RFID out of reset
wait(0.25);
-
- while(!uart.readable()) // wait for RESET message from RFID
- {
+
+ while(!uart.readable()) { // wait for RESET message from RFID
led_err.write(LEDON); // flash LED until it arrives
- wait(0.1);
+ wait(0.1); // This is a good way to see if the RFID cable is properly seated
led_err.write(LEDOFF);
wait(0.1);
- }
-
- uart.txBufferFlush(); // clear out UART buffers
+ }
+
+ uart.txBufferFlush(); // clear out UART buffers - we don't need the reset message
uart.rxBufferFlush();
-
- led_err.write(LEDOFF);
-
- // Prox & EEPROM
- i2c.frequency(I2CRATE); // I2C speed = 400Kbps
- prox_int.mode(PullUp); // pull up proximity sensor interrupt at MCU
- prox_int.fall(&prox_irq); // VL6180X interrupt is low active
- prox_int.enable_irq(); // Enable proximity interrupt inputs
-
+
// LEDs // Cycle through the LEDs.
led_err.write(LEDON);
led_com.write(LEDON);
@@ -152,67 +367,63 @@
led_err.write(LEDOFF);
wait(0.5);
led_com.write(LEDOFF);
-
+
return ERR_NONE;
}
/**
* @name rfid_wr
- * @brief Forwards command to RFID reader
+ * @brief Forwards command to RFID reader
*
* RFID reader is connected to the KL25Z UART interface. The host PC will have a USB CDC class COM port device driver.
- * The host PC sends the RFID command over the COM port. Messages destined for the RFID reader (0xBB leading byte) are
+ * The host PC sends the RFID command over the COM port. Messages destined for the RFID reader (0xBB leading byte) are
* forwarded as-is to the RFID reader. The reader then responds in kind. All RFID commands are described in the
* RFID-FE module manual.
*
* @param [out] uart_buffer_tx - messages to the RFID reader
- *
+ *
* @retval ERR_NONE No error
* @retval ERR_UART_NOT_WRITEABLE UART has no buffer space
* @retval ERR_UART_NO_TX_ENDMARK message for UART has no 0x7E end-mark
* @example
- * BB 00 03 00 01 02 7E 2E C9 = read
+ * BB 00 03 00 01 02 7E 2E C9 = read
*/
int rfid_wr(void)
{
int em_pos = 0;
-
- for (i = 0; i < sizeof(uart_buffer_tx); i++)
- {
+
+ for (i = 0; i < sizeof(uart_buffer_tx); i++) {
if (uart_buffer_tx[i] == 0x7E) em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark
}
- if (em_pos == 0)
- {
+ if (em_pos == 0) {
led_err.write(LEDON); // end mark never reached
return ERR_UART_NO_TX_ENDMARK;
}
- if (!uart.writeable())
- {
+ if (!uart.writeable()) {
led_err.write(LEDON);
return ERR_UART_NOT_WRITEABLE; // if no space in uart, return error
}
- for (i = 0; i < (em_pos + 2); i++)
- {
+ for (i = 0; i < (em_pos + 2); i++) {
uart.putc(uart_buffer_tx[i]); // send uart message
}
-
+
return ERR_NONE;
-}
+}
/**
* @name prox_msg_wr
- * @brief Forwards command to VL6180X sensor
+ * @brief Forwards command to VL6180X sensor
*
- * Proximity/ALS reader is connected to the KL25Z I2C interface.
- * The host PC sends the sensor command over the COM port. Messages destined for the proximity/ALS sensor (0xCC leading byte) are
- * forwarded to the proximity/ALS sensor after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
+ * Proximity/ALS reader is connected to the KL25Z I2C interface.
+ * The host PC sends the sensor command over the COM port. Messages destined for the proximity/ALS sensor (0xCC leading byte) are
+ * forwarded to the proximity/ALS sensor after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
* The sensor then responds in kind. Firmware re-attaches the leading 0xCC and trailing bytes before sending the response over the
* CDC port to the host PC.
*
- * I2C-prox messages:
+ * I2C-prox messages:
* - 0xCC (byte) leading value = 0xCC
* - r/w# (byte) 0 = write, 1 = read
* - number of data bytes(byte) 0 to 32 (size of declared buffers)
@@ -225,12 +436,12 @@
* VL6180X registers are defined in the sensor datasheet.
*
* @param [in] i2c_buffer - messages to and from the VL6180X and EEPROM
- *
+ *
* @retval 0 No error
* @retval 1 I2C bus has NAK'd / failure
*
* @param [in/out] i2c_buffer - messages to and from the i2c bus - see above
- *
+ *
*/
int prox_msg_wr() // write proximity I2C register
{
@@ -238,18 +449,18 @@
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.
return i2c_err; // 0 = ACK received, 1 = NAK/failure
}
-
+
/**
* @name prox_msg_rd
* @brief retrieves response from VL6180X sensor
*
- * Proximity/ALS reader is connected to the KL25Z I2C interface.
- * The host PC sends the sensor command over the COM port. Messages destined for the proximity/ALS sensor (0xCC leading byte) are
- * forwarded to the proximity/ALS sensor after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
+ * Proximity/ALS reader is connected to the KL25Z I2C interface.
+ * The host PC sends the sensor command over the COM port. Messages destined for the proximity/ALS sensor (0xCC leading byte) are
+ * forwarded to the proximity/ALS sensor after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
* The sensor then responds in kind. Firmware re-attaches the leading 0xCC and trailing bytes before sending the response over the
* CDC port to the host PC.
*
- * I2C-prox messages:
+ * I2C-prox messages:
* - 0xCC (byte) leading value = 0xCC
* - r/w# (byte) 0 = write, 1 = read
* - number of data bytes(byte) 0 to 32 (size of declared buffers)
@@ -266,7 +477,7 @@
* @retval 0 No error
* @retval 1 I2C bus has NAK'd / failure
*
- *
+ *
*/
int prox_msg_rd()
{
@@ -280,11 +491,11 @@
* @name gpio_rd
* @brief retrieves instantaneous value of GPIO pins
*
- * GPIO signals are defined directly off of the KL25Z.
+ * GPIO signals are defined directly off of the KL25Z.
* 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.
* This allows a read-modify-write GPIO sequence.
*
- * GPIO messages:
+ * GPIO messages:
* - 0xDD (byte) leading value = 0xDD
* - r/w# (byte) 0 = write, 1 = read
* - data (2 bytes) see below
@@ -292,7 +503,7 @@
* - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes
*
* GPIO data bits - First Byte
- * - 0 LED - Error 0 = on, 1 = off
+ * - 0 LED - Error 0 = on, 1 = off
* - 1 LED - Comm state 0 = on, 1 = off
* - 2 RFID interrupt input 0 = off, 1 = on (inverted in h/w)
* - 3 RFID in-system-prog 0 = off, 1 = on (inverted in h/w)
@@ -310,13 +521,13 @@
* @param [in/out] gpio_buffer - GPIO states
*
* @retval 0 No error
- *
+ *
*/
int gpio_rd()
{
- gpio_buffer[2] = ( led_err.read() & 0x01); // read all of the GPIO pins and store in a single byte
- gpio_buffer[2] |= ((led_com_state << 1) & 0x02); // use of led_com_state allows the led to be ON during this call, but send back the pre-call state.
+ gpio_buffer[2] = ( led_err.read() & 0x01); // read first byte of the GPIO pins
+ 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
gpio_buffer[2] |= ((rfid_int.read() << 2) & 0x04);
gpio_buffer[2] |= ((rfid_isp.read() << 3) & 0x08);
gpio_buffer[2] |= ((rfid_rst.read() << 4) & 0x10);
@@ -324,14 +535,14 @@
gpio_buffer[2] |= ((rfid_hot.read() << 6) & 0x40);
gpio_buffer[2] |= ((prox_int.read() << 7) & 0x80);
- gpio_buffer[3] = ( gpio_0.read() & 0x01); // read all of the GPIO pins and store in a single byte
- gpio_buffer[3] |= (( gpio_1.read() << 1) & 0x02); // use of led_com_state allows the led to be ON during this call, but send back the pre-call state.
- gpio_buffer[3] |= (( 0 << 2) & 0x04); // bits 2-7 not implemented for read
+ gpio_buffer[3] = ( gpio_0.read() & 0x01); // read second byte of the GPIO pins
+ gpio_buffer[3] |= (( gpio_1.read() << 1) & 0x02);
+ gpio_buffer[3] |= (( 0 << 2) & 0x04); // bits 2-7 always return zero
gpio_buffer[3] |= (( 0 << 3) & 0x08);
gpio_buffer[3] |= (( 0 << 4) & 0x10);
gpio_buffer[3] |= (( 0 << 5) & 0x20);
gpio_buffer[3] |= (( 0 << 6) & 0x40);
- gpio_buffer[2] |= (( 0 << 7) & 0x80);
+ gpio_buffer[3] |= (( 0 << 7) & 0x80);
return ERR_NONE;
}
@@ -340,19 +551,19 @@
* @name gpio_wr
* @brief sets value of GPIO pins
*
- * GPIO signals are defined directly off of the KL25Z.
+ * GPIO signals are defined directly off of the KL25Z.
* 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.
* This allows a read-modify-write GPIO sequence.
*
- * GPIO messages:
+ * GPIO messages:
* - 0xDD (byte) leading value = 0xDD
* - r/w# (byte) 0 = write, 1 = read
- * - data (byte) see below
+ * - data (2 bytes) see below
* - end_mark (byte) 0x7E
* - dummy (2 bytes) values are don't-care - fillers for RFID CRC bytes
*
- * GPIO data bits:
- * - 0 LED - Error 0 = on, 1 = off
+ * GPIO data bits - First Byte:
+ * - 0 LED - Error 0 = on, 1 = off
* - 1 LED - Comm state 0 = on, 1 = off
* - 2 RFID interrupt input 0 = off, 1 = on (inverted in h/w)
* - 3 RFID in-system-prog 0 = off, 1 = on (inverted in h/w)
@@ -370,48 +581,44 @@
* @param [in/out] gpio_buffer - GPIO states
*
* @retval 0 No error
- *
+ *
*/
int gpio_wr()
{
- if ((gpio_buffer[2] & 0x02) == 0x00)
- {
+ if ((gpio_buffer[2] & 0x02) == 0x00) { // Set the desired state of the yellow LED
led_com_state = LEDON;
- }
- else
- {
+ } else {
led_com_state = LEDOFF;
}
- led_err.write(gpio_buffer[2] & 0x01); // Write GPIO bits - first byte
- led_com.write(led_com_state); // use of led_com_state allows the led to be ON during this call, but send back the pre-call state.
- rfid_int.write(gpio_buffer[2] & 0x04);
- rfid_isp.write(gpio_buffer[2] & 0x08);
- rfid_rst.write(gpio_buffer[2] & 0x10);
- rfid_pwr.write(gpio_buffer[2] & 0x20);
+ led_err.write(gpio_buffer[2] & 0x01); // Write GPIO bits - first byte
+ led_com.write(led_com_state); // use of led_com_state allows the LED to remain ON in the main loop if desired
+ rfid_int.write(gpio_buffer[2] & 0x04);
+ rfid_isp.write(gpio_buffer[2] & 0x08);
+ rfid_rst.write(gpio_buffer[2] & 0x10);
+ rfid_pwr.write(gpio_buffer[2] & 0x20);
- gpio_0.write(gpio_buffer[3] & 0x01); // Write GPIO bits - second byte
- gpio_1.write(gpio_buffer[3] & 0x02); // Write GPIO bits - second byte
- gpio_7.write(gpio_buffer[3] & 0x80); // Write GPIO bits - second byte
+ gpio_0.write(gpio_buffer[3] & 0x01); // Write GPIO bits - second byte
+ gpio_1.write(gpio_buffer[3] & 0x02); // Write GPIO bits - second byte
+ gpio_7.write(gpio_buffer[3] & 0x80); // Write GPIO bits - second byte
return ERR_NONE;
}
-
-
+
+
/**
* @name eeprom_msg_wr
* @brief writes data to the I2C EEPROM
- * @note *** UNTESTED with first prototype ***
*
- * The EEPROM is connected to the KL25Z I2C interface.
- * The host PC sends the sensor command over the COM port. Messages destined for the EERPOM (0xEE leading byte) are
- * forwarded to the EEPROM after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
- * Firmware re-attaches the leading 0xFF and trailing bytes before sending the response over the
+ * The EEPROM is connected to the KL25Z I2C interface.
+ * The host PC sends the sensor command over the COM port. Messages destined for the EERPOM (0xEE leading byte) are
+ * forwarded to the EEPROM after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
+ * Firmware re-attaches the leading 0xEE and trailing bytes before sending the response over the
* CDC port to the host PC.
*
- * I2C-EEPROM messages:
+ * I2C-EEPROM messages:
* - 0xEE (byte) leading value = 0xEE
* - r/w# (byte) 0 = write, 1 = read
- * - number of data bytes(byte) 0 to 32 (size of declared buffers)
+ * - number of data bytes(byte) 0 to 16 bytes for write
* - block (byte) lower 3 bits are logically OR'd with the I2C address
* - address (byte) memory location within block
* - data (n bytes) number of data bytes noted above
@@ -424,38 +631,45 @@
* 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.
*
* @param [in] i2c_buffer - messages to and from the VL6180X and EEPROM
- *
+ *
* @retval 0 No error
* @retval 1 I2C bus has NAK'd / failure
+ * @retval ERR_I2C_WRITE_TOO_LARGE buffer size too large
*
* @param [in/out] i2c_buffer - messages to and from the i2c bus - see above
- *
+ *
*/
int eeprom_msg_wr() // write proximity I2C register
{
- int i2c_err;
- i2c_err = i2c.write((EEPROM | (i2c_buffer[3] << 1 )), &i2c_buffer[4], i2c_buffer[2] + 1, 0);
- // I2C Address & block select, pointer to buffer, number of bytes (for address + data), stop at end.
- while ( i2c.write(EEPROM | (i2c_buffer[3] << 1 ))); // wait until write is done (EEPROM will ACK = 0 for single byte i2c.write)
+ int i2c_err = ERR_NONE;
+ char wr[2] = {0xFF, 0xFF};
+
+ for (i = 0; i < i2c_buffer[2]; i++){ // done with single-byte writes to avoid addressing wrap-around
+ wr[0] = i2c_buffer[4]+i;
+ wr[1] = i2c_buffer[5+i];
+ i2c_err |= i2c.write((EEPROM | (i2c_buffer[3] << 1 )), wr, 2, 0);
+ while ( i2c.write(EEPROM | (i2c_buffer[3] << 1 ))); // wait until write is done (EEPROM will ACK = 0 for single byte i2c.write)
+ // I2C Address & block select, pointer to buffer, 2 bytes (address + one data), stop at end.
+ }
return i2c_err; // 0 = ACK received, 1 = NAK/failure
}
-
+
/**
* @name eeprom_msg_rd
* @brief read data from the I2C EEPROM
- * @note *** UNTESTED with first prototype ***
+ * @note EEPROM only availalbe on REV B and later
*
- * The EEPROM is connected to the KL25Z I2C interface.
- * The host PC sends the sensor command over the COM port. Messages destined for the EERPOM (0xEE leading byte) are
- * forwarded to the EEPROM after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
- * Firmware re-attaches the leading 0xFF and trailing bytes before sending the response over the
+ * The EEPROM is connected to the KL25Z I2C interface.
+ * The host PC sends the sensor command over the COM port. Messages destined for the EERPOM (0xEE leading byte) are
+ * forwarded to the EEPROM after removing the leading byte and trailing bytes (0x7E endmark plus 2 bytes).
+ * Firmware re-attaches the leading 0xEE and trailing bytes before sending the response over the
* CDC port to the host PC.
*
- * I2C-EEPROM messages:
+ * I2C-EEPROM messages:
* - 0xEE (byte) leading value = 0xEE
* - r/w# (byte) 0 = write, 1 = read
- * - number of data bytes(byte) 0 to 32 (size of declared buffers)
+ * - number of data bytes(byte) 0 to 128 bytes for read (size of declared buffer)
* - block (byte) lower 3 bits are logically OR'd with the I2C address
* - address (byte) memory location within block
* - data (n bytes) number of data bytes noted above
@@ -468,106 +682,112 @@
* 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.
*
* @param [in/out] i2c_buffer - messages to and from the VL6180X and EEPROM
- *
+ *
* @retval [none]0 No error
* @retval 1 I2C bus has NAK'd / failure
*
* @param [in/out] i2c_buffer - messages to and from the i2c bus - see above
- *
+ *
*/
- int eeprom_msg_rd()
+int eeprom_msg_rd()
{
int i2c_err;
- i2c_err = i2c.write((EEPROM | (i2c_buffer[3] << 1)), &i2c_buffer[4], 1, 1);
- // I2C Address & block select, pointer to buffer (just the index), index, number of bytes (for address + data), no stop at end.
- i2c_err |= i2c.read((EEPROM | (i2c_buffer[3] << 1)), &i2c_buffer[5], i2c_buffer[2], 0);
- // I2C Address & block select, pointer to buffer (just the data), number of data bytes, stop at end.
+ i2c_err = i2c.write((EEPROM | (i2c_buffer[3] << 1)), &i2c_buffer[4], 1, 1);
+ // I2C Address & block select, pointer to buffer (just the index), index, number of bytes (for address + data), no stop at end.
+ i2c_err |= i2c.read((EEPROM | (i2c_buffer[3] << 1)), &i2c_buffer[5], i2c_buffer[2], 0);
+ // I2C Address & block select, pointer to buffer (just the data), number of data bytes, stop at end.
return i2c_err; // 0 = ACK received, 1 = NAK/failure
}
/**
* @name main
- * @brief main firmware loop
+ * @brief Main firmware loop
*
* @returns [none]
*/
-int main(void)
+int main(void)
{
int em_pos = 0; // end of message count - allows multiple 0x7e in message.
+ char msgcount;
+ char temploc;
+ char autorange[] = {0x00, 0x18, 0x00}; // Proximity sensor automatic measurement. Set last byte = 0x03 to start
+ char proxintclr[] = {0x00, 0x15, 0x07}; // Clear proximity interrupt
- //wait(5.0); // gives a chance to connect the COM port - this can be removed for production
+ char i2c_addr = (EEPROM | (2 << 1)); // EEPROM base address is 0xA0 (already shifted). Bank 2 in use here, shifted for I2C addressing.
init_periph(); // initialize everything
-
- while(1)
- {
+
+ while(1) { // main loop
led_com.write(led_com_state); // turn off communication LED unless it was specifically turned on by GPIO command
- if (prox_irq_state == 1) // process the proximity interrupt
- {
- prox_irq_state = 0;
- cdc_buffer_tx[0] = 0xFF; // send message to PC
- cdc_buffer_tx[1] = 0x7E;
- cdc_buffer_tx[2] = 0x0F;
- cdc_buffer_tx[3] = 0xF0;
- cdc.writeBlock(cdc_buffer_tx, 4);
+ if (prox_irq_state == 1) { // process the proximity interrupt
+ if (prox_irq_msg[0] != 0xBB){ // no message to send to RFID
+ cdc_buffer_tx[0] = 0xFF; // just send a dummy message back to the host
+ cdc_buffer_tx[1] = 0x7E;
+ cdc_buffer_tx[2] = 0x0F;
+ cdc_buffer_tx[3] = 0xF0;
+ cdc.writeBlock(cdc_buffer_tx, 4);
+ led_err.write(LEDON); // we shouldn't get here
+ }
+ else{
+ msgcount = prox_irq_msg[2] + 6; // See RFID-FE manual for message construction
+ for (i = 0; i < msgcount; i++) {
+ uart.putc(prox_irq_msg[i]); // send message to RFID-FE module for a single read
+ }
+ }
+ prox_irq_state = 0; // reset proximity interrupt state
+ wait(0.5); // wait 1/2 sec so the COM LED can be seen
+ led_com.write(led_com_state); // turn off COM LED if not on by GPIO (it was turned on in the ISR)
+ i2c.write(PROX, proxintclr, 3, 0); // i2c prox sensor, interrupt clear message, 3 bytes, stop at end
+
}
- if (uart.readable()) // message availalbe from rfid
- {
+ if (uart.readable()) { // message availalbe from rfid (all responses (0x01) and broadcast (0x02))
int rfid_len = 0;
led_com.write(LEDON);
- for (i = 0; i < (RFIDLENLOW); i++) // Get first part of message to find out total count
- {
- uart_buffer_rx[i] = uart.getc(); // get a byte from rfid
+ for (i = 0; i < (RFIDLENLOW); i++) { // Get first part of message to find out total count
+ uart_buffer_rx[i] = uart.getc(); // get a byte from rfid
}
rfid_len = ((uart_buffer_rx[i-2]<<8) + (uart_buffer_rx[i-1])); // location of message length for RFID
- for (i = RFIDLENLOW; i < (RFIDLENLOW + rfid_len + 3); i++)
- {
- uart_buffer_rx[i] = uart.getc(); // get a byte from rfid
+ for (i = RFIDLENLOW; i < (RFIDLENLOW + rfid_len + 3); i++) { // get the reset of the message
+ uart_buffer_rx[i] = uart.getc(); // get a byte from rfid
}
- for (i = 0; i < (RFIDLENLOW + rfid_len + 3); i++)
- {
+ for (i = 0; i < (RFIDLENLOW + rfid_len + 3); i++) { // copy the message to the USB buffer
cdc_buffer_tx[i] = uart_buffer_rx[i];
}
- cdc.writeBlock(cdc_buffer_tx, (RFIDLENLOW + rfid_len + 3));
- led_com.write(LEDOFF);
- }
- if (usb_irq_state == 1) // message available from PC
- {
- led_com.write(LEDON); // Message received - turn on LED
- usb_irq_state = 0;
+ cdc.writeBlock(cdc_buffer_tx, (RFIDLENLOW + rfid_len + 3)); // send the RFID message to the PC
+ led_com.write(led_com_state);
+ }
+ if (usb_irq_state == 1) { // message available from PC
+ usb_irq_state = 0; // allow another USB interrupt
- for (i = 0; i < sizeof(cdc_buffer_rx); i++)
- {
+ for (i = 0; i < sizeof(cdc_buffer_rx); i++) {
if (cdc.readable()) cdc_buffer_rx[i] = cdc._getc(); // read data from USB side
}
- for (i = 0; i < sizeof(cdc_buffer_rx); i++)
- {
- if (cdc_buffer_rx[i] == 0x7E) // check for rfid end mark in outbound message
- {
+ if ((cdc_buffer_rx[0] == 'A') && (cdc_buffer_rx[1] == 'T')) { // check for Hayes command and ignore it
+ break; // Linux systems will enumerate as ttyACMx
+ } // and attempt to initialize the non-existent modem
+ for (i = 0; i < sizeof(cdc_buffer_rx); i++) {
+ if (cdc_buffer_rx[i] == 0x7E) { // check for rfid end mark in outbound message
em_pos = (i + 1);
}
}
- if (em_pos == 0) // end mark never reached
- {
+ led_com.write(LEDON); // Message received - turn on LED
+ if (em_pos == 0) { // end mark never reached
led_err.write(LEDON);
break;
}
-
- switch(cdc_buffer_rx[0]) // check first byte for "destination"
- {
+
+ switch(cdc_buffer_rx[0]) { // check first byte for "destination"
case 0xBB: // RFID-FE
- for (i = 0; i < sizeof(cdc_buffer_rx); i++)
- {
+ for (i = 0; i < sizeof(cdc_buffer_rx); i++) {
uart_buffer_tx[i] = cdc_buffer_rx[i]; // copy USB message to UART for RFID
}
-
+
status = rfid_wr(); // send buffer to RFID and get response according to RFID board
break;
-
+
case 0xCC: // Proximity Sensor
led_com.write(LEDON);
- for (i = 0; i < sizeof(cdc_buffer_rx); i++)
- {
+ for (i = 0; i < sizeof(cdc_buffer_rx); i++) {
i2c_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for I2C
}
@@ -576,99 +796,109 @@
else if (i2c_buffer[1] == 0) // I2C write = 0
status = prox_msg_wr(); // send buffer to proximity sensor and get response
- if (status) led_err.write(LEDON);
-
+ if (status) led_err.write(LEDON); // we shouldn't get here
+
em_pos = 0;
- for (i = 0; i < sizeof(cdc_buffer_tx); i++)
- {
+ for (i = 0; i < sizeof(cdc_buffer_tx); i++) {
cdc_buffer_tx[i] = i2c_buffer[i]; // copy RFID response back to USB buffer
- if (cdc_buffer_tx[i] == 0x7E)
- {
+ if (cdc_buffer_tx[i] == 0x7E) {
em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark
}
}
- if (em_pos == 0)
- {
+ if (em_pos == 0) {
led_err.write(LEDON); // end mark never reached
break;
}
cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
- led_com.write(LEDOFF);
+ led_com.write(led_com_state);
break;
-
+
case 0xDD: // GPIO (LEDs and RFID-FE control)
-
led_com.write(LEDON);
- for (i = 0; i < sizeof(cdc_buffer_rx); i++)
- {
- gpio_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for I2C
+ for (i = 0; i < sizeof(cdc_buffer_rx); i++) {
+ gpio_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for GPIO
}
-
+
if (gpio_buffer[1] == 1) // GPIO read = 1
status = gpio_rd(); // read the requested data
else if (gpio_buffer[1] == 0) // GPIO write = 0
status = gpio_wr(); // send GPIO pin data
-
+
em_pos = 0;
- for (i = 0; i < sizeof(cdc_buffer_tx); i++)
- {
+ for (i = 0; i < sizeof(cdc_buffer_tx); i++) {
cdc_buffer_tx[i] = gpio_buffer[i]; // copy RFID response back to USB buffer
- if (cdc_buffer_tx[i] == 0x7E)
- {
+ if (cdc_buffer_tx[i] == 0x7E) {
em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark
}
}
- if (em_pos == 0)
- {
+ if (em_pos == 0) {
led_err.write(LEDON); // end mark never reached
break;
}
cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
- led_com.write(LEDOFF);
+ led_com.write(led_com_state);
+
+ break;
- break;
-
case 0xEE: // Read/write EEPROM
- led_com.write(LEDON);
- for (i = 0; i < sizeof(cdc_buffer_rx); i++)
- {
+ led_com.write(LEDON);
+ for (i = 0; i < sizeof(cdc_buffer_rx); i++) {
i2c_buffer[i] = cdc_buffer_rx[i]; // copy USB message to buffer for I2C
}
if (i2c_buffer[1] == 1) // I2C read = 1
status = eeprom_msg_rd(); // read the requested data
else if (i2c_buffer[1] == 0) // I2C write = 0
- status = eeprom_msg_wr(); // send buffer to proximity sensor and get response
+ status = eeprom_msg_wr(); // send buffer to EEPROM and get response
if (status) led_err.write(LEDON);
-
+
em_pos = 0;
- for (i = 0; i < sizeof(cdc_buffer_tx); i++)
- {
+ for (i = 0; i < sizeof(cdc_buffer_tx); i++) {
cdc_buffer_tx[i] = i2c_buffer[i]; // copy RFID response back to USB buffer
- if (cdc_buffer_tx[i] == 0x7E)
- {
+ if (cdc_buffer_tx[i] == 0x7E) {
em_pos = (i + 1); // allows 0x7E to appear in the data payload - uses last one for end-mark
}
}
- if (em_pos == 0)
- {
+ if (em_pos == 0) {
led_err.write(LEDON); // end mark never reached
break;
}
cdc.writeBlock(cdc_buffer_tx, (em_pos + 2));
- led_com.write(LEDOFF);
+ led_com.write(led_com_state);
break;
+
+ case 0xFF:
+ if (cdc_buffer_rx[1] > 0){
+ // read message sent to RFID on interrupt
+
+ temploc = 0x12;
+ i2c.write(i2c_addr, &temploc, 1, 1); // i2c address+bank 0, RFID message size location, 1 byte, no stop at end
+ i2c.read(i2c_addr, &msgcount, 1, 0); // i2c address+bank 0, RFID message size, 1 byte, stop at end
+ msgcount += 6; // get the real size
+ temploc = 0x10;
+ i2c.write(i2c_addr, &temploc, 1, 1); // i2c address+bank 0, RFID message location, 1 byte, no stop at end
+ i2c.read(i2c_addr, prox_irq_msg, msgcount, 0); // i2c address+bank 0, description string, string size, stop at end
+
+ autorange[2] = 0x03;
+ i2c.write(PROX, autorange, 3, 0); // Start contonuous proximity range read
+ }
+ else {
+ prox_irq_msg[0] = 0xFF; // clear first byte
+ autorange[2] = 0x00;
+ i2c.write(PROX, autorange, 3, 0); // Stop range read
+ }
+ break;
default:
- led_err.write(LEDON);
- while(1);
+ led_err.write(LEDON); // we should never get here
+ while(1); // halt!
}
}
- led_com.write(LEDOFF);
+ led_com.write(led_com_state);
}
}
-//EOF
\ No newline at end of file
+//EOF main.cpp
\ No newline at end of file
