esp12 max3421e и arduino ide

Grigory
Offline
Зарегистрирован: 29.03.2014

Доброго дня, подключил max3421e к esp12, пытаюсь данные со сканера ШК отправлять на сервак. Но ни ка не могу прочитать данные с max3421. Прошивка на esp стоит NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4. 

вот теперь думаю как мне из esp сделать хост и читать данные со сканера шк 

Grigory
Offline
Зарегистрирован: 29.03.2014

USB_Host_Shield_2.0-master пытаюсь через эту библиотеку читать данные с max3421, но IDE говорит не буду заливать скеч на esp 

 

Logik
Offline
Зарегистрирован: 05.08.2014

Как раз сейчас ковыряю esp8266-01. И прошивка похожа, чуть старше.

NodeMCU 0.9.5 build 20150213  powered by Lua 5.1.4
 
Отлично работает с ESPlorer v0.1. 
Но разумеется пишу на ЛУНе. 
Вы уверены что эта прошивка может работать с ИДЕ ардуины? Я например очень не уверен в этом. Хотя в  обратном тоже, но если сказано  by Lua то это  by Lua.
Grigory
Offline
Зарегистрирован: 29.03.2014

стандартные вещи на lua прекрассно отрабатывают, но вот работа с hspi для меня дебри

Logik
Offline
Зарегистрирован: 05.08.2014

Давайте не про дебрм, а выясним таки совместима ли такая прошивка с ИДЕ Ардуины.

ПС. SPI ногодрыгом не напрягаясь за 15 минут. Можна и либы под лун поискать. Был несказанно удивлен как нашел под лун либки sha1 и base64. Думал безнадежно. Реализация в них конечно мрачная, работоспособность еще не проверял. Но факт - есть в наличии :)

Logik
Offline
Зарегистрирован: 05.08.2014

Кстати spi в луне плохо искали - https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru#spisetup

Grigory
Offline
Зарегистрирован: 29.03.2014

