NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NeuroShield.cpp Source File

NeuroShield.cpp

00001 /*
00002  * NeuroShield.cpp - Driver for NeuroShield
00003  * Copyright (c) 2016, General Vision Inc, All rights reserved
00004  * Copyright (c) 2017, nepes inc, All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright notice,
00010  * this list of conditions and the following disclaimer.
00011  *
00012  * 2. Redistributions in binary form must reproduce the above copyright notice,
00013  * this list of conditions and the following disclaimer in the documentation
00014  * and/or other materials provided with the distribution.
00015  *
00016  * 3. Neither the name of the copyright holder nor the names of its contributors
00017  * may be used to endorse or promote products derived from this software without
00018  * specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00021  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00024  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00025  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00026  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00029  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030  * POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  */
00033 
00034 /*
00035  * Revision History (v1.1.5)
00036  * 2020/02/04    v1.1.5    Add dummy for switching between sd-card and nm spi
00037  * 2018/06/22    v1.1.4    Minor changes
00038  * 2018/01/03    v1.1.3    Add burst-mode read
00039  * 2017/12/20    v1.1.2    Modify the structure of neurondata
00040  * 2017/12/11    v1.1.1    Add Powersave command and Minor changes to the library
00041  * 2017/08/17    v1.0.0    First Release
00042  */
00043 
00044 #include "mbed.h"
00045 #include <NeuroShield.h>
00046 #include <NeuroShieldSPI.h>
00047 
00048 NeuroShieldSPI spi;
00049 
00050 // ------------------------------------------------------------ //
00051 //    Constructor to the class NeuroShield
00052 // ------------------------------------------------------------
00053 NeuroShield::NeuroShield() {
00054 }
00055 
00056 // ------------------------------------------------------------ 
00057 // Initialize the neural network
00058 // 0: fail,  other: success(return total_neurons)
00059 // ------------------------------------------------------------
00060 uint16_t NeuroShield::begin()
00061 {
00062     bool read_val = spi.connect();
00063     
00064     if (read_val != 1) {
00065         return(0);
00066     }
00067     else {
00068         countTotalNeurons();
00069         clearNeurons();
00070         
00071         uint16_t fpga_version = spi.version();
00072         if ((fpga_version != 0x0001) && (fpga_version != 0x0002))
00073             support_burst_read = 1;
00074         else
00075             support_burst_read = 0;
00076         
00077         return(total_neurons);
00078     }
00079 }
00080 
00081 // --------------------------------------------------------
00082 // Get/Set the Neuron Context Register
00083 //---------------------------------------------------------
00084 void NeuroShield::setNcr(uint16_t value)
00085 {
00086     spi.write(NM_NCR, value);
00087     POWERSAVE;
00088 }
00089 
00090 uint16_t NeuroShield::getNcr()
00091 {
00092     uint16_t ret_val = spi.read(NM_NCR);
00093     POWERSAVE;
00094     return(ret_val);
00095 }
00096 
00097 // --------------------------------------------------------
00098 // Get/Set the COMP register (component)
00099 //---------------------------------------------------------
00100 void NeuroShield::setComp(uint8_t value)
00101 {
00102     spi.write(NM_COMP, (value & 0x00FF));
00103     POWERSAVE;
00104 }
00105 
00106 uint8_t NeuroShield::getComp()
00107 {
00108     uint8_t ret_val = (uint8_t)(spi.read(NM_COMP) & 0x00FF);
00109     POWERSAVE;
00110     return(ret_val);
00111 }
00112 
00113 // --------------------------------------------------------
00114 // Set the LCOMP register (last component)
00115 //---------------------------------------------------------
00116 void NeuroShield::setLastComp(uint8_t value)
00117 {
00118     spi.write(NM_LCOMP, (value & 0x00FF));
00119     POWERSAVE;
00120 }
00121 
00122 // --------------------------------------------------------
00123 // Set the Component Index register
00124 //---------------------------------------------------------
00125 void NeuroShield::setIndexComp(uint16_t value)
00126 {
00127     spi.write(NM_INDEXCOMP, value);
00128     POWERSAVE;
00129 }
00130 
00131 // --------------------------------------------------------
00132 // Get the Distance register
00133 //---------------------------------------------------------
00134 uint16_t NeuroShield::getDist()
00135 {
00136     uint16_t ret_val = spi.read(NM_DIST);
00137     POWERSAVE;
00138     return(ret_val);
00139 }
00140 
00141 // --------------------------------------------------------
00142 // Get/Set the Category register
00143 //---------------------------------------------------------
00144 void NeuroShield::setCat(uint16_t value)
00145 {
00146     spi.write(NM_CAT, value);
00147     POWERSAVE;
00148 }
00149 
00150 uint16_t NeuroShield::getCat()
00151 {
00152     uint16_t ret_val = spi.read(NM_CAT);
00153     POWERSAVE;
00154     return(ret_val);
00155 }
00156 
00157 // --------------------------------------------------------
00158 // Get/Set the AIF register
00159 //---------------------------------------------------------
00160 void NeuroShield::setAif(uint16_t value)
00161 {
00162     spi.write(NM_AIF, value);
00163     POWERSAVE;
00164 }
00165 
00166 uint16_t NeuroShield::getAif()
00167 {
00168     uint16_t ret_val = spi.read(NM_AIF);
00169     POWERSAVE;
00170     return(ret_val);
00171 }
00172 
00173 // --------------------------------------------------------
00174 // Get/Set the Minimum Influence Field register
00175 //---------------------------------------------------------
00176 void NeuroShield::setMinif(uint16_t value)
00177 {
00178     spi.write(NM_MINIF, value);
00179     POWERSAVE;
00180 }
00181 
00182 uint16_t NeuroShield::getMinif()
00183 {
00184     uint16_t ret_val = spi.read(NM_MINIF);
00185     POWERSAVE;
00186     return(ret_val);
00187 }
00188 
00189 // --------------------------------------------------------
00190 // Get/Set the Maximum Influence Field register
00191 //---------------------------------------------------------
00192 void NeuroShield::setMaxif(uint16_t value)
00193 {
00194     spi.write(NM_MAXIF, value);
00195     POWERSAVE;
00196 }
00197 
00198 uint16_t NeuroShield::getMaxif()
00199 {
00200     uint16_t ret_val = spi.read(NM_MAXIF);
00201     POWERSAVE;
00202     return(ret_val);
00203 }
00204 
00205 // --------------------------------------------------------
00206 // Get the Neuron Identifier
00207 //---------------------------------------------------------
00208 uint16_t NeuroShield::getNid()
00209 {
00210     uint16_t ret_val = spi.read(NM_NID);
00211     POWERSAVE;
00212     return(ret_val);
00213 }
00214 
00215 // --------------------------------------------------------
00216 // Get/Set the Global Context register
00217 //---------------------------------------------------------
00218 void NeuroShield::setGcr(uint16_t value)
00219 {
00220     // GCR[15-8]= unused
00221     // GCR[7]= Norm (0 for L1; 1 for LSup)
00222     // GCR[6-0]= Active context value
00223     spi.write(NM_GCR, value);
00224     POWERSAVE;
00225 }
00226 
00227 uint16_t NeuroShield::getGcr()
00228 {
00229     uint16_t ret_val = spi.read(NM_GCR);
00230     POWERSAVE;
00231     return(ret_val);
00232 }
00233 
00234 // --------------------------------------------------------
00235 // Reset the chain to first neuron in SR Mode
00236 //---------------------------------------------------------
00237 void NeuroShield::resetChain()
00238 {
00239     spi.write(NM_RSTCHAIN, 0);
00240     POWERSAVE;
00241 }
00242 
00243 // --------------------------------------------------------
00244 // Get/Set the Network Status register
00245 // bit 2 = UNC (read only)
00246 // bit 3 = ID (read only)
00247 // bit 4 = SR mode
00248 // bit 5 = KNN mode
00249 //---------------------------------------------------------
00250 void NeuroShield::setNsr(uint16_t value)
00251 {
00252     spi.write(NM_NSR, value);
00253     POWERSAVE;
00254 }
00255 
00256 uint16_t NeuroShield::getNsr()
00257 {
00258     uint16_t ret_val = spi.read(NM_NSR);
00259     POWERSAVE;
00260     return(ret_val);
00261 }
00262 
00263 // --------------------------------------------------------
00264 // Read the number of committed neurons
00265 //---------------------------------------------------------
00266 uint16_t NeuroShield::getNcount()
00267 {
00268     uint16_t ret_val = spi.read(NM_NCOUNT);
00269     POWERSAVE;
00270     return(ret_val);
00271 }
00272 
00273 // --------------------------------------------------------
00274 // Set the PowerSave mode
00275 //---------------------------------------------------------
00276 void NeuroShield::setPowerSave()
00277 {
00278     spi.write(NM_POWERSAVE, 1);
00279     POWERSAVE;
00280 }
00281 
00282 // ------------------------------------------------------------ 
00283 // Un-commit all the neurons, so they become ready to learn
00284 // Reset the Maximum Influence Field to default value=0x4000
00285 // ------------------------------------------------------------ 
00286 void NeuroShield::forget()
00287 {
00288     spi.write(NM_FORGET, 0);
00289     POWERSAVE;
00290 }
00291 
00292 // ------------------------------------------------------------ 
00293 // Un-commit all the neurons, so they become ready to learn,
00294 // Set the Maximum Influence Field (default value=0x4000)
00295 // ------------------------------------------------------------ 
00296 void NeuroShield::forget(uint16_t maxif)
00297 {
00298     spi.write(NM_FORGET, 0);
00299     spi.write(NM_MAXIF, maxif);
00300     POWERSAVE;
00301 }
00302 
00303 // ------------------------------------------------------------ 
00304 // Count total neurons in SR-mode
00305 // ------------------------------------------------------------ 
00306 void NeuroShield::countTotalNeurons()
00307 {
00308     uint16_t read_cat;
00309     
00310     spi.write(NM_FORGET, 0);
00311     spi.write(NM_NSR, 0x0010);
00312     spi.write(NM_TESTCAT, 0x0001);
00313     spi.write(NM_RSTCHAIN, 0);
00314     
00315     total_neurons = 0;
00316     while (1) {
00317         read_cat = spi.read(NM_CAT);
00318         if (read_cat == 0xFFFF)
00319             break;
00320         total_neurons++;
00321     }
00322     spi.write(NM_NSR, 0x0000);
00323     spi.write(NM_FORGET, 0);
00324     POWERSAVE;
00325 }
00326 
00327 // --------------------------------------------------------------
00328 // Un-commit all the neurons, so they become ready to learn,
00329 // Set the Maximum Influence Field (default value=0x4000)
00330 // Clear the memory of the neurons
00331 // --------------------------------------------------------------
00332 void NeuroShield::clearNeurons()
00333 {
00334     spi.write(NM_FORGET, 0);
00335     spi.write(NM_NSR, 0x0010);
00336     spi.write(NM_TESTCAT, 1);
00337     spi.write(NM_NSR, 0x0000);
00338     for (int i = 0; i < NEURON_SIZE; i++) {
00339         spi.write(NM_INDEXCOMP, i);
00340         spi.write(NM_TESTCOMP, 0);
00341     }
00342     spi.write(NM_FORGET, 0);
00343     POWERSAVE;
00344 }
00345 
00346 // --------------------------------------------------------
00347 // Broadcast a vector to the neurons and return the recognition status
00348 // 0= unknown, 4=uncertain, 8=Identified
00349 //---------------------------------------------------------
00350 uint16_t NeuroShield::broadcast(uint8_t vector[], uint16_t length)
00351 {
00352     uint16_t ret_val;
00353     spi.writeVector(vector, (length - 1));
00354     spi.write(NM_LCOMP, vector[length - 1]);
00355     ret_val = spi.read(NM_NSR);
00356     POWERSAVE;
00357     return(ret_val);
00358 }
00359 
00360 //-----------------------------------------------
00361 // Learn a vector using the current context value
00362 //----------------------------------------------
00363 uint16_t NeuroShield::learn(uint8_t vector[], uint16_t length, uint16_t category)
00364 {
00365     uint16_t ret_val;
00366     broadcast(vector, length);
00367     spi.write(NM_CAT, category);
00368     ret_val = spi.read(NM_NCOUNT);
00369     POWERSAVE;
00370     return(ret_val);
00371 }
00372 
00373 // ---------------------------------------------------------
00374 // Classify a vector and return its classification status
00375 // NSR=0, unknown
00376 // NSR=8, identified
00377 // NSR=4, uncertain
00378 // ---------------------------------------------------------
00379 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length)
00380 {
00381     uint16_t ret_val;
00382     broadcast(vector, length);
00383     ret_val = spi.read(NM_NSR);
00384     POWERSAVE;
00385     return(ret_val);
00386 }
00387 
00388 //----------------------------------------------
00389 // Recognize a vector and return the best match, or the 
00390 // category, distance and identifier of the top firing neuron
00391 //----------------------------------------------
00392 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length, uint16_t* distance, uint16_t* category, uint16_t* nid)
00393 {
00394     uint16_t ret_val;
00395     broadcast(vector, length);
00396     *distance = spi.read(NM_DIST);
00397     *category = spi.read(NM_CAT);
00398     *nid = spi.read(NM_NID);
00399     ret_val = spi.read(NM_NSR);
00400     POWERSAVE;
00401     return(ret_val);
00402 }
00403 
00404 //----------------------------------------------
00405 // Recognize a vector and return the response  of up to K top firing neurons
00406 // The response includes the distance, category and identifier of the neuron
00407 // The Degenerated flag of the category is masked rmask the degenerated response, use the current context value
00408 // Return the number of firing neurons or K whichever is smaller
00409 //----------------------------------------------
00410 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length, uint16_t k, uint16_t distance[], uint16_t category[], uint16_t nid[])
00411 {
00412     uint16_t recog_nbr = 0;
00413     
00414     broadcast(vector, length);
00415     for (int i = 0; i < k; i++) {
00416         distance[i] = spi.read(NM_DIST);
00417         if (distance[i] == 0xFFFF) {
00418             category[i] = 0xFFFF;
00419             nid[i] = 0xFFFF;
00420         }
00421         else {
00422             recog_nbr++;
00423             category[i] = spi.read(NM_CAT);
00424             nid[i] = spi.read(NM_NID);
00425         }
00426     }
00427     POWERSAVE;
00428     return(recog_nbr);
00429 }
00430 
00431 // ------------------------------------------------------------ 
00432 // Set a context and associated minimum and maximum influence fields
00433 // ------------------------------------------------------------ 
00434 void NeuroShield::setContext(uint8_t context)
00435 {
00436     // context[15-8]= unused
00437     // context[7]= Norm (0 for L1; 1 for LSup)
00438     // context[6-0]= Active context value
00439     uint16_t read_val = spi.read(NM_GCR);
00440     read_val = (read_val & 0xFF80) | (context & 0x007F);
00441     spi.write(NM_GCR, read_val);
00442     POWERSAVE;
00443 }
00444 
00445 // ------------------------------------------------------------ 
00446 // Set a context and associated minimum and maximum influence fields
00447 // ------------------------------------------------------------ 
00448 void NeuroShield::setContext(uint8_t context, uint16_t minif, uint16_t maxif)
00449 {
00450     // context[15-8]= unused
00451     // context[7]= Norm (0 for L1; 1 for LSup)
00452     // context[6-0]= Active context value
00453     uint16_t read_val = spi.read(NM_GCR);
00454     read_val = (read_val & 0xFF80) | (context & 0x007F);
00455     spi.write(NM_GCR, read_val);
00456     spi.write(NM_MINIF, minif);
00457     spi.write(NM_MAXIF, maxif);
00458     POWERSAVE;
00459 }
00460 
00461 // ------------------------------------------------------------ 
00462 // Get a context and associated minimum and maximum influence fields
00463 // ------------------------------------------------------------ 
00464 void NeuroShield::getContext(uint8_t* context, uint16_t* minif, uint16_t* maxif)
00465 {
00466     // context[15-8]= unused
00467     // context[7]= Norm (0 for L1; 1 for LSup)
00468     // context[6-0]= Active context value
00469     *context = (uint8_t)(spi.read(NM_GCR) & 0x007F);
00470     *minif = spi.read(NM_MINIF);
00471     *maxif = spi.read(NM_MAXIF);
00472     POWERSAVE;
00473 }
00474 
00475 // --------------------------------------------------------
00476 // Set the neurons in Radial Basis Function mode (default)
00477 //---------------------------------------------------------
00478 void NeuroShield::setRbfClassifier()
00479 {
00480     uint16_t temp_nsr = spi.read(NM_NSR);
00481     spi.write(NM_NSR, (temp_nsr & 0x00DF));
00482     POWERSAVE;
00483 }
00484 
00485 // --------------------------------------------------------
00486 // Set the neurons in K-Nearest Neighbor mode
00487 //---------------------------------------------------------
00488 void NeuroShield::setKnnClassifier()
00489 {
00490     uint16_t temp_nsr = spi.read(NM_NSR);
00491     spi.write(NM_NSR, (temp_nsr | 0x0020));
00492     POWERSAVE;
00493 }
00494 
00495 //-------------------------------------------------------------
00496 // Read the contents of the neuron pointed by index in the chain of neurons
00497 // starting at index 1
00498 //-------------------------------------------------------------
00499 void NeuroShield::readNeuron(uint16_t nid, uint16_t model[], uint16_t* ncr, uint16_t* aif, uint16_t* cat)
00500 {
00501     if (nid == 0) {
00502         *ncr = 0xFFFF;
00503         *aif = 0xFFFF;
00504         *cat = 0xFFFF;
00505         return;
00506     }
00507     
00508     uint16_t temp_nsr = spi.read(NM_NSR);
00509     spi.write(NM_NSR, 0x0010);
00510     spi.write(NM_RSTCHAIN, 0);
00511     if (nid > 1) {
00512         // move to index in the chain of neurons
00513         for (int i = 1; i < nid; i++)
00514             spi.read(NM_CAT);
00515     }
00516     
00517     *ncr = spi.read(NM_NCR);
00518     if (support_burst_read == 1) {
00519         spi.readVector16(model, NEURON_SIZE);
00520     }
00521     else {
00522         for (int i = 0; i < NEURON_SIZE; i++)
00523             model[i] = spi.read(NM_COMP);
00524     }
00525     *aif = spi.read(NM_AIF);
00526     *cat = spi.read(NM_CAT);
00527     spi.write(NM_NSR, temp_nsr);        // set the NN back to its calling status
00528     POWERSAVE;
00529 }
00530 
00531 //-------------------------------------------------------------
00532 // Read the contents of the neuron pointed by index in the chain of neurons
00533 // starting index is 1
00534 // Returns an array of (NEURON_SIZE + 4) words with the following format
00535 // NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
00536 //-------------------------------------------------------------
00537 void NeuroShield::readNeuron(uint16_t nid, uint16_t neuron[])
00538 {
00539     if (nid == 0) {
00540         for (int i = 0; i < (NEURON_SIZE + 4); i++) {
00541             neuron[i] = 0xFFFF;
00542         }
00543         return;
00544     }
00545     
00546     uint16_t temp_nsr = spi.read(NM_NSR);
00547     spi.write(NM_NSR, 0x0010);
00548     spi.write(NM_RSTCHAIN, 0);
00549     if (nid > 1) {
00550         // move to index in the chain of neurons
00551         for (int i = 1; i < nid; i++)
00552             spi.read(NM_CAT);
00553     }
00554     
00555     neuron[0] = spi.read(NM_NCR);
00556     if (support_burst_read == 1) {
00557         spi.readVector16(&neuron[1], NEURON_SIZE);
00558     }
00559     else {
00560         for (int i = 0; i < NEURON_SIZE; i++)
00561             neuron[i + 1] = spi.read(NM_COMP);
00562     }
00563     neuron[NEURON_SIZE + 1] = spi.read(NM_AIF);
00564     neuron[NEURON_SIZE + 2] = spi.read(NM_MINIF);
00565     neuron[NEURON_SIZE + 3] = spi.read(NM_CAT);
00566     spi.write(NM_NSR, temp_nsr);        // set the NN back to its calling status
00567     POWERSAVE;
00568 }
00569 
00570 //----------------------------------------------------------------------------
00571 // Read the contents of the committed neurons
00572 // The output array has a dimension ncount * neurondata
00573 // neurondata describes the content of a neuron and has a dimension (NEURON_SIZE + 4) words
00574 // and with the following format NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
00575 //----------------------------------------------------------------------------
00576 uint16_t NeuroShield::readNeurons(uint16_t neurons[])
00577 {
00578     uint32_t offset = 0;
00579     uint16_t ncount = spi.read(NM_NCOUNT);
00580     uint16_t temp_nsr = spi.read(NM_NSR);       // save value to restore NN status upon exit
00581     spi.write(NM_NSR, 0x0010);
00582     spi.write(NM_RSTCHAIN, 0);
00583     for (int i = 0; i < ncount; i++) {
00584         neurons[offset + 0] = spi.read(NM_NCR);
00585         if (support_burst_read == 1) {
00586             spi.readVector16(&neurons[offset + 1], NEURON_SIZE);
00587         }
00588         else {
00589             for (int j = 0; j < NEURON_SIZE; j++) {
00590                 neurons[offset + 1 + j] = spi.read(NM_COMP);
00591             }
00592         }
00593         neurons[offset + 1 + NEURON_SIZE] = spi.read(NM_AIF);
00594         neurons[offset + 2 + NEURON_SIZE] = spi.read(NM_MINIF);
00595         neurons[offset + 3 + NEURON_SIZE] = spi.read(NM_CAT);
00596         offset += (NEURON_SIZE + 4);
00597     }
00598     spi.write(NM_NSR, temp_nsr);                // set the NN back to its calling status
00599     POWERSAVE;
00600     return(ncount);
00601 }
00602 
00603 void NeuroShield::readCompVector(uint16_t* data, uint16_t size)
00604 {
00605     if (support_burst_read == 1) {
00606         spi.readVector16(data, size);
00607     }
00608     else {
00609         for (int i = 0; i < size; i++) {
00610             *data = spi.read(NM_COMP);
00611             data++;
00612         }
00613     }
00614     POWERSAVE;
00615 }
00616 
00617 //---------------------------------------------------------------------
00618 // Clear the neurons and write their content from an input array
00619 // The input array has a dimension ncount * neurondata
00620 // neurondata describes the content of a neuron and has a dimension (NEURON_SIZE + 4) words
00621 // and with the following format NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
00622 //---------------------------------------------------------------------
00623 void NeuroShield::writeNeurons(uint16_t neurons[], uint16_t ncount)
00624 {
00625     uint32_t offset = 0;
00626     if (ncount > total_neurons)
00627         ncount = total_neurons;
00628     uint16_t temp_nsr = spi.read(NM_NSR);       // save value to restore NN status upon exit
00629     uint16_t temp_gcr = spi.read(NM_GCR);
00630     clearNeurons();
00631     spi.write(NM_NSR, 0x0010);
00632     spi.write(NM_RSTCHAIN, 0);
00633     for (int i = 0; i < ncount; i++) {
00634         spi.write(NM_NCR, neurons[offset + 0]);
00635         spi.writeVector16(&neurons[offset + 1], NEURON_SIZE);
00636         spi.write(NM_AIF, neurons[offset + 1 + NEURON_SIZE]);
00637         spi.write(NM_MINIF, neurons[offset + 2 + NEURON_SIZE]);
00638         spi.write(NM_CAT, neurons[offset + 3 + NEURON_SIZE]);
00639         offset += (NEURON_SIZE + 4);
00640     }
00641     spi.write(NM_NSR, temp_nsr);                // set the NN back to its calling status
00642     spi.write(NM_GCR, temp_gcr);
00643     POWERSAVE;
00644 }
00645 
00646 // --------------------------------------------------------
00647 // Write N-component
00648 //---------------------------------------------------------
00649 void NeuroShield::writeCompVector(uint16_t* data, uint16_t size)
00650 {
00651     spi.writeVector16(data, size);
00652     POWERSAVE;
00653 }
00654 
00655 // --------------------------------------------------------
00656 // Get/Set the NM500 register value
00657 //---------------------------------------------------------
00658 uint16_t NeuroShield::testCommand(uint8_t read_write, uint8_t reg, uint16_t data)
00659 {
00660     uint16_t ret_val = 0;
00661     if (read_write == 0) {
00662         ret_val = spi.read(reg);
00663     }
00664     else if (read_write == 1) {
00665         spi.write(reg, data);
00666     }
00667     POWERSAVE;
00668     return(ret_val);
00669 }
00670 
00671 // ----------------------------------------------------------------
00672 // Get FPGA Version
00673 // [15:8] board type : 00 = NeuroShield, 01 = Prodigy ...
00674 // [ 7:4] board version
00675 // [ 3:0] fpga version
00676 // ----------------------------------------------------------------
00677 uint16_t NeuroShield::fpgaVersion()
00678 {
00679     return(spi.version());
00680 }
00681 
00682 // ----------------------------------------------------------------
00683 // Excute NM500 SW Reset
00684 // ----------------------------------------------------------------
00685 void NeuroShield::nm500Reset()
00686 {
00687     spi.reset();
00688 }
00689 
00690 // ----------------------------------------------------------------
00691 // Select LED Scenario
00692 // ----------------------------------------------------------------
00693 void NeuroShield::ledSelect(uint8_t data)
00694 {
00695     spi.ledSelect(data);
00696 }