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 SPI device(SPI_MOSI, SPI_MISO, SPI_SCK); // PA_7, PA_6, PA_5
nepes_ai 0:529602524696 49 DigitalOut nm500_ss(D7); // NM500_SSn
nepes_ai 0:529602524696 50
nepes_ai 0:529602524696 51 // ------------------------------------------------------------ //
nepes_ai 0:529602524696 52 // Constructor to the class ShieldSPI
nepes_ai 0:529602524696 53 // ------------------------------------------------------------
nepes_ai 0:529602524696 54 NeuroShieldSPI::NeuroShieldSPI(){
nepes_ai 0:529602524696 55 }
nepes_ai 0:529602524696 56
nepes_ai 0:529602524696 57 // ------------------------------------------------------------
nepes_ai 0:529602524696 58 // Initialize the SPI communication and verify proper interface
nepes_ai 0:529602524696 59 // to the NM500 by reading the default Minif value of 2-bytes
nepes_ai 0:529602524696 60 // return an error=0 otherwise=1
nepes_ai 0:529602524696 61 // ------------------------------------------------------------
nepes_ai 0:529602524696 62 bool NeuroShieldSPI::connect()
nepes_ai 0:529602524696 63 {
nepes_ai 0:529602524696 64 uint16_t read_value;
nepes_ai 0:529602524696 65
nepes_ai 0:529602524696 66 // for shield board test
nepes_ai 0:529602524696 67 nm500_ss = HIGH;
nepes_ai 0:529602524696 68
nepes_ai 0:529602524696 69 //
nepes_ai 0:529602524696 70 device.format(8,0);
nepes_ai 0:529602524696 71 device.frequency(2000000); // 2MHz
nepes_ai 0:529602524696 72
nepes_ai 0:529602524696 73 // return 1 if NM500 present and SPI comm successful
nepes_ai 0:529602524696 74 for (int i = 0; i < 10; i++) {
nepes_ai 0:529602524696 75 reset(); // NM500 reset
nepes_ai 0:529602524696 76 wait_ms(100);
nepes_ai 0:529602524696 77 write(NM_FORGET, 0);
nepes_ai 0:529602524696 78 wait_ms(50);
nepes_ai 0:529602524696 79 read_value = read(NM_MINIF);
nepes_ai 0:529602524696 80 if (read_value == 2)
nepes_ai 0:529602524696 81 return(1);
nepes_ai 0:529602524696 82 wait_ms(50);
nepes_ai 0:529602524696 83 }
nepes_ai 0:529602524696 84
nepes_ai 0:529602524696 85 return(0);
nepes_ai 0:529602524696 86 }
nepes_ai 0:529602524696 87
nepes_ai 0:529602524696 88 // --------------------------------------------------------
nepes_ai 0:529602524696 89 // SPI Read the register of a given module (module + reg = addr)
nepes_ai 0:529602524696 90 //---------------------------------------------------------
nepes_ai 0:529602524696 91 uint16_t NeuroShieldSPI::read(uint8_t reg)
nepes_ai 0:529602524696 92 {
nepes_ai 0:529602524696 93 //device.lock();
nepes_ai 0:529602524696 94
nepes_ai 3:6163399b611e 95 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 96
nepes_ai 0:529602524696 97 nm500_ss = LOW;
nepes_ai 0:529602524696 98 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 99 device.write((uint8_t)module_nm500);
nepes_ai 0:529602524696 100 device.write(0);
nepes_ai 0:529602524696 101 device.write(0);
nepes_ai 0:529602524696 102 device.write(reg);
nepes_ai 0:529602524696 103 device.write(0);
nepes_ai 0:529602524696 104 device.write(0);
nepes_ai 0:529602524696 105 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 106 uint16_t data = device.write(0); // Send 0 to push upper data out
nepes_ai 0:529602524696 107 data = (data << 8) + device.write(0); // Send 0 to push lower data out
nepes_ai 0:529602524696 108 nm500_ss = HIGH;
nepes_ai 0:529602524696 109
nepes_ai 0:529602524696 110 //device.unlock();
nepes_ai 0:529602524696 111
nepes_ai 0:529602524696 112 return(data);
nepes_ai 0:529602524696 113 }
nepes_ai 0:529602524696 114
nepes_ai 1:0c6bf23f2fc8 115 void NeuroShieldSPI::readVector16(uint16_t* data, uint16_t size)
nepes_ai 1:0c6bf23f2fc8 116 {
nepes_ai 1:0c6bf23f2fc8 117 //device.lock();
nepes_ai 1:0c6bf23f2fc8 118
nepes_ai 3:6163399b611e 119 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 120
nepes_ai 1:0c6bf23f2fc8 121 nm500_ss = LOW;
nepes_ai 1:0c6bf23f2fc8 122 device.write(1);
nepes_ai 1:0c6bf23f2fc8 123 device.write((uint8_t)module_nm500);
nepes_ai 1:0c6bf23f2fc8 124 device.write(0);
nepes_ai 1:0c6bf23f2fc8 125 device.write(0);
nepes_ai 1:0c6bf23f2fc8 126 device.write(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 127 device.write(0);
nepes_ai 1:0c6bf23f2fc8 128 device.write((uint8_t)((size >> 8) & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 129 device.write((uint8_t)(size & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 130 for (int i = 0; i < size; i++) {
nepes_ai 1:0c6bf23f2fc8 131 *data = device.write(0);
nepes_ai 1:0c6bf23f2fc8 132 *data = (*data << 8) + device.write(0);
nepes_ai 1:0c6bf23f2fc8 133 data++;
nepes_ai 1:0c6bf23f2fc8 134 }
nepes_ai 1:0c6bf23f2fc8 135 nm500_ss = HIGH;
nepes_ai 1:0c6bf23f2fc8 136
nepes_ai 1:0c6bf23f2fc8 137 //device.unlock();
nepes_ai 1:0c6bf23f2fc8 138 }
nepes_ai 1:0c6bf23f2fc8 139
nepes_ai 0:529602524696 140 // ---------------------------------------------------------
nepes_ai 0:529602524696 141 // SPI Write the register of a given module (module + reg = addr)
nepes_ai 0:529602524696 142 // ---------------------------------------------------------
nepes_ai 0:529602524696 143 void NeuroShieldSPI::write(uint8_t reg, uint16_t data)
nepes_ai 0:529602524696 144 {
nepes_ai 0:529602524696 145 //device.lock();
nepes_ai 0:529602524696 146
nepes_ai 3:6163399b611e 147 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 148
nepes_ai 0:529602524696 149 nm500_ss = LOW;
nepes_ai 0:529602524696 150 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 151 device.write((uint8_t)(module_nm500 + 0x80)); // module and write flag
nepes_ai 0:529602524696 152 device.write(0);
nepes_ai 0:529602524696 153 device.write(0);
nepes_ai 0:529602524696 154 device.write(reg);
nepes_ai 0:529602524696 155 device.write(0);
nepes_ai 0:529602524696 156 device.write(0);
nepes_ai 0:529602524696 157 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 158 if ((reg == NM_COMP) || (reg == NM_LCOMP)) {
nepes_ai 0:529602524696 159 device.write(0x00); // upper data
nepes_ai 0:529602524696 160 device.write((uint8_t)(data & 0x00FF)); // lower data
nepes_ai 0:529602524696 161 }
nepes_ai 0:529602524696 162 else {
nepes_ai 0:529602524696 163 device.write((uint8_t)((data >> 8) & 0x00FF)); // upper data
nepes_ai 0:529602524696 164 device.write((uint8_t)(data & 0x00FF)); // lower data
nepes_ai 0:529602524696 165 }
nepes_ai 0:529602524696 166 nm500_ss = HIGH;
nepes_ai 0:529602524696 167
nepes_ai 0:529602524696 168 //device.unlock();
nepes_ai 0:529602524696 169 }
nepes_ai 0:529602524696 170
nepes_ai 0:529602524696 171 // ----------------------------------------------------------------
nepes_ai 0:529602524696 172 // SPI Write burst mode at COMP register
nepes_ai 0:529602524696 173 // ----------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 174 uint16_t NeuroShieldSPI::writeVector(uint8_t* data, uint16_t size)
nepes_ai 0:529602524696 175 {
nepes_ai 1:0c6bf23f2fc8 176 if (size > NEURON_SIZE) // to use SR-mode
nepes_ai 0:529602524696 177 return(0);
nepes_ai 0:529602524696 178
nepes_ai 0:529602524696 179 //device.lock();
nepes_ai 0:529602524696 180
nepes_ai 3:6163399b611e 181 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 182
nepes_ai 0:529602524696 183 nm500_ss = LOW;
nepes_ai 0:529602524696 184 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 185 device.write((uint8_t)(module_nm500 + 0x80)); // module and write flag
nepes_ai 0:529602524696 186 device.write(0);
nepes_ai 0:529602524696 187 device.write(0);
nepes_ai 1:0c6bf23f2fc8 188 device.write(NM_COMP);
nepes_ai 0:529602524696 189 device.write(0);
nepes_ai 1:0c6bf23f2fc8 190 device.write((uint8_t)((size >> 8) & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 191 device.write((uint8_t)(size & 0x00FF)); // 1 ~ 256 byte
nepes_ai 0:529602524696 192 for (int i = 0; i < size; i++) {
nepes_ai 0:529602524696 193 device.write(0x00); // COMP' upper data = 0x00
nepes_ai 0:529602524696 194 device.write((uint8_t)(*data)); // lower data
nepes_ai 0:529602524696 195 data++;
nepes_ai 0:529602524696 196 }
nepes_ai 0:529602524696 197 nm500_ss = HIGH;
nepes_ai 0:529602524696 198
nepes_ai 0:529602524696 199 //device.unlock();
nepes_ai 0:529602524696 200
nepes_ai 0:529602524696 201 return(size);
nepes_ai 0:529602524696 202 }
nepes_ai 0:529602524696 203
nepes_ai 1:0c6bf23f2fc8 204 uint16_t NeuroShieldSPI::writeVector16(uint16_t* data, uint16_t size)
nepes_ai 1:0c6bf23f2fc8 205 {
nepes_ai 1:0c6bf23f2fc8 206 if (size > NEURON_SIZE) // to use SR-mode
nepes_ai 1:0c6bf23f2fc8 207 return(0);
nepes_ai 1:0c6bf23f2fc8 208
nepes_ai 1:0c6bf23f2fc8 209 //device.lock();
nepes_ai 1:0c6bf23f2fc8 210
nepes_ai 3:6163399b611e 211 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 212
nepes_ai 1:0c6bf23f2fc8 213 nm500_ss = LOW;
nepes_ai 1:0c6bf23f2fc8 214 device.write(1); // Dummy for ID
nepes_ai 1:0c6bf23f2fc8 215 device.write((uint8_t)(module_nm500 + 0x80)); // module and write flag
nepes_ai 1:0c6bf23f2fc8 216 device.write(0);
nepes_ai 1:0c6bf23f2fc8 217 device.write(0);
nepes_ai 1:0c6bf23f2fc8 218 device.write(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 219 device.write(0);
nepes_ai 1:0c6bf23f2fc8 220 device.write((uint8_t)((size >> 8) & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 221 device.write((uint8_t)(size & 0x00FF)); // 1 ~ 256 byte
nepes_ai 1:0c6bf23f2fc8 222 for (int i = 0; i < size; i++) {
nepes_ai 1:0c6bf23f2fc8 223 device.write(0x00); // COMP' upper data = 0x00
nepes_ai 1:0c6bf23f2fc8 224 device.write((uint8_t)((*data) & 0x00FF)); // lower data
nepes_ai 1:0c6bf23f2fc8 225 data++;
nepes_ai 1:0c6bf23f2fc8 226 }
nepes_ai 1:0c6bf23f2fc8 227 nm500_ss = HIGH;
nepes_ai 1:0c6bf23f2fc8 228
nepes_ai 1:0c6bf23f2fc8 229 //device.unlock();
nepes_ai 1:0c6bf23f2fc8 230
nepes_ai 1:0c6bf23f2fc8 231 return(size);
nepes_ai 1:0c6bf23f2fc8 232 }
nepes_ai 1:0c6bf23f2fc8 233
nepes_ai 0:529602524696 234 // ----------------------------------------------------------------
nepes_ai 0:529602524696 235 // read FPGA Version
nepes_ai 0:529602524696 236 // ----------------------------------------------------------------
nepes_ai 0:529602524696 237 uint16_t NeuroShieldSPI::version()
nepes_ai 0:529602524696 238 {
nepes_ai 0:529602524696 239 //device.lock();
nepes_ai 0:529602524696 240
nepes_ai 3:6163399b611e 241 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 242
nepes_ai 0:529602524696 243 nm500_ss = LOW;
nepes_ai 0:529602524696 244 device.write(1); // Dummy for ID
nepes_ai 3:6163399b611e 245 device.write((uint8_t)module_fpga); // address (4-byte)
nepes_ai 0:529602524696 246 device.write(0);
nepes_ai 0:529602524696 247 device.write(0);
nepes_ai 0:529602524696 248 device.write(1); // version check : 0x01
nepes_ai 0:529602524696 249 device.write(0); // word size (3-byte)
nepes_ai 0:529602524696 250 device.write(0);
nepes_ai 0:529602524696 251 device.write(1);
nepes_ai 0:529602524696 252 uint16_t data = device.write(0); // Send 0 to push upper data out
nepes_ai 0:529602524696 253 data = (data << 8) + device.write(0); // Send 0 to push lower data out
nepes_ai 0:529602524696 254 nm500_ss = HIGH;
nepes_ai 0:529602524696 255
nepes_ai 0:529602524696 256 //device.unlock();
nepes_ai 0:529602524696 257
nepes_ai 0:529602524696 258 return(data);
nepes_ai 0:529602524696 259 }
nepes_ai 0:529602524696 260
nepes_ai 0:529602524696 261 // ----------------------------------------------------------------
nepes_ai 0:529602524696 262 // excute NM500 SW reset
nepes_ai 0:529602524696 263 // ----------------------------------------------------------------
nepes_ai 0:529602524696 264 void NeuroShieldSPI::reset()
nepes_ai 0:529602524696 265 {
nepes_ai 0:529602524696 266 //device.lock();
nepes_ai 0:529602524696 267
nepes_ai 3:6163399b611e 268 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 269
nepes_ai 0:529602524696 270 nm500_ss = LOW;
nepes_ai 0:529602524696 271 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 272 device.write((uint8_t)(module_fpga + 0x80)); // address (4-byte)
nepes_ai 0:529602524696 273 device.write(0);
nepes_ai 0:529602524696 274 device.write(0);
nepes_ai 0:529602524696 275 device.write(2); // nm500 sw reset : 0x02
nepes_ai 0:529602524696 276 device.write(0); // word size (3-byte)
nepes_ai 0:529602524696 277 device.write(0);
nepes_ai 0:529602524696 278 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 279 device.write(0);
nepes_ai 0:529602524696 280 device.write(0);
nepes_ai 0:529602524696 281 nm500_ss = HIGH;
nepes_ai 0:529602524696 282
nepes_ai 0:529602524696 283 //device.unlock();
nepes_ai 0:529602524696 284 }
nepes_ai 0:529602524696 285
nepes_ai 0:529602524696 286 // ----------------------------------------------------------------
nepes_ai 0:529602524696 287 // LED scenario select
nepes_ai 0:529602524696 288 // ----------------------------------------------------------------
nepes_ai 0:529602524696 289 void NeuroShieldSPI::ledSelect(uint8_t data)
nepes_ai 0:529602524696 290 {
nepes_ai 0:529602524696 291 //device.lock();
nepes_ai 0:529602524696 292
nepes_ai 3:6163399b611e 293 device.write(0xff); // dummy for switching between sd-card and nm spi
nepes_ai 3:6163399b611e 294
nepes_ai 0:529602524696 295 nm500_ss = LOW;
nepes_ai 0:529602524696 296 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 297 device.write((uint8_t)(module_led + 0x80)); // address (4-byte)
nepes_ai 0:529602524696 298 device.write(0);
nepes_ai 0:529602524696 299 device.write(0);
nepes_ai 0:529602524696 300 device.write(data); // led scenario select
nepes_ai 0:529602524696 301 device.write(0); // word size (3-byte)
nepes_ai 0:529602524696 302 device.write(0);
nepes_ai 0:529602524696 303 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 304 device.write(0);
nepes_ai 0:529602524696 305 device.write(0);
nepes_ai 0:529602524696 306 nm500_ss = HIGH;
nepes_ai 0:529602524696 307
nepes_ai 0:529602524696 308 //deviece.unlock();
nepes_ai 0:529602524696 309 }