читал эту документацию, однако пришел к выводу что на max нужно отправлять нужные команды((( 

вчера попробовал этот скеч 

01#include <SPI.h>
02#include <SPI_ESP.h>
03 
04 
05uint8_t errorCode = 0;
06 
07SPI_ESP mySPI = SPI_ESP(D1,D2);
08 
09void setup()
10{
11    Serial.begin(38400);
12    //long unsigned debug_start = millis();
13    //while (!Serial && ((millis() - debug_start) <= 5000));
14    errorCode = mySPI.begin();
15    if (errorCode) {
16        Serial.println(">> SPI FIFO ready <<");
17        Serial.print("Using bus:SPI");
18        Serial.println(mySPI.getSPIbus());
19    }
20    else {
21        Serial.println(">> ERROR <<");
22        if (bitRead(errorCode, 0) == 0) {
23            Serial.print("mosi,sclk or miso pin mismatch!");
24        }
25        else if (bitRead(errorCode, 1) == 0){
26            Serial.print("cs pin mismatch");
27        }
28        else if (bitRead(errorCode, 2) == 0) {
29            Serial.print("dc pin mismatch");
30        }
31    }
32 
33}
34 
35void loop()
36{
37 
38 
39}
40 
41/*
42writeByte_cont(data,dataMode)
43writeByte_last(data,dataMode)
44writeWord_cont(data,dataMode)
45writeWord_last(data,dataMode)
46dataMode default is false, mean command mode. This is true only when DC pin is configured or it will be ignored
47Here's an example of use, we have 2 basic type of functions, _cont and _last, _cont = pull down CS, _last = pull Up it (disable)
48after trasfer data so must be used as last one, if you just have one trasfer, use always _last.
49It's important start with startTransaction and end with endTransaction!
50In this example a byte is tranfered using only CS (even you you are using the dc pin as well)
51If you want transfer a byte in data mode (such used in some OLED/TFT libraries), use:
52mySPI.writeByte_last(data,true);
53*/
54void writeByte(byte data)
55{
56    mySPI.startTransaction();
57    mySPI.writeByte_last(data);
58    mySPI.endTransaction();
59}

но в ответ сыится абракадабра в сериал порт

Logik
Offline
Зарегистрирован: 05.08.2014

Grigory пишет:

читал эту документацию, однако пришел к выводу что на max нужно отправлять нужные команды((( 

Какой ужас! Не может быть! Нада слать шо попало, а не нужные команды;)

ПС. Эпопея с либкой для SHA1 развивалась так. Нашол их даже несколько, одна страшней другой. И ни одна не становится, всем "not enough memory". Начал еще искать, выбирая поменьше. Попалась одна совсем мелкая, аж подозрительно. Открываю и вижу... ну вобщем не нужна либка. Код

1cred="12345678"
2print(crypto.toHex(crypto.hash("sha1",cred)))
 
Правильно считает sha1 для заданой строки )))
Это я к чему: изучайте "нужные команды" а не на либки надейтесь. Их часто пишут полные долбаки.
Grigory
Offline
Зарегистрирован: 29.03.2014

согласен, но spi и работа с байтами для меня темный лес

Logik
Offline
Зарегистрирован: 05.08.2014

Так и ESP как появилось, было всем - темный лес, ниче, просеки рубим, чащу прореживаем. Так и Вы, раз вззялись - не бойтесь доки читать и код писать, все приложится.

Grigory
Offline
Зарегистрирован: 29.03.2014

итак вот что поучилось сделать

01-- Config
02local MISO = 6            --> GPIO14
03local CLK = 5             --> GPIO12
04local CS = 7              --> GPIO13
05local duration = 3000     --> 3 seconds
06local i = 0
07local result = 0
08 
09-- Pin Initialization
10gpio.mode(CS, gpio.OUTPUT)
11gpio.mode(CLK, gpio.OUTPUT)
12gpio.mode(MISO, gpio.INPUT)
13gpio.write(CS,gpio.HIGH)
14 
15-- Function to read SPI
16function readSPI()
17    gpio.write(CS, gpio.LOW)      -->Activate the chip
18    tmr.delay(1)                  -->1us Delay
19 
20    gpio.write(CLK, gpio.HIGH)    -->First bit is dummy, ignore it(refer MAX6675 datasheet)
21    tmr.delay(2)
22    gpio.write(CLK, gpio.LOW)
23    tmr.delay(2)
24 
25    result = 0
26     
27   for i=15,1,-1
28    do
29      result = bit.lshift(result, 1)
30      result = bit.bor(result ,(bit.band(gpio.read(MISO),0x01)))
31      gpio.write(CLK, gpio.HIGH)  
32      print(result)
33      tmr.delay(2)
34      gpio.write(CLK, gpio.LOW)
35      tmr.delay(2)
36    end
37    if(bit.isset(result,2)) then
38        print("Sensor not connected")
39        gpio.write(CS, gpio.HIGH)
40        do return end
41    end
42         
43    gpio.write(CS, gpio.HIGH)
44    print(bit.rshift(result,3))
45 
46end
47 
48-- Create an interval
49tmr.alarm(0, duration, 1, readSPI)

в этом варианте приходит 

1
3
7
15
31
63
127
255
511
1023
2047
4095
8191
16383
32767
Sensor not connected
 
если  поставить
1local MISO = 5            --> GPIO14
2local CLK = 6             --> GPIO12

то постоянно возвращается 0 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Что то или я туплю, но я вообще не могу понять что вы тут написали. Во первых, в SPI две линии передачи данных MOSI и MISO, по первой передаются данные от MASTER устройства к SLAVE, по второй - наоборот. У вас я вижу только одну в описании пинов. Или может быть у вас не SPI интерфейс?

К чему была в конце текста перетасовка пинов, я вообще не понял. Если у вас устройство с интерфейсом SPI, то берется стандартная библиотека SPI и с ней работаете. Зачем все эти извраты с ручным дерганьем пинов я вообще не могу понять.

Grigory
Offline
Зарегистрирован: 29.03.2014

я пробовал на lua и через arduino ide, esp использует spi для работы с flash памятью на борту, доступ к max3421 идет через hspi. 

Grigory
Offline
Зарегистрирован: 29.03.2014

на lua я не нашел информации на эту тему, вот и эксперементирую 

AlexeySh
Offline
Зарегистрирован: 16.01.2017

В общем скачал я даташит по Max3421, там обычный SPI интерфейс. Подключаете как обычно 5-ю проводами (4 сигнальных и земля) и используете библиотеку SPI для управления. И все у вас будет работать.

Grigory
Offline
Зарегистрирован: 29.03.2014
001/*
002    SPI Master Demo Sketch
003    Connect the SPI Master device to the following pins on the esp8266:
004 
005    GPIO    NodeMCU   Name  |   Uno
006   ===================================
007     15       D8       SS   |   D10
008     13       D7      MOSI  |   D11
009     12       D6      MISO  |   D12
010     14       D5      SCK   |   D13
011 
012    Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected)
013    the ESP8266 WILL FAIL to boot!
014    See SPISlave_SafeMaster example for possible workaround
015 
016*/
017#include <SPI.h>
018 
019class ESPMaster
020{
021private:
022    uint8_t _ss_pin;
023 
024public:
025    ESPMaster(uint8_t pin):_ss_pin(pin) {}
026    void begin()
027    {
028        pinMode(_ss_pin, OUTPUT);
029        digitalWrite(_ss_pin, HIGH);
030    }
031 
032    uint32_t readStatus()
033    {
034        digitalWrite(_ss_pin, LOW);
035        SPI.transfer(0x04);
036        uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24));
037        digitalWrite(_ss_pin, HIGH);
038        return status;
039    }
040 
041    void writeStatus(uint32_t status)
042    {
043        digitalWrite(_ss_pin, LOW);
044        SPI.transfer(0x01);
045        SPI.transfer(status & 0xFF);
046        SPI.transfer((status >> 8) & 0xFF);
047        SPI.transfer((status >> 16) & 0xFF);
048        SPI.transfer((status >> 24) & 0xFF);
049        digitalWrite(_ss_pin, HIGH);
050    }
051 
052    void readData(uint8_t * data)
053    {
054        digitalWrite(_ss_pin, LOW);
055        SPI.transfer(0x03);
056        SPI.transfer(0x00);
057        for(uint8_t i=0; i<32; i++) {
058            data[i] = SPI.transfer(0);
059        }
060        digitalWrite(_ss_pin, HIGH);
061    }
062 
063    void writeData(uint8_t * data, size_t len)
064    {
065        uint8_t i=0;
066        digitalWrite(_ss_pin, LOW);
067        SPI.transfer(0x02);
068        SPI.transfer(0x00);
069        while(len-- && i < 32) {
070            SPI.transfer(data[i++]);
071        }
072        while(i++ < 32) {
073            SPI.transfer(0);
074        }
075        digitalWrite(_ss_pin, HIGH);
076    }
077 
078    String readData()
079    {
080        char data[33];
081        data[32] = 0;
082        readData((uint8_t *)data);
083        return String(data);
084    }
085 
086    void writeData(const char * data)
087    {
088        writeData((uint8_t *)data, strlen(data));
089    }
090};
091 
092ESPMaster esp(SS);
093 
094void send(const char * message)
095{
096    Serial.print("Master: ");
097    Serial.println(message);
098    esp.writeData(message);
099    delay(10);
100    Serial.print("Slave: ");
101    Serial.println(esp.readData());
102    Serial.println();
103}
104 
105void setup()
106{
107    Serial.begin(115200);
108    SPI.begin();
109    esp.begin();
110    delay(1000);
111    send("Hello Slave!");
112}
113 
114void loop()
115{
116    delay(1000);
117    send("Are you alive?");
118}

