Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using two SPI buses #9

Closed
wcpettus opened this issue Feb 14, 2019 · 11 comments
Closed

Using two SPI buses #9

wcpettus opened this issue Feb 14, 2019 · 11 comments

Comments

@wcpettus
Copy link

I'm trying to configure an ESP32-Gateway to talk with an SPI device. I feel I must be missing something about the hardware configuration.

I've started with the SPI_Multiple_Buses example code, but the default pins for VSPI (18,19,23,5) and HSPI (14,12,13,15) are mostly not exposed to the extension headers. Consulting the schematic (I'm using a rev C) I have access to
GPIO 5,16,17,32,33
GPI 34,35,36,39
Debug only 6,7,8,9,10,11

I've verified I can see SPI signals on the 5 pins I have access to, I'm explicitly told to skip the 6 SD-related pins, and the other 4 are input only? That seems like a waste of header real estate, and how can one operate two SPI buses concurrently (alternatively this would limit the number of SS pins for a single SPI bus)?

Probably some trivial ignorance on my part?

@DrTester0x42
Copy link

@wcpettus This is a good question have you found the answer to this yet?

Looking at the boards headers I am not seeing any dedicated SPI ports. What are your thoughts? @TsvetanUsunov

@wcpettus
Copy link
Author

I would love to know the answer. I also tried asking on the forums but never heard anything back:
https://www.olimex.com/forum/index.php?topic=7090.0

@drdelgado
Copy link

Hello

@drdelgado
Copy link

@wcpettus Just out of curiosity what did you use for your CLK? GPIO6?

@wcpettus
Copy link
Author

I used GPIO32 - I didn't want to touch GPIO6 since it's one of the reserved for debug only pins that I don't understand. Beyond that my choice for which was MISO/MOSI/CLK/CS were pretty random.

@drdelgado
Copy link

@wcpettus were you able to get SPI peripheral + ethernet functionality working?

@wcpettus
Copy link
Author

that's right - I've been using an SPI to communicate with an ADC and ethernet to readout the data

@drdelgado
Copy link

@wcpettus any chance you'd be willing to share your code?

@fightforlife
Copy link

I would also love to hear how an external SPI Device can be User with this Board? ( HSPI and VSPI seems Not to be available in the Header)

@wcpettus
Copy link
Author

Prefaced with the disclaimer that I don't think this is the final code version, but this is what I found digging through old code directories; clearly I should have documented better and answered 3.5 years ago when the original question was fresh (or made the undergrad who was doing the implementation do so :D)

This at least seems to work with an ADC, use SPI, and have ethernet functionality.

