diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 1ed9a09cb..af6d99468 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -227,6 +227,13 @@ FlashMode_t EspClass::getFlashChipMode(void) */ uint32_t EspClass::getFlashChipSizeByChipId(void) { uint32_t chipId = getFlashChipId(); + /** + * Chip ID + * 00 - always 00 (Chip ID use only 3 byte) + * 17 - ? looks like 2^xx is size in Byte ? //todo: find docu to this + * 40 - ? may be Speed ? //todo: find docu to this + * C8 - manufacturer ID + */ switch(chipId) { // GigaDevice diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index 347259f4d..9292c8895 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -1,79 +1,117 @@ /* - SPI.cpp - SPI library for esp8266 + SPI.cpp - SPI library for esp8266 - Copyright (c) 2015 Hristo Gochkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "SPI.h" +#include "HardwareSerial.h" +typedef struct { + uint32_t divider; + uint32_t regValue; +} spiClockDiv_t; + +static const spiClockDiv_t spiClockDiv[] = { + { 0, (0x80000000) }, ///< @80Mhz = 80 MHz @160Mhz = 160 MHz + { 2, (0x00001001) }, ///< @80Mhz = 40 MHz @160Mhz = 80 MHz + { 4, (0x00041001) }, ///< @80Mhz = 20 MHz @160Mhz = 40 MHz + { 6, (0x000fffc0) }, ///< @80Mhz = 16 MHz @160Mhz = 32 MHz + { 8, (0x000c1001) }, ///< @80Mhz = 10 MHz @160Mhz = 20 MHz + { 10, (0x00101001) }, ///< @80Mhz = 8 MHz @160Mhz = 16 MHz + { 16, (0x001c1001) }, ///< @80Mhz = 5 MHz @160Mhz = 10 MHz + { 20, (0x00241001) }, ///< @80Mhz = 4 MHz @160Mhz = 8 MHz + { 40, (0x004c1001) }, ///< @80Mhz = 2 MHz @160Mhz = 4 MHz + { 80, (0x009c1001) }, ///< @80Mhz = 1 MHz @160Mhz = 2 MHz + { 160, (0x013c1001) }, ///< @80Mhz = 500 KHz @160Mhz = 1 MHz + { 320, (0x027c1001) }, ///< @80Mhz = 250 KHz @160Mhz = 500 KHz + { 640, (0x04fc1001) } ///< @80Mhz = 125 KHz @160Mhz = 250 KHz +}; + +static const uint8_t spiClockDiv_count = (sizeof(spiClockDiv) / sizeof(spiClockDiv_t)); SPIClass SPI; -SPIClass::SPIClass(){} +SPIClass::SPIClass() { +} -void SPIClass::begin(){ - pinMode(SCK, SPECIAL); - pinMode(MISO, SPECIAL); - pinMode(MOSI, SPECIAL); - - GPMUX = 0x105; - SPI1C = 0; - SPI1CLK = SPI_CLOCK_DIV16;//1MHz - SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; - SPI1U1 = (7 << SPILMOSI) | (7 << SPILMISO); - SPI1C1 = 0; +void SPIClass::begin() { + pinMode(SCK, SPECIAL); ///< GPIO14 + pinMode(MISO, SPECIAL); ///< GPIO12 + pinMode(MOSI, SPECIAL); ///< GPIO13 + + GPMUX = 0x105; // note crash if spi flash Frequency < 40MHz + SPI1C = 0; + setFrequency(1000000); ///< 1Mhz + SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE; + SPI1U1 = (7 << SPILMOSI) | (7 << SPILMISO); + SPI1C1 = 0; } void SPIClass::end() { - pinMode(SCK, INPUT); - pinMode(MISO, INPUT); - pinMode(MOSI, INPUT); + pinMode(SCK, INPUT); + pinMode(MISO, INPUT); + pinMode(MOSI, INPUT); } void SPIClass::beginTransaction(SPISettings settings) { - setClockDivider(settings._clock); - setBitOrder(settings._bitOrder); - setDataMode(settings._dataMode); + setFrequency(settings._clock); + setBitOrder(settings._bitOrder); + setDataMode(settings._dataMode); } -void SPIClass::endTransaction() {} +void SPIClass::endTransaction() { +} void SPIClass::setDataMode(uint8_t dataMode) { - + // todo find way to set } void SPIClass::setBitOrder(uint8_t bitOrder) { - if (bitOrder == MSBFIRST) { - SPI1C &= ~(SPICWBO | SPICRBO); - } else { - SPI1C |= (SPICWBO | SPICRBO); - } + if(bitOrder == MSBFIRST) { + SPI1C &= ~(SPICWBO | SPICRBO); + } else { + SPI1C |= (SPICWBO | SPICRBO); + } +} + +void SPIClass::setFrequency(uint32_t freq) { + uint8_t i = 0; + // find the best match + if(freq < F_CPU) { + for(i = 1; i < (spiClockDiv_count-1); i++) { + if(freq >= (F_CPU/spiClockDiv[i].divider)) { + break; + } + } + } + setClockDivider(spiClockDiv[i].regValue); } void SPIClass::setClockDivider(uint32_t clockDiv) { - SPI1CLK = clockDiv; + SPI1CLK = clockDiv; } uint8_t SPIClass::transfer(uint8_t data) { - while(SPI1CMD & SPIBUSY); - SPI1W0 = data; - SPI1CMD |= SPIBUSY; - while(SPI1CMD & SPIBUSY); - return (uint8_t)(SPI1W0 & 0xff); + while(SPI1CMD & SPIBUSY); + SPI1W0 = data; + SPI1CMD |= SPIBUSY; + while(SPI1CMD & SPIBUSY); + return (uint8_t) (SPI1W0 & 0xff); } uint16_t SPIClass::transfer16(uint16_t data) { diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index 5ff10d3a3..3daf57c62 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -26,35 +26,8 @@ #define FCPU80 80000000L -#if F_CPU == FCPU80 -#define SPI_CLOCK_DIV80M 0x80000000 //80 MHz -#define SPI_CLOCK_DIV40M 0x00001001 //40 MHz -#define SPI_CLOCK_DIV20M 0x00041001 //20 MHz -#define SPI_CLOCK_DIV16M 0x000fffc0 //16 MHz -#define SPI_CLOCK_DIV10M 0x000c1001 //10 MHz -#define SPI_CLOCK_DIV2 0x00101001 //8 MHz -#define SPI_CLOCK_DIV5M 0x001c1001 //5 MHz -#define SPI_CLOCK_DIV4 0x00241001 //4 MHz -#define SPI_CLOCK_DIV8 0x004c1001 //2 MHz -#define SPI_CLOCK_DIV16 0x009c1001 //1 MHz -#define SPI_CLOCK_DIV32 0x013c1001 //500 KHz -#define SPI_CLOCK_DIV64 0x027c1001 //250 KHz -#define SPI_CLOCK_DIV128 0x04fc1001 //125 KHz -#else -#define SPI_CLOCK_DIV160M 0x80000000 //160 MHz -#define SPI_CLOCK_DIV80M 0x00001001 //80 MHz -#define SPI_CLOCK_DIV40M 0x00041001 //40 MHz -#define SPI_CLOCK_DIV32M 0x000fffc0 //32 MHz -#define SPI_CLOCK_DIV20M 0x000c1001 //20 MHz -#define SPI_CLOCK_DIV16M 0x00101001 //16 MHz -#define SPI_CLOCK_DIV10M 0x001c1001 //10 MHz -#define SPI_CLOCK_DIV2 0x00241001 //8 MHz -#define SPI_CLOCK_DIV4 0x004c1001 //4 MHz -#define SPI_CLOCK_DIV8 0x009c1001 //2 MHz -#define SPI_CLOCK_DIV16 0x013c1001 //1 MHz -#define SPI_CLOCK_DIV32 0x027c1001 //500 KHz -#define SPI_CLOCK_DIV64 0x04fc1001 //250 KHz -#endif + + const uint8_t SPI_MODE0 = 0x00; const uint8_t SPI_MODE1 = 0x04; @@ -63,7 +36,7 @@ const uint8_t SPI_MODE3 = 0x0C; class SPISettings { public: - SPISettings() :_clock(SPI_CLOCK_DIV16), _bitOrder(LSBFIRST), _dataMode(SPI_MODE0){} + SPISettings() :_clock(1000000), _bitOrder(LSBFIRST), _dataMode(SPI_MODE0){} SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) :_clock(clock), _bitOrder(bitOrder), _dataMode(dataMode){} uint32_t _clock; uint8_t _bitOrder; @@ -77,6 +50,7 @@ public: void end(); void setBitOrder(uint8_t bitOrder); void setDataMode(uint8_t dataMode); + void setFrequency(uint32_t freq); void setClockDivider(uint32_t clockDiv); void beginTransaction(SPISettings settings); uint8_t transfer(uint8_t data);