Full version for Rev C Hardware Also needs modified USBDevice driver in SV repository

Dependencies:   MODSERIAL USBDevice_for_Rev_C_HW mbed

Fork of mbed_sv_firmware_with_init by Bob Recny

Files at this revision

API Documentation at this revision

Comitter:
bob_tpc
Date:
Tue Jun 23 00:59:31 2015 +0000
Parent:
23:52504c8f63c5
Commit message:
Now can read KL25Z unique ID and set it to the USB serial number; ; EEPROM strings for the USB Mfg and Description no longer supported. (There is a race condition in the USB drivers which prevent the EEPROM from *always* being read in time.)

Changed in this revision

SV_USBConfig.h Show annotated file Show diff for this revision Revisions of this file
USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- a/SV_USBConfig.h	Tue Jun 16 23:03:29 2015 +0000
+++ b/SV_USBConfig.h	Tue Jun 23 00:59:31 2015 +0000
@@ -5,15 +5,11 @@
  * @brief  Freescale KL25Z firmware for USB-RFID adapter
  *
  * Includes USB Config Descriptor strings in UNICODE
- *   iManufacturer = "SV"
+ *   iManufacturer = "Supervision"
  *   iSerial       = "SV1"
- *   iProduct      = "SV USB-RFID"
+ *   iProduct      = "USB-RFID Adapter"
  *
- * These are shortened strings should only visible directly after manufacture and before factory testing.
- * Factory tests will write more appropriate strings into the I2C EEPROM, which then override
- * these defaults.  If these strings are seen, then the adapter has not been properly tested at
- * the factory.
- *
+ * The Serial Number string will be reassigned to the 80-bit KL25Z unique ID
  *
  */
 #ifndef SV_USBConfig_h
@@ -23,13 +19,14 @@
 #define SV_VID      0x0425
 #define SV_PID      0x0415
 
+
 // Strings
-#define SV_MFG_CNT  0x06    // String length in UNICODE plus two bytes for the count (this value) and string type
-#define SV_MFG      'S',0,'V',0,' ',0,
-#define SV_SER_CNT  0x08
+#define SV_MFG_CNT  24      // String length in UNICODE plus two bytes for the count (this value) and string type
+#define SV_MFG      'S',0,'u',0,'p',0,'e',0,'r',0,'v',0,'i',0,'s',0,'i',0,'o',0,'n',0,
+#define SV_SER_CNT  8
 #define SV_SER      'S',0,'V',0,'1',0,
-#define SV_DES_CNT  0x18
-#define SV_DES      'S',0,'V',0,' ',0,'U',0,'S',0,'B',0,'-',0,'R',0,'F',0,'I',0,'D',0,
+#define SV_DES_CNT  34
+#define SV_DES      'U',0,'S',0,'B',0,'-',0,'R',0,'F',0,'I',0,'D',0,' ',0,'A',0,'d',0,'a',0,'p',0,'t',0,'e',0,'r',0,
 
 #endif
 // EOF SV_USBConfig.h
--- a/USBDevice.lib	Tue Jun 16 23:03:29 2015 +0000
+++ b/USBDevice.lib	Tue Jun 23 00:59:31 2015 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/teams/Super-Vision/code/USBDevice_for_Rev_C_HW/#20a8b5851253
+http://developer.mbed.org/teams/Super-Vision/code/USBDevice_for_Rev_C_HW/#c52294509471
--- a/main.cpp	Tue Jun 16 23:03:29 2015 +0000
+++ b/main.cpp	Tue Jun 23 00:59:31 2015 +0000
@@ -26,6 +26,8 @@
 
 // mbed.org headers
 #include "mbed.h"                       // main mbed.org libraries
+#include "iostream"
+#include "string"
 #include "USBDevice.h"
 #include "USBSerial.h"                  // USB CDC drivers
 #include "MODSERIAL.h"                  // UART drivers - MODSERIAL allows block writes compared to the mbed driver
@@ -59,6 +61,7 @@
 #define PROX                    (0x29 << 1) // default I2C address of VL6180X, shift into upper 7 bits
 #define EEPROM                  (0xA0)  // default I2C address of EEPROM, already shifted
 #define I2CRATE                 400000  // I2C speed
