NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nepes_ai 0:529602524696 1 /*
nepes_ai 0:529602524696 2 * NeuroShield.cpp - Driver for NeuroShield
nepes_ai 0:529602524696 3 * Copyright (c) 2016, General Vision Inc, All rights reserved
nepes_ai 0:529602524696 4 * Copyright (c) 2017, nepes inc, All rights reserved.
nepes_ai 0:529602524696 5 *
nepes_ai 0:529602524696 6 * Redistribution and use in source and binary forms, with or without
nepes_ai 0:529602524696 7 * modification, are permitted provided that the following conditions are met:
nepes_ai 0:529602524696 8 *
nepes_ai 0:529602524696 9 * 1. Redistributions of source code must retain the above copyright notice,
nepes_ai 0:529602524696 10 * this list of conditions and the following disclaimer.
nepes_ai 0:529602524696 11 *
nepes_ai 0:529602524696 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
nepes_ai 0:529602524696 13 * this list of conditions and the following disclaimer in the documentation
nepes_ai 0:529602524696 14 * and/or other materials provided with the distribution.
nepes_ai 0:529602524696 15 *
nepes_ai 0:529602524696 16 * 3. Neither the name of the copyright holder nor the names of its contributors
nepes_ai 0:529602524696 17 * may be used to endorse or promote products derived from this software without
nepes_ai 0:529602524696 18 * specific prior written permission.
nepes_ai 0:529602524696 19 *
nepes_ai 0:529602524696 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
nepes_ai 0:529602524696 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
nepes_ai 0:529602524696 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
nepes_ai 0:529602524696 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
nepes_ai 0:529602524696 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
nepes_ai 0:529602524696 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
nepes_ai 0:529602524696 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
nepes_ai 0:529602524696 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
nepes_ai 0:529602524696 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
nepes_ai 0:529602524696 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
nepes_ai 0:529602524696 30 * POSSIBILITY OF SUCH DAMAGE.
nepes_ai 0:529602524696 31 *
nepes_ai 0:529602524696 32 */
nepes_ai 0:529602524696 33
nepes_ai 1:0c6bf23f2fc8 34 /*
nepes_ai 2:2812bcbcaaea 35 * Revision History (v1.1.4)
nepes_ai 2:2812bcbcaaea 36 * 2018/06/22 v1.1.4 Minor changes
nepes_ai 1:0c6bf23f2fc8 37 * 2018/01/03 v1.1.3 Add burst-mode read
nepes_ai 1:0c6bf23f2fc8 38 * 2017/12/20 v1.1.2 Modify the structure of neurondata
nepes_ai 1:0c6bf23f2fc8 39 * 2017/12/11 v1.1.1 Add Powersave command and Minor changes to the library
nepes_ai 1:0c6bf23f2fc8 40 * 2017/08/17 v1.0.0 First Release
nepes_ai 1:0c6bf23f2fc8 41 */
nepes_ai 1:0c6bf23f2fc8 42
nepes_ai 0:529602524696 43 #include "mbed.h"
nepes_ai 0:529602524696 44 #include <NeuroShield.h>
nepes_ai 0:529602524696 45 #include <NeuroShieldSPI.h>
nepes_ai 0:529602524696 46
nepes_ai 0:529602524696 47 SPI device(SPI_MOSI, SPI_MISO, SPI_SCK); // PA_7, PA_6, PA_5
nepes_ai 0:529602524696 48 DigitalOut nm500_ss(D7); // NM500_SSn
nepes_ai 0:529602524696 49
nepes_ai 0:529602524696 50 // ------------------------------------------------------------ //
nepes_ai 0:529602524696 51 // Constructor to the class ShieldSPI
nepes_ai 0:529602524696 52 // ------------------------------------------------------------
nepes_ai 0:529602524696 53 NeuroShieldSPI::NeuroShieldSPI(){
nepes_ai 0:529602524696 54 }
nepes_ai 0:529602524696 55
nepes_ai 0:529602524696 56 // ------------------------------------------------------------
nepes_ai 0:529602524696 57 // Initialize the SPI communication and verify proper interface
nepes_ai 0:529602524696 58 // to the NM500 by reading the default Minif value of 2-bytes
nepes_ai 0:529602524696 59 // return an error=0 otherwise=1
nepes_ai 0:529602524696 60 // ------------------------------------------------------------
nepes_ai 0:529602524696 61 bool NeuroShieldSPI::connect()
nepes_ai 0:529602524696 62 {
nepes_ai 0:529602524696 63 uint16_t read_value;
nepes_ai 0:529602524696 64
nepes_ai 0:529602524696 65 // for shield board test
nepes_ai 0:529602524696 66 nm500_ss = HIGH;
nepes_ai 0:529602524696 67
nepes_ai 0:529602524696 68 //
nepes_ai 0:529602524696 69 device.format(8,0);
nepes_ai 0:529602524696 70 device.frequency(2000000); // 2MHz
nepes_ai 0:529602524696 71
nepes_ai 0:529602524696 72 // return 1 if NM500 present and SPI comm successful
nepes_ai 0:529602524696 73 for (int i = 0; i < 10; i++) {
nepes_ai 0:529602524696 74 reset(); // NM500 reset
nepes_ai 0:529602524696 75 wait_ms(100);
nepes_ai 0:529602524696 76 write(NM_FORGET, 0);
nepes_ai 0:529602524696 77 wait_ms(50);
nepes_ai 0:529602524696 78 read_value = read(NM_MINIF);
nepes_ai 0:529602524696 79 if (read_value == 2)
nepes_ai 0:529602524696 80 return(1);
nepes_ai 0:529602524696 81 wait_ms(50);
nepes_ai 0:529602524696 82 }
nepes_ai 0:529602524696 83
nepes_ai 0:529602524696 84 return(0);
nepes_ai 0:529602524696 85 }
nepes_ai 0:529602524696 86
nepes_ai 0:529602524696 87 // --------------------------------------------------------
nepes_ai 0:529602524696 88 // SPI Read the register of a given module (module + reg = addr)
nepes_ai 0:529602524696 89 //---------------------------------------------------------
nepes_ai 0:529602524696 90 uint16_t NeuroShieldSPI::read(uint8_t reg)
nepes_ai 0:529602524696 91 {
nepes_ai 0:529602524696 92 //device.lock();
nepes_ai 0:529602524696 93
nepes_ai 0:529602524696 94 nm500_ss = LOW;
nepes_ai 0:529602524696 95 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 96 device.write((uint8_t)module_nm500);
nepes_ai 0:529602524696 97 device.write(0);
nepes_ai 0:529602524696 98 device.write(0);
nepes_ai 0:529602524696 99 device.write(reg);
nepes_ai 0:529602524696 100 device.write(0);
nepes_ai 0:529602524696 101 device.write(0);
nepes_ai 0:529602524696 102 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 103 uint16_t data = device.write(0); // Send 0 to push upper data out
nepes_ai 0:529602524696 104 data = (data << 8) + device.write(0); // Send 0 to push lower data out
nepes_ai 0:529602524696 105 nm500_ss = HIGH;
nepes_ai 0:529602524696 106
nepes_ai 0:529602524696 107 //device.unlock();
nepes_ai 0:529602524696 108
nepes_ai 0:529602524696 109 return(data);
nepes_ai 0:529602524696 110 }
nepes_ai 0:529602524696 111
nepes_ai 1:0c6bf23f2fc8 112 void NeuroShieldSPI::readVector16(uint16_t* data, uint16_t size)
nepes_ai 1:0c6bf23f2fc8 113 {
nepes_ai 1:0c6bf23f2fc8 114 //device.lock();
nepes_ai 1:0c6bf23f2fc8 115
nepes_ai 1:0c6bf23f2fc8 116 nm500_ss = LOW;
nepes_ai 1:0c6bf23f2fc8 117 device.write(1);
nepes_ai 1:0c6bf23f2fc8 118 device.write((uint8_t)module_nm500);
nepes_ai 1:0c6bf23f2fc8 119 device.write(0);
nepes_ai 1:0c6bf23f2fc8 120 device.write(0);
nepes_ai 1:0c6bf23f2fc8 121 device.write(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 122 device.write(0);
nepes_ai 1:0c6bf23f2fc8 123 device.write((uint8_t)((size >> 8) & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 124 device.write((uint8_t)(size & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 125 for (int i = 0; i < size; i++) {
nepes_ai 1:0c6bf23f2fc8 126 *data = device.write(0);
nepes_ai 1:0c6bf23f2fc8 127 *data = (*data << 8) + device.write(0);
nepes_ai 1:0c6bf23f2fc8 128 data++;
nepes_ai 1:0c6bf23f2fc8 129 }
nepes_ai 1:0c6bf23f2fc8 130 nm500_ss = HIGH;
nepes_ai 1:0c6bf23f2fc8 131
nepes_ai 1:0c6bf23f2fc8 132 //device.unlock();
nepes_ai 1:0c6bf23f2fc8 133 }
nepes_ai 1:0c6bf23f2fc8 134
nepes_ai 0:529602524696 135 // ---------------------------------------------------------
nepes_ai 0:529602524696 136 // SPI Write the register of a given module (module + reg = addr)
nepes_ai 0:529602524696 137 // ---------------------------------------------------------
nepes_ai 0:529602524696 138 void NeuroShieldSPI::write(uint8_t reg, uint16_t data)
nepes_ai 0:529602524696 139 {
nepes_ai 0:529602524696 140 //device.lock();
nepes_ai 0:529602524696 141
nepes_ai 0:529602524696 142 nm500_ss = LOW;
nepes_ai 0:529602524696 143 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 144 device.write((uint8_t)(module_nm500 + 0x80)); // module and write flag
nepes_ai 0:529602524696 145 device.write(0);
nepes_ai 0:529602524696 146 device.write(0);
nepes_ai 0:529602524696 147 device.write(reg);
nepes_ai 0:529602524696 148 device.write(0);
nepes_ai 0:529602524696 149 device.write(0);
nepes_ai 0:529602524696 150 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 151 if ((reg == NM_COMP) || (reg == NM_LCOMP)) {
nepes_ai 0:529602524696 152 device.write(0x00); // upper data
nepes_ai 0:529602524696 153 device.write((uint8_t)(data & 0x00FF)); // lower data
nepes_ai 0:529602524696 154 }
nepes_ai 0:529602524696 155 else {
nepes_ai 0:529602524696 156 device.write((uint8_t)((data >> 8) & 0x00FF)); // upper data
nepes_ai 0:529602524696 157 device.write((uint8_t)(data & 0x00FF)); // lower data
nepes_ai 0:529602524696 158 }
nepes_ai 0:529602524696 159 nm500_ss = HIGH;
nepes_ai 0:529602524696 160
nepes_ai 0:529602524696 161 //device.unlock();
nepes_ai 0:529602524696 162 }
nepes_ai 0:529602524696 163
nepes_ai 0:529602524696 164 // ----------------------------------------------------------------
nepes_ai 0:529602524696 165 // SPI Write burst mode at COMP register
nepes_ai 0:529602524696 166 // ----------------------------------------------------------------
nepes_ai 1:0c6bf23f2fc8 167 uint16_t NeuroShieldSPI::writeVector(uint8_t* data, uint16_t size)
nepes_ai 0:529602524696 168 {
nepes_ai 1:0c6bf23f2fc8 169 if (size > NEURON_SIZE) // to use SR-mode
nepes_ai 0:529602524696 170 return(0);
nepes_ai 0:529602524696 171
nepes_ai 0:529602524696 172 //device.lock();
nepes_ai 0:529602524696 173
nepes_ai 0:529602524696 174 nm500_ss = LOW;
nepes_ai 0:529602524696 175 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 176 device.write((uint8_t)(module_nm500 + 0x80)); // module and write flag
nepes_ai 0:529602524696 177 device.write(0);
nepes_ai 0:529602524696 178 device.write(0);
nepes_ai 1:0c6bf23f2fc8 179 device.write(NM_COMP);
nepes_ai 0:529602524696 180 device.write(0);
nepes_ai 1:0c6bf23f2fc8 181 device.write((uint8_t)((size >> 8) & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 182 device.write((uint8_t)(size & 0x00FF)); // 1 ~ 256 byte
nepes_ai 0:529602524696 183 for (int i = 0; i < size; i++) {
nepes_ai 0:529602524696 184 device.write(0x00); // COMP' upper data = 0x00
nepes_ai 0:529602524696 185 device.write((uint8_t)(*data)); // lower data
nepes_ai 0:529602524696 186 data++;
nepes_ai 0:529602524696 187 }
nepes_ai 0:529602524696 188 nm500_ss = HIGH;
nepes_ai 0:529602524696 189
nepes_ai 0:529602524696 190 //device.unlock();
nepes_ai 0:529602524696 191
nepes_ai 0:529602524696 192 return(size);
nepes_ai 0:529602524696 193 }
nepes_ai 0:529602524696 194
nepes_ai 1:0c6bf23f2fc8 195 uint16_t NeuroShieldSPI::writeVector16(uint16_t* data, uint16_t size)
nepes_ai 1:0c6bf23f2fc8 196 {
nepes_ai 1:0c6bf23f2fc8 197 if (size > NEURON_SIZE) // to use SR-mode
nepes_ai 1:0c6bf23f2fc8 198 return(0);
nepes_ai 1:0c6bf23f2fc8 199
nepes_ai 1:0c6bf23f2fc8 200 //device.lock();
nepes_ai 1:0c6bf23f2fc8 201
nepes_ai 1:0c6bf23f2fc8 202 nm500_ss = LOW;
nepes_ai 1:0c6bf23f2fc8 203 device.write(1); // Dummy for ID
nepes_ai 1:0c6bf23f2fc8 204 device.write((uint8_t)(module_nm500 + 0x80)); // module and write flag
nepes_ai 1:0c6bf23f2fc8 205 device.write(0);
nepes_ai 1:0c6bf23f2fc8 206 device.write(0);
nepes_ai 1:0c6bf23f2fc8 207 device.write(NM_COMP);
nepes_ai 1:0c6bf23f2fc8 208 device.write(0);
nepes_ai 1:0c6bf23f2fc8 209 device.write((uint8_t)((size >> 8) & 0x00FF));
nepes_ai 1:0c6bf23f2fc8 210 device.write((uint8_t)(size & 0x00FF)); // 1 ~ 256 byte
nepes_ai 1:0c6bf23f2fc8 211 for (int i = 0; i < size; i++) {
nepes_ai 1:0c6bf23f2fc8 212 device.write(0x00); // COMP' upper data = 0x00
nepes_ai 1:0c6bf23f2fc8 213 device.write((uint8_t)((*data) & 0x00FF)); // lower data
nepes_ai 1:0c6bf23f2fc8 214 data++;
nepes_ai 1:0c6bf23f2fc8 215 }
nepes_ai 1:0c6bf23f2fc8 216 nm500_ss = HIGH;
nepes_ai 1:0c6bf23f2fc8 217
nepes_ai 1:0c6bf23f2fc8 218 //device.unlock();
nepes_ai 1:0c6bf23f2fc8 219
nepes_ai 1:0c6bf23f2fc8 220 return(size);
nepes_ai 1:0c6bf23f2fc8 221 }
nepes_ai 1:0c6bf23f2fc8 222
nepes_ai 0:529602524696 223 // ----------------------------------------------------------------
nepes_ai 0:529602524696 224 // read FPGA Version
nepes_ai 0:529602524696 225 // ----------------------------------------------------------------
nepes_ai 0:529602524696 226 uint16_t NeuroShieldSPI::version()
nepes_ai 0:529602524696 227 {
nepes_ai 0:529602524696 228 //device.lock();
nepes_ai 0:529602524696 229
nepes_ai 0:529602524696 230 nm500_ss = LOW;
nepes_ai 0:529602524696 231 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 232 device.write((uint8_t)module_fpga); // address (4-byte)
nepes_ai 0:529602524696 233 device.write(0);
nepes_ai 0:529602524696 234 device.write(0);
nepes_ai 0:529602524696 235 device.write(1); // version check : 0x01
nepes_ai 0:529602524696 236 device.write(0); // word size (3-byte)
nepes_ai 0:529602524696 237 device.write(0);
nepes_ai 0:529602524696 238 device.write(1);
nepes_ai 0:529602524696 239 uint16_t data = device.write(0); // Send 0 to push upper data out
nepes_ai 0:529602524696 240 data = (data << 8) + device.write(0); // Send 0 to push lower data out
nepes_ai 0:529602524696 241 nm500_ss = HIGH;
nepes_ai 0:529602524696 242
nepes_ai 0:529602524696 243 //device.unlock();
nepes_ai 0:529602524696 244
nepes_ai 0:529602524696 245 return(data);
nepes_ai 0:529602524696 246 }
nepes_ai 0:529602524696 247
nepes_ai 0:529602524696 248 // ----------------------------------------------------------------
nepes_ai 0:529602524696 249 // excute NM500 SW reset
nepes_ai 0:529602524696 250 // ----------------------------------------------------------------
nepes_ai 0:529602524696 251 void NeuroShieldSPI::reset()
nepes_ai 0:529602524696 252 {
nepes_ai 0:529602524696 253 //device.lock();
nepes_ai 0:529602524696 254
nepes_ai 0:529602524696 255 nm500_ss = LOW;
nepes_ai 0:529602524696 256 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 257 device.write((uint8_t)(module_fpga + 0x80)); // address (4-byte)
nepes_ai 0:529602524696 258 device.write(0);
nepes_ai 0:529602524696 259 device.write(0);
nepes_ai 0:529602524696 260 device.write(2); // nm500 sw reset : 0x02
nepes_ai 0:529602524696 261 device.write(0); // word size (3-byte)
nepes_ai 0:529602524696 262 device.write(0);
nepes_ai 0:529602524696 263 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 264 device.write(0);
nepes_ai 0:529602524696 265 device.write(0);
nepes_ai 0:529602524696 266 nm500_ss = HIGH;
nepes_ai 0:529602524696 267
nepes_ai 0:529602524696 268 //device.unlock();
nepes_ai 0:529602524696 269 }
nepes_ai 0:529602524696 270
nepes_ai 0:529602524696 271 // ----------------------------------------------------------------
nepes_ai 0:529602524696 272 // LED scenario select
nepes_ai 0:529602524696 273 // ----------------------------------------------------------------
nepes_ai 0:529602524696 274 void NeuroShieldSPI::ledSelect(uint8_t data)
nepes_ai 0:529602524696 275 {
nepes_ai 0:529602524696 276 //device.lock();
nepes_ai 0:529602524696 277
nepes_ai 0:529602524696 278 nm500_ss = LOW;
nepes_ai 0:529602524696 279 device.write(1); // Dummy for ID
nepes_ai 0:529602524696 280 device.write((uint8_t)(module_led + 0x80)); // address (4-byte)
nepes_ai 0:529602524696 281 device.write(0);
nepes_ai 0:529602524696 282 device.write(0);
nepes_ai 0:529602524696 283 device.write(data); // led scenario select
nepes_ai 0:529602524696 284 device.write(0); // word size (3-byte)
nepes_ai 0:529602524696 285 device.write(0);
nepes_ai 0:529602524696 286 device.write(1); // expect 1 word back
nepes_ai 0:529602524696 287 device.write(0);
nepes_ai 0:529602524696 288 device.write(0);
nepes_ai 0:529602524696 289 nm500_ss = HIGH;
nepes_ai 0:529602524696 290
nepes_ai 0:529602524696 291 //deviece.unlock();
nepes_ai 0:529602524696 292 }