fix nrf51822 i2c & spi conflict

Dependencies:   BLE_API eMPL_MPU6050 nRF51822

Fork of Seeed_Tiny_BLE_Flash by Darren Huang

Files at this revision

API Documentation at this revision

Comitter:
SOTB_DA
Date:
Fri Nov 13 08:22:27 2015 +0000
Parent:
3:24e365bd1b97
Child:
5:b8c02645e6af
Commit message:
try to add flash on tiny ble

Changed in this revision

W25Q16BV/W25Q16BV.cpp Show annotated file Show diff for this revision Revisions of this file
W25Q16BV/W25Q16BV.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/W25Q16BV/W25Q16BV.cpp	Fri Nov 13 08:22:27 2015 +0000
@@ -0,0 +1,252 @@
+// W25Q16BV.cpp
+
+#include"W25Q16BV.h"
+
+// CONSTRUCTOR 
+W25Q16BV::W25Q16BV(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi, miso, sclk), _cs(cs) {
+    _spi.format(SPI_NBIT, SPI_MODE);
+    _spi.frequency(SPI_FREQ);
+    chipDisable();
+
+    exitDeepPowerDown();
+    // The SPI Flash cannot safely be accessed the first 1-10 ms after power ON
+//    wait_us(WAIT_US_TPUW);
+}
+
+
+// READING
+int W25Q16BV::readByte(int addr) {
+    chipEnable();
+    _spi.write(R_INST);
+    _spi.write((addr >> 16) & 0xff);
+    _spi.write((addr >>  8) & 0xff);
+    _spi.write((addr      ) & 0xff);
+    int response = _spi.write(DUMMY_ADDR);
+    chipDisable();
+    return response;
+}
+int W25Q16BV::readByte(int a2, int a1, int a0) {
+   chipEnable();
+   _spi.write(R_INST);
+   _spi.write(a2);
+   _spi.write(a1);
+   _spi.write(a0);
+   int response = _spi.write(DUMMY_ADDR);
+    chipDisable();
+    return response;
+}
+void W25Q16BV::readStream(int addr, char* buf, int count) {
+    if (count < 1)
+        return;
+    chipEnable();
+    _spi.write(R_INST);
+    _spi.write((addr >> 16) & 0xff);
+    _spi.write((addr >>  8) & 0xff);
+    _spi.write((addr      ) & 0xff);
+    for (int i = 0; i < count; i++)
+        buf[i] =  _spi.write(DUMMY_ADDR);
+    chipDisable();
+}
+void W25Q16BV::readJEDEC(uint8_t* manId, uint8_t* memType, uint8_t* cap)
+{
+    chipEnable();
+    _spi.write(JDEC_INST);
+    *manId = _spi.write(DUMMY_ADDR);
+    *memType = _spi.write(DUMMY_ADDR);
+    *cap = _spi.write(DUMMY_ADDR);
+    chipDisable();
+}
+uint8_t W25Q16BV::readStatus1()
+{
+  uint8_t status;
+  chipEnable();
+  _spi.write(STATUS1_INST);
+  status = _spi.write(DUMMY_ADDR);
+  chipDisable();
+  return status;
+}
+uint8_t W25Q16BV::readStatus2()
+{
+  uint8_t status;
+  chipEnable();
+  _spi.write(STATUS2_INST);
+  status = _spi.write(DUMMY_ADDR);
+  chipDisable();
+  return status;
+}
+
+// WRITING
+void W25Q16BV::writeByte(int addr, int data) {
+    writeEnable();
+    chipEnable();
+    _spi.write(W_INST);
+    _spi.write((addr >> 16) & 0xff);
+    _spi.write((addr >>  8) & 0xff);
+    _spi.write((addr      ) & 0xff);
+    _spi.write(data);
+    chipDisable();
+    writeDisable();
+//    wait_us(WAIT_US_TBP);
+    waitWhileBusy();
+}
+void W25Q16BV::writeByte(int a2, int a1, int a0, int data) {
+    writeEnable();
+    chipEnable();
+    _spi.write(W_INST);
+    _spi.write(a2);
+    _spi.write(a1);
+    _spi.write(a0);
+    _spi.write(data);
+    chipDisable();
+    writeDisable();
+//    wait_us(WAIT_US_TBP);
+    waitWhileBusy();
+}
+#if 0
+void W25Q16BV::writeStream(int addr, char* buf, int count) {
+    if (count < 1)
+        return;
+    writeEnable();
+    chipEnable();
+    _spi.write(W_INST);
+    _spi.write((addr & ADDR_BMASK2) >> ADDR_BSHIFT2);
+    _spi.write((addr & ADDR_BMASK1) >> ADDR_BSHIFT1);
+    _spi.write((addr & ADDR_BMASK0) >> ADDR_BSHIFT0);
+    for (int i = 0; i < count; i++)
+        _spi.write(buf[i]);
+    chipDisable();
+    writeDisable();
+    wait(WAIT_TIME_MS);
+}
+#else
+void W25Q16BV::writeStream(int addr, char* buf, int count)
+{
+  int left = count;
+  int offset = 0;
+  int len = 0;
+  
+  if (count < 1) {
+    return;
+  }
+    
+  // find length of first page write
+  if ((addr / PAGE_SIZE) != ((addr + count) / PAGE_SIZE)) {
+    //spans across at least one boundary
+    len = PAGE_SIZE - (addr % PAGE_SIZE);
+  } else {
+    // ends inside same page => use normal length
+    len = count % PAGE_SIZE;
+  }
+  
+  //break up large write operation into several page write operations
+  while (left > 0) {
+    writeEnable();
+    chipEnable();
+    _spi.write(W_INST);
+    _spi.write(((addr + offset) >> 16) & 0xff);
+    _spi.write(((addr + offset) >>  8) & 0xff);
+    _spi.write(((addr + offset)      ) & 0xff);
+    for (int i = 0; i < len; i++) {
+      _spi.write(buf[offset + i]);
+    }
+    chipDisable();
+    //writeDisable();
+    
+    offset += len;
+    left -= len;
+    len = (left < PAGE_SIZE) ? left : PAGE_SIZE;
+    
+    //wait_us(WAIT_US_TPP);
+    waitWhileBusy();
+  }
+}
+#endif
+
+//ERASING
+void W25Q16BV::chipErase() {
+    writeEnable();
+    chipEnable();
+    _spi.write(C_ERASE_INST);
+    chipDisable();
+//    writeDisable();
+//    wait_us(WAIT_US_TCE);
+    waitWhileBusy();
+}
+bool W25Q16BV::blockErase(int startBlock, int num) {
+  if ((num < 1) || (startBlock < 0) || ((startBlock+num) > NUM_64KB_BLOCKS)) {
+    return false;
+  }
+  for (int i = 0; i < num; i++) {
+    writeEnable();
+    chipEnable();
+    _spi.write(B_ERASE_INST);
+    _spi.write(startBlock + i);
+    _spi.write(0);
+    _spi.write(0);
+    chipDisable();
+//    writeDisable();
+//    wait_us(WAIT_US_TBE);
+    waitWhileBusy();
+  }
+  return true;
+}
+bool W25Q16BV::sectorErase(int startSector, int num) {
+  if ((num < 1) || (startSector < 0) || ((startSector+num) > NUM_SECTORS)) {
+    return false;
+  }
+  int addr = startSector * SECTOR_SIZE;
+  for (int i = 0; i < num; i++) {
+    writeEnable();
+    chipEnable();
+    _spi.write(S_ERASE_INST);
+    _spi.write((addr >> 16) & 0xff);
+    _spi.write((addr >>  8) & 0xff);
+    _spi.write((addr      ) & 0xff);
+    chipDisable();
+//    writeDisable();
+//    wait_us(WAIT_US_TSE);
+    waitWhileBusy();
+    
+    addr += SECTOR_SIZE;
+  }
+  return true;
+}
+
+// Wakeup from deep power down (default state)
+void W25Q16BV::exitDeepPowerDown() {
+    chipEnable();
+    _spi.write(POWERUP_INST);
+    chipDisable();
+  wait_us(WAIT_US_TRES1);
+}
+
+void W25Q16BV::waitWhileBusy() {
+  uint8_t status = 0;
+  int i = 0;
+
+  do {
+    for (i = 0; i < 0x2000; i++);
+
+    status = readStatus1();
+  }
+  while ((status & STATUS_1_BUSY) != 0);
+}
+
+//ENABLE/DISABLE (private functions)
+void W25Q16BV::writeEnable() {
+    chipEnable();
+    _spi.write(WE_INST);
+    chipDisable();
+}
+void W25Q16BV::writeDisable() {
+    chipEnable();
+    _spi.write(WD_INST);
+    chipDisable();
+}
+void W25Q16BV::chipEnable() {
+    _cs = 0;
+}
+void W25Q16BV::chipDisable() {
+    _cs = 1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/W25Q16BV/W25Q16BV.h	Fri Nov 13 08:22:27 2015 +0000
@@ -0,0 +1,87 @@
+// W25Q16BV.h
+
+#ifndef W25Q16BV_H
+#define W25Q16BV_H
+
+#include "mbed.h"
+//#include "BitBangedSPI.h"
+
+#define SPI_FREQ        1000000
+#define SPI_MODE        0
+#define SPI_NBIT        8
+
+#define POWERUP_INST    0xAB
+#define STATUS1_INST    0x05
+#define STATUS2_INST    0x35
+#define JDEC_INST       0x9F
+#define UNIQUE_INST     0x4B
+#define WE_INST         0x06
+#define WD_INST         0x04
+#define R_INST          0x03
+#define W_INST          0x02
+#define S_ERASE_INST    0x20  /* 4KB sector erase */
+#define B_ERASE_INST    0xD8  /* 64KB block erase */
+#define C_ERASE_INST    0x60
+
+#define DUMMY_ADDR      0x00
+
+#define WAIT_US_TRES1          5   /* Power Up:                 3us */
+//#define WAIT_US_TPUW       10000   /* Power Up Write Time:   1-10ms */
+//#define WAIT_US_TBP           50   /* Byte Program Time:    20-50us */
+//#define WAIT_US_TPP         3000   /* Page Program Time:    0.7-3ms */
+//#define WAIT_US_TSE       400000   /* Sector Erase Time:   30-400ms */
+//#define WAIT_US_TBE      1000000   /* 64KB Block Erase Time: 1000ms */
+//#define WAIT_US_TCE     10000000   /* Chip Erase Time:       3-10s  */
+
+//#define ADDR_BMASK2     0x00ff0000
+//#define ADDR_BMASK1     0x0000ff00
+//#define ADDR_BMASK0     0x000000ff
+
+//#define ADDR_BSHIFT2    16
+//#define ADDR_BSHIFT1    8
+//#define ADDR_BSHIFT0    0
+
+#define PAGE_SIZE          256
+#define SECTOR_SIZE       4096
+#define NUM_SECTORS        512
+#define NUM_64KB_BLOCKS     32
+
+#define STATUS_1_BUSY     0x01
+
+class W25Q16BV /*: public BitBangedSPI*/ {
+public:
+    W25Q16BV(PinName mosi, PinName miso, PinName sclk, PinName cs);
+    
+    int readByte(int addr);                                 // takes a 24-bit (3 bytes) address and returns the data (1 byte) at that location
+    int readByte(int a2, int a1, int a0);                   // takes the address in 3 separate bytes A[23,16], A[15,8], A[7,0]
+    void readStream(int addr, char* buf, int count);        // takes a 24-bit address, reads count bytes, and stores results in buf
+
+    void readJEDEC(uint8_t* manId, uint8_t* memType, uint8_t* cap);
+    uint8_t readStatus1();
+    uint8_t readStatus2();
+    
+    void writeByte(int addr, int data);                     // takes a 24-bit (3 bytes) address and a byte of data to write at that location
+    void writeByte(int a2, int a1, int a0, int data);       // takes the address in 3 separate bytes A[23,16], A[15,8], A[7,0]
+    void writeStream(int addr, char* buf, int count);       // write count bytes of data from buf to memory, starting at addr  
+    
+    void chipErase();                                       // erase all data on chip
+    bool blockErase(int startBlock, int num=1);             // erase all data in the specified number of 64KB blocks, return false if block number is invalid
+    bool sectorErase(int startSector, int num=1);           // erase all data in the specified number of  4KB sectors, return false if sector number is invalid
+    
+private:
+
+    void exitDeepPowerDown();
+    void waitWhileBusy();
+
+    void writeEnable();                                     // write enable
+    void writeDisable();                                    // write disable
+    void chipEnable();                                      // chip enable
+    void chipDisable();                                     // chip disable
+    
+//    BitBangedSPI _spi;
+    SPI _spi;
+    DigitalOut _cs;
+};
+
+#endif
+
--- a/main.cpp	Thu Nov 05 06:58:30 2015 +0000
+++ b/main.cpp	Fri Nov 13 08:22:27 2015 +0000
@@ -10,6 +10,16 @@
 #include "DFUService.h"
 #include "UARTService.h"
 
+#include "W25Q16BV.h"
+// flash
+DigitalOut vccFlash(p30, 1);
+#define PIN_SPI_MOSI p3
+#define PIN_SPI_MISO p5
+#define PIN_SPI_SCLK p4
+#define PIN_CS_FLASH p6
+W25Q16BV flash(PIN_SPI_MOSI, PIN_SPI_MISO, PIN_SPI_SCLK, PIN_CS_FLASH); // mosi,miso,clk,cs
+int offsetAddr = 0;
+bool saveBufferFull = false;
 
 #define LOG(...)    { pc.printf(__VA_ARGS__); }
 
@@ -28,7 +38,7 @@
 #define UART_RTS    p10
 
 /* Starting sampling rate. */
-#define DEFAULT_MPU_HZ  (100)
+#define DEFAULT_MPU_HZ  (200)
 
 DigitalOut blue(LED_BLUE);
 DigitalOut green(LED_GREEN);
@@ -73,13 +83,13 @@
     bleIsConnected = false;
 }
 
