NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

Committer:
nepes_ai
Date:
Tue Feb 11 00:48:18 2020 +0000
Revision:
3:6163399b611e
Parent:
2:2812bcbcaaea
Release version 1.1.5

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