SPI locking and sx1278 configurability

pull/134/head
Hansi, dl9rdz 2021-08-14 00:30:51 +02:00
rodzic beab0fa9aa
commit 4dcbbc9eb3
8 zmienionych plików z 196 dodań i 55 usunięć

Wyświetl plik

@ -663,6 +663,12 @@ struct st_configitems config_list[] = {
{"led_pout", "LED output port", 0, &sonde.config.led_pout},
{"gps_rxd", "GPS RXD pin (-1 to disable)", 0, &sonde.config.gps_rxd},
{"gps_txd", "GPS TXD pin (not really needed)", 0, &sonde.config.gps_txd},
#if 1
{"sx1278_ss", "SX1278 SS", 0, &sonde.config.sx1278_ss},
{"sx1278_miso", "SX1278 MISO", 0, &sonde.config.sx1278_miso},
{"sx1278_mosi", "SX1278 MOSI", 0, &sonde.config.sx1278_mosi},
{"sx1278_sck", "SX1278 SCK", 0, &sonde.config.sx1278_sck},
#endif
{"mdnsname", "mDNS name", 14, &sonde.config.mdnsname},
#if FEATURE_SONDEHUB
@ -1844,6 +1850,7 @@ int scanI2Cdevice(void)
extern int initlevels[40];
extern xSemaphoreHandle globalLock;
#ifdef ESP_MEM_DEBUG
typedef void (*esp_alloc_failed_hook_t) (size_t size, uint32_t caps, const char * function_name);
@ -1928,8 +1935,14 @@ void setup()
Serial.println("AXP192 Begin FAIL");
}
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
if(sonde.config.type == TYPE_M5_CORE2) {
// Display backlight on M5 Core2
axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);
axp.setDCDC3Voltage(3300);
} else {
// GPS on T-Beam, buzzer on M5 Core2
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
}
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
@ -2044,9 +2057,30 @@ void setup()
}
// == show initial values from config.txt ========================= //
#if 0
#if 1
if(sonde.config.type == TYPE_M5_CORE2) {
// Core2 uses Pin 38 for MISO
SPI.begin(18, 38, 23, -1);
} else {
SPI.begin();
}
//Set most significant bit first
SPI.setBitOrder(MSBFIRST);
//Divide the clock frequency
SPI.setClockDivider(SPI_CLOCK_DIV2);
//Set data mode
SPI.setDataMode(SPI_MODE0);
sx1278.setup(globalLock);
uint8_t state = 2;
int i=0;
while(++i<3) {
delay(500);
// == check the radio chip by setting default frequency =========== //
if (rs41.setFrequency(402700000) == 0) {
sx1278.ON();
if (sx1278.setFrequency(402700000) == 0) {
Serial.println(F("Setting freq: SUCCESS "));
} else {
Serial.println(F("Setting freq: ERROR "));
@ -2055,6 +2089,7 @@ void setup()
Serial.print("Frequency set to ");
Serial.println(f);
// == check the radio chip by setting default frequency =========== //
}
#endif
//sx1278.setLNAGain(-48);
@ -2128,9 +2163,12 @@ void enterMode(int mode) {
// trigger activation of background task
// currentSonde should be set before enterMode()
rxtask.activate = ACT_SONDE(sonde.currentSonde);
//
Serial.println("clearing and updating display");
sonde.clearDisplay();
sonde.updateDisplay();
}
printf("enterMode ok\n");
}
static char text[40];
@ -2511,6 +2549,7 @@ void enableNetwork(bool enable) {
MDNS.end();
connected = false;
}
Serial.println("enableNetwork done");
}
// Events used only for debug output right now
@ -3422,8 +3461,8 @@ void sondehub_send_next(WiFiClient * client, SondeInfo * s, struct st_sondehub *
client->print("\r\n");
Serial.printf("%x\r\n", chunklen + 1);
Serial.write(first ? "[" : ",", 1);
Serial.write(chunk, chunklen);
Serial.write((const uint8_t *)(first ? "[" : ","), 1);
Serial.write((const uint8_t *)chunk, chunklen);
Serial.print("\r\n");
}
void sondehub_send_last(WiFiClient * client, SondeInfo * s, struct st_sondehub * conf) {

Wyświetl plik

@ -1,4 +1,4 @@
const char *version_name = "rdzTTGOsonde";
const char *version_id = "devel20210812";
const char *version_id = "devel20210813-M5";
const int SPIFFS_MAJOR=2;
const int SPIFFS_MINOR=14;

Wyświetl plik

@ -1,3 +1,4 @@
#include "../../RX_FSK/features.h"
#include <U8x8lib.h>
#include <U8g2lib.h>
#include <SPIFFS.h>
@ -24,6 +25,13 @@ extern AXP20X_Class axp;
extern bool axp192_found;
extern SemaphoreHandle_t axpSemaphore;
extern xSemaphoreHandle globalLock;
#define SPI_MUTEX_LOCK() \
do \
{ \
} while (xSemaphoreTake(globalLock, portMAX_DELAY) != pdPASS)
#define SPI_MUTEX_UNLOCK() xSemaphoreGive(globalLock)
struct GpsPos gpsPos;
//SPIClass spiDisp(HSPI);
@ -341,8 +349,15 @@ Arduino_DataBus *bus;
void ILI9225Display::begin() {
Serial.println("ILI9225/ILI9341 init");
bus = new Arduino_ESP32SPI( sonde.config.tft_rs, sonde.config.tft_cs,
sonde.config.oled_scl, sonde.config.oled_sda, -1, HSPI);
// On the M5, the display and the Lora chip are on the same SPI interface (VSPI default pins),
// we must use the same SPI bus with correct locking
if(sonde.config.type == TYPE_M5_CORE2) {
bus = new Arduino_ESP32SPI( sonde.config.tft_rs, sonde.config.tft_cs,
sonde.config.oled_scl, sonde.config.oled_sda, 38, VSPI);
} else {
bus = new Arduino_ESP32SPI( sonde.config.tft_rs, sonde.config.tft_cs,
sonde.config.oled_scl, sonde.config.oled_sda, -1, HSPI);
}
if(_type == 3)
tft = new Arduino_ILI9341(bus, sonde.config.oled_rst);
else if(_type == 4)
@ -354,10 +369,14 @@ void ILI9225Display::begin() {
tft->fillScreen(BLACK);
tft->setRotation(sonde.config.tft_orient);
tft->setTextWrap(false);
if(sonde.config.type == TYPE_M5_CORE2)
tft->invertDisplay(true);
}
void ILI9225Display::clear() {
SPI_MUTEX_LOCK();
tft->fillScreen(BLACK);
SPI_MUTEX_UNLOCK();
}
// for now, 0=small=FreeSans9pt7b, 1=large=FreeSans18pt7b
@ -412,6 +431,7 @@ void ILI9225Display::drawString(uint8_t x, uint8_t y, const char *s, int16_t wid
}
// Standard font
if(findex<3) {
SPI_MUTEX_LOCK();
DebugPrintf(DEBUG_DISPLAY, "Simple Text %s at %d,%d [%d]\n", s, x, y, width);
// for gpx fonts and new library, cursor is at baseline!!
int h = 6; if(findex>1) h=12;
@ -445,9 +465,11 @@ void ILI9225Display::drawString(uint8_t x, uint8_t y, const char *s, int16_t wid
// tft->fillRectangle(curx, y, x + width - 1, y + h - 1, bg);
//}
}
SPI_MUTEX_UNLOCK();
return;
}
// GFX font
SPI_MUTEX_LOCK();
int16_t x1, y1;
if(1||width==WIDTH_AUTO || alignright) {
tft->getTextBounds(s, x, y + gfxoffsets[findex-3].yofs, &x1, &y1, (uint16_t *)&w, (uint16_t *)&h);
@ -515,10 +537,12 @@ void ILI9225Display::drawString(uint8_t x, uint8_t y, const char *s, int16_t wid
free(bitmap);
#endif
#endif
SPI_MUTEX_UNLOCK();
}
void ILI9225Display::drawTile(uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_ptr) {
int i,j;
SPI_MUTEX_LOCK();
tft->startWrite();
for(i=0; i<cnt*8; i++) {
uint8_t v = tile_ptr[i];
@ -528,6 +552,7 @@ void ILI9225Display::drawTile(uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_p
}
}
tft->endWrite();
SPI_MUTEX_UNLOCK();
#if 0
int i,j;
tft->startWrite();
@ -545,18 +570,24 @@ void ILI9225Display::drawTile(uint8_t x, uint8_t y, uint8_t cnt, uint8_t *tile_p
}
void ILI9225Display::drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color, boolean fill) {
SPI_MUTEX_LOCK();
if(fill)
tft->fillTriangle(x1, y1, x2, y2, x3, y3, color);
else
tft->drawTriangle(x1, y1, x2, y2, x3, y3, color);
SPI_MUTEX_UNLOCK();
}
void ILI9225Display::drawBitmap(uint16_t x1, uint16_t y1, const uint16_t* bitmap, int16_t w, int16_t h) {
SPI_MUTEX_LOCK();
tft->draw16bitRGBBitmap(x1, y1, bitmap, w, h);
SPI_MUTEX_UNLOCK();
}
void ILI9225Display::welcome() {
SPI_MUTEX_LOCK();
tft->fillScreen(0);
SPI_MUTEX_UNLOCK();
setFont(6);
drawString(0, 0*22, version_name, WIDTH_AUTO, 0xff00);
setFont(5);

Wyświetl plik

@ -14,13 +14,38 @@
#include <Sonde.h>
#include <Display.h>
SX1278FSK::SX1278FSK()
#define SPI_MUTEX_LOCK() \
do \
{ \
} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
#define SPI_MUTEX_UNLOCK() xSemaphoreGive(_lock)
SX1278FSK::SX1278FSK() {}
void SX1278FSK::setup(xSemaphoreHandle lock)
{
// Initialize class variables
_lock = lock;
Serial.println("Setup sx1278");
if(_lock) SPI_MUTEX_LOCK();
digitalWrite(sonde.config.sx1278_ss, HIGH);
pinMode(sonde.config.sx1278_ss, OUTPUT);
Serial.printf("Configuing SX1278FSK SPI with miso=%d, mosi=%d, sck=%d, ss=%d\n", sonde.config.sx1278_miso,
sonde.config.sx1278_mosi, sonde.config.sx1278_sck, sonde.config.sx1278_ss);
SPI.begin(sonde.config.sx1278_sck, sonde.config.sx1278_miso, sonde.config.sx1278_mosi, -1); // no hardware CS
// was: SPI.begin();
//Set most significant bit first
SPI.setBitOrder(MSBFIRST);
//Divide the clock frequency
SPI.setClockDivider(SPI_CLOCK_DIV2);
//Set data mode
SPI.setDataMode(SPI_MODE0);
if(_lock) SPI_MUTEX_UNLOCK();
};
static SPISettings spiset = SPISettings(40000000L, MSBFIRST, SPI_MODE0);
static SPISettings spiset = SPISettings(10000000L, MSBFIRST, SPI_MODE0);
/*
Function: Turns the module ON.
@ -34,19 +59,6 @@ uint8_t SX1278FSK::ON()
Serial.println(F("Starting 'ON'"));
#endif
// Powering the module
pinMode(SX1278_SS, OUTPUT);
digitalWrite(SX1278_SS, HIGH);
//Configure the MISO, MOSI, CS, SPCR.
SPI.begin();
//Set most significant bit first
SPI.setBitOrder(MSBFIRST);
//Divide the clock frequency
SPI.setClockDivider(SPI_CLOCK_DIV2);
//Set data mode
SPI.setDataMode(SPI_MODE0);
// Set Maximum Over Current Protection
state = setMaxCurrent(0x1B);
if( state == 0 )
@ -60,7 +72,6 @@ uint8_t SX1278FSK::ON()
{
return 1;
}
// set FSK mode
state = setFSK();
return state;
@ -77,10 +88,12 @@ void SX1278FSK::OFF()
Serial.println(F("Starting 'OFF'"));
#endif
SPI.end();
//SPI.end();
#if 0
// Powering the module
pinMode(SX1278_SS,OUTPUT);
digitalWrite(SX1278_SS,LOW);
#endif
#if (SX1278FSK_debug_mode > 1)
Serial.println(F("## Setting OFF ##"));
@ -98,15 +111,16 @@ byte SX1278FSK::readRegister(byte address)
{
byte value = 0x00;
if(_lock) SPI_MUTEX_LOCK();
digitalWrite(sonde.config.sx1278_ss,LOW);
SPI.beginTransaction(spiset);
digitalWrite(SX1278_SS,LOW);
//delay(1);
bitClear(address, 7); // Bit 7 cleared to write in registers
SPI.transfer(address);
value = SPI.transfer(0x00);
digitalWrite(SX1278_SS,HIGH);
SPI.endTransaction();
digitalWrite(sonde.config.sx1278_ss,HIGH);
#if (SX1278FSK_debug_mode > 1)
if(address!=0x3F) {
@ -118,7 +132,7 @@ byte SX1278FSK::readRegister(byte address)
Serial.println();
}
#endif
if(_lock) SPI_MUTEX_UNLOCK();
return value;
}
@ -131,15 +145,16 @@ Parameters:
*/
void SX1278FSK::writeRegister(byte address, byte data)
{
if(_lock) SPI_MUTEX_LOCK();
digitalWrite(sonde.config.sx1278_ss,LOW);
SPI.beginTransaction(spiset);
digitalWrite(SX1278_SS,LOW);
//delay(1);
bitSet(address, 7); // Bit 7 set to read from registers
SPI.transfer(address);
SPI.transfer(data);
digitalWrite(SX1278_SS,HIGH);
SPI.endTransaction();
digitalWrite(sonde.config.sx1278_ss,HIGH);
#if (SX1278FSK_debug_mode > 1)
Serial.print(F("## Writing: ##\t"));
@ -150,7 +165,7 @@ void SX1278FSK::writeRegister(byte address, byte data)
Serial.print(data, HEX);
Serial.println();
#endif
if(_lock) SPI_MUTEX_UNLOCK();
}
/*
@ -867,4 +882,5 @@ void SX1278FSK::showRxRegisters()
}
#endif
xSemaphoreHandle globalLock =xSemaphoreCreateMutex();
SX1278FSK sx1278 = SX1278FSK();

Wyświetl plik

@ -35,8 +35,6 @@
#define SX1278FSK_debug_mode 0
#define SX1278_SS SS
//! MACROS //
#define bitRead(value, bit) (((value) >> (bit)) & 0x01) // read a bit
#define bitSet(value, bit) ((value) |= (1UL << (bit))) // set bit to '1'
@ -171,7 +169,9 @@ class SX1278FSK
{
public:
// class constructor
SX1278FSK();
SX1278FSK();
void setup(xSemaphoreHandle lock);
// Turn on SX1278 module (return 0 on sucess, 1 otherwise)
uint8_t ON();
@ -256,7 +256,7 @@ public:
// Receive a packet
uint8_t receivePacketTimeout(uint32_t wait, byte *data);
xSemaphoreHandle _lock = NULL;
#if 0
//! It gets the internal temperature of the module.

Wyświetl plik

@ -82,9 +82,14 @@ void Sonde::defaultConfig() {
config.power_pout = -1;
config.spectrum=10;
// Try autodetecting board type
config.type = TYPE_TTGO;
// Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards?
config.gps_rxd = -1;
config.gps_txd = -1;
config.sx1278_ss = SS; // default SS pin, on all TTGOs
config.sx1278_miso = MISO;
config.sx1278_mosi = MOSI;
config.sx1278_sck = SCK;
config.oled_rst = 16;
config.disptype = 0;
config.tft_orient = 1;
@ -103,32 +108,55 @@ void Sonde::defaultConfig() {
} else {
config.oled_sda = 21;
config.oled_scl = 22;
if(initlevels[17]==0) { // T-Beam
if(initlevels[17]==0) { // T-Beam or M5Stack Core2?
int tbeam=7;
if(initlevels[12]==0) {
tbeam = 10;
Serial.println("Autoconfig: looks like T-Beam 1.0 board");
Serial.println("Autoconfig: looks like T-Beam 1.0 or M5Stack Core2 board");
} else if ( initlevels[4]==1 && initlevels[12]==1 ) {
tbeam = 11;
Serial.println("Autoconfig: looks like T-Beam 1.1 board");
}
if(tbeam == 10 || tbeam == 11) { // T-Beam v1.0 or T-Beam v1.1
config.button_pin = 38;
config.button2_pin = 15 + 128; //T4 + 128; // T4 = GPIO13
// Maybe in future use as default only PWR as button2?
//config.button2_pin = 255;
config.button2_axp = 1;
config.gps_rxd = 34;
config.gps_txd = 12;
// Check for I2C-Display@21,22
#define SSD1306_ADDRESS 0x3c
Wire.begin(21, 22);
Wire.beginTransmission(SSD1306_ADDRESS);
byte err = Wire.endTransmission();
delay(100); // otherwise its too fast?!
Wire.beginTransmission(SSD1306_ADDRESS);
err = Wire.endTransmission();
if(err!=0 && fingerprint!=17) { // hmm. 17 after powerup with oled commected and no i2c answer!?!?
#define BM8563_ADDRESS 0x51
Wire.beginTransmission(BM8563_ADDRESS);
byte err = Wire.endTransmission();
if(err==0) {
Serial.println("M5stack Core2 board detected\n");
config.type = TYPE_M5_CORE2;
config.button_pin = 255;
config.button2_pin = 255;
config.button2_axp = 1;
config.disptype = 4; // ILI9342
config.oled_sda = 23;
config.oled_scl = 18;
config.oled_rst = -1;
config.tft_rs = 15;
config.tft_cs = 5;
config.screenfile = 4;
config.gps_rxd = 13;
config.gps_txd = -1; // 14
config.sx1278_ss = 33;
config.sx1278_miso = 38;
config.sx1278_mosi = 23; //MOSI;
config.sx1278_sck = 18; // SCK;
} else { // some t-beam...
config.button_pin = 38;
config.button2_pin = 15 + 128; //T4 + 128; // T4 = GPIO13
// Maybe in future use as default only PWR as button2?
//config.button2_pin = 255;
config.button2_axp = 1;
config.gps_rxd = 34;
config.gps_txd = 12;
// Check for I2C-Display@21,22
#define SSD1306_ADDRESS 0x3c
Wire.beginTransmission(SSD1306_ADDRESS);
err = Wire.endTransmission();
delay(100); // otherwise its too fast?!
Wire.beginTransmission(SSD1306_ADDRESS);
err = Wire.endTransmission();
if(err!=0 && fingerprint!=17) { // hmm. 17 after powerup with oled commected and no i2c answer!?!?
fingerprint |= 128;
Serial.println("no I2C display found, assuming large TFT display\n");
// CS=0, RST=14, RS=2, SDA=4, CLK=13
@ -141,10 +169,11 @@ void Sonde::defaultConfig() {
config.tft_cs = 0;
config.spectrum = -1; // no spectrum for now on large display
config.screenfile = 2;
} else {
} else {
// OLED display, pins 21,22 ok...
config.disptype = 0;
Serial.println("... with small OLED display\n");
}
}
} else {
Serial.println("Autoconfig: looks like T-Beam v0.7 board");
@ -270,6 +299,14 @@ void Sonde::setConfig(const char *cfg) {
config.gps_rxd = atoi(val);
} else if(strcmp(cfg,"gps_txd")==0) {
config.gps_txd = atoi(val);
} else if(strcmp(cfg,"sx1278_ss")==0) {
config.sx1278_ss = atoi(val);
} else if(strcmp(cfg,"sx1278_miso")==0) {
config.sx1278_miso = atoi(val);
} else if(strcmp(cfg,"sx1278_mosi")==0) {
config.sx1278_mosi = atoi(val);
} else if(strcmp(cfg,"sx1278_sck")==0) {
config.sx1278_sck = atoi(val);
} else if(strcmp(cfg,"maxsonde")==0) {
config.maxsonde = atoi(val);
if(config.maxsonde>MAXSONDE) config.maxsonde=MAXSONDE;

Wyświetl plik

@ -194,7 +194,11 @@ struct st_sondehub {
char email[64];
};
// to be extended
enum { TYPE_TTGO, TYPE_M5_CORE2 };
typedef struct st_rdzconfig {
int type; // autodetected type, TTGO or M5_CORE2
// hardware configuration
int button_pin; // PIN port number menu button (+128 for touch mode)
int button2_pin; // PIN port number menu button (+128 for touch mode)
@ -212,6 +216,10 @@ typedef struct st_rdzconfig {
int tft_spifreq; // SPI transfer speed (default 40M is out of spec for some TFT)
int gps_rxd; // GPS module RXD pin. We expect 9600 baud NMEA data.
int gps_txd; // GPS module TXD pin
int sx1278_ss; // SPI slave select for sx1278
int sx1278_miso; // SPI MISO for sx1278
int sx1278_mosi; // SPI MOSI for sx1278
int sx1278_sck; // SPI SCK for sx1278
// software configuration
int debug; // show port and config options after reboot
int wifi; // connect to known WLAN 0=skip

Wyświetl plik

@ -34,6 +34,16 @@ TTGO T-Team 1.0 with IL9225 TFT => fingerprint 23
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
0:1 1:1 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
M5Stack Core2
0:1 1:0 2:0 3:1 4:1 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:1 14:1 15:1 16:1 17:0 18:1 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
0:1 1:1 2:0 3:1 4:1 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:1 14:1 15:1 16:1 17:0 18:1 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
Board fingerprint is 87 (nach power on)
0:1 1:0 2:0 3:1 4:0 5:0 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
0:1 1:1 2:0 3:1 4:0 5:0 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
Board fingerprint is 22 (nach reset)
Autoconfig: looks like T-Beam 1.0 board
vs 0010111
T-Beam 1.1 seems to be different: 1110111
GPIO4 = 1 (additional pullup) => +64