-void tick(void)
-{
-    static uint32_t count = 0;
-    
-    LOG("%d\r\n", count++);
-    green = !green;
-}
+//void tick(void)
+//{
+//    static uint32_t count = 0;
+//    
+//    LOG("%d\r\n", count++);
+//    green = !green;
+//}
 
 void detect(void)
 {
@@ -103,6 +113,45 @@
 }
 
 
+void saveMPUDataToFlash(int addr, unsigned long timestamp, short accel[3], short gyro[3], long quat[4])
+{
+    uint8_t mpuRawData[32] = {0,};
+    mpuRawData[0] = timestamp; 
+    mpuRawData[1] = timestamp>>8;
+    mpuRawData[2] = timestamp>>16;
+    mpuRawData[3] = timestamp>>24;
+    mpuRawData[4] = accel[0]; 
+    mpuRawData[5] = accel[0]>>8;
+    mpuRawData[6] = accel[1];
+    mpuRawData[7] = accel[1]>>8;
+    mpuRawData[8] = accel[2]; 
+    mpuRawData[9] = accel[2]>>8;
+    mpuRawData[10] = gyro[0];
+    mpuRawData[11] = gyro[0]>>8;
+    mpuRawData[12] = gyro[1]; 
+    mpuRawData[13] = gyro[1]>>8;
+    mpuRawData[14] = gyro[2];
+    mpuRawData[15] = gyro[2]>>8;
+    mpuRawData[16] = quat[0]; 
+    mpuRawData[17] = quat[0]>>8;
+    mpuRawData[18] = quat[0]>>16;
+    mpuRawData[19] = quat[0]>>24;
+    mpuRawData[20] = quat[1]; 
+    mpuRawData[21] = quat[1]>>8;
+    mpuRawData[22] = quat[1]>>16;
+    mpuRawData[23] = quat[1]>>24;
+    mpuRawData[24] = quat[2]; 
+    mpuRawData[25] = quat[2]>>8;
+    mpuRawData[26] = quat[2]>>16;
+    mpuRawData[27] = quat[2]>>24;
+    mpuRawData[28] = quat[3]; 
+    mpuRawData[29] = quat[3]>>8;
+    mpuRawData[30] = quat[3]>>16;
+    mpuRawData[31] = quat[3]>>24;
+    flash.writeStream(addr, (char *)mpuRawData, 32);
+    pc.printf("%02x %02x %02x %02x\r\n", mpuRawData[0], mpuRawData[1], mpuRawData[2], mpuRawData[3]);
+}
+
 int main(void)
 {
     blue  = 1;
@@ -111,6 +160,49 @@
 
     pc.baud(115200);
     
+    pc.printf("SPI init done\n");
+    flash.chipErase();
+    pc.printf("Flash Erase done\n");
+    uint8_t buff[128];
+    pc.printf("write after erase\r\n");
+    uint8_t datas[100] = {0,};
+    for (uint8_t i=0; i<100;i++) {
+        datas[i] = i+0x01;
+    }
+    long dfa = 32524;
+    datas[0] = dfa;
+    datas[1] = dfa >> 8;
+    datas[2] = dfa >> 16;
+    datas[3] = dfa >> 24;
+    flash.writeStream(100, (char *)datas, 100); 
+    
+    pc.printf("read after write\r\n");
+    flash.readStream(100, (char*)buff, 100);
+    for (int i=0; i<100; i++) {
+        pc.printf("%02x", buff[i]);
+    }
+    pc.printf("\r\n");
+    
+    pc.printf("%d\r\n", flash.readByte(0x34));
+    int tmp = 66;
+    pc.printf("%d\r\n", flash.readByte(tmp));
+    // read stream from 0x168
+    char str2[11] = {0};
+    flash.readStream(tmp, str2, 11);
+    pc.printf("%s\n",str2);
+    
+    for (int i=50; i< 150;i++){
+        pc.printf("%02x", flash.readByte(i));
+    }
+    pc.printf("\r\n");
+    
+    char string[] = "ABCDEFGHIJK";
+    flash.writeStream(tmp, string, 11);
+    
+    char str3[11] = {0};
+    flash.readStream(tmp, str3, 11);
+    pc.printf("%s\n",str3);
+    
     wait(1);
     
     LOG("---- Seeed Tiny BLE ----\n");
@@ -123,44 +215,27 @@
         LOG("failed to initialize mpu6050\r\n");
     }
     
