NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

Committer:
nepes_ai
Date:
Fri Jun 22 06:17:56 2018 +0000
Revision:
2:2812bcbcaaea
Parent:
1:0c6bf23f2fc8
Child:
3:6163399b611e
Release version 1.1.4

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nepes_ai 0:529602524696 1 /*
nepes_ai 0:529602524696 2 * NeuroShield.cpp - Driver for NeuroShield
nepes_ai 0:529602524696 3 * Copyright (c) 2016, General Vision Inc, All rights reserved
nepes_ai 0:529602524696 4 * Copyright (c) 2017, nepes inc, All rights reserved.
nepes_ai 0:529602524696 5 *
nepes_ai 0:529602524696 6 * Redistribution and use in source and binary forms, with or without
nepes_ai 0:529602524696 7 * modification, are permitted provided that the following conditions are met:
nepes_ai 0:529602524696 8 *
nepes_ai 0:529602524696 9 * 1. Redistributions of source code must retain the above copyright notice,
nepes_ai 0:529602524696 10 * this list of conditions and the following disclaimer.
nepes_ai 0:529602524696 11 *
nepes_ai 0:529602524696 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
nepes_ai 0:529602524696 13 * this list of conditions and the following disclaimer in the documentation
nepes_ai 0:529602524696 14 * and/or other materials provided with the distribution.
nepes_ai 0:529602524696 15 *
nepes_ai 0:529602524696 16 * 3. Neither the name of the copyright holder nor the names of its contributors
nepes_ai 0:529602524696 17 * may be used to endorse or promote products derived from this software without
nepes_ai 0:529602524696 18 * specific prior written permission.
nepes_ai 0:529602524696 19 *
nepes_ai 0:529602524696 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
nepes_ai 0:529602524696 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
nepes_ai 0:529602524696 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
nepes_ai 0:529602524696 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
nepes_ai 0:529602524696 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
nepes_ai 0:529602524696 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
nepes_ai 0:529602524696 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
nepes_ai 0:529602524696 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
nepes_ai 0:529602524696 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
nepes_ai 0:529602524696 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
nepes_ai 0:529602524696 30 * POSSIBILITY OF SUCH DAMAGE.
nepes_ai 0:529602524696 31 *
nepes_ai 0:529602524696 32 */
nepes_ai 0:529602524696 33
nepes_ai 1:0c6bf23f2fc8 34 /*
nepes_ai 2:2812bcbcaaea 35 * Revision History (v1.1.4)
nepes_ai 2:2812bcbcaaea 36 * 2018/06/22 v1.1.4 Minor changes
nepes_ai 1:0c6bf23f2fc8 37 * 2018/01/03 v1.1.3 Add burst-mode read
nepes_ai 1:0c6bf23f2fc8 38 * 2017/12/20 v1.1.2 Modify the structure of neurondata
nepes_ai 1:0c6bf23f2fc8 39 * 2017/12/11 v1.1.1 Add Powersave command and Minor changes to the library
nepes_ai 1:0c6bf23f2fc8 40 * 2017/08/17 v1.0.0 First Release
nepes_ai 1:0c6bf23f2fc8 41 */
nepes_ai 1:0c6bf23f2fc8 42
nepes_ai 0:529602524696 43 #include "mbed.h"
nepes_ai 0:529602524696 44 #include <NeuroShield.h>
nepes_ai 0:529602524696 45 #include <NeuroShieldSPI.h>
nepes_ai 0:529602524696 46
nepes_ai 0:529602524696 47 NeuroShieldSPI spi;
nepes_ai 0:529602524696 48
nepes_ai 0:529602524696 49 // ------------------------------------------------------------ //
nepes_ai 0:529602524696 50 // Constructor to the class NeuroShield
nepes_ai 0:529602524696 51 // ------------------------------------------------------------
nepes_ai 0:529602524696 52 NeuroShield::NeuroShield() {
nepes_ai 0:529602524696 53 }
nepes_ai 0:529602524696 54
nepes_ai 0:529602524696 55 // ------------------------------------------------------------
nepes_ai 0:529602524696 56 // Initialize the neural network
nepes_ai 0:529602524696 57 // 0: fail, other: success(return total_neurons)
nepes_ai 0:529602524696 58 // ------------------------------------------------------------
nepes_ai 0:529602524696 59 uint16_t NeuroShield::begin()
nepes_ai 0:529602524696 60 {
nepes_ai 0:529602524696 61 bool read_val = spi.connect();
nepes_ai 0:529602524696 62
nepes_ai 0:529602524696 63 if (read_val != 1) {
nepes_ai 0:529602524696 64 return(0);
nepes_ai 0:529602524696 65 }
nepes_ai 0:529602524696 66 else {
nepes_ai 0:529602524696 67 countTotalNeurons();
nepes_ai 0:529602524696 68 clearNeurons();
nepes_ai 1:0c6bf23f2fc8 69
nepes_ai 1:0c6bf23f2fc8 70 uint16_t fpga_version = spi.version();
nepes_ai 1:0c6bf23f2fc8 71 if ((fpga_version != 0x0001) && (fpga_version != 0x0002))
nepes_ai 1:0c6bf23f2fc8 72 support_burst_read = 1;
nepes_ai 1:0c6bf23f2fc8 73 else
nepes_ai 1:0c6bf23f2fc8 74 support_burst_read = 0;
nepes_ai 1:0c6bf23f2fc8 75
nepes_ai 1:0c6bf23f2fc8 76 return(total_neurons);
nepes_ai 0:529602524696 77 }
nepes_ai 0:529602524696 78 }
nepes_ai 0:529602524696 79
nepes_ai 0:529602524696 80 // --------------------------------------------------------
nepes_ai 0:529602524696 81 // Get/Set the Neuron Context Register
nepes_ai 0:529602524696 82 //---------------------------------------------------------
nepes_ai 0:529602524696 83 void NeuroShield::setNcr(uint16_t value)
nepes_ai 0:529602524696 84 {
nepes_ai 0:529602524696 85 spi.write(NM_NCR, value);
nepes_ai 1:0c6bf23f2fc8 86 POWERSAVE;
nepes_ai 0:529602524696 87 }
nepes_ai 0:529602524696 88
nepes_ai 0:529602524696 89 uint16_t NeuroShield::getNcr()
nepes_ai 0:529602524696 90 {
nepes_ai 1:0c6bf23f2fc8 91 uint16_t ret_val = spi.read(NM_NCR);
nepes_ai 1:0c6bf23f2fc8 92 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 93 return(ret_val);
nepes_ai 0:529602524696 94 }
nepes_ai 0:529602524696 95
nepes_ai 0:529602524696 96 // --------------------------------------------------------
nepes_ai 0:529602524696 97 // Get/Set the COMP register (component)
nepes_ai 0:529602524696 98 //---------------------------------------------------------
nepes_ai 0:529602524696 99 void NeuroShield::setComp(uint8_t value)
nepes_ai 0:529602524696 100 {
nepes_ai 0:529602524696 101 spi.write(NM_COMP, (value & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 102 POWERSAVE;
nepes_ai 0:529602524696 103 }
nepes_ai 0:529602524696 104
nepes_ai 0:529602524696 105 uint8_t NeuroShield::getComp()
nepes_ai 0:529602524696 106 {
nepes_ai 1:0c6bf23f2fc8 107 uint8_t ret_val = (uint8_t)(spi.read(NM_COMP) & 0x00FF);
nepes_ai 1:0c6bf23f2fc8 108 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 109 return(ret_val);
nepes_ai 0:529602524696 110 }
nepes_ai 0:529602524696 111
nepes_ai 0:529602524696 112 // --------------------------------------------------------
nepes_ai 0:529602524696 113 // Set the LCOMP register (last component)
nepes_ai 0:529602524696 114 //---------------------------------------------------------
nepes_ai 0:529602524696 115 void NeuroShield::setLastComp(uint8_t value)
nepes_ai 0:529602524696 116 {
nepes_ai 0:529602524696 117 spi.write(NM_LCOMP, (value & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 118 POWERSAVE;
nepes_ai 0:529602524696 119 }
nepes_ai 0:529602524696 120
nepes_ai 0:529602524696 121 // --------------------------------------------------------
nepes_ai 0:529602524696 122 // Set the Component Index register
nepes_ai 0:529602524696 123 //---------------------------------------------------------
nepes_ai 0:529602524696 124 void NeuroShield::setIndexComp(uint16_t value)
nepes_ai 0:529602524696 125 {
nepes_ai 0:529602524696 126 spi.write(NM_INDEXCOMP, value);
nepes_ai 1:0c6bf23f2fc8 127 POWERSAVE;
nepes_ai 0:529602524696 128 }
nepes_ai 0:529602524696 129
nepes_ai 0:529602524696 130 // --------------------------------------------------------
nepes_ai 0:529602524696 131 // Get the Distance register
nepes_ai 0:529602524696 132 //---------------------------------------------------------
nepes_ai 0:529602524696 133 uint16_t NeuroShield::getDist()
nepes_ai 0:529602524696 134 {
nepes_ai 1:0c6bf23f2fc8 135 uint16_t ret_val = spi.read(NM_DIST);
nepes_ai 1:0c6bf23f2fc8 136 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 137 return(ret_val);
nepes_ai 0:529602524696 138 }
nepes_ai 0:529602524696 139
nepes_ai 0:529602524696 140 // --------------------------------------------------------
nepes_ai 0:529602524696 141 // Get/Set the Category register
nepes_ai 0:529602524696 142 //---------------------------------------------------------
nepes_ai 0:529602524696 143 void NeuroShield::setCat(uint16_t value)
nepes_ai 0:529602524696 144 {
nepes_ai 0:529602524696 145 spi.write(NM_CAT, value);
nepes_ai 1:0c6bf23f2fc8 146 POWERSAVE;
nepes_ai 0:529602524696 147 }
nepes_ai 0:529602524696 148
nepes_ai 0:529602524696 149 uint16_t NeuroShield::getCat()
nepes_ai 0:529602524696 150 {
nepes_ai 1:0c6bf23f2fc8 151 uint16_t ret_val = spi.read(NM_CAT);
nepes_ai 1:0c6bf23f2fc8 152 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 153 return(ret_val);
nepes_ai 0:529602524696 154 }
nepes_ai 0:529602524696 155
nepes_ai 0:529602524696 156 // --------------------------------------------------------
nepes_ai 0:529602524696 157 // Get/Set the AIF register
nepes_ai 0:529602524696 158 //---------------------------------------------------------
nepes_ai 0:529602524696 159 void NeuroShield::setAif(uint16_t value)
nepes_ai 0:529602524696 160 {
nepes_ai 0:529602524696 161 spi.write(NM_AIF, value);
nepes_ai 1:0c6bf23f2fc8 162 POWERSAVE;
nepes_ai 0:529602524696 163 }
nepes_ai 0:529602524696 164
nepes_ai 0:529602524696 165 uint16_t NeuroShield::getAif()
nepes_ai 0:529602524696 166 {
nepes_ai 1:0c6bf23f2fc8 167 uint16_t ret_val = spi.read(NM_AIF);
nepes_ai 1:0c6bf23f2fc8 168 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 169 return(ret_val);
nepes_ai 0:529602524696 170 }
nepes_ai 0:529602524696 171
nepes_ai 0:529602524696 172 // --------------------------------------------------------
nepes_ai 0:529602524696 173 // Get/Set the Minimum Influence Field register
nepes_ai 0:529602524696 174 //---------------------------------------------------------
nepes_ai 0:529602524696 175 void NeuroShield::setMinif(uint16_t value)
nepes_ai 0:529602524696 176 {
nepes_ai 0:529602524696 177 spi.write(NM_MINIF, value);
nepes_ai 1:0c6bf23f2fc8 178 POWERSAVE;
nepes_ai 0:529602524696 179 }
nepes_ai 0:529602524696 180
nepes_ai 0:529602524696 181 uint16_t NeuroShield::getMinif()
nepes_ai 0:529602524696 182 {
nepes_ai 1:0c6bf23f2fc8 183 uint16_t ret_val = spi.read(NM_MINIF);
nepes_ai 1:0c6bf23f2fc8 184 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 185 return(ret_val);
nepes_ai 0:529602524696 186 }
nepes_ai 0:529602524696 187
nepes_ai 0:529602524696 188 // --------------------------------------------------------
nepes_ai 0:529602524696 189 // Get/Set the Maximum Influence Field register
nepes_ai 0:529602524696 190 //---------------------------------------------------------
nepes_ai 0:529602524696 191 void NeuroShield::setMaxif(uint16_t value)
nepes_ai 0:529602524696 192 {
nepes_ai 0:529602524696 193 spi.write(NM_MAXIF, value);
nepes_ai 1:0c6bf23f2fc8 194 POWERSAVE;
nepes_ai 0:529602524696 195 }
nepes_ai 0:529602524696 196
nepes_ai 0:529602524696 197 uint16_t NeuroShield::getMaxif()
nepes_ai 0:529602524696 198 {
nepes_ai 1:0c6bf23f2fc8 199 uint16_t ret_val = spi.read(NM_MAXIF);
nepes_ai 1:0c6bf23f2fc8 200 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 201 return(ret_val);
nepes_ai 0:529602524696 202 }
nepes_ai 0:529602524696 203
nepes_ai 0:529602524696 204 // --------------------------------------------------------
nepes_ai 0:529602524696 205 // Get the Neuron Identifier
nepes_ai 0:529602524696 206 //---------------------------------------------------------
nepes_ai 0:529602524696 207 uint16_t NeuroShield::getNid()
nepes_ai 0:529602524696 208 {
nepes_ai 1:0c6bf23f2fc8 209 uint16_t ret_val = spi.read(NM_NID);
nepes_ai 1:0c6bf23f2fc8 210 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 211 return(ret_val);
nepes_ai 0:529602524696 212 }
nepes_ai 0:529602524696 213
nepes_ai 0:529602524696 214 // --------------------------------------------------------
nepes_ai 0:529602524696 215 // Get/Set the Global Context register
nepes_ai 0:529602524696 216 //---------------------------------------------------------
nepes_ai 0:529602524696 217 void NeuroShield::setGcr(uint16_t value)
nepes_ai 0:529602524696 218 {
nepes_ai 0:529602524696 219 // GCR[15-8]= unused
nepes_ai 0:529602524696 220 // GCR[7]= Norm (0 for L1; 1 for LSup)
nepes_ai 0:529602524696 221 // GCR[6-0]= Active context value
nepes_ai 0:529602524696 222 spi.write(NM_GCR, value);
nepes_ai 1:0c6bf23f2fc8 223 POWERSAVE;
nepes_ai 0:529602524696 224 }
nepes_ai 0:529602524696 225
nepes_ai 0:529602524696 226 uint16_t NeuroShield::getGcr()
nepes_ai 0:529602524696 227 {
nepes_ai 1:0c6bf23f2fc8 228 uint16_t ret_val = spi.read(NM_GCR);
nepes_ai 1:0c6bf23f2fc8 229 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 230 return(ret_val);
nepes_ai 0:529602524696 231 }
nepes_ai 0:529602524696 232
nepes_ai 0:529602524696 233 // --------------------------------------------------------
nepes_ai 0:529602524696 234 // Reset the chain to first neuron in SR Mode
nepes_ai 0:529602524696 235 //---------------------------------------------------------
nepes_ai 0:529602524696 236 void NeuroShield::resetChain()
nepes_ai 0:529602524696 237 {
nepes_ai 0:529602524696 238 spi.write(NM_RSTCHAIN, 0);
nepes_ai 1:0c6bf23f2fc8 239 POWERSAVE;
nepes_ai 0:529602524696 240 }
nepes_ai 0:529602524696 241
nepes_ai 0:529602524696 242 // --------------------------------------------------------
nepes_ai 0:529602524696 243 // Get/Set the Network Status register
nepes_ai 0:529602524696 244 // bit 2 = UNC (read only)
nepes_ai 0:529602524696 245 // bit 3 = ID (read only)
nepes_ai 0:529602524696 246 // bit 4 = SR mode
nepes_ai 0:529602524696 247 // bit 5 = KNN mode
nepes_ai 0:529602524696 248 //---------------------------------------------------------
nepes_ai 0:529602524696 249 void NeuroShield::setNsr(uint16_t value)
nepes_ai 0:529602524696 250 {
nepes_ai 0:529602524696 251 spi.write(NM_NSR, value);
nepes_ai 1:0c6bf23f2fc8 252 POWERSAVE;
nepes_ai 0:529602524696 253 }
nepes_ai 0:529602524696 254
nepes_ai 0:529602524696 255 uint16_t NeuroShield::getNsr()
nepes_ai 0:529602524696 256 {
nepes_ai 1:0c6bf23f2fc8 257 uint16_t ret_val = spi.read(NM_NSR);
nepes_ai 1:0c6bf23f2fc8 258 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 259 return(ret_val);
nepes_ai 0:529602524696 260 }
nepes_ai 0:529602524696 261
nepes_ai 0:529602524696 262 // --------------------------------------------------------
nepes_ai 0:529602524696 263 // Read the number of committed neurons
nepes_ai 0:529602524696 264 //---------------------------------------------------------
nepes_ai 0:529602524696 265 uint16_t NeuroShield::getNcount()
nepes_ai 0:529602524696 266 {
nepes_ai 1:0c6bf23f2fc8 267 uint16_t ret_val = spi.read(NM_NCOUNT);
nepes_ai 1:0c6bf23f2fc8 268 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 269 return(ret_val);
nepes_ai 0:529602524696 270 }
nepes_ai 0:529602524696 271
nepes_ai 0:529602524696 272 // --------------------------------------------------------
nepes_ai 0:529602524696 273 // Set the PowerSave mode
nepes_ai 0:529602524696 274 //---------------------------------------------------------
nepes_ai 0:529602524696 275 void NeuroShield::setPowerSave()
nepes_ai 0:529602524696 276 {
nepes_ai 0:529602524696 277 spi.write(NM_POWERSAVE, 1);
nepes_ai 1:0c6bf23f2fc8 278 POWERSAVE;
nepes_ai 0:529602524696 279 }
nepes_ai 0:529602524696 280
nepes_ai 0:529602524696 281 // ------------------------------------------------------------
nepes_ai 0:529602524696 282 // Un-commit all the neurons, so they become ready to learn
nepes_ai 0:529602524696 283 // Reset the Maximum Influence Field to default value=0x4000
nepes_ai 0:529602524696 284 // ------------------------------------------------------------
nepes_ai 0:529602524696 285 void NeuroShield::forget()
nepes_ai 0:529602524696 286 {
nepes_ai 0:529602524696 287 spi.write(NM_FORGET, 0);
nepes_ai 1:0c6bf23f2fc8 288 POWERSAVE;
nepes_ai 0:529602524696 289 }
nepes_ai 0:529602524696 290
nepes_ai 0:529602524696 291 // ------------------------------------------------------------
nepes_ai 0:529602524696 292 // Un-commit all the neurons, so they become ready to learn,
nepes_ai 0:529602524696 293 // Set the Maximum Influence Field (default value=0x4000)
nepes_ai 0:529602524696 294 // ------------------------------------------------------------
nepes_ai 0:529602524696 295 void NeuroShield::forget(uint16_t maxif)
nepes_ai 0:529602524696 296 {
nepes_ai 0:529602524696 297 spi.write(NM_FORGET, 0);
nepes_ai 0:529602524696 298 spi.write(NM_MAXIF, maxif);
nepes_ai 1:0c6bf23f2fc8 299 POWERSAVE;
nepes_ai 0:529602524696 300 }
nepes_ai 0:529602524696 301
nepes_ai 0:529602524696 302 // ------------------------------------------------------------
nepes_ai 0:529602524696 303 // Count total neurons in SR-mode
nepes_ai 0:529602524696 304 // ------------------------------------------------------------
nepes_ai 0:529602524696 305 void NeuroShield::countTotalNeurons()
nepes_ai 0:529602524696 306 {
nepes_ai 0:529602524696 307 uint16_t read_cat;
nepes_ai 0:529602524696 308
nepes_ai 0:529602524696 309 spi.write(NM_FORGET, 0);
nepes_ai 0:529602524696 310 spi.write(NM_NSR, 0x0010);
nepes_ai 0:529602524696 311 spi.write(NM_TESTCAT, 0x0001);
nepes_ai 0:529602524696 312 spi.write(NM_RSTCHAIN, 0);
nepes_ai 0:529602524696 313
nepes_ai 0:529602524696 314 total_neurons = 0;
nepes_ai 0:529602524696 315 while (1) {
nepes_ai 0:529602524696 316 read_cat = spi.read(NM_CAT);
nepes_ai 0:529602524696 317 if (read_cat == 0xFFFF)
nepes_ai 0:529602524696 318 break;
nepes_ai 0:529602524696 319 total_neurons++;
nepes_ai 0:529602524696 320 }
nepes_ai 0:529602524696 321 spi.write(NM_NSR, 0x0000);
nepes_ai 0:529602524696 322 spi.write(NM_FORGET, 0);
nepes_ai 1:0c6bf23f2fc8 323 POWERSAVE;
nepes_ai 0:529602524696 324 }
nepes_ai 0:529602524696 325
nepes_ai 0:529602524696 326 // --------------------------------------------------------------
nepes_ai 0:529602524696 327 // Un-commit all the neurons, so they become ready to learn,
nepes_ai 0:529602524696 328 // Set the Maximum Influence Field (default value=0x4000)
nepes_ai 0:529602524696 329 // Clear the memory of the neurons
nepes_ai 0:529602524696 330 // --------------------------------------------------------------
nepes_ai 0:529602524696 331 void NeuroShield::clearNeurons()
nepes_ai 0:529602524696 332 {
nepes_ai 0:529602524696 333 spi.write(NM_FORGET, 0);
nepes_ai 0:529602524696 334 spi.write(NM_NSR, 0x0010);
nepes_ai 1:0c6bf23f2fc8 335 spi.write(NM_TESTCAT, 1);
nepes_ai 1:0c6bf23f2fc8 336 spi.write(NM_NSR, 0x0000);
nepes_ai 1:0c6bf23f2fc8 337 for (int i = 0; i < NEURON_SIZE; i++) {
nepes_ai 1:0c6bf23f2fc8 338 spi.write(NM_INDEXCOMP, i);
nepes_ai 0:529602524696 339 spi.write(NM_TESTCOMP, 0);
nepes_ai 1:0c6bf23f2fc8 340 }
nepes_ai 1:0c6bf23f2fc8 341 spi.write(NM_FORGET, 0);
nepes_ai 1:0c6bf23f2fc8 342 POWERSAVE;
nepes_ai 0:529602524696 343 }
nepes_ai 0:529602524696 344
nepes_ai 0:529602524696 345 // --------------------------------------------------------
nepes_ai 0:529602524696 346 // Broadcast a vector to the neurons and return the recognition status
nepes_ai 0:529602524696 347 // 0= unknown, 4=uncertain, 8=Identified
nepes_ai 0:529602524696 348 //---------------------------------------------------------
nepes_ai 0:529602524696 349 uint16_t NeuroShield::broadcast(uint8_t vector[], uint16_t length)
nepes_ai 0:529602524696 350 {
nepes_ai 1:0c6bf23f2fc8 351 uint16_t ret_val;
nepes_ai 1:0c6bf23f2fc8 352 spi.writeVector(vector, (length - 1));
nepes_ai 0:529602524696 353 spi.write(NM_LCOMP, vector[length - 1]);
nepes_ai 1:0c6bf23f2fc8 354 ret_val = spi.read(NM_NSR);
nepes_ai 1:0c6bf23f2fc8 355 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 356 return(ret_val);
nepes_ai 0:529602524696 357 }
nepes_ai 0:529602524696 358
nepes_ai 0:529602524696 359 //-----------------------------------------------
nepes_ai 0:529602524696 360 // Learn a vector using the current context value
nepes_ai 0:529602524696 361 //----------------------------------------------
nepes_ai 0:529602524696 362 uint16_t NeuroShield::learn(uint8_t vector[], uint16_t length, uint16_t category)
nepes_ai 0:529602524696 363 {
nepes_ai 1:0c6bf23f2fc8 364 uint16_t ret_val;
nepes_ai 0:529602524696 365 broadcast(vector, length);
nepes_ai 0:529602524696 366 spi.write(NM_CAT, category);
nepes_ai 1:0c6bf23f2fc8 367 ret_val = spi.read(NM_NCOUNT);
nepes_ai 1:0c6bf23f2fc8 368 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 369 return(ret_val);
nepes_ai 0:529602524696 370 }
nepes_ai 0:529602524696 371
nepes_ai 0:529602524696 372 // ---------------------------------------------------------
nepes_ai 0:529602524696 373 // Classify a vector and return its classification status
nepes_ai 0:529602524696 374 // NSR=0, unknown
nepes_ai 0:529602524696 375 // NSR=8, identified
nepes_ai 0:529602524696 376 // NSR=4, uncertain
nepes_ai 0:529602524696 377 // ---------------------------------------------------------
nepes_ai 0:529602524696 378 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length)
nepes_ai 0:529602524696 379 {
nepes_ai 1:0c6bf23f2fc8 380 uint16_t ret_val;
nepes_ai 0:529602524696 381 broadcast(vector, length);
nepes_ai 1:0c6bf23f2fc8 382 ret_val = spi.read(NM_NSR);
nepes_ai 1:0c6bf23f2fc8 383 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 384 return(ret_val);
nepes_ai 0:529602524696 385 }
nepes_ai 0:529602524696 386
nepes_ai 0:529602524696 387 //----------------------------------------------
nepes_ai 0:529602524696 388 // Recognize a vector and return the best match, or the
nepes_ai 0:529602524696 389 // category, distance and identifier of the top firing neuron
nepes_ai 0:529602524696 390 //----------------------------------------------
nepes_ai 0:529602524696 391 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length, uint16_t* distance, uint16_t* category, uint16_t* nid)
nepes_ai 0:529602524696 392 {
nepes_ai 1:0c6bf23f2fc8 393 uint16_t ret_val;
nepes_ai 0:529602524696 394 broadcast(vector, length);
nepes_ai 0:529602524696 395 *distance = spi.read(NM_DIST);
nepes_ai 0:529602524696 396 *category = spi.read(NM_CAT);
nepes_ai 0:529602524696 397 *nid = spi.read(NM_NID);
nepes_ai 1:0c6bf23f2fc8 398 ret_val = spi.read(NM_NSR);
nepes_ai 1:0c6bf23f2fc8 399 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 400 return(ret_val);
nepes_ai 0:529602524696 401 }
nepes_ai 0:529602524696 402
nepes_ai 0:529602524696 403 //----------------------------------------------
nepes_ai 0:529602524696 404 // Recognize a vector and return the response of up to K top firing neurons
nepes_ai 0:529602524696 405 // The response includes the distance, category and identifier of the neuron
nepes_ai 0:529602524696 406 // The Degenerated flag of the category is masked rmask the degenerated response, use the current context value
nepes_ai 0:529602524696 407 // Return the number of firing neurons or K whichever is smaller
nepes_ai 0:529602524696 408 //----------------------------------------------
nepes_ai 0:529602524696 409 uint16_t NeuroShield::classify(uint8_t vector[], uint16_t length, uint16_t k, uint16_t distance[], uint16_t category[], uint16_t nid[])
nepes_ai 0:529602524696 410 {
nepes_ai 0:529602524696 411 uint16_t recog_nbr = 0;
nepes_ai 0:529602524696 412
nepes_ai 0:529602524696 413 broadcast(vector, length);
nepes_ai 0:529602524696 414 for (int i = 0; i < k; i++) {
nepes_ai 0:529602524696 415 distance[i] = spi.read(NM_DIST);
nepes_ai 0:529602524696 416 if (distance[i] == 0xFFFF) {
nepes_ai 0:529602524696 417 category[i] = 0xFFFF;
nepes_ai 0:529602524696 418 nid[i] = 0xFFFF;
nepes_ai 0:529602524696 419 }
nepes_ai 0:529602524696 420 else {
nepes_ai 0:529602524696 421 recog_nbr++;
nepes_ai 0:529602524696 422 category[i] = spi.read(NM_CAT);
nepes_ai 0:529602524696 423 nid[i] = spi.read(NM_NID);
nepes_ai 0:529602524696 424 }
nepes_ai 0:529602524696 425 }
nepes_ai 1:0c6bf23f2fc8 426 POWERSAVE;
nepes_ai 0:529602524696 427 return(recog_nbr);
nepes_ai 0:529602524696 428 }
nepes_ai 0:529602524696 429
nepes_ai 0:529602524696 430 // ------------------------------------------------------------
nepes_ai 0:529602524696 431 // Set a context and associated minimum and maximum influence fields
nepes_ai 0:529602524696 432 // ------------------------------------------------------------
nepes_ai 0:529602524696 433 void NeuroShield::setContext(uint8_t context)
nepes_ai 0:529602524696 434 {
nepes_ai 0:529602524696 435 // context[15-8]= unused
nepes_ai 0:529602524696 436 // context[7]= Norm (0 for L1; 1 for LSup)
nepes_ai 0:529602524696 437 // context[6-0]= Active context value
nepes_ai 0:529602524696 438 uint16_t read_val = spi.read(NM_GCR);
nepes_ai 0:529602524696 439 read_val = (read_val & 0xFF80) | (context & 0x007F);
nepes_ai 0:529602524696 440 spi.write(NM_GCR, read_val);
nepes_ai 1:0c6bf23f2fc8 441 POWERSAVE;
nepes_ai 0:529602524696 442 }
nepes_ai 0:529602524696 443
nepes_ai 0:529602524696 444 // ------------------------------------------------------------
nepes_ai 0:529602524696 445 // Set a context and associated minimum and maximum influence fields
nepes_ai 0:529602524696 446 // ------------------------------------------------------------
nepes_ai 0:529602524696 447 void NeuroShield::setContext(uint8_t context, uint16_t minif, uint16_t maxif)
nepes_ai 0:529602524696 448 {
nepes_ai 0:529602524696 449 // context[15-8]= unused
nepes_ai 0:529602524696 450 // context[7]= Norm (0 for L1; 1 for LSup)
nepes_ai 0:529602524696 451 // context[6-0]= Active context value
nepes_ai 0:529602524696 452 uint16_t read_val = spi.read(NM_GCR);
nepes_ai 0:529602524696 453 read_val = (read_val & 0xFF80) | (context & 0x007F);
nepes_ai 0:529602524696 454 spi.write(NM_GCR, read_val);
nepes_ai 0:529602524696 455 spi.write(NM_MINIF, minif);
nepes_ai 0:529602524696 456 spi.write(NM_MAXIF, maxif);
nepes_ai 1:0c6bf23f2fc8 457 POWERSAVE;
nepes_ai 0:529602524696 458 }
nepes_ai 0:529602524696 459
nepes_ai 0:529602524696 460 // ------------------------------------------------------------
nepes_ai 0:529602524696 461 // Get a context and associated minimum and maximum influence fields
nepes_ai 0:529602524696 462 // ------------------------------------------------------------
nepes_ai 0:529602524696 463 void NeuroShield::getContext(uint8_t* context, uint16_t* minif, uint16_t* maxif)
nepes_ai 0:529602524696 464 {
nepes_ai 0:529602524696 465 // context[15-8]= unused
nepes_ai 0:529602524696 466 // context[7]= Norm (0 for L1; 1 for LSup)
nepes_ai 0:529602524696 467 // context[6-0]= Active context value
nepes_ai 0:529602524696 468 *context = (uint8_t)(spi.read(NM_GCR) & 0x007F);
nepes_ai 0:529602524696 469 *minif = spi.read(NM_MINIF);
nepes_ai 0:529602524696 470 *maxif = spi.read(NM_MAXIF);
nepes_ai 1:0c6bf23f2fc8 471 POWERSAVE;
nepes_ai 0:529602524696 472 }
nepes_ai 0:529602524696 473
nepes_ai 0:529602524696 474 // --------------------------------------------------------
nepes_ai 0:529602524696 475 // Set the neurons in Radial Basis Function mode (default)
nepes_ai 0:529602524696 476 //---------------------------------------------------------
nepes_ai 0:529602524696 477 void NeuroShield::setRbfClassifier()
nepes_ai 0:529602524696 478 {
nepes_ai 0:529602524696 479 uint16_t temp_nsr = spi.read(NM_NSR);
nepes_ai 0:529602524696 480 spi.write(NM_NSR, (temp_nsr & 0x00DF));
nepes_ai 1:0c6bf23f2fc8 481 POWERSAVE;
nepes_ai 0:529602524696 482 }
nepes_ai 0:529602524696 483
nepes_ai 0:529602524696 484 // --------------------------------------------------------
nepes_ai 0:529602524696 485 // Set the neurons in K-Nearest Neighbor mode
nepes_ai 0:529602524696 486 //---------------------------------------------------------
nepes_ai 0:529602524696 487 void NeuroShield::setKnnClassifier()
nepes_ai 0:529602524696 488 {
nepes_ai 0:529602524696 489 uint16_t temp_nsr = spi.read(NM_NSR);
nepes_ai 0:529602524696 490 spi.write(NM_NSR, (temp_nsr | 0x0020));
nepes_ai 1:0c6bf23f2fc8 491 POWERSAVE;
nepes_ai 0:529602524696 492 }
nepes_ai 0:529602524696 493
nepes_ai 0:529602524696 494 //-------------------------------------------------------------
nepes_ai 0:529602524696 495 // Read the contents of the neuron pointed by index in the chain of neurons
nepes_ai 1:0c6bf23f2fc8 496 // starting at index 1
nepes_ai 0:529602524696 497 //-------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 498 void NeuroShield::readNeuron(uint16_t nid, uint16_t model[], uint16_t* ncr, uint16_t* aif, uint16_t* cat)
nepes_ai 0:529602524696 499 {
nepes_ai 1:0c6bf23f2fc8 500 if (nid == 0) {
nepes_ai 1:0c6bf23f2fc8 501 *ncr = 0xFFFF;
nepes_ai 1:0c6bf23f2fc8 502 *aif = 0xFFFF;
nepes_ai 1:0c6bf23f2fc8 503 *cat = 0xFFFF;
nepes_ai 1:0c6bf23f2fc8 504 return;
nepes_ai 1:0c6bf23f2fc8 505 }
nepes_ai 1:0c6bf23f2fc8 506
nepes_ai 0:529602524696 507 uint16_t temp_nsr = spi.read(NM_NSR);
nepes_ai 0:529602524696 508 spi.write(NM_NSR, 0x0010);
nepes_ai 0:529602524696 509 spi.write(NM_RSTCHAIN, 0);
nepes_ai 1:0c6bf23f2fc8 510 if (nid > 1) {
nepes_ai 0:529602524696 511 // move to index in the chain of neurons
nepes_ai 1:0c6bf23f2fc8 512 for (int i = 1; i < nid; i++)
nepes_ai 0:529602524696 513 spi.read(NM_CAT);
nepes_ai 0:529602524696 514 }
nepes_ai 0:529602524696 515
nepes_ai 0:529602524696 516 *ncr = spi.read(NM_NCR);
nepes_ai 1:0c6bf23f2fc8 517 if (support_burst_read == 1) {
nepes_ai 1:0c6bf23f2fc8 518 spi.readVector16(model, NEURON_SIZE);
nepes_ai 1:0c6bf23f2fc8 519 }
nepes_ai 1:0c6bf23f2fc8 520 else {
nepes_ai 1:0c6bf23f2fc8 521 for (int i = 0; i < NEURON_SIZE; i++)
nepes_ai 1:0c6bf23f2fc8 522 model[i] = spi.read(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 523 }
nepes_ai 0:529602524696 524 *aif = spi.read(NM_AIF);
nepes_ai 0:529602524696 525 *cat = spi.read(NM_CAT);
nepes_ai 1:0c6bf23f2fc8 526 spi.write(NM_NSR, temp_nsr); // set the NN back to its calling status
nepes_ai 1:0c6bf23f2fc8 527 POWERSAVE;
nepes_ai 0:529602524696 528 }
nepes_ai 0:529602524696 529
nepes_ai 0:529602524696 530 //-------------------------------------------------------------
nepes_ai 0:529602524696 531 // Read the contents of the neuron pointed by index in the chain of neurons
nepes_ai 1:0c6bf23f2fc8 532 // starting index is 1
nepes_ai 1:0c6bf23f2fc8 533 // Returns an array of (NEURON_SIZE + 4) words with the following format
nepes_ai 1:0c6bf23f2fc8 534 // NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
nepes_ai 0:529602524696 535 //-------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 536 void NeuroShield::readNeuron(uint16_t nid, uint16_t neuron[])
nepes_ai 0:529602524696 537 {
nepes_ai 1:0c6bf23f2fc8 538 if (nid == 0) {
nepes_ai 1:0c6bf23f2fc8 539 for (int i = 0; i < (NEURON_SIZE + 4); i++) {
nepes_ai 1:0c6bf23f2fc8 540 neuron[i] = 0xFFFF;
nepes_ai 1:0c6bf23f2fc8 541 }
nepes_ai 1:0c6bf23f2fc8 542 return;
nepes_ai 1:0c6bf23f2fc8 543 }
nepes_ai 1:0c6bf23f2fc8 544
nepes_ai 0:529602524696 545 uint16_t temp_nsr = spi.read(NM_NSR);
nepes_ai 0:529602524696 546 spi.write(NM_NSR, 0x0010);
nepes_ai 0:529602524696 547 spi.write(NM_RSTCHAIN, 0);
nepes_ai 1:0c6bf23f2fc8 548 if (nid > 1) {
nepes_ai 0:529602524696 549 // move to index in the chain of neurons
nepes_ai 1:0c6bf23f2fc8 550 for (int i = 1; i < nid; i++)
nepes_ai 0:529602524696 551 spi.read(NM_CAT);
nepes_ai 0:529602524696 552 }
nepes_ai 1:0c6bf23f2fc8 553
nepes_ai 1:0c6bf23f2fc8 554 neuron[0] = spi.read(NM_NCR);
nepes_ai 1:0c6bf23f2fc8 555 if (support_burst_read == 1) {
nepes_ai 1:0c6bf23f2fc8 556 spi.readVector16(&neuron[1], NEURON_SIZE);
nepes_ai 1:0c6bf23f2fc8 557 }
nepes_ai 1:0c6bf23f2fc8 558 else {
nepes_ai 1:0c6bf23f2fc8 559 for (int i = 0; i < NEURON_SIZE; i++)
nepes_ai 1:0c6bf23f2fc8 560 neuron[i + 1] = spi.read(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 561 }
nepes_ai 1:0c6bf23f2fc8 562 neuron[NEURON_SIZE + 1] = spi.read(NM_AIF);
nepes_ai 1:0c6bf23f2fc8 563 neuron[NEURON_SIZE + 2] = spi.read(NM_MINIF);
nepes_ai 1:0c6bf23f2fc8 564 neuron[NEURON_SIZE + 3] = spi.read(NM_CAT);
nepes_ai 1:0c6bf23f2fc8 565 spi.write(NM_NSR, temp_nsr); // set the NN back to its calling status
nepes_ai 1:0c6bf23f2fc8 566 POWERSAVE;
nepes_ai 0:529602524696 567 }
nepes_ai 0:529602524696 568
nepes_ai 0:529602524696 569 //----------------------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 570 // Read the contents of the committed neurons
nepes_ai 1:0c6bf23f2fc8 571 // The output array has a dimension ncount * neurondata
nepes_ai 1:0c6bf23f2fc8 572 // neurondata describes the content of a neuron and has a dimension (NEURON_SIZE + 4) words
nepes_ai 1:0c6bf23f2fc8 573 // and with the following format NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
nepes_ai 0:529602524696 574 //----------------------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 575 uint16_t NeuroShield::readNeurons(uint16_t neurons[])
nepes_ai 0:529602524696 576 {
nepes_ai 1:0c6bf23f2fc8 577 uint32_t offset = 0;
nepes_ai 0:529602524696 578 uint16_t ncount = spi.read(NM_NCOUNT);
nepes_ai 1:0c6bf23f2fc8 579 uint16_t temp_nsr = spi.read(NM_NSR); // save value to restore NN status upon exit
nepes_ai 0:529602524696 580 spi.write(NM_NSR, 0x0010);
nepes_ai 0:529602524696 581 spi.write(NM_RSTCHAIN, 0);
nepes_ai 0:529602524696 582 for (int i = 0; i < ncount; i++) {
nepes_ai 1:0c6bf23f2fc8 583 neurons[offset + 0] = spi.read(NM_NCR);
nepes_ai 1:0c6bf23f2fc8 584 if (support_burst_read == 1) {
nepes_ai 1:0c6bf23f2fc8 585 spi.readVector16(&neurons[offset + 1], NEURON_SIZE);
nepes_ai 0:529602524696 586 }
nepes_ai 1:0c6bf23f2fc8 587 else {
nepes_ai 1:0c6bf23f2fc8 588 for (int j = 0; j < NEURON_SIZE; j++) {
nepes_ai 1:0c6bf23f2fc8 589 neurons[offset + 1 + j] = spi.read(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 590 }
nepes_ai 1:0c6bf23f2fc8 591 }
nepes_ai 1:0c6bf23f2fc8 592 neurons[offset + 1 + NEURON_SIZE] = spi.read(NM_AIF);
nepes_ai 1:0c6bf23f2fc8 593 neurons[offset + 2 + NEURON_SIZE] = spi.read(NM_MINIF);
nepes_ai 1:0c6bf23f2fc8 594 neurons[offset + 3 + NEURON_SIZE] = spi.read(NM_CAT);
nepes_ai 1:0c6bf23f2fc8 595 offset += (NEURON_SIZE + 4);
nepes_ai 0:529602524696 596 }
nepes_ai 1:0c6bf23f2fc8 597 spi.write(NM_NSR, temp_nsr); // set the NN back to its calling status
nepes_ai 1:0c6bf23f2fc8 598 POWERSAVE;
nepes_ai 0:529602524696 599 return(ncount);
nepes_ai 0:529602524696 600 }
nepes_ai 0:529602524696 601
nepes_ai 1:0c6bf23f2fc8 602 void NeuroShield::readCompVector(uint16_t* data, uint16_t size)
nepes_ai 1:0c6bf23f2fc8 603 {
nepes_ai 1:0c6bf23f2fc8 604 if (support_burst_read == 1) {
nepes_ai 1:0c6bf23f2fc8 605 spi.readVector16(data, size);
nepes_ai 1:0c6bf23f2fc8 606 }
nepes_ai 1:0c6bf23f2fc8 607 else {
nepes_ai 1:0c6bf23f2fc8 608 for (int i = 0; i < size; i++) {
nepes_ai 1:0c6bf23f2fc8 609 *data = spi.read(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 610 data++;
nepes_ai 1:0c6bf23f2fc8 611 }
nepes_ai 1:0c6bf23f2fc8 612 }
nepes_ai 2:2812bcbcaaea 613 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 614 }
nepes_ai 1:0c6bf23f2fc8 615
nepes_ai 0:529602524696 616 //---------------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 617 // Clear the neurons and write their content from an input array
nepes_ai 1:0c6bf23f2fc8 618 // The input array has a dimension ncount * neurondata
nepes_ai 1:0c6bf23f2fc8 619 // neurondata describes the content of a neuron and has a dimension (NEURON_SIZE + 4) words
nepes_ai 1:0c6bf23f2fc8 620 // and with the following format NCR, NEURON_SIZE * COMP, AIF, MINIF, CAT
nepes_ai 0:529602524696 621 //---------------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 622 void NeuroShield::writeNeurons(uint16_t neurons[], uint16_t ncount)
nepes_ai 0:529602524696 623 {
nepes_ai 1:0c6bf23f2fc8 624 uint32_t offset = 0;
nepes_ai 0:529602524696 625 if (ncount > total_neurons)
nepes_ai 0:529602524696 626 ncount = total_neurons;
nepes_ai 1:0c6bf23f2fc8 627 uint16_t temp_nsr = spi.read(NM_NSR); // save value to restore NN status upon exit
nepes_ai 0:529602524696 628 uint16_t temp_gcr = spi.read(NM_GCR);
nepes_ai 1:0c6bf23f2fc8 629 clearNeurons();
nepes_ai 0:529602524696 630 spi.write(NM_NSR, 0x0010);
nepes_ai 0:529602524696 631 spi.write(NM_RSTCHAIN, 0);
nepes_ai 0:529602524696 632 for (int i = 0; i < ncount; i++) {
nepes_ai 1:0c6bf23f2fc8 633 spi.write(NM_NCR, neurons[offset + 0]);
nepes_ai 1:0c6bf23f2fc8 634 spi.writeVector16(&neurons[offset + 1], NEURON_SIZE);
nepes_ai 1:0c6bf23f2fc8 635 spi.write(NM_AIF, neurons[offset + 1 + NEURON_SIZE]);
nepes_ai 1:0c6bf23f2fc8 636 spi.write(NM_MINIF, neurons[offset + 2 + NEURON_SIZE]);
nepes_ai 1:0c6bf23f2fc8 637 spi.write(NM_CAT, neurons[offset + 3 + NEURON_SIZE]);
nepes_ai 1:0c6bf23f2fc8 638 offset += (NEURON_SIZE + 4);
nepes_ai 0:529602524696 639 }
nepes_ai 1:0c6bf23f2fc8 640 spi.write(NM_NSR, temp_nsr); // set the NN back to its calling status
nepes_ai 0:529602524696 641 spi.write(NM_GCR, temp_gcr);
nepes_ai 1:0c6bf23f2fc8 642 POWERSAVE;
nepes_ai 0:529602524696 643 }
nepes_ai 0:529602524696 644
nepes_ai 0:529602524696 645 // --------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 646 // Write N-component
nepes_ai 1:0c6bf23f2fc8 647 //---------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 648 void NeuroShield::writeCompVector(uint16_t* data, uint16_t size)
nepes_ai 1:0c6bf23f2fc8 649 {
nepes_ai 1:0c6bf23f2fc8 650 spi.writeVector16(data, size);
nepes_ai 2:2812bcbcaaea 651 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 652 }
nepes_ai 1:0c6bf23f2fc8 653
nepes_ai 1:0c6bf23f2fc8 654 // --------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 655 // Get/Set the NM500 register value
nepes_ai 0:529602524696 656 //---------------------------------------------------------
nepes_ai 0:529602524696 657 uint16_t NeuroShield::testCommand(uint8_t read_write, uint8_t reg, uint16_t data)
nepes_ai 0:529602524696 658 {
nepes_ai 1:0c6bf23f2fc8 659 uint16_t ret_val = 0;
nepes_ai 0:529602524696 660 if (read_write == 0) {
nepes_ai 1:0c6bf23f2fc8 661 ret_val = spi.read(reg);
nepes_ai 0:529602524696 662 }
nepes_ai 0:529602524696 663 else if (read_write == 1) {
nepes_ai 0:529602524696 664 spi.write(reg, data);
nepes_ai 0:529602524696 665 }
nepes_ai 1:0c6bf23f2fc8 666 POWERSAVE;
nepes_ai 1:0c6bf23f2fc8 667 return(ret_val);
nepes_ai 0:529602524696 668 }
nepes_ai 0:529602524696 669
nepes_ai 0:529602524696 670 // ----------------------------------------------------------------
nepes_ai 0:529602524696 671 // Get FPGA Version
nepes_ai 1:0c6bf23f2fc8 672 // [15:8] board type : 00 = NeuroShield, 01 = Prodigy ...
nepes_ai 1:0c6bf23f2fc8 673 // [ 7:4] board version
nepes_ai 1:0c6bf23f2fc8 674 // [ 3:0] fpga version
nepes_ai 0:529602524696 675 // ----------------------------------------------------------------
nepes_ai 0:529602524696 676 uint16_t NeuroShield::fpgaVersion()
nepes_ai 0:529602524696 677 {
nepes_ai 0:529602524696 678 return(spi.version());
nepes_ai 0:529602524696 679 }
nepes_ai 0:529602524696 680
nepes_ai 0:529602524696 681 // ----------------------------------------------------------------
nepes_ai 0:529602524696 682 // Excute NM500 SW Reset
nepes_ai 0:529602524696 683 // ----------------------------------------------------------------
nepes_ai 0:529602524696 684 void NeuroShield::nm500Reset()
nepes_ai 0:529602524696 685 {
nepes_ai 0:529602524696 686 spi.reset();
nepes_ai 0:529602524696 687 }
nepes_ai 0:529602524696 688
nepes_ai 0:529602524696 689 // ----------------------------------------------------------------
nepes_ai 0:529602524696 690 // Select LED Scenario
nepes_ai 0:529602524696 691 // ----------------------------------------------------------------
nepes_ai 0:529602524696 692 void NeuroShield::ledSelect(uint8_t data)
nepes_ai 0:529602524696 693 {
nepes_ai 0:529602524696 694 spi.ledSelect(data);
nepes_ai 0:529602524696 695 }