Need Help with Possible SPI Issue with ESP32 on Arduino IDE - Page 1
Forum section: electronics / general

author: ProtoG42
author_rank: Contributor
timestamp: January 08, 2018, 03:59:49 pm
content: I'm using an ESP32 to to trigger 16 outputs with SPI and an NXP MC33996.Here's the data sheet:https://www.nxp.com/docs/en/data-sheet/MC33996.pdfI made a small breakout board with 16 LEDs(one for each output). My code works fine except output 8 and output 0 are not turning on. They just so happen to be the outputs associated with the last bit of the last two bytes sent to the chip. I've tried turning on one LED on at a time but I still miss output 8 and output 0. There are no shorts on the board and all the LEDs have been tested in circuit. Any ideas? See the code below for turning on all LEDs at once:#include <SPI.h>#define CSpin 5/*ESP32 SPI PINOUT MISO 19 MOSI 23 SLK 18 CS 5 */int dlay = 100;void setup() {Serial.begin(115200);SPI.setClockDivider(SPI_CLOCK_DIV8);SPI.setDataMode(SPI_MODE1);SPI.setBitOrder(MSBFIRST);pinMode(CSpin, OUTPUT);digitalWrite(CSpin, HIGH);SPI.begin(); }void loop() {Serial.println("ON"); digitalWrite(CSpin, LOW); //select slaveSPI.transfer(0b00000000); //commandSPI.transfer(0b11111111); //first 8 outputs ONSPI.transfer(0b11111111); //last 8 outputs ONdigitalWrite(CSpin, HIGH); //de-select slavedelay(dlay);}//end of main

author: phil from seattle
author_rank: Super Contributor
timestamp: January 08, 2018, 07:05:29 pm
content: Please use code tags for posting code. Makes it more likely that people will actually help you.This all looks straightforward. Do you have a logic analyzer or scope with protocol modules available? I'd look to see if the right things are being sent to the MC33996. In a pinch you could make an SPI watcher with another processor (arduino or what ever). The idea is to figure out which side is screwing up.I'd also dig around the ESP32 sites to see if this an ESP32 issue.

author: mikerj
author_rank: Super Contributor
timestamp: January 08, 2018, 07:06:01 pm
content: Missing the first bit can happen when the SPI mode is set incorrectly, although the MC33996 looks to be a Mode 1 device which you have set. Is it possible the ESP32 library is a bit buggy? Have you checked the SPI bus with a scope to ensure Mode 1 is being set correctly?

author: ProtoG42
author_rank: Contributor
timestamp: January 08, 2018, 08:14:31 pm
content: Quote from: phil from seattle on January 08, 2018, 07:05:29 pmHow do I use code tags? I'm going to try with a different MCU first and then use my logic analyzer to check the SPI integrity.Quote from: mikerj on January 08, 2018, 07:06:01 pmI posted in the ESP32 github repository to see if it's a known issue. I'll update here if I figure out the problem.

author: ProtoG42
author_rank: Contributor
timestamp: January 08, 2018, 09:34:48 pm
content: Just tried it with an Atmel ATmega168 and it works just fine with the same exact code. Hmmm...

author: phil from seattle
author_rank: Super Contributor
timestamp: January 08, 2018, 10:14:32 pm
content: Well, that settles the question of where the problem lies!See the hash button in the row above the emoticons for inserting code.

author: ProtoG42
author_rank: Contributor
timestamp: January 09, 2018, 03:05:41 am
content: Here's a picture of the decoded SPI from the ATmega168:Here's a picture of the decoded SPI from the ESP32:They both decode to the same value: 00000000 - 11111111 - 11111111Which is what the code is instructing them to do but the ATmega seems to keep the MOSI(purple) high between bytes and the ESP32 pulls MOSI low between bytes.The NXP MC33996 is rated for 6MHz. I've tried SPI @2MHz and @4MHz with no luck. Any ideas?

author: ProtoG42
author_rank: Contributor
timestamp: January 09, 2018, 10:39:13 pm
content: So I just tried a few thing and I managed to consistently pick up the last bit of the second byte but I'm still missing the last bit of the third byte.Here's a screenshot of my attempt at passing 32bits with SPI.transfer32():The NXP MC3396 doesn't seem to like the 32bit transfer and doesn't turn any of the outputs on.Here's a screenshot of first transferring 8bits with SPI.transfer(0b00000000) and then transferring the 16bits associated with the outputs with SPI.transfer16(0b1111111111111111):That works and I can get the last bit of the second byte but I'm still missing the last bit of the third byte.Here's another screenshot with the same technique at 125kHz:Looking back at the ATmega168 screenshot above, the MCU keeps MOSI high even after the clock stops until the chip select pin is pull back high. Is there anyway to do something similar with the ESP32?I didn't seem to notice a difference between change the SPI mode from 0, 1, 2, or 3. Is that potentially the issue? The NXP MC33996 responds the same with all SPI modes and all outputs but output 0 work fine.The decoding from my scope matches exactly with my code so everything seems fine.

author: ProtoG42
author_rank: Contributor
timestamp: January 10, 2018, 12:45:21 am
content: If anyone is interested, I found the issue and discussed it on the github repository here:https://github.com/espressif/arduino-esp32/issues/981#issuecomment-356460989

author: TomS_
author_rank: Frequent Contributor
timestamp: January 10, 2018, 10:39:46 am
content: Quote from: ProtoG42 on January 09, 2018, 03:05:41 amCan you post a screen cap more closely zoomed in on one byte of the ESP transmission?Some crude measurements on my screen here, but it allllmost looks like the MOSI pin is going low maybe slightly before the clock pin does with the ESP module. Dont forget - how the scope interprets your SPI signal may be entirely different to how the LED driver does... The scope has the advantage of software, whereas the hardware doesnt.If that is the case, and since the ESP module brings MOSI low between bytes, maybe this is causing the LED driver to read the last bit of each byte as a zero, hence you "lose" those bits? It seems somewhat coincidental, given the ATmega leaves the MOSI pin high.