espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
12.95k stars 7.28k forks source link

unable to connect ESp32 S3 using SPI to a TRF7970A (works on arduino) #8314

Open marunlejo opened 1 year ago

marunlejo commented 1 year ago

Board

ESP32 S3

Device Description

UM Feather S3 board

Hardware Configuration

There will be multiple devices connected at the end but while testing the sensor, it is the only device connected using SPI lines, GPIO 10 for SS and, GPIO 7 for enable

Version

latest development Release Candidate (RC-X)

IDE Name

Arduino IDE

Operating System

Windows 11

Flash frequency

80Mhz

PSRAM enabled

yes

Upload speed

115200

Description

Using the Arduino IDE with ESP IDF I have try to communicate with a TRF7970. The commands seem to go out of the microcontroller but the sensor does not respond to it. Also I am unable to read commands back. this is only happening with this sensor. I can use the same microcontroller with other devices. The TRF7970 sensor is in good condition since I can control it with two other microcontrollers (the MSP430 and the Arduino UNO) I tried multiple SPI configurations but nothing has work so far for the ESP. the sketch example is only trying to read the values of some of the registers after sending a reset to the TRF7970A

Sketch

#include <Arduino.h>
#include <SPI.h>

#define TRF_ENABLE 6
#define TRF_CS 10

void setup() {
  Serial.begin(9600);

  Serial.println("starting");

  pinMode(TRF_ENABLE, OUTPUT);
    pinMode(TRF_CS, OUTPUT);

  digitalWrite(TRF_CS, HIGH);
  delay(4); //required delay between CS and enable pin only once
    digitalWrite(TRF_ENABLE, HIGH);
  delay(5);

  SPI.setDataMode(SPI_MODE1);
    SPI.setBitOrder(MSBFIRST);
  SPI.begin();

  delay(5);

  SPI_directCommand(0x03);  // soft init
    SPI_directCommand(0x00);  // idle
  delay(1);
  SPI_directCommand(0x0F);
  Serial.println("after rst");
}

void loop() {
  while(1){
    SPI_directCommand(0x03);  // soft init
    SPI_directCommand(0x00);  // idle

    Serial.print("ISO control: ");
    Serial.println(SPI_readReg(0x41));
    delay(1000);

    Serial.print("Chip status control: ");
    Serial.println(SPI_readReg(0x40));
    delay(1000);

    Serial.print("RSSI levels and oscillator status: ");
    Serial.println(SPI_readReg(0x4F));
    delay(1000);
  }
}

void SPI_directCommand(uint8_t ui8Command)
{   
    digitalWrite(TRF_CS, LOW);                      // Start SPI Mode

    // set Address/Command Word Bit Distribution to command
    ui8Command = (0x80 | ui8Command);                   // command
    ui8Command = (0x9f & ui8Command);                   // command code

    SPI.transfer(ui8Command);

    digitalWrite(TRF_CS, HIGH);                         //Stop SPI Mode
}

//-------------------------------------------------------

uint8_t SPI_readReg(uint8_t reg)
{
  uint8_t received;
    digitalWrite(TRF_CS, LOW);                      // Start SPI Mode

    SPI.transfer(reg);
    received = SPI.transfer(0);

    digitalWrite(TRF_CS, HIGH);                         // Stop SPI Mode
  return received;
}

Debug Message

On ESP32 S3:
ISO control: 0
Chip status control: 0
RSSI levels and oscillator status: 0

on arduino uno:
ISO control: 33
Chip status control: 1
RSSI levels and oscillator status: 64

Other Steps to Reproduce

the program communicate correctly on Arduino uno and the MSP430. the sensor receive the commands correctly and responds back in these two. I have also try to change the esp32 in case that the one I am using has any kind of problem but none of the other ones connect to the sensor correctly

I have checked existing issues, online documentation and the Troubleshooting Guide

SuGlider commented 1 year ago

@marunlejo - How are the other GPIO connected (CLK, MISO, MOSI)? It may be just a typo, but in the description it says that GPIO 7 is EN, but the code uses GPIO 6.

me-no-dev commented 1 year ago

I will also suggest to use SPI settings before each transaction:

void SPI_directCommand(uint8_t ui8Command)
{
  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE1));
  digitalWrite(TRF_CS, LOW);                        // Start SPI Mode
  // set Address/Command Word Bit Distribution to command
  ui8Command = (0x80 | ui8Command);                 // command
  ui8Command = (0x9f & ui8Command);                 // command code
  SPI.transfer(ui8Command);
  digitalWrite(TRF_CS, HIGH);                       //Stop SPI Mode
  SPI.endTransaction();
}

uint8_t SPI_readReg(uint8_t reg)
{
  uint8_t received;
  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE1));
  digitalWrite(TRF_CS, LOW);
  SPI.transfer(reg);
  received = SPI.transfer(0);
  digitalWrite(TRF_CS, HIGH);
  SPI.endTransaction();
  return received;
}
me-no-dev commented 1 year ago

BTW are you sure that SPI should be in MODE1?

marunlejo commented 1 year ago

I did not specify the GPIO of the SPI pins since they are different from one ESP from another. and yes I forgot to change pin 7 to pin 6 on my description. but I do have it connected correctly.

@me-no-dev I will included. I imagine it does not make to much diference when using only one component about the MODE1 yes I am sure from the timing diagram on the datasheet and because it does work correctly using an Arduino UNO.

The commands since to go out of the MISO line on the ESP but there is not reaction on the sensor.

Is there any special configuration for ESP other than set the SPI configuration on each transaction?

me-no-dev commented 1 year ago

Is there any special configuration for ESP other than set the SPI configuration on each transaction?

No and transactions are not strictly necessary, but very much recommended on ESP as they ensure that code is safe. Our SPI so far has worked with everything, so it is really strange that you can not get it going.

marunlejo commented 1 year ago

I got communication with the device now. it took me some time. The datasheet suggest a 2MHz on SPI but It did not work until I increase it to 4MHz or 8Mhz. I do not have the device fully working yet but It now it is responding to the commands I send.

marunlejo commented 1 year ago

I did encounter another problem. now that the device is communicating I am using my main code to use the sensor but the terminal on the IDE gets constantly disconnected and I cannot tell how is the device working. The ESP32 has an RGB LED flashing when it gets disconnected on the terminal

If I put a delay on the code to print values slower then it never loses connection but it mess up the reading on the sensor since everything needs to work at most in 5 milliseconds. I cannot have the delay to use the device but if I do not have it then the ESP32 do not respond to the code

Xylopyrographer commented 1 year ago

The terminal implementation is Arduino IDE 2 is not the greatest. It disconnects when the USB port goes away and it never auto reconnects. I believe the issue is know to the Arduino IDE devs and a solution is pending.

In the meantime, try another terminal app. CoolTerm is recommended.

Just remember to disconnect from the external terminal app before trying to upload new code to the board.

marunlejo commented 1 year ago

I try that one, putty and termite but it keeps happening. but I fund that when I stop using interrupt functions the connection is stable. I have try the function with IRAM_ATTR type and without it. but when I comment attachInterrupt() is when the conection is stable. also I test with and without the digitalpintoInterrupt(). this is not the first time I have conection problems when using interrupts but I do not know what I am ding wrong

here is how I am using it (just the code for the interrupt)

define TRF_IRQ 5

void TRF79xxA_irqHandler(void) { // read sensor registers }

void() { pinMode(TRF_IRQ, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(TRF_IRQ), TRF79xxA_irqHandler, RISING); }