-    /* Get/set hardware configuration. Start gyro. */
-    /* Wake up all sensors. */
     mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL);
-    /* Push both gyro and accel data into the FIFO. */
     mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL);
     mpu_set_sample_rate(DEFAULT_MPU_HZ);
-    
-    /* Read back configuration in case it was set improperly. */
-    unsigned char accel_fsr;
-    unsigned short gyro_rate, gyro_fsr;
-    mpu_get_sample_rate(&gyro_rate);
-    mpu_get_gyro_fsr(&gyro_fsr);
-    mpu_get_accel_fsr(&accel_fsr);
-    
+    mpu_set_gyro_fsr(2000);
+    mpu_set_accel_fsr(16);
     dmp_load_motion_driver_firmware();
     dmp_set_orientation(
         inv_orientation_matrix_to_scalar(board_orientation));
     dmp_register_tap_cb(tap_cb);
     dmp_register_android_orient_cb(android_orient_cb);
-    
     uint16_t dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
-                       DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
-                       DMP_FEATURE_GYRO_CAL;
+                       DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | 
+                       DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL;
     dmp_enable_feature(dmp_features);
     dmp_set_fifo_rate(DEFAULT_MPU_HZ);
     mpu_set_dmp_state(1);
-    
-    dmp_set_interrupt_mode(DMP_INT_GESTURE);
     dmp_set_tap_thresh(TAP_XYZ, 50);
     
     
     motion_probe.fall(motion_interrupt_handle);
 
