NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

Revision:
1:0c6bf23f2fc8
Parent:
0:529602524696
Child:
2:2812bcbcaaea
--- a/NeuroShield.cpp	Thu Aug 17 23:31:15 2017 +0000
+++ b/NeuroShield.cpp	Thu Jan 25 02:20:37 2018 +0000
@@ -31,6 +31,14 @@
  *
  */
 
+/*
+ * Revision History (v1.1.3)
+ * 2018/01/03    v1.1.3    Add burst-mode read
+ * 2017/12/20    v1.1.2    Modify the structure of neurondata
+ * 2017/12/11    v1.1.1    Add Powersave command and Minor changes to the library
+ * 2017/08/17    v1.0.0    First Release
+ */
+
 #include "mbed.h"
 #include <NeuroShield.h>
 #include <NeuroShieldSPI.h>
@@ -57,9 +65,15 @@
     else {
         countTotalNeurons();
         clearNeurons();
+        
+        uint16_t fpga_version = spi.version();
+        if ((fpga_version != 0x0001) && (fpga_version != 0x0002))
+            support_burst_read = 1;
+        else
+            support_burst_read = 0;
+        
+        return(total_neurons);
     }
-    
-    return(total_neurons);
 }
 
 // --------------------------------------------------------
@@ -68,11 +82,14 @@
 void NeuroShield::setNcr(uint16_t value)
 {
     spi.write(NM_NCR, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getNcr()
 {
-    return(spi.read(NM_NCR));
+    uint16_t ret_val = spi.read(NM_NCR);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -81,11 +98,14 @@
 void NeuroShield::setComp(uint8_t value)
 {
     spi.write(NM_COMP, (value & 0x00FF));
+    POWERSAVE;
 }
 
 uint8_t NeuroShield::getComp()
 {
-    return((uint8_t)(spi.read(NM_COMP) & 0x00FF));
+    uint8_t ret_val = (uint8_t)(spi.read(NM_COMP) & 0x00FF);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -94,6 +114,7 @@
 void NeuroShield::setLastComp(uint8_t value)
 {
     spi.write(NM_LCOMP, (value & 0x00FF));
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
@@ -102,6 +123,7 @@
 void NeuroShield::setIndexComp(uint16_t value)
 {
     spi.write(NM_INDEXCOMP, value);
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
@@ -109,7 +131,9 @@
 //---------------------------------------------------------
 uint16_t NeuroShield::getDist()
 {
-    return(spi.read(NM_DIST));
+    uint16_t ret_val = spi.read(NM_DIST);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -118,11 +142,14 @@
 void NeuroShield::setCat(uint16_t value)
 {
     spi.write(NM_CAT, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getCat()
 {
-    return(spi.read(NM_CAT));
+    uint16_t ret_val = spi.read(NM_CAT);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -131,11 +158,14 @@
 void NeuroShield::setAif(uint16_t value)
 {
     spi.write(NM_AIF, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getAif()
 {
-    return(spi.read(NM_AIF));
+    uint16_t ret_val = spi.read(NM_AIF);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -144,11 +174,14 @@
 void NeuroShield::setMinif(uint16_t value)
 {
     spi.write(NM_MINIF, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getMinif()
 {
-    return(spi.read(NM_MINIF));
+    uint16_t ret_val = spi.read(NM_MINIF);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -157,11 +190,14 @@
 void NeuroShield::setMaxif(uint16_t value)
 {
     spi.write(NM_MAXIF, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getMaxif()
 {
-    return(spi.read(NM_MAXIF));
+    uint16_t ret_val = spi.read(NM_MAXIF);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -169,7 +205,9 @@
 //---------------------------------------------------------
 uint16_t NeuroShield::getNid()
 {
-    return(spi.read(NM_NID));
+    uint16_t ret_val = spi.read(NM_NID);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -181,11 +219,14 @@
     // GCR[7]= Norm (0 for L1; 1 for LSup)
     // GCR[6-0]= Active context value
     spi.write(NM_GCR, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getGcr()
 {
-    return(spi.read(NM_GCR));
+    uint16_t ret_val = spi.read(NM_GCR);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -194,6 +235,7 @@
 void NeuroShield::resetChain()
 {
     spi.write(NM_RSTCHAIN, 0);
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
@@ -206,11 +248,14 @@
 void NeuroShield::setNsr(uint16_t value)
 {
     spi.write(NM_NSR, value);
+    POWERSAVE;
 }
 
 uint16_t NeuroShield::getNsr()
 {
-    return(spi.read(NM_NSR));
+    uint16_t ret_val = spi.read(NM_NSR);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -218,7 +263,9 @@
 //---------------------------------------------------------
 uint16_t NeuroShield::getNcount()
 {
-    return(spi.read(NM_NCOUNT));
+    uint16_t ret_val = spi.read(NM_NCOUNT);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // --------------------------------------------------------
@@ -227,6 +274,7 @@
 void NeuroShield::setPowerSave()
 {
     spi.write(NM_POWERSAVE, 1);
+    POWERSAVE;
 }
 
 // ------------------------------------------------------------ 
@@ -236,6 +284,7 @@
 void NeuroShield::forget()
 {
     spi.write(NM_FORGET, 0);
+    POWERSAVE;
 }
 
 // ------------------------------------------------------------ 
@@ -246,6 +295,7 @@
 {
     spi.write(NM_FORGET, 0);
     spi.write(NM_MAXIF, maxif);
+    POWERSAVE;
 }
 
 // ------------------------------------------------------------ 
@@ -269,6 +319,7 @@
     }
     spi.write(NM_NSR, 0x0000);
     spi.write(NM_FORGET, 0);
+    POWERSAVE;
 }
 
 // --------------------------------------------------------------
@@ -280,10 +331,14 @@
 {
     spi.write(NM_FORGET, 0);
     spi.write(NM_NSR, 0x0010);
-    for (int i = 0; i < NEURON_SIZE; i++)
+    spi.write(NM_TESTCAT, 1);
+    spi.write(NM_NSR, 0x0000);
+    for (int i = 0; i < NEURON_SIZE; i++) {
+        spi.write(NM_INDEXCOMP, i);
         spi.write(NM_TESTCOMP, 0);
-    spi.write(NM_RSTCHAIN, 0);
-    spi.write(NM_NSR, 0x0000);
+    }
+    spi.write(NM_FORGET, 0);
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
@@ -292,10 +347,12 @@
 //---------------------------------------------------------
 uint16_t NeuroShield::broadcast(uint8_t vector[], uint16_t length)
 {
-    spi.writeVector(NM_COMP, vector, (length - 1));
+    uint16_t ret_val;
+    spi.writeVector(vector, (length - 1));
     spi.write(NM_LCOMP, vector[length - 1]);
-    
-    return(spi.read(NM_NSR));
+    ret_val = spi.read(NM_NSR);
+    POWERSAVE;
+    return(ret_val);
 }
 
 //-----------------------------------------------
@@ -303,9 +360,12 @@
 //----------------------------------------------
 uint16_t NeuroShield::learn(uint8_t vector[], uint16_t length, uint16_t category)
 {
+    uint16_t ret_val;
     broadcast(vector, length);
     spi.write(NM_CAT, category);
-    return(spi.read(NM_NCOUNT));
+    ret_val = spi.read(NM_NCOUNT);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // ---------------------------------------------------------
@@ -316,8 +376,11 @@
 // ---------------------------------------------------------
 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length)
 {
+    uint16_t ret_val;
     broadcast(vector, length);
-    return(spi.read(NM_NSR));
+    ret_val = spi.read(NM_NSR);
+    POWERSAVE;
+    return(ret_val);
 }
 
 //----------------------------------------------
@@ -326,11 +389,14 @@
 //----------------------------------------------
 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length, uint16_t* distance, uint16_t* category, uint16_t* nid)
 {
+    uint16_t ret_val;
     broadcast(vector, length);
     *distance = spi.read(NM_DIST);
     *category = spi.read(NM_CAT);
     *nid = spi.read(NM_NID);
-    return(spi.read(NM_NSR));
+    ret_val = spi.read(NM_NSR);
+    POWERSAVE;
+    return(ret_val);
 }
 
 //----------------------------------------------
@@ -356,6 +422,7 @@
             nid[i] = spi.read(NM_NID);
         }
     }
+    POWERSAVE;
     return(recog_nbr);
 }
 
@@ -370,6 +437,7 @@
     uint16_t read_val = spi.read(NM_GCR);
     read_val = (read_val & 0xFF80) | (context & 0x007F);
     spi.write(NM_GCR, read_val);
+    POWERSAVE;
 }
 
 // ------------------------------------------------------------ 
@@ -385,6 +453,7 @@
     spi.write(NM_GCR, read_val);
     spi.write(NM_MINIF, minif);
     spi.write(NM_MAXIF, maxif);
+    POWERSAVE;
 }
 
 // ------------------------------------------------------------ 
@@ -398,6 +467,7 @@
     *context = (uint8_t)(spi.read(NM_GCR) & 0x007F);
     *minif = spi.read(NM_MINIF);
     *maxif = spi.read(NM_MAXIF);
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
@@ -407,6 +477,7 @@
 {
     uint16_t temp_nsr = spi.read(NM_NSR);
     spi.write(NM_NSR, (temp_nsr & 0x00DF));
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
@@ -416,161 +487,188 @@
 {
     uint16_t temp_nsr = spi.read(NM_NSR);
     spi.write(NM_NSR, (temp_nsr | 0x0020));
+    POWERSAVE;
 }
 
 //-------------------------------------------------------------
 // Read the contents of the neuron pointed by index in the chain of neurons
-// starting at index 0
+// starting at index 1
 //-------------------------------------------------------------
-void NeuroShield::readNeuron(uint16_t nid, uint8_t model[], uint16_t* ncr, uint16_t* aif, uint16_t* cat)
+void NeuroShield::readNeuron(uint16_t nid, uint16_t model[], uint16_t* ncr, uint16_t* aif, uint16_t* cat)
 {
+    if (nid == 0) {
+        *ncr = 0xFFFF;
+        *aif = 0xFFFF;
+        *cat = 0xFFFF;
+        return;
+    }
+    
     uint16_t temp_nsr = spi.read(NM_NSR);
     spi.write(NM_NSR, 0x0010);
     spi.write(NM_RSTCHAIN, 0);
-    if (nid > 0) {
+    if (nid > 1) {
         // move to index in the chain of neurons
-        for (int i = 0; i < nid; i++)
+        for (int i = 1; i < nid; i++)
             spi.read(NM_CAT);
     }
     
     *ncr = spi.read(NM_NCR);
-    for (int i = 0; i < NEURON_SIZE; i++)
-        model[i] = spi.read(NM_COMP);
+    if (support_burst_read == 1) {
+        spi.readVector16(model, NEURON_SIZE);
+    }
+    else {
+        for (int i = 0; i < NEURON_SIZE; i++)
+            model[i] = spi.read(NM_COMP);
+    }
     *aif = spi.read(NM_AIF);
     *cat = spi.read(NM_CAT);
-    spi.write(NM_NSR, temp_nsr);     // set the NN back to its calling status
+    spi.write(NM_NSR, temp_nsr);        // set the NN back to its calling status
+    POWERSAVE;
 }
 
 //-------------------------------------------------------------
 // Read the contents of the neuron pointed by index in the chain of neurons
-// starting index is 0
-// Returns an array of NEURONSIZE bytes with the following format
-// 2-bytes NCR, NEURONSIZE-bytes COMP, 2-bytes AIF, 2-bytes MINIF, 2-bytes CAT
+// starting index is 1
+// Returns an array of (NEURON_SIZE + 4) words with the following format
+// NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
 //-------------------------------------------------------------
-void NeuroShield::readNeuron(uint16_t nid, uint8_t neuron[])
+void NeuroShield::readNeuron(uint16_t nid, uint16_t neuron[])
 {
+    if (nid == 0) {
+        for (int i = 0; i < (NEURON_SIZE + 4); i++) {
+            neuron[i] = 0xFFFF;
+        }
+        return;
+    }
+    
     uint16_t temp_nsr = spi.read(NM_NSR);
     spi.write(NM_NSR, 0x0010);
     spi.write(NM_RSTCHAIN, 0);
-    if (nid > 0) {
+    if (nid > 1) {
         // move to index in the chain of neurons
-        for (int i = 0; i < nid; i++)
+        for (int i = 1; i < nid; i++)
             spi.read(NM_CAT);
     }
-    uint16_t read_val = spi.read(NM_NCR);
-    neuron[0] = (uint8_t)((read_val >> 8) & 0x00FF);
-    neuron[1] = (uint8_t)(read_val & 0x00FF);
-    for (int i = 0; i < NEURON_SIZE; i++)
-        neuron[i + 2] = spi.read(NM_COMP);
-    read_val = spi.read(NM_AIF);
-    neuron[NEURON_SIZE + 2] = (uint8_t)((read_val >> 8) & 0x00FF);
-    neuron[NEURON_SIZE + 3] = (uint8_t)(read_val & 0x00FF);
-    read_val = spi.read(NM_MINIF);
-    neuron[NEURON_SIZE + 4] = (uint8_t)((read_val >> 8) & 0x00FF);
-    neuron[NEURON_SIZE + 5] = (uint8_t)(read_val & 0x00FF);
-    read_val = spi.read(NM_CAT);
-    neuron[NEURON_SIZE + 6] = (uint8_t)((read_val >> 8) & 0x00FF);
-    neuron[NEURON_SIZE + 7] = (uint8_t)(read_val & 0x00FF);
-    spi.write(NM_NSR, temp_nsr);     // set the NN back to its calling status
+    
+    neuron[0] = spi.read(NM_NCR);
+    if (support_burst_read == 1) {
+        spi.readVector16(&neuron[1], NEURON_SIZE);
+    }
+    else {
+        for (int i = 0; i < NEURON_SIZE; i++)
+            neuron[i + 1] = spi.read(NM_COMP);
+    }
+    neuron[NEURON_SIZE + 1] = spi.read(NM_AIF);
+    neuron[NEURON_SIZE + 2] = spi.read(NM_MINIF);
+    neuron[NEURON_SIZE + 3] = spi.read(NM_CAT);
+    spi.write(NM_NSR, temp_nsr);        // set the NN back to its calling status
+    POWERSAVE;
 }
 
 //----------------------------------------------------------------------------
-// Read the contents of the committed neurons and output in a generic format compatible with
-// all NeuroMem chips regardless of their neuron size and capacity
-// The neurons array should be sized to HEADERSIZE + MAXNEURON * (NEURONSIZE + 8)
-// Default header size of 8 bytes: headerSize, reserved, 2-bytes MaxLength, 4-bytes neuronCount
-// followed by neuroCount record of (MaxLength + 8) bytes: 
-// 2-bytes NCR, MaxLength-bytes COMP, 2-bytes AIF, 2-bytes MINIF, 2-bytes CAT
+// Read the contents of the committed neurons
+// The output array has a dimension ncount * neurondata
+// neurondata describes the content of a neuron and has a dimension (NEURON_SIZE + 4) words
+// and with the following format NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
 //----------------------------------------------------------------------------
-uint16_t NeuroShield::readNeurons(uint8_t neurons[])
+uint16_t NeuroShield::readNeurons(uint16_t neurons[])
 {
-    uint32_t offset = 8;
-    
+    uint32_t offset = 0;
     uint16_t ncount = spi.read(NM_NCOUNT);
-    uint16_t temp_nsr = spi.read(NM_NSR);     // save value to restore NN status upon exit
+    uint16_t temp_nsr = spi.read(NM_NSR);       // save value to restore NN status upon exit
     spi.write(NM_NSR, 0x0010);
     spi.write(NM_RSTCHAIN, 0);
-    neurons[0] = offset;                // default header size of 8 bytes
-    neurons[1] = 0;                     // reserved to encode a future format identifier
-    neurons[2] = 0x01;
-    neurons[3] = 0x00;
-    neurons[4] = 0;
-    neurons[5] = 0;
-    neurons[6] = ((ncount >> 8) & 0x00FF);
-    neurons[7] = (ncount & 0x00FF);
     for (int i = 0; i < ncount; i++) {
-        uint16_t read_val = spi.read(NM_NCR);
-        neurons[offset] = (uint8_t)((read_val >> 8) & 0x00FF);
-        neurons[offset + 1] = (uint8_t)(read_val & 0x00FF);
-        for (int j = 0; j < NEURON_SIZE; j++) {
-            read_val = spi.read(NM_COMP);
-            neurons[offset + 2 + j] = (uint8_t)(read_val & 0x00FF);
+        neurons[offset + 0] = spi.read(NM_NCR);
+        if (support_burst_read == 1) {
+            spi.readVector16(&neurons[offset + 1], NEURON_SIZE);
         }
-        read_val = spi.read(NM_AIF);
-        neurons[offset + NEURON_SIZE + 2] = (uint8_t)((read_val >> 8) & 0x00FF);
-        neurons[offset + NEURON_SIZE + 3] = (uint8_t)(read_val & 0x00FF);
-        read_val = spi.read(NM_MINIF);
-        neurons[offset + NEURON_SIZE + 4] = (uint8_t)((read_val >> 8) & 0x00FF);
-        neurons[offset + NEURON_SIZE + 5] = (uint8_t)(read_val & 0x00FF);
-        read_val = spi.read(NM_CAT);
-        neurons[offset + NEURON_SIZE + 6] = (uint8_t)((read_val >> 8) & 0x00FF);
-        neurons[offset + NEURON_SIZE + 7] = (uint8_t)(read_val & 0x00FF);
-        offset += (NEURON_SIZE + 8);
+        else {
+            for (int j = 0; j < NEURON_SIZE; j++) {
+                neurons[offset + 1 + j] = spi.read(NM_COMP);
+            }
+        }
+        neurons[offset + 1 + NEURON_SIZE] = spi.read(NM_AIF);
+        neurons[offset + 2 + NEURON_SIZE] = spi.read(NM_MINIF);
+        neurons[offset + 3 + NEURON_SIZE] = spi.read(NM_CAT);
+        offset += (NEURON_SIZE + 4);
     }
-    spi.write(NM_NSR, temp_nsr);         // set the NN back to its calling status
+    spi.write(NM_NSR, temp_nsr);                // set the NN back to its calling status
+    POWERSAVE;
     return(ncount);
 }
 
+void NeuroShield::readCompVector(uint16_t* data, uint16_t size)
+{
+    if (support_burst_read == 1) {
+        spi.readVector16(data, size);
+    }
+    else {
+        for (int i = 0; i < size; i++) {
+            *data = spi.read(NM_COMP);
+            data++;
+        }
+    }
+}
+
 //---------------------------------------------------------------------
-// Clear the committed neurons and restore a new content for the neurons
-// from an input array formatted as follows
-// Default header size of 8 bytes: headerSize, reserved, 2-bytes MaxLength, 4-bytes neuronCount
-// followed by neuroCount record of (MaxLength + 8) bytes: 
-// 2-bytes NCR, MaxLength-bytes COMP, 2-bytes AIF, 2-bytes MINIF, 2-bytes CAT
+// Clear the neurons and write their content from an input array
+// The input array has a dimension ncount * neurondata
+// neurondata describes the content of a neuron and has a dimension (NEURON_SIZE + 4) words
+// and with the following format NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
 //---------------------------------------------------------------------
-uint16_t NeuroShield::writeNeurons(uint8_t neurons[])
+void NeuroShield::writeNeurons(uint16_t neurons[], uint16_t ncount)
 {
-    uint32_t offset = neurons[0];
-    uint16_t ncount = (neurons[6] << 8) + neurons[7];
+    uint32_t offset = 0;
     if (ncount > total_neurons)
         ncount = total_neurons;
-    uint16_t temp_nsr = spi.read(NM_NSR);     // save value to restore NN status upon exit
+    uint16_t temp_nsr = spi.read(NM_NSR);       // save value to restore NN status upon exit
     uint16_t temp_gcr = spi.read(NM_GCR);
-    spi.write(NM_FORGET, 0);
+    clearNeurons();
     spi.write(NM_NSR, 0x0010);
     spi.write(NM_RSTCHAIN, 0);
     for (int i = 0; i < ncount; i++) {
-        spi.write(NM_NCR, neurons[offset + 1]);
-        for (int j = 0; j < NEURON_SIZE; j++)
-            spi.write(NM_COMP, neurons[offset + 2 + j]);
-        spi.write(NM_AIF, (neurons[offset + NEURON_SIZE + 2] << 8) + neurons[offset + NEURON_SIZE + 3]);
-        spi.write(NM_MINIF, (neurons[offset + NEURON_SIZE + 4] << 8) + neurons[offset + NEURON_SIZE + 5]);
-        spi.write(NM_CAT, (neurons[offset + NEURON_SIZE + 6] << 8) + neurons[offset + NEURON_SIZE + 7]);
-        offset += (NEURON_SIZE + 8);
+        spi.write(NM_NCR, neurons[offset + 0]);
+        spi.writeVector16(&neurons[offset + 1], NEURON_SIZE);
+        spi.write(NM_AIF, neurons[offset + 1 + NEURON_SIZE]);
+        spi.write(NM_MINIF, neurons[offset + 2 + NEURON_SIZE]);
+        spi.write(NM_CAT, neurons[offset + 3 + NEURON_SIZE]);
+        offset += (NEURON_SIZE + 4);
     }
-    spi.write(NM_NSR, temp_nsr);         // set the NN back to its calling status
+    spi.write(NM_NSR, temp_nsr);                // set the NN back to its calling status
     spi.write(NM_GCR, temp_gcr);
-    return(spi.read(NM_NCOUNT));
+    POWERSAVE;
 }
 
 // --------------------------------------------------------
-// just for TEST, must be modified
+// Write N-component
+//---------------------------------------------------------
+void NeuroShield::writeCompVector(uint16_t* data, uint16_t size)
+{
+    spi.writeVector16(data, size);
+}
+
+// --------------------------------------------------------
+// Get/Set the NM500 register value
 //---------------------------------------------------------
 uint16_t NeuroShield::testCommand(uint8_t read_write, uint8_t reg, uint16_t data)
 {
+    uint16_t ret_val = 0;
     if (read_write == 0) {
-        return(spi.read(reg));
+        ret_val = spi.read(reg);
     }
     else if (read_write == 1) {
         spi.write(reg, data);
-        return(0);
     }
-    
-    return(0);
+    POWERSAVE;
+    return(ret_val);
 }
 
 // ----------------------------------------------------------------
 // Get FPGA Version
+// [15:8] board type : 00 = NeuroShield, 01 = Prodigy ...
+// [ 7:4] board version
+// [ 3:0] fpga version
 // ----------------------------------------------------------------
 uint16_t NeuroShield::fpgaVersion()
 {
@@ -591,28 +689,4 @@
 void NeuroShield::ledSelect(uint8_t data)
 {
     spi.ledSelect(data);
-}
-
-// ----------------------------------------------------------------
-// Display committed neurons information
-// ----------------------------------------------------------------
-void NeuroShield::displayNeurons(uint16_t length)
-{
-    // display the neurons
-    uint16_t ncount = spi.read(NM_NCOUNT);
-    printf("\n  Committed neurons = %u", ncount);
-    
-    spi.write(NM_NSR, 0x0010);
-    spi.write(NM_RSTCHAIN, 0);
-    
-    for (int i = 0; i < ncount; i++) {
-        printf("\n  NeuronID = %u \tComponents=", (i + 1));
-        for (int j = 0; j < length; j++) {
-            printf("%u, " , spi.read(NM_COMP));
-        }
-        printf("\tAIF = %u, ", spi.read(NM_AIF));
-        printf("\tCAT = %u, ", spi.read(NM_CAT));
-    }
-    
-    spi.write(NM_NSR, 0x0000);
 }
\ No newline at end of file