При данном варианте постоянно возвращается строка "яяяяяяяяяяяяяяяяяяяяяяя", хотя сканер ШК производит сканировнаие

Grigory
Offline
Зарегистрирован: 29.03.2014

?

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Библиотеку SPI выложите которую используете. Что то мне не нравится ваша инициализация SPI.

Grigory
Offline
Зарегистрирован: 29.03.2014
001/*
002 SPI.cpp - SPI library for esp8266
003 
004 Copyright (c) 2015 Hristo Gochkov. All rights reserved.
005 This file is part of the esp8266 core for Arduino environment.
006  
007 This library is free software; you can redistribute it and/or
008 modify it under the terms of the GNU Lesser General Public
009 License as published by the Free Software Foundation; either
010 version 2.1 of the License, or (at your option) any later version.
011 
012 This library is distributed in the hope that it will be useful,
013 but WITHOUT ANY WARRANTY; without even the implied warranty of
014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 Lesser General Public License for more details.
016 
017 You should have received a copy of the GNU Lesser General Public
018 License along with this library; if not, write to the Free Software
019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020 */
021 
022#include "SPI.h"
023#include "HardwareSerial.h"
024 
025typedef union {
026        uint32_t regValue;
027        struct {
028                unsigned regL :6;
029                unsigned regH :6;
030                unsigned regN :6;
031                unsigned regPre :13;
032                unsigned regEQU :1;
033        };
034} spiClk_t;
035 
036SPIClass::SPIClass() {
037    useHwCs = false;
038}
039 
040void SPIClass::begin() {
041    pinMode(SCK, SPECIAL);  ///< GPIO14
042    pinMode(MISO, SPECIAL); ///< GPIO12
043    pinMode(MOSI, SPECIAL); ///< GPIO13
044 
045    SPI1C = 0;
046    setFrequency(1000000); ///< 1MHz
047    SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE;
048    SPI1U1 = (7 << SPILMOSI) | (7 << SPILMISO);
049    SPI1C1 = 0;
050}
051 
052void SPIClass::end() {
053    pinMode(SCK, INPUT);
054    pinMode(MISO, INPUT);
055    pinMode(MOSI, INPUT);
056    if(useHwCs) {
057        pinMode(SS, INPUT);
058    }
059}
060 
061void SPIClass::setHwCs(bool use) {
062    if(use) {
063        pinMode(SS, SPECIAL); ///< GPIO15
064        SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
065    } else {
066        if(useHwCs) {
067            pinMode(SS, INPUT);
068            SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
069        }
070    }
071    useHwCs = use;
072}
073 
074void SPIClass::beginTransaction(SPISettings settings) {
075    while(SPI1CMD & SPIBUSY) {}
076    setFrequency(settings._clock);
077    setBitOrder(settings._bitOrder);
078    setDataMode(settings._dataMode);
079}
080 
081void SPIClass::endTransaction() {
082}
083 
084void SPIClass::setDataMode(uint8_t dataMode) {
085 
086    /**
087     SPI_MODE0 0x00 - CPOL: 0  CPHA: 0
088     SPI_MODE1 0x01 - CPOL: 0  CPHA: 1
089     SPI_MODE2 0x10 - CPOL: 1  CPHA: 0
090     SPI_MODE3 0x11 - CPOL: 1  CPHA: 1
091     */
092 
093    bool CPOL = (dataMode & 0x10); ///< CPOL (Clock Polarity)
094    bool CPHA = (dataMode & 0x01); ///< CPHA (Clock Phase)
095 
096    if(CPHA) {
097        SPI1U |= (SPIUSME);
098    } else {
099        SPI1U &= ~(SPIUSME);
100    }
101 
102    if(CPOL) {
103        SPI1P |= 1<<29;
104    } else {
105        SPI1P &= ~(1<<29);
106        //todo test whether it is correct to set CPOL like this.
107    }
108 
109}
110 
111void SPIClass::setBitOrder(uint8_t bitOrder) {
112    if(bitOrder == MSBFIRST) {
113        SPI1C &= ~(SPICWBO | SPICRBO);
114    } else {
115        SPI1C |= (SPICWBO | SPICRBO);
116    }
117}
118 
119/**
120 * calculate the Frequency based on the register value
121 * @param reg
122 * @return
123 */
124static uint32_t ClkRegToFreq(spiClk_t * reg) {
125    return (ESP8266_CLOCK / ((reg->regPre + 1) * (reg->regN + 1)));
126}
127 
128void SPIClass::setFrequency(uint32_t freq) {
129    static uint32_t lastSetFrequency = 0;
130    static uint32_t lastSetRegister = 0;
131 
132    if(freq >= ESP8266_CLOCK) {
133        setClockDivider(0x80000000);
134        return;
135    }
136 
137    if(lastSetFrequency == freq && lastSetRegister == SPI1CLK) {
138        // do nothing (speed optimization)
139        return;
140    }
141 
142    const spiClk_t minFreqReg = { 0x7FFFF000 };
143    uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
144    if(freq < minFreq) {
145        // use minimum possible clock
146        setClockDivider(minFreqReg.regValue);
147        lastSetRegister = SPI1CLK;
148        lastSetFrequency = freq;
149        return;
150    }
151 
152    uint8_t calN = 1;
153 
154    spiClk_t bestReg = { 0 };
155    int32_t bestFreq = 0;
156 
157    // find the best match
158    while(calN <= 0x3F) { // 0x3F max for N
159 
160        spiClk_t reg = { 0 };
161        int32_t calFreq;
162        int32_t calPre;
163        int8_t calPreVari = -2;
164 
165        reg.regN = calN;
166 
167        while(calPreVari++ <= 1) { // test different variants for Pre (we calculate in int so we miss the decimals, testing is the easyest and fastest way)
168            calPre = (((ESP8266_CLOCK / (reg.regN + 1)) / freq) - 1) + calPreVari;
169            if(calPre > 0x1FFF) {
170                reg.regPre = 0x1FFF; // 8191
171            } else if(calPre <= 0) {
172                reg.regPre = 0;
173            } else {
174                reg.regPre = calPre;
175            }
176 
177            reg.regL = ((reg.regN + 1) / 2);
178            // reg.regH = (reg.regN - reg.regL);
179 
180            // test calculation
181            calFreq = ClkRegToFreq(&reg);
182            //os_printf("-----[0x%08X][%d]\t EQU: %d\t Pre: %d\t N: %d\t H: %d\t L: %d = %d\n", reg.regValue, freq, reg.regEQU, reg.regPre, reg.regN, reg.regH, reg.regL, calFreq);
183 
184            if(calFreq == (int32_t) freq) {
185                // accurate match use it!
186                memcpy(&bestReg, &reg, sizeof(bestReg));
187                break;
188            } else if(calFreq < (int32_t) freq) {
189                // never go over the requested frequency
190                if(abs(freq - calFreq) < abs(freq - bestFreq)) {
191                    bestFreq = calFreq;
192                    memcpy(&bestReg, &reg, sizeof(bestReg));
193                }
194            }
195        }
196        if(calFreq == (int32_t) freq) {
197            // accurate match use it!
198            break;
199        }
200        calN++;
201    }
202 
203    // os_printf("[0x%08X][%d]\t EQU: %d\t Pre: %d\t N: %d\t H: %d\t L: %d\t - Real Frequency: %d\n", bestReg.regValue, freq, bestReg.regEQU, bestReg.regPre, bestReg.regN, bestReg.regH, bestReg.regL, ClkRegToFreq(&bestReg));
204 
205    setClockDivider(bestReg.regValue);
206    lastSetRegister = SPI1CLK;
207    lastSetFrequency = freq;
208 
209}
210 
211void SPIClass::setClockDivider(uint32_t clockDiv) {
212    if(clockDiv == 0x80000000) {
213        GPMUX |= (1 << 9); // Set bit 9 if sysclock required
214    } else {
215        GPMUX &= ~(1 << 9);
216    }
217    SPI1CLK = clockDiv;
218}
219 
220inline void SPIClass::setDataBits(uint16_t bits) {
221    const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
222    bits--;
223    SPI1U1 = ((SPI1U1 & mask) | ((bits << SPILMOSI) | (bits << SPILMISO)));
224}
225 
226uint8_t SPIClass::transfer(uint8_t data) {
227    while(SPI1CMD & SPIBUSY) {}
228    // reset to 8Bit mode
229    setDataBits(8);
230    SPI1W0 = data;
231    SPI1CMD |= SPIBUSY;
232    while(SPI1CMD & SPIBUSY) {}
233    return (uint8_t) (SPI1W0 & 0xff);
234}
235 
236uint16_t SPIClass::transfer16(uint16_t data) {
237    union {
238            uint16_t val;
239            struct {
240                    uint8_t lsb;
241                    uint8_t msb;
242            };
243    } in, out;
244    in.val = data;
245 
246    if((SPI1C & (SPICWBO | SPICRBO))) {
247        //LSBFIRST
248        out.lsb = transfer(in.lsb);
249        out.msb = transfer(in.msb);
250    } else {
251        //MSBFIRST
252        out.msb = transfer(in.msb);
253        out.lsb = transfer(in.lsb);
254    }
255    return out.val;
256}
257 
258void SPIClass::write(uint8_t data) {
259    while(SPI1CMD & SPIBUSY) {}
260    // reset to 8Bit mode
261    setDataBits(8);
262    SPI1W0 = data;
263    SPI1CMD |= SPIBUSY;
264    while(SPI1CMD & SPIBUSY) {}
265}
266 
267void SPIClass::write16(uint16_t data) {
268    write16(data, !(SPI1C & (SPICWBO | SPICRBO)));
269}
270 
271void SPIClass::write16(uint16_t data, bool msb) {
272    while(SPI1CMD & SPIBUSY) {}
273    // Set to 16Bits transfer
274    setDataBits(16);
275    if(msb) {
276        // MSBFIRST Byte first
277        SPI1W0 = (data >> 8) | (data << 8);
278        SPI1CMD |= SPIBUSY;
279    } else {
280        // LSBFIRST Byte first
281        SPI1W0 = data;
282        SPI1CMD |= SPIBUSY;
283    }
284    while(SPI1CMD & SPIBUSY) {}
285}
286 
287void SPIClass::write32(uint32_t data) {
288    write32(data, !(SPI1C & (SPICWBO | SPICRBO)));
289}
290 
291void SPIClass::write32(uint32_t data, bool msb) {
292    while(SPI1CMD & SPIBUSY) {}
293    // Set to 32Bits transfer
294    setDataBits(32);
295    if(msb) {
296        union {
297                uint32_t l;
298                uint8_t b[4];
299        } data_;
300        data_.l = data;
301        // MSBFIRST Byte first
302        SPI1W0 = (data_.b[3] | (data_.b[2] << 8) | (data_.b[1] << 16) | (data_.b[0] << 24));
303        SPI1CMD |= SPIBUSY;
304    } else {
305        // LSBFIRST Byte first
306        SPI1W0 = data;
307        SPI1CMD |= SPIBUSY;
308    }
309    while(SPI1CMD & SPIBUSY) {}
310}
311 
312/**
313 * Note:
314 *  data need to be aligned to 32Bit
315 *  or you get an Fatal exception (9)
316 * @param data uint8_t *
317 * @param size uint32_t
318 */
319void SPIClass::writeBytes(uint8_t * data, uint32_t size) {
320    while(size) {
321        if(size > 64) {
322            writeBytes_(data, 64);
323            size -= 64;
324            data += 64;
325        } else {
326            writeBytes_(data, size);
327            size = 0;
328        }
329    }
330}
331 
332void SPIClass::writeBytes_(uint8_t * data, uint8_t size) {
333    while(SPI1CMD & SPIBUSY) {}
334    // Set Bits to transfer
335    setDataBits(size * 8);
336 
337    volatile uint32_t * fifoPtr = &SPI1W0;
338    uint32_t * dataPtr = (uint32_t*) data;
339    uint8_t dataSize = ((size + 3) / 4);
340 
341    while(dataSize--) {
342        *fifoPtr = *dataPtr;
343        dataPtr++;
344        fifoPtr++;
345    }
346 
347    SPI1CMD |= SPIBUSY;
348    while(SPI1CMD & SPIBUSY) {}
349}
350 
351/**
352 * @param data uint8_t *
353 * @param size uint8_t  max for size is 64Byte
354 * @param repeat uint32_t
355 */
356void SPIClass::writePattern(uint8_t * data, uint8_t size, uint32_t repeat) {
357    if(size > 64) return; //max Hardware FIFO
358 
359    while(SPI1CMD & SPIBUSY) {}
360 
361    uint32_t buffer[16];
362    uint8_t *bufferPtr=(uint8_t *)&buffer;
363    uint8_t *dataPtr = data;
364    volatile uint32_t * fifoPtr = &SPI1W0;
365    uint8_t r;
366    uint32_t repeatRem;
367    uint8_t i;
368 
369    if((repeat * size) <= 64){
370        repeatRem = repeat * size;
371        r = repeat;
372        while(r--){
373            dataPtr = data;
374            for(i=0; i<size; i++){
375                *bufferPtr = *dataPtr;
376                bufferPtr++;
377                dataPtr++;
378            }
379        }
380 
381        r = repeatRem;
382        if(r & 3) r = r / 4 + 1;
383        else r = r / 4;
384        for(i=0; i<r; i++){
385            *fifoPtr = buffer[i];
386            fifoPtr++;
387        }
388        SPI1U = SPIUMOSI | SPIUSSE;
389    } else {
390        //Orig
391        r = 64 / size;
392        repeatRem = repeat % r * size;
393        repeat = repeat / r;
394 
395        while(r--){
396            dataPtr = data;
397            for(i=0; i<size; i++){
398                *bufferPtr = *dataPtr;
399                bufferPtr++;
400                dataPtr++;
401            }
402        }
403 
404        //Fill fifo with data
405        for(i=0; i<16; i++){
406            *fifoPtr = buffer[i];
407            fifoPtr++;
408        }
409 
410        r = 64 / size;
411 
412        SPI1U = SPIUMOSI | SPIUSSE;
413        setDataBits(r * size * 8);
414        while(repeat--){
415            SPI1CMD |= SPIBUSY;
416            while(SPI1CMD & SPIBUSY) {}
417        }
418    }
419    //End orig
420    setDataBits(repeatRem * 8);
421    SPI1CMD |= SPIBUSY;
422    while(SPI1CMD & SPIBUSY) {}
423 
424    SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE;
425}
426 
427/**
428 * Note:
429 *  in and out need to be aligned to 32Bit
430 *  or you get an Fatal exception (9)
431 * @param out uint8_t *
432 * @param in  uint8_t *
433 * @param size uint32_t
434 */
435void SPIClass::transferBytes(uint8_t * out, uint8_t * in, uint32_t size) {
436    while(size) {
437        if(size > 64) {
438            transferBytes_(out, in, 64);
439            size -= 64;
440            if(out) out += 64;
441            if(in) in += 64;
442        } else {
443            transferBytes_(out, in, size);
444            size = 0;
445        }
446    }
447}
448 
449void SPIClass::transferBytes_(uint8_t * out, uint8_t * in, uint8_t size) {
450    while(SPI1CMD & SPIBUSY) {}
451    // Set in/out Bits to transfer
452 
453    setDataBits(size * 8);
454 
455    volatile uint32_t * fifoPtr = &SPI1W0;
456    uint8_t dataSize = ((size + 3) / 4);
457 
458    if(out) {
459        uint32_t * dataPtr = (uint32_t*) out;
460        while(dataSize--) {
461            *fifoPtr = *dataPtr;
462            dataPtr++;
463            fifoPtr++;
464        }
465    } else {
466        // no out data only read fill with dummy data!
467        while(dataSize--) {
468            *fifoPtr = 0xFFFFFFFF;
469            fifoPtr++;
470        }
471    }
472 
473    SPI1CMD |= SPIBUSY;
474    while(SPI1CMD & SPIBUSY) {}
475 
476    if(in) {
477        volatile uint8_t * fifoPtr8 = (volatile uint8_t *) &SPI1W0;
478        dataSize = size;
479        while(dataSize--) {
480            *in = *fifoPtr8;
481            in++;
482            fifoPtr8++;
483        }
484    }
485}
486 
487#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SPI)
488SPIClass SPI;
489#endif