-
-    
-    Ticker ticker;
-    ticker.attach(tick, 3);
-
     button.fall(detect);
 
     LOG("Initialising the nRF51822\n");
@@ -184,6 +259,10 @@
     ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
     ble.gap().startAdvertising();
     
+    
+    uint8_t tmp1[32] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};
+    Timer timer;
+    timer.start();
     while (true) {
         if (motion_event) {
             
@@ -208,6 +287,10 @@
                 dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,
                               &more);
                 
+//                saveMPUDataToFlash(offsetAddr, sensor_timestamp, accel, gyro, quat);
+//                char tmpe[32];
+//                flash.readStream(offsetAddr, tmpe, 32);
+//                pc.printf("%02x%02x%02x%02x\r\n", tmpe[0],tmpe[1],tmpe[2],tmpe[3]);
                 
                 /* Gyro and accel data are written to the FIFO by the DMP in chip
                  * frame and hardware units. This behavior is convenient because it
@@ -215,7 +298,7 @@
                  * mpu_read_fifo consistent.
                  */
                 if (sensors & INV_XYZ_GYRO) {
-                    // LOG("GYRO: %d, %d, %d\n", gyro[0], gyro[1], gyro[2]);
+                     LOG("time:%d, GYRO: %d, %d, %d\n", timer.read_ms(), gyro[0], gyro[1], gyro[2]);
                 }
                 if (sensors & INV_XYZ_ACCEL) {
                     //LOG("ACC: %d, %d, %d\n", accel[0], accel[1], accel[2]);
@@ -241,7 +324,20 @@
                     }
                 }
             }
-            
+            // test flash
+            flash.writeStream(offsetAddr, (char *)tmp1, 32);
+            char tmpe[32];
+            flash.readStream(offsetAddr, tmpe, 32);
+            for (int i=0; i<32; i++) {
+                pc.printf("%02x", tmpe[i]);
+                tmp1[i] += 1;
+            }
+            pc.printf("\r\n");
+            offsetAddr += 32;
+            if (offsetAddr >= 0xFFF) {
+                printf("one turn\r\n");
+                offsetAddr = 0;
+            }
             motion_event = 0;
         } else {
             ble.waitForEvent();