add SPI support - tested with TitanX1.

This commit is contained in:
Lady Ada 2019-11-16 19:06:07 -05:00
parent dcc7dcc76f
commit 7bb6e004a6
3 changed files with 112 additions and 14 deletions

View File

@ -455,8 +455,8 @@ size_t Adafruit_GPS::available(void) {
if (gpsHwSerial) { if (gpsHwSerial) {
return gpsHwSerial->available(); return gpsHwSerial->available();
} }
if (gpsI2C) { if (gpsI2C || gpsSPI) {
return 1; // I2C doesnt have 'availability' so always has a byte at least to read! return 1; // I2C/SPI doesnt have 'availability' so always has a byte at least to read!
} }
return 0; return 0;
} }
@ -486,6 +486,19 @@ size_t Adafruit_GPS::write(uint8_t c) {
return 1; return 1;
} }
} }
if (gpsSPI) {
gpsSPI->beginTransaction(gpsSPI_settings);
if (gpsSPI_cs >= 0) {
digitalWrite(gpsSPI_cs, LOW);
}
c = gpsSPI->transfer(c);
if (gpsSPI_cs >= 0) {
digitalWrite(gpsSPI_cs, HIGH);
}
gpsSPI->endTransaction();
return 1;
}
return 0; return 0;
} }
@ -515,14 +528,14 @@ char Adafruit_GPS::read(void) {
c = gpsHwSerial->read(); c = gpsHwSerial->read();
} }
if (gpsI2C) { if (gpsI2C) {
if (_i2cbuff_idx <= _i2cbuff_max) { if (_buff_idx <= _buff_max) {
c = _i2cbuffer[_i2cbuff_idx]; c = _i2cbuffer[_buff_idx];
_i2cbuff_idx++; _buff_idx++;
} else { } else {
// refill the buffer! // refill the buffer!
if (Wire.requestFrom(0x10, GPS_MAX_I2C_TRANSFER, true) == GPS_MAX_I2C_TRANSFER) { if (Wire.requestFrom(0x10, GPS_MAX_I2C_TRANSFER, true) == GPS_MAX_I2C_TRANSFER) {
// got data! // got data!
_i2cbuff_max = 0; _buff_max = 0;
char curr_char = 0; char curr_char = 0;
for (int i=0; i<GPS_MAX_I2C_TRANSFER; i++) { for (int i=0; i<GPS_MAX_I2C_TRANSFER; i++) {
curr_char = Wire.read(); curr_char = Wire.read();
@ -531,19 +544,34 @@ char Adafruit_GPS::read(void) {
continue; continue;
} }
last_char = curr_char; last_char = curr_char;
_i2cbuffer[_i2cbuff_max] = curr_char; _i2cbuffer[_buff_max] = curr_char;
_i2cbuff_max++; _buff_max++;
} }
_i2cbuff_max--; // back up to the last valid slot _buff_max--; // back up to the last valid slot
if ((_i2cbuff_max == 0) && (_i2cbuffer[0] == 0x0A)) { if ((_buff_max == 0) && (_i2cbuffer[0] == 0x0A)) {
_i2cbuff_max = -1; // ahh there was nothing to read after all _buff_max = -1; // ahh there was nothing to read after all
} }
_i2cbuff_idx = 0; _buff_idx = 0;
} }
return c; return c;
} }
} }
if (gpsSPI) {
do {
gpsSPI->beginTransaction(gpsSPI_settings);
if (gpsSPI_cs >= 0) {
digitalWrite(gpsSPI_cs, LOW);
}
c = gpsSPI->transfer(0xFF);
if (gpsSPI_cs >= 0) {
digitalWrite(gpsSPI_cs, HIGH);
}
gpsSPI->endTransaction();
// skip duplicate 0x0A's - but keep as part of a CRLF
} while (((c == 0x0A) && (last_char != 0x0D)) || (!isprint(c) && !isspace(c)) );
last_char = c;
}
//Serial.print(c); //Serial.print(c);
currentline[lineidx++] = c; currentline[lineidx++] = c;
@ -612,6 +640,20 @@ Adafruit_GPS::Adafruit_GPS(TwoWire *theWire) {
gpsI2C = theWire; // ...override gpsI2C gpsI2C = theWire; // ...override gpsI2C
} }
/**************************************************************************/
/*!
@brief Constructor when using SPI
@param theSPI Pointer to an SPI device object
@param cspin The pin connected to the GPS CS, can be -1 if unused
*/
/**************************************************************************/
Adafruit_GPS::Adafruit_GPS(SPIClass *theSPI, int8_t cspin) {
common_init(); // Set everything to common state, then...
gpsSPI = theSPI; // ...override gpsSPI
gpsSPI_cs = cspin;
}
/**************************************************************************/ /**************************************************************************/
/*! /*!
@brief Initialization code used by all constructor types @brief Initialization code used by all constructor types
@ -623,6 +665,7 @@ void Adafruit_GPS::common_init(void) {
#endif #endif
gpsHwSerial = NULL; // port pointer in corresponding constructor gpsHwSerial = NULL; // port pointer in corresponding constructor
gpsI2C = NULL; gpsI2C = NULL;
gpsSPI = NULL;
recvdflag = false; recvdflag = false;
paused = false; paused = false;
lineidx = 0; lineidx = 0;
@ -666,6 +709,15 @@ bool Adafruit_GPS::begin(uint32_t baud_or_i2caddr)
gpsI2C->beginTransmission(_i2caddr); gpsI2C->beginTransmission(_i2caddr);
return (gpsI2C->endTransmission () == 0); return (gpsI2C->endTransmission () == 0);
} }
if (gpsSPI) {
gpsSPI->begin();
gpsSPI_settings = SPISettings(baud_or_i2caddr, MSBFIRST, SPI_MODE0);
if (gpsSPI_cs >= 0) {
pinMode(gpsSPI_cs, OUTPUT);
digitalWrite(gpsSPI_cs, HIGH);
}
}
delay(10); delay(10);
return true; return true;
} }

View File

@ -35,7 +35,7 @@
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
#endif #endif
#include <Wire.h> #include <Wire.h>
#include <SPI.h>
/**************************************************************************/ /**************************************************************************/
/** /**
@ -112,6 +112,7 @@ class Adafruit_GPS : public Print{
#endif #endif
Adafruit_GPS(HardwareSerial *ser); // Constructor when using HardwareSerial Adafruit_GPS(HardwareSerial *ser); // Constructor when using HardwareSerial
Adafruit_GPS(TwoWire *theWire); // Constructor when using I2C Adafruit_GPS(TwoWire *theWire); // Constructor when using I2C
Adafruit_GPS(SPIClass *theSPI, int8_t cspin); // Constructor when using SPI
char *lastNMEA(void); char *lastNMEA(void);
boolean newNMEAreceived(); boolean newNMEAreceived();
@ -208,9 +209,13 @@ class Adafruit_GPS : public Print{
#endif #endif
HardwareSerial *gpsHwSerial; HardwareSerial *gpsHwSerial;
TwoWire *gpsI2C; TwoWire *gpsI2C;
SPIClass *gpsSPI;
int8_t gpsSPI_cs = -1;
SPISettings gpsSPI_settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); // default
char _spibuffer[GPS_MAX_SPI_TRANSFER]; // for when we write data, we need to read it too!
uint8_t _i2caddr; uint8_t _i2caddr;
char _i2cbuffer[GPS_MAX_I2C_TRANSFER]; char _i2cbuffer[GPS_MAX_I2C_TRANSFER];
int8_t _i2cbuff_max = -1, _i2cbuff_idx = 0; int8_t _buff_max = -1, _buff_idx = 0;
char last_char = 0; char last_char = 0;
}; };
/**************************************************************************/ /**************************************************************************/

View File

@ -0,0 +1,41 @@
// Test code for Adafruit GPS That Support Using SPI
//
// This code shows how to test a passthru between USB and SPI
//
// Pick one up today at the Adafruit electronics shop
// and help support open source hardware & software! -ada
#include <Adafruit_GPS.h>
// Connect to the GPS on the hardware SPI port
// with CS on pin #10
Adafruit_GPS GPS(&SPI, 10);
#define RESET_PIN 9
void setup() {
// wait for hardware serial to appear
while (!Serial);
// make this baud rate fast enough to we aren't waiting on it
Serial.begin(115200);
Serial.println("Adafruit GPS library basic SPI test!");
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, LOW);
delay(10);
digitalWrite(RESET_PIN, HIGH);
delay(100);
GPS.begin(100000); // use 100kHz for SPI data rate
}
void loop() {
if (Serial.available()) {
char c = Serial.read();
GPS.write(c);
}
if (GPS.available()) {
char c = GPS.read();
Serial.write(c);
}
}