NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

Committer:
nepes_ai
Date:
Thu Jan 25 02:20:37 2018 +0000
Revision:
1:0c6bf23f2fc8
Parent:
0:529602524696
Child:
2:2812bcbcaaea
Release version 1.1.3; ; Add burst-mode read function; Modify HW/FPGA version information; Modify the structure of neurondata; Add POWERSAVE command

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