NM500 / NeuroShield

Dependents:   NeuroShield_SimpleScript NeuroShield_andIMU NeuroShield_Gesture_Recognition

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NeuroShieldSPI.cpp Source File

NeuroShieldSPI.cpp

00001 /*
00002  * NeuroShield.cpp - Driver for NeuroShield
00003  * Copyright (c) 2016, General Vision Inc, All rights reserved
00004  * Copyright (c) 2017, nepes inc, All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  * 1. Redistributions of source code must retain the above copyright notice,
00010  * this list of conditions and the following disclaimer.
00011  *
00012  * 2. Redistributions in binary form must reproduce the above copyright notice,
00013  * this list of conditions and the following disclaimer in the documentation
00014  * and/or other materials provided with the distribution.
00015  *
00016  * 3. Neither the name of the copyright holder nor the names of its contributors
00017  * may be used to endorse or promote products derived from this software without
00018  * specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00021  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00024  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00025  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00026  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00029  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030  * POSSIBILITY OF SUCH DAMAGE.
00031  *
00032  */
00033 
00034 /*
00035  * Revision History (v1.1.5)
00036  * 2020/02/04    v1.1.5    Add dummy for switching between sd-card and nm spi
00037  * 2018/06/22    v1.1.4    Minor changes
00038  * 2018/01/03    v1.1.3    Add burst-mode read
00039  * 2017/12/20    v1.1.2    Modify the structure of neurondata
00040  * 2017/12/11    v1.1.1    Add Powersave command and Minor changes to the library
00041  * 2017/08/17    v1.0.0    First Release
00042  */
00043 
00044 #include "mbed.h"
00045 #include <NeuroShield.h>
00046 #include <NeuroShieldSPI.h>
00047 
00048 SPI device(SPI_MOSI, SPI_MISO, SPI_SCK);    // PA_7, PA_6, PA_5
00049 DigitalOut nm500_ss(D7);                    // NM500_SSn
00050 
00051 // ------------------------------------------------------------ //
00052 //    Constructor to the class ShieldSPI
00053 // ------------------------------------------------------------ 
00054 NeuroShieldSPI::NeuroShieldSPI(){ 
00055 }
00056 
00057 // ------------------------------------------------------------ 
00058 // Initialize the SPI communication and verify proper interface
00059 // to the NM500 by reading the default Minif value of 2-bytes
00060 // return an error=0 otherwise=1
00061 // ------------------------------------------------------------ 
00062 bool NeuroShieldSPI::connect()
00063 {
00064     uint16_t read_value;
00065     
00066     // for shield board test
00067     nm500_ss = HIGH;
00068     
00069     //
00070     device.format(8,0);
00071     device.frequency(2000000);  // 2MHz
00072     
00073     // return 1 if NM500 present and SPI comm successful
00074     for (int i = 0; i < 10; i++) {
00075         reset();    // NM500 reset
00076         wait_ms(100);
00077         write(NM_FORGET, 0);
00078         wait_ms(50);
00079         read_value = read(NM_MINIF);
00080         if (read_value == 2)
00081             return(1);
00082         wait_ms(50);
00083     }
00084     
00085     return(0);
00086 }
00087 
00088 // --------------------------------------------------------
00089 // SPI Read the register of a given module (module + reg = addr)
00090 //---------------------------------------------------------
00091 uint16_t NeuroShieldSPI::read(uint8_t reg)
00092 {
00093     //device.lock();
00094     
00095     device.write(0xff);                     // dummy for switching between sd-card and nm spi
00096     
00097     nm500_ss = LOW;
00098     device.write(1);                        // Dummy for ID
00099     device.write((uint8_t)module_nm500);
00100     device.write(0);
00101     device.write(0);
00102     device.write(reg);
00103     device.write(0);
00104     device.write(0);
00105     device.write(1);                        // expect 1 word back
00106     uint16_t data = device.write(0);        // Send 0 to push upper data out
00107     data = (data << 8) + device.write(0);   // Send 0 to push lower data out
00108     nm500_ss = HIGH;
00109     
00110     //device.unlock();
00111     
00112     return(data);
00113 }
00114 
00115 void NeuroShieldSPI::readVector16(uint16_t* data, uint16_t size)
00116 {
00117     //device.lock();
00118     
00119     device.write(0xff);                                 // dummy for switching between sd-card and nm spi
00120     
00121     nm500_ss = LOW;
00122     device.write(1);
00123     device.write((uint8_t)module_nm500);
00124     device.write(0);
00125     device.write(0);
00126     device.write(NM_COMP);
00127     device.write(0);
00128     device.write((uint8_t)((size >> 8) & 0x00FF));
00129     device.write((uint8_t)(size & 0x00FF));
00130     for (int i = 0; i < size; i++) {
00131         *data = device.write(0);
00132         *data = (*data << 8) + device.write(0);
00133         data++;
00134     }
00135     nm500_ss = HIGH;
00136     
00137     //device.unlock();
00138 }
00139 
00140 // ---------------------------------------------------------
00141 // SPI Write the register of a given module (module + reg = addr)
00142 // ---------------------------------------------------------
00143 void NeuroShieldSPI::write(uint8_t reg, uint16_t data)
00144 {
00145     //device.lock();
00146     
00147     device.write(0xff);                                 // dummy for switching between sd-card and nm spi
00148     
00149     nm500_ss = LOW;
00150     device.write(1);                                    // Dummy for ID
00151     device.write((uint8_t)(module_nm500 + 0x80));       // module and write flag
00152     device.write(0);
00153     device.write(0);
00154     device.write(reg);
00155     device.write(0);
00156     device.write(0);
00157     device.write(1);                                    // expect 1 word back
00158     if ((reg == NM_COMP) || (reg == NM_LCOMP)) {
00159         device.write(0x00);                             // upper data
00160         device.write((uint8_t)(data & 0x00FF));         // lower data
00161     }
00162     else {
00163         device.write((uint8_t)((data >> 8) & 0x00FF));  // upper data
00164         device.write((uint8_t)(data & 0x00FF));         // lower data
00165     }
00166     nm500_ss = HIGH;
00167     
00168     //device.unlock();
00169 }
00170 
00171 // ----------------------------------------------------------------
00172 // SPI Write burst mode at COMP register
00173 // ----------------------------------------------------------------
00174 uint16_t NeuroShieldSPI::writeVector(uint8_t* data, uint16_t size)
00175 {
00176     if (size > NEURON_SIZE)                         // to use SR-mode
00177         return(0);
00178     
00179     //device.lock();
00180     
00181     device.write(0xff);                             // dummy for switching between sd-card and nm spi
00182     
00183     nm500_ss = LOW;
00184     device.write(1);                                // Dummy for ID
00185     device.write((uint8_t)(module_nm500 + 0x80));   // module and write flag
00186     device.write(0);
00187     device.write(0);
00188     device.write(NM_COMP);
00189     device.write(0);
00190     device.write((uint8_t)((size >> 8) & 0x00FF));
00191     device.write((uint8_t)(size & 0x00FF));         // 1 ~ 256 byte
00192     for (int i = 0; i < size; i++) {
00193         device.write(0x00);                         // COMP' upper data = 0x00
00194         device.write((uint8_t)(*data));             // lower data
00195         data++;
00196     }
00197     nm500_ss = HIGH;
00198     
00199     //device.unlock();
00200     
00201     return(size);
00202 }
00203 
00204 uint16_t NeuroShieldSPI::writeVector16(uint16_t* data, uint16_t size)
00205 {
00206     if (size > NEURON_SIZE)                         // to use SR-mode
00207         return(0);
00208     
00209     //device.lock();
00210     
00211     device.write(0xff);                             // dummy for switching between sd-card and nm spi
00212     
00213     nm500_ss = LOW;
00214     device.write(1);                                // Dummy for ID
00215     device.write((uint8_t)(module_nm500 + 0x80));   // module and write flag
00216     device.write(0);
00217     device.write(0);
00218     device.write(NM_COMP);
00219     device.write(0);
00220     device.write((uint8_t)((size >> 8) & 0x00FF));
00221     device.write((uint8_t)(size & 0x00FF));         // 1 ~ 256 byte
00222     for (int i = 0; i < size; i++) {
00223         device.write(0x00);                         // COMP' upper data = 0x00
00224         device.write((uint8_t)((*data) & 0x00FF));  // lower data
00225         data++;
00226     }
00227     nm500_ss = HIGH;
00228     
00229     //device.unlock();
00230     
00231     return(size);
00232 }
00233 
00234 // ----------------------------------------------------------------
00235 // read FPGA Version
00236 // ----------------------------------------------------------------
00237 uint16_t NeuroShieldSPI::version()
00238 {
00239     //device.lock();
00240     
00241     device.write(0xff);                     // dummy for switching between sd-card and nm spi
00242     
00243     nm500_ss = LOW;
00244     device.write(1);                        // Dummy for ID
00245     device.write((uint8_t)module_fpga);     // address (4-byte)
00246     device.write(0);
00247     device.write(0);
00248     device.write(1);                        // version check : 0x01
00249     device.write(0);                        // word size (3-byte)
00250     device.write(0);
00251     device.write(1);
00252     uint16_t data = device.write(0);        // Send 0 to push upper data out
00253     data = (data << 8) + device.write(0);   // Send 0 to push lower data out
00254     nm500_ss = HIGH;
00255     
00256     //device.unlock();
00257     
00258     return(data);
00259 }
00260 
00261 // ----------------------------------------------------------------
00262 // excute NM500 SW reset
00263 // ----------------------------------------------------------------
00264 void NeuroShieldSPI::reset()
00265 {
00266     //device.lock();
00267     
00268     device.write(0xff);                             // dummy for switching between sd-card and nm spi
00269     
00270     nm500_ss = LOW;
00271     device.write(1);                                // Dummy for ID
00272     device.write((uint8_t)(module_fpga + 0x80));    // address (4-byte)
00273     device.write(0);
00274     device.write(0);
00275     device.write(2);                                // nm500 sw reset : 0x02
00276     device.write(0);                                // word size (3-byte)
00277     device.write(0);
00278     device.write(1);                                // expect 1 word back
00279     device.write(0);
00280     device.write(0);
00281     nm500_ss = HIGH;
00282     
00283     //device.unlock();
00284 }
00285 
00286 // ----------------------------------------------------------------
00287 // LED scenario select
00288 // ----------------------------------------------------------------
00289 void NeuroShieldSPI::ledSelect(uint8_t data)
00290 {
00291     //device.lock();
00292     
00293     device.write(0xff);                             // dummy for switching between sd-card and nm spi
00294     
00295     nm500_ss = LOW;
00296     device.write(1);                                // Dummy for ID
00297     device.write((uint8_t)(module_led + 0x80));     // address (4-byte)
00298     device.write(0);
00299     device.write(0);
00300     device.write(data);                             // led scenario select
00301     device.write(0);                                // word size (3-byte)
00302     device.write(0);
00303     device.write(1);                                // expect 1 word back
00304     device.write(0);
00305     device.write(0);
00306     nm500_ss = HIGH;
00307     
00308     //deviece.unlock();
00309 }