include <MCP3XXX.h>
 #include <ETH.h>

 //Define ADC interfaces
 #define CS_PIN 5     // ESP8266 default SPI pins
 #define CLK_PIN 32  // Should work with any other GPIO pins, since the library does not formally
 #define MOSI_PIN 16   // use SPI, but rather performs pin bit banging to emulate SPI communication.
 #define MISO_PIN 17   //
 MCP3204 adc;

 //Define network settings
 static bool eth_connected = false;
 IPAddress ip(10, 0, 0, 2);
 IPAddress gate(10, 0, 0, 1);
 IPAddress mask(255, 255, 255, 0);

 //Define telnet server parameters
 #define MAX_SRV_CLIENTS 4
 WiFiServer server(23);
 WiFiClient serverClients[MAX_SRV_CLIENTS];
 const byte charLim = 32;
 const char terminator = '\n';

 void WiFiEvent(WiFiEvent_t event)
 {
   switch (event) {
     case SYSTEM_EVENT_ETH_START:
       Serial.println("ETH Started");
       //set eth hostname here
       ETH.setHostname("arduino1");
       break;
     case SYSTEM_EVENT_ETH_CONNECTED:
       Serial.println("ETH Connected");
       break;
     case SYSTEM_EVENT_ETH_GOT_IP:
       Serial.print("ETH MAC: ");
       Serial.print(ETH.macAddress());
       Serial.print(", IPv4: ");
       Serial.print(ETH.localIP());
       if (ETH.fullDuplex()) Serial.print(", FULL_DUPLEX");
       Serial.print(", ");
       Serial.print(ETH.linkSpeed());
       Serial.println("Mbps");
       eth_connected = true;
       break;
     case SYSTEM_EVENT_ETH_DISCONNECTED:
       Serial.println("ETH Disconnected");
       eth_connected = false;
       break;
     case SYSTEM_EVENT_ETH_STOP:
       Serial.println("ETH Stopped");
       eth_connected = false;
       break;
     default:
       break;
   }
 }

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

   WiFi.onEvent(WiFiEvent);
   ETH.begin();
   ETH.config(ip, gate, mask, gate);
   server.begin();
   server.setNoDelay(true);
   Serial.println("network and server setup initialized");
   adc.begin(CS_PIN, MOSI_PIN, MISO_PIN, CLK_PIN);
   Serial.println("setup done");
 }

 // function to handle new connections
 void handle_connection()
 {
   uint8_t i;
   if (server.hasClient()) {
     for (i = 0; i < MAX_SRV_CLIENTS; i++) {
       //find free/disconnected spot
       if (!serverClients[i] || !serverClients[i].connected()) {
         if (serverClients[i]) serverClients[i].stop();
         serverClients[i] = server.available();
         if (!serverClients[i]) Serial.println("available broken");
         Serial.print("New client: ");
         Serial.print(i); Serial.print(' ');
         Serial.println(serverClients[i].remoteIP());
         serverClients[i].print("You are connection ");
         serverClients[i].print(i); serverClients[i].print(" to ");
         serverClients[i].println(ETH.getHostname());
         serverClients[i].print(">");
         //flush input buffer on connection
         while (serverClients[i].available()) serverClients[i].read();
         break;
       }
     }
     if (i >= MAX_SRV_CLIENTS) {
       //no free/disconnected spot so reject
       server.available().stop();
     }
   }
 }

 // function to read commands from controls
 void read_connection()
 {
   uint8_t i;
   for (i = 0; i < MAX_SRV_CLIENTS; i++) {
     if (serverClients[i] && serverClients[i].connected()) {
       if (serverClients[i].available()) {
         char input[charLim + 2];
         uint8_t nRx = 0;
         bool incomplete = true;
         while (serverClients[i].available()) {
           input[nRx] = serverClients[i].read();
           if (input[nRx] == terminator) {
             input[nRx + 2] = '\0';
             parse_command(&serverClients[i], input);
             incomplete = false;
             break;
           } else if (nRx < charLim) {
             nRx ++;
           }
         }
         if (incomplete) serverClients[i].println("ERROR: Incomplete transmission");
       }
     }
     else {
       if (serverClients[i]) serverClients[i].stop();
     }
   }
 }

 // funtion to interpret received command
 void parse_command(WiFiClient *client, char *input)
 {
   Serial.print("Received command: ");
   Serial.println(input);
   client->print(input);
   switch (input[0]) {
     // READ option, <RN>, return ADC input N value
     case 'R':
       measurement(client, input[1] - '0'); // expect a uint8_t
       break;
     // TEST option, <T> return 1
     case 'T':
       client->println(1);
       break;
     default:
       client->println("ERROR: Invalid command");
       break;
   }
   client->print(">");
 }

 // function to record measurements from a coldhead ADC
 void measurement(WiFiClient *client, uint8_t chanID)
 {
   if (chanID > 3) return;
   client->print("Ch: ");
   client->print(chanID);
   client->print("; Val: ");
   client->println(adc.analogRead(chanID));
 }

 void loop()
 {
   if (eth_connected) {
     //check if there are any new clients
     handle_connection();
     //check clients for data
     read_connection();
   } else {
     Serial.println("ETH not connected!");
     delay(100);
     for (uint8_t i = 0; i < MAX_SRV_CLIENTS; i++) {
       if (serverClients[i]) serverClients[i].stop();
     }
   }
 }

@fightforlife
Copy link

Thanks you very much for the example of using Software SPI/bitbanging.
While checking the Docs I found that the Hardware HSPI Pins are available on the header in newer Board revisions. (But then ofcourse you can Not use the sdcard at the same time).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants