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