fix nrf51822 i2c & spi conflict
Dependencies: BLE_API eMPL_MPU6050 nRF51822
Fork of Seeed_Tiny_BLE_Flash by
Revision 4:19a0764d6b81, committed 2015-11-13
- 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
--- /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();