+#define I2CRATE1M               1000000 // EEPROM can run at 1Mbps
 
 // UART-RFID baud rate
 #define RFIDBAUD                115200  // RFID-FE board default rate = 115.2Kbps
@@ -112,6 +115,64 @@
 char des_str[0x3E] = {SV_DES};          // Default USB strings - Product Description
 char des_str_cnt = SV_DES_CNT;
 
+/**
+ * @name    get_id
+ * @brief   Reads KL25Z unique ID (80 bits) and converts it to a string for use as the USB Serial Number
+ *
+ * @param [out] char* id = USB Serial Number string
+ */
+void get_id(void)
+{
+    uint32_t val;
+    int i;
+    int len = 4;
+ 
+    val = SIM->UIDMH;
+    for (i = (2*len-2); i >= 0; i-=2){
+        char byte = (char)(val & 0xF);
+
+        if(byte < 0xA){
+            ser_str[i] = (char)(byte + '0');
+        }
+        else{
+            byte -= 0xA;
+            ser_str[i] = (char)(byte + 'A');
+        }
+        val >>= 4;
+    }
+    
+    val = SIM->UIDML;
+    for (i = (2*len-2); i >= 0; i-=2){
+        char byte = (char)(val & 0xF);
+
+        if(byte < 0xA){
+            ser_str[i+8] = (char)(byte + '0');
+        }
+        else{
+            byte -= 0xA;
+            ser_str[i+8] = (char)(byte + 'A');
+        }
+        val >>= 4;
+    }
+    
+    val = SIM->UIDL;
+    for (i = (2*len-2); i >= 0; i-=2){
+        char byte = (char)(val & 0xF);
+
+        if(byte < 0xA){
+            ser_str[i+16] = (char)(byte + '0');
+        }
+        else{
+            byte -= 0xA;
+            ser_str[i+16] = (char)(byte + 'A');
+        }
+        val >>= 4;
+    }
+
+}
+
+
+
 // These next functions are modified from the original USBDevice.cpp and USBCDC.cpp mbed drivers
 // in order to allow custom USB descriptor strings.
 
@@ -150,6 +211,11 @@
 
 uint8_t * USBDevice::stringIserialDesc() {
     static uint8_t stringIserialDescriptor[0x30];
+    
+    // Read KL25Z ID and set to USB serial number string
+    get_id();                                                   // Read the unique ID from the KL25Z
+    ser_str_cnt = 26;                                           // 12 bytes of ID *2 for Unicode, plus 2 to include the length and USB string type
+
     stringIserialDescriptor[0] = ser_str_cnt;
     stringIserialDescriptor[1] = STRING_DESCRIPTOR;
     for (int i = 0; i < sizeof(ser_str); i++){
@@ -232,55 +298,13 @@
     char prox_ee[254] = {0};                                        // buffer for Proximity initialization values stored
                                                                     // in EEPROM, especially the cover glass calibration
     // Set up peripherals on KL25Z
-
+    // Prox & EEPROM
     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.
-    // Address 0x10 holds Manufacturer string
-    // Address 0x40 holds Serial Number string
-    // Address 0x70 holds Product Description string
+    i2c.frequency(I2CRATE);                                         // I2C speed = 400Kbps
+    ee_wp.write(0);                                                 // no write protection on EEPROM
 
-    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)
 
@@ -447,6 +471,8 @@
 {
     int i2c_err;
     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.
+    while (i2c.write(PROX, 0, 0, 0));         // wait until write is done (PROX will ACK = 0 for single byte i2c.write)
+
     return i2c_err;                                                 // 0 = ACK received, 1 = NAK/failure
 }
 
@@ -649,7 +675,7 @@
         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)
+        while ( (i2c.write(EEPROM | (i2c_buffer[3] << 1 )), 0, 0, 0));         // 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
@@ -662,7 +688,7 @@
  *
  * 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).
+ * forwarded tjo 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.
  *
@@ -724,6 +750,8 @@
         cdc_buffer_rx[i] = 0x00;                                    // clear CDC tx buffer
     }    
 }
+
+
 /**
  * @name    main
  * @brief   Main firmware loop
--- a/mbed.bld	Tue Jun 16 23:03:29 2015 +0000
+++ b/mbed.bld	Tue Jun 23 00:59:31 2015 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/7cff1c4259d7
\ No newline at end of file