а это заголовочный

 

01/*
02  SPI.h - SPI library for esp8266
03 
04  Copyright (c) 2015 Hristo Gochkov. All rights reserved.
05  This file is part of the esp8266 core for Arduino environment.
06  
07  This library is free software; you can redistribute it and/or
08  modify it under the terms of the GNU Lesser General Public
09  License as published by the Free Software Foundation; either
10  version 2.1 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License along with this library; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20*/
21#ifndef _SPI_H_INCLUDED
22#define _SPI_H_INCLUDED
23 
24#include <Arduino.h>
25#include <stdlib.h>
26 
27#define SPI_HAS_TRANSACTION
28 
29// This defines are not representing the real Divider of the ESP8266
30// the Defines match to an AVR Arduino on 16MHz for better compatibility
31#define SPI_CLOCK_DIV2      0x00101001 //8 MHz
32#define SPI_CLOCK_DIV4      0x00241001 //4 MHz
33#define SPI_CLOCK_DIV8      0x004c1001 //2 MHz
34#define SPI_CLOCK_DIV16     0x009c1001 //1 MHz
35#define SPI_CLOCK_DIV32     0x013c1001 //500 KHz
36#define SPI_CLOCK_DIV64     0x027c1001 //250 KHz
37#define SPI_CLOCK_DIV128    0x04fc1001 //125 KHz
38 
39const uint8_t SPI_MODE0 = 0x00; ///<  CPOL: 0  CPHA: 0
40const uint8_t SPI_MODE1 = 0x01; ///<  CPOL: 0  CPHA: 1
41const uint8_t SPI_MODE2 = 0x10; ///<  CPOL: 1  CPHA: 0
42const uint8_t SPI_MODE3 = 0x11; ///<  CPOL: 1  CPHA: 1
43 
44class SPISettings {
45public:
46  SPISettings() :_clock(1000000), _bitOrder(LSBFIRST), _dataMode(SPI_MODE0){}
47  SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) :_clock(clock), _bitOrder(bitOrder), _dataMode(dataMode){}
48  uint32_t _clock;
49  uint8_t  _bitOrder;
50  uint8_t  _dataMode;
51};
52 
53class SPIClass {
54public:
55  SPIClass();
56  void begin();
57  void end();
58  void setHwCs(bool use);
59  void setBitOrder(uint8_t bitOrder); 
60  void setDataMode(uint8_t dataMode);
61  void setFrequency(uint32_t freq);
62  void setClockDivider(uint32_t clockDiv);
63  void beginTransaction(SPISettings settings);
64  uint8_t transfer(uint8_t data);
65  uint16_t transfer16(uint16_t data);
66  void write(uint8_t data);
67  void write16(uint16_t data);
68  void write16(uint16_t data, bool msb);
69  void write32(uint32_t data);
70  void write32(uint32_t data, bool msb);
71  void writeBytes(uint8_t * data, uint32_t size);
72  void writePattern(uint8_t * data, uint8_t size, uint32_t repeat);
73  void transferBytes(uint8_t * out, uint8_t * in, uint32_t size);
74  void endTransaction(void);
75private:
76  bool useHwCs;
77  void writeBytes_(uint8_t * data, uint8_t size);
78  void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
79  inline void setDataBits(uint16_t bits);
80};
81 
82#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SPI)
83extern SPIClass SPI;
84#endif
85 
86#endif

 

Grigory
Offline
Зарегистрирован: 29.03.2014

вот с чем работаю

AlexeySh
Offline
Зарегистрирован: 16.01.2017

Я понял так, что посылаемые через SPI команды выполняются. Но в ответ приходит всякая ерунда. Правильно?

В таком случае проверьте синтаксис команды чтения с SPI. Может быть есть несоответсвие с даташитом.