kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
				
				
				
			Add more info-parameters, BME280 support, remove I2C mutex
							rodzic
							
								
									1aae80e8d7
								
							
						
					
					
						commit
						2a0e0fa849
					
				|  | @ -0,0 +1,113 @@ | |||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <math.h> | ||||
| 
 | ||||
| #include "nmea.h" | ||||
| #include "format.h" | ||||
| 
 | ||||
| #include "bmp280.h" | ||||
| 
 | ||||
| class BME280: public BMP280 | ||||
| { private: | ||||
|     static uint16_t SwapBytes(uint16_t Word) { return (Word>>8) | (Word<<8); } | ||||
| 
 | ||||
|     static const uint8_t ADDR0        = 0x76; // possible I2C addresses
 | ||||
|     static const uint8_t ADDR1        = 0x77; | ||||
| 
 | ||||
|     static const uint8_t REG_CALIB_A1 = 0xA1; // calibration register:
 | ||||
|     static const uint8_t REG_CALIB_HUM= 0xE1; // calibration register:
 | ||||
|     static const uint8_t REG_ID       = 0xD0; // ID register: always reads 0x60
 | ||||
|     static const uint8_t REG_CTRL_HUM = 0xF2; // control: _____HHH HHH=humidity oversampling
 | ||||
| 
 | ||||
|     static const uint8_t REG_HUM        = 0xFD; // Humidity result:
 | ||||
|     static const uint8_t REG_HUM_MSB    = 0xFD; // Humidity result: MSB
 | ||||
|     static const uint8_t REG_HUM_LSB    = 0xFE; // Humidity result: LSB
 | ||||
|     uint8_t  H1; | ||||
|     int16_t H2; | ||||
|     uint8_t  H3; | ||||
|     int16_t H4; | ||||
|     int16_t H5; | ||||
|     int8_t  H6; | ||||
| 
 | ||||
|   public: | ||||
|     uint16_t RawHum;        //      raw humidity - to be processed
 | ||||
|     int32_t Humidity;       // [0.1 %] relative humidity after processing
 | ||||
| 
 | ||||
|   uint8_t CheckID(void) // check ID, to make sure the BME280 is connected and works correctly
 | ||||
|    { uint8_t ID; | ||||
|      ADDR=0; | ||||
|      Error=I2C_Read(Bus, ADDR0, REG_ID, ID); | ||||
|      if( (!Error) && (ID==0x60) ) { ADDR=ADDR0; return 0; } | ||||
|      Error=I2C_Read(Bus, ADDR1, REG_ID, ID); | ||||
|      if( (!Error) && (ID==0x60) ) { ADDR=ADDR1; return 0; } | ||||
|      return 1; } // 0 => no error and correct ID
 | ||||
| 
 | ||||
|   uint8_t ReadCalib(void) // read the calibration constants from the EEPROM
 | ||||
|   { Error=BMP280::ReadCalib(); if(Error) return Error; | ||||
|     Error=I2C_Read(Bus, ADDR, REG_CALIB_A1, (uint8_t *)(&H1), 1); if(Error) return Error; | ||||
|     uint8_t buf[7]; | ||||
|     Error=I2C_Read(Bus, ADDR, REG_CALIB_HUM, buf, 7); if(Error) return Error; | ||||
|     parse_humidity_calib_data(buf); | ||||
|     return 0; } | ||||
| 
 | ||||
|   void parse_humidity_calib_data(uint8_t *s) | ||||
|   { | ||||
|   int16_t lsb, msb; | ||||
| 
 | ||||
|   H2 = (int16_t)(((uint16_t)s[1] << 8) | (uint16_t)s[0]); | ||||
|   H3 = s[2]; | ||||
| 
 | ||||
|   msb = (int16_t)(int8_t)s[3] * 16; | ||||
|   lsb = (int16_t)(s[4] & 0x0F); | ||||
|   H4 = msb | lsb; | ||||
| 
 | ||||
|   msb = (int16_t)(int8_t)s[5] * 16; | ||||
|   lsb = (int16_t)(s[4] >> 4); | ||||
|   H5 = msb | lsb; | ||||
|   H6 = (int8_t)s[6]; | ||||
|   } | ||||
| 
 | ||||
|   uint8_t Trigger(void)                                    // start  measurement
 | ||||
|   { uint8_t Data=0x03; Error=I2C_Write(Bus, ADDR, REG_CTRL_HUM, Data); if(Error) return Error; // H.osp=3x
 | ||||
| 	return BMP280::Trigger(); } | ||||
| 
 | ||||
|   uint8_t ReadRawHum(void) | ||||
|   { RawHum=0; | ||||
|     Error=I2C_Read(Bus, ADDR, REG_HUM, (uint8_t *)(&RawHum), 2); if(Error) return Error; | ||||
|     RawHum = SwapBytes(RawHum); | ||||
|     return 0; } | ||||
| 
 | ||||
|   uint8_t Acquire(void) | ||||
|   { Error=BMP280::Acquire(); if(Error) return Error; | ||||
|     return ReadRawHum(); } | ||||
| 
 | ||||
|   void Calculate(void) | ||||
|   { BMP280::Calculate(); | ||||
|     CalcHumidity(); } | ||||
| 
 | ||||
|   void CalcHumidity(void)   // calculate the humidity from raw readout and calibration values
 | ||||
|   { | ||||
|     int32_t var1, var2, var3, var4, var5; | ||||
|     int32_t humidity_max = 100000; | ||||
| 
 | ||||
|     var1 = FineTemp - ((int32_t)76800); | ||||
|     var2 = (int32_t)(((uint32_t)RawHum & 0xFFFF) << 14); | ||||
|     var3 = (int32_t)(((int32_t)H4) << 20); | ||||
|     var4 = ((int32_t)H5) * var1; | ||||
|     var5 = (((var2 - var3) - var4) + (int32_t)16384) >> 15; | ||||
|     var2 = (var1 * ((int32_t)H6)) >> 10; | ||||
|     var3 = (var1 * ((int32_t)H3)) >> 11; | ||||
|     var4 = ((var2 * (var3 + (int32_t)32768)) >> 10) + (int32_t)2097152; | ||||
|     var2 = ((var4 * ((int32_t)H2)) + 8192) >> 14; | ||||
|     var3 = var5 * var2; | ||||
|     var4 = ((var3 >> 15) * (var3 >> 15)) >> 7; | ||||
|     var5 = var3 - ((var4 * ((int32_t)H1)) >> 4); | ||||
|     var5 = (var5 < 0 ? 0 : var5); | ||||
|     var5 = (var5 > 419430400 ? 419430400 : var5); | ||||
|     Humidity = (uint32_t)(var5 >> 12); | ||||
|     if (Humidity > humidity_max) Humidity = humidity_max; | ||||
|     Humidity /= 100; | ||||
|   } | ||||
| 
 | ||||
| } ; | ||||
| 
 | ||||
|  | @ -65,6 +65,7 @@ class BMP280 | |||
|     D   =      0; } | ||||
| 
 | ||||
|   uint8_t CheckID(void) // check ID, to make sure the BMP280 is connected and works correctly
 | ||||
|   			// if it finds a BME280 it will use it without the humidity part
 | ||||
|    { uint8_t ID; | ||||
|      ADDR=0; | ||||
|      Error=I2C_Read(Bus, ADDR0, REG_ID, ID); | ||||
|  |  | |||
|  | @ -84,9 +84,9 @@ const uint8_t  GPS_dynModel       =     7; // for UBX GPS's: 6 = airborne with > | |||
| int16_t GPS_AverageSpeed(void)                        // get average speed based on stored GPS positions
 | ||||
| { uint8_t Count=0; | ||||
|   int16_t Speed=0; | ||||
|   for(uint8_t Idx=0; Idx<4; Idx++)                    // loop over GPS positions
 | ||||
|   for(uint8_t Idx=0; Idx<GPS_PosPipeSize; Idx++)      // loop over GPS positions
 | ||||
|   { GPS_Position *Pos = Position+Idx; | ||||
|     if( !Pos->hasGPS || !Pos->isValid() ) continue;      // skip invalid positions
 | ||||
|     if( !Pos->hasGPS || !Pos->isValid() ) continue;   // skip invalid positions
 | ||||
|     Speed += Pos->Speed +abs(Pos->ClimbRate); Count++; | ||||
|   } | ||||
|   if(Count==0) return -1; | ||||
|  | @ -400,11 +400,13 @@ static void GPS_NMEA(void)                                                 // wh | |||
| } | ||||
| 
 | ||||
| #ifdef WITH_GPS_UBX | ||||
| #ifdef DEBUG_PRINT | ||||
| static void DumpUBX(void) | ||||
| { Format_String(CONS_UART_Write, "UBX:"); | ||||
|   for(uint8_t Idx=0; Idx<20; Idx++) | ||||
|   { CONS_UART_Write(' '); Format_Hex(CONS_UART_Write, UBX.Byte[Idx]); } | ||||
|   Format_String(CONS_UART_Write, "\n"); } | ||||
| #endif // DEBUG_PRINT
 | ||||
| 
 | ||||
| static void GPS_UBX(void)                                                         // when GPS gets an UBX packet
 | ||||
| { GPS_Status.UBX=1; | ||||
|  |  | |||
							
								
								
									
										33
									
								
								main/hal.cpp
								
								
								
								
							
							
						
						
									
										33
									
								
								main/hal.cpp
								
								
								
								
							|  | @ -86,7 +86,12 @@ UART2 pins: | |||
| 
 | ||||
| */ | ||||
| 
 | ||||
| #ifdef WITH_TTGO | ||||
| #define PIN_LED_PCB  GPIO_NUM_2   // status LED on the PCB: 25 or 2. GPIO25 id DAC2
 | ||||
| #endif | ||||
| #ifdef WITH_HELTEC | ||||
| #define PIN_LED_PCB  GPIO_NUM_25  // status LED on the PCB: 25 or 2. GPIO25 id DAC2
 | ||||
| #endif | ||||
| // #define PIN_LED_TX   GPIO_NUM_??
 | ||||
| // #define PIN_LED_RX   GPIO_NUM_??
 | ||||
| 
 | ||||
|  | @ -445,26 +450,32 @@ static const esp_spp_role_t role_slave   = ESP_SPP_ROLE_SLAVE; | |||
| 
 | ||||
| // static uint32_t ConnHandle=0;
 | ||||
| 
 | ||||
| extern "C" | ||||
| // extern "C"
 | ||||
| void esp_spp_cb(esp_spp_cb_event_t Event, esp_spp_cb_param_t *Param) | ||||
| { switch (Event) | ||||
|   { case ESP_SPP_INIT_EVT: | ||||
|       esp_bt_dev_set_device_name("TRACKER"); | ||||
|       esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); | ||||
|       esp_spp_start_srv(sec_mask, role_slave, 0, "OGN"); | ||||
|       esp_spp_start_srv(sec_mask, role_slave, 0, "SPP_SERVER"); | ||||
|       break; | ||||
| /*
 | ||||
|     case ESP_SPP_SRV_OPEN_EVT:  // open connection: new handle comes
 | ||||
|     case ESP_SPP_DISCOVERY_COMP_EVT: | ||||
|       break; | ||||
|     case ESP_SPP_START_EVT:                                       // SPP server started succesfully
 | ||||
|       break; | ||||
|     case ESP_SPP_SRV_OPEN_EVT:                                    // server connection opens: new handle comes
 | ||||
|       // Param->open.handle, Param->open.rem_bda
 | ||||
|     case ESP_SPP_SRV_CLOSE_EVT: // connection closes for given handle
 | ||||
|       break; | ||||
|     case ESP_SPP_OPEN_EVT:                                        // connection opens
 | ||||
|       // Param->close.handle, Param->close.rem_bda
 | ||||
|       break; | ||||
|     case ESP_SPP_DATA_IND_EVT:  // data is sent by the client
 | ||||
|     case ESP_SPP_CLOSE_EVT:                                       // connection closes for given handle
 | ||||
|       // Param->close.handle, Param->close.rem_bda
 | ||||
|       break; | ||||
|     case ESP_SPP_DATA_IND_EVT:                                    // data is sent by the client
 | ||||
|       // Param->data_ind.handle, Param->data_ind.data, Param->data_ind.len
 | ||||
|       break; | ||||
|     case ESP_SPP_WRITE_EVT:     // data has been sent to the cielnt
 | ||||
|     case ESP_SPP_WRITE_EVT:                                       // (queued) data has been sent to the client
 | ||||
|       break; | ||||
| */ | ||||
|     default: | ||||
|       break; | ||||
|   } | ||||
|  | @ -481,8 +492,8 @@ int BT_SPP_Init(void) | |||
|   esp_err_t Err; | ||||
|   Err = esp_bt_controller_init(&BTconf); if(Err!=ESP_OK) return Err; | ||||
|   Err = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT); if(Err!=ESP_OK) return Err; | ||||
|   Err = esp_bluedroid_init(); if(Err!=ESP_OK) return Err; | ||||
|   Err = esp_bluedroid_enable(); if(Err!=ESP_OK) return Err; | ||||
|   Err = esp_bluedroid_init(); if(Err!=ESP_OK) return Err;                                   // init the BT stack
 | ||||
|   Err = esp_bluedroid_enable(); if(Err!=ESP_OK) return Err;                                 // enable the BT stack
 | ||||
|   Err = esp_spp_register_callback(esp_spp_cb); if(Err!=ESP_OK) return Err; | ||||
|   Err = esp_spp_init(esp_spp_mode); if(Err!=ESP_OK) return Err; | ||||
|   return Err; } | ||||
|  | @ -518,7 +529,7 @@ int SPIFFS_Info(size_t &Total, size_t &Used, const char *Label) | |||
| 
 | ||||
| // ======================================================================================================
 | ||||
| 
 | ||||
| SemaphoreHandle_t I2C_Mutex; | ||||
| // SemaphoreHandle_t I2C_Mutex;
 | ||||
| 
 | ||||
| uint8_t I2C_Read(uint8_t Bus, uint8_t Addr, uint8_t Reg, uint8_t *Data, uint8_t Len, uint8_t Wait) | ||||
| { i2c_cmd_handle_t Cmd = i2c_cmd_link_create(); | ||||
|  |  | |||
							
								
								
									
										14
									
								
								main/hal.h
								
								
								
								
							
							
						
						
									
										14
									
								
								main/hal.h
								
								
								
								
							|  | @ -17,8 +17,13 @@ | |||
| 
 | ||||
| #define USE_BLOCK_SPI                      // use block SPI interface for RF chip
 | ||||
| 
 | ||||
| #define WITH_RFM95                         // RF chip selection
 | ||||
| #define WITH_HELTEC                        // HELTEC module: PCB LED on GPI025
 | ||||
| // #define WITH_TTGO                          // TTGO module: PCB LED on GPIO2, GPIO25 free to use as DAC2 output
 | ||||
| #define WITH_OLED                          // OLED display on the I2C: some TTGO modules are without OLED display
 | ||||
| 
 | ||||
| #define WITH_RFM95                         // RF chip selection:  both HELTEC and TTGO use sx1276 which is same af RFM95
 | ||||
| // #define WITH_RFM69
 | ||||
| 
 | ||||
| // #define WITH_LED_RX
 | ||||
| // #define WITH_LED_TX
 | ||||
| 
 | ||||
|  | @ -32,16 +37,15 @@ | |||
| 
 | ||||
| // #define WITH_BMP180                        // BMP180 pressure sensor
 | ||||
| // #define WITH_BMP280                        // BMP280 pressure sensor
 | ||||
| // #define WITH_BME280                        // with humidity
 | ||||
| // #define WITH_MS5607                        // MS5607 pressure sensor
 | ||||
| 
 | ||||
| #define I2C_SPEED 1000000                  // [Hz]
 | ||||
| #define I2C_SPEED 1000000                  // [Hz] bit rate on the I2C (nominally up to 400000)
 | ||||
| 
 | ||||
| #define WITH_PFLAA                         // PFLAU and PFLAA for compatibility with XCsoar and LK8000
 | ||||
| 
 | ||||
| #define WITH_CONFIG                        // interpret the console input: $POGNS to change parameters
 | ||||
| 
 | ||||
| #define WITH_OLED                          // OLED display on the I2C
 | ||||
| 
 | ||||
| // #define WITH_BT_SPP                        // Bluetooth serial port fo smartphone/tablet link
 | ||||
| 
 | ||||
| // ============================================================================================================
 | ||||
|  | @ -56,7 +60,7 @@ extern uint8_t  MAV_Seq;                   // sequence number for MAVlink messag | |||
| // ============================================================================================================
 | ||||
| 
 | ||||
| extern SemaphoreHandle_t CONS_Mutex;       // console port Mutex
 | ||||
| extern SemaphoreHandle_t I2C_Mutex;        // I2C port Mutex (OLED and Baro)
 | ||||
| // extern SemaphoreHandle_t I2C_Mutex;        // I2C port Mutex (OLED and Baro)
 | ||||
| 
 | ||||
| uint64_t getUniqueID(void);                // get some unique ID of the CPU/chip
 | ||||
| uint32_t getUniqueAddress(void);           // get unique 24-bit address for the transmitted IF
 | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ void app_main(void) | |||
|     // printf("OGN Tracker on ESP32\n");
 | ||||
| 
 | ||||
|     CONS_Mutex = xSemaphoreCreateMutex();    // semaphore for sharing the writing to the console
 | ||||
|     I2C_Mutex  = xSemaphoreCreateMutex();    // semaphore for sharing the I2C bus
 | ||||
|     // I2C_Mutex  = xSemaphoreCreateMutex();    // semaphore for sharing the I2C bus
 | ||||
| 
 | ||||
|     NVS_Init();                              // initialize Non-Volatile-Storage in Flash and read the tracker parameters
 | ||||
| 
 | ||||
|  | @ -27,16 +27,16 @@ void app_main(void) | |||
| 
 | ||||
|     SPIFFS_Register();                       // initialize the file system in the Flash
 | ||||
| 
 | ||||
|     IO_Configuration();                      // initialize the GPIO/UART/I2C/SPI for Radio, GPS, OLED, Baro
 | ||||
| 
 | ||||
| #ifdef WITH_BT_SPP | ||||
|     BT_SPP_Init();                           // start BT SPP
 | ||||
| #endif | ||||
| 
 | ||||
|     IO_Configuration();                      // initialize the GPIO/UART/I2C/SPI for Radio, GPS, OLED, Baro
 | ||||
| 
 | ||||
|     xTaskCreate(vTaskRF,    "RF",    2048, 0, tskIDLE_PRIORITY+4, 0); | ||||
|     xTaskCreate(vTaskPROC,  "PROC",  2048, 0, tskIDLE_PRIORITY+3, 0); | ||||
|     xTaskCreate(vTaskGPS,   "GPS",   2048, 0, tskIDLE_PRIORITY+4, 0); | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(BME280) || defined(WITH_MS5607) | ||||
|     xTaskCreate(vTaskSENS,  "SENS",  2048, 0, tskIDLE_PRIORITY+4, 0); | ||||
| #endif | ||||
|     // xTaskCreate(vTaskCTRL,  "CTRL",  1536, 0, tskIDLE_PRIORITY+2, 0);
 | ||||
|  |  | |||
|  | @ -15,5 +15,5 @@ uint8_t NMEA_AppendCheck(uint8_t *NMEA, uint8_t Len) | |||
| 
 | ||||
| uint8_t NMEA_AppendCheckCRNL(uint8_t *NMEA, uint8_t Len) | ||||
| { uint8_t CheckLen=NMEA_AppendCheck(NMEA, Len); | ||||
|   Len+=CheckLen; NMEA[Len]='\r'; NMEA[Len+1]='\n'; | ||||
|   return CheckLen+2; } | ||||
|   Len+=CheckLen; NMEA[Len]='\n'; | ||||
|   return CheckLen+1; } | ||||
|  |  | |||
|  | @ -625,8 +625,8 @@ class OGN_Packet           // Packet structure for the OGN tracker | |||
|    { return DecodeUR2V12(Position.Altitude); } | ||||
| 
 | ||||
|    void EncodeDOP(uint8_t DOP) | ||||
|    {      if(DOP<0)    DOP=0; | ||||
|      else if(DOP<0x10) { } | ||||
|    { // if(DOP<0)    DOP=0;
 | ||||
|           if(DOP<0x10) { } | ||||
|      else if(DOP<0x30) DOP = 0x10 | ((DOP-0x10)>>1); | ||||
|      else if(DOP<0x70) DOP = 0x20 | ((DOP-0x30)>>2); | ||||
|      else if(DOP<0xF0) DOP = 0x30 | ((DOP-0x70)>>3); | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ | |||
| 
 | ||||
| #include "hal.h" | ||||
| 
 | ||||
| #include "ogn.h" | ||||
| 
 | ||||
| #ifdef WITH_ESP32 | ||||
| #include "nvs.h" | ||||
| #endif | ||||
|  | @ -53,20 +55,26 @@ class FlashParameters | |||
|   uint16_t  SoftPPSdelay;    // [ms]
 | ||||
| 
 | ||||
|    static const uint8_t InfoParmLen = 16; // [char] max. size of an infp-parameter
 | ||||
|    static const uint8_t InfoParmNum =  6; // [int]  number of info-parameters
 | ||||
|          char *InfoParmValue(uint8_t Idx)       { return Idx<InfoParmNum ? Pilot + Idx*InfoParmLen:0; } | ||||
|    const char *InfoParmName(uint8_t Idx) const { static const char *Name[InfoParmNum] = { "Pilot", "Manuf", "Model", "Reg", "Base", "ICE" } ; | ||||
|    static const uint8_t InfoParmNum = 11; // [int]  number of info-parameters
 | ||||
|          char *InfoParmValue(uint8_t Idx)      { return Idx<InfoParmNum ? Pilot + Idx*InfoParmLen:0; } | ||||
|       uint8_t  InfoParmValueLen(uint8_t Idx)   { return strlen(InfoParmValue(Idx)); } | ||||
|    const char *InfoParmName(uint8_t Idx) const { static const char *Name[InfoParmNum] = | ||||
|                                                { "Pilot", "Manuf", "Model", "Type", "SN", "Reg", "ID", "Class", "Task", "Base", "ICE" } ; | ||||
|                                                   return Idx<InfoParmNum ? Name[Idx]:0; } | ||||
|      char   Pilot[InfoParmLen]; | ||||
|      char   Manuf[InfoParmLen]; | ||||
|      char   Model[InfoParmLen]; | ||||
|      char     Reg[InfoParmLen]; | ||||
|      char    Base[InfoParmLen]; | ||||
|      char     ICE[InfoParmLen]; | ||||
|      char   Pilot[InfoParmLen];                // Pilot name
 | ||||
|      char   Manuf[InfoParmLen];                // Manufacturer
 | ||||
|      char   Model[InfoParmLen];                // Model
 | ||||
|      char    Type[InfoParmLen];                // Type
 | ||||
|      char      SN[InfoParmLen];                // Serial Number
 | ||||
|      char     Reg[InfoParmLen];                // Registration
 | ||||
|      char      ID[InfoParmLen];                // Competition ID
 | ||||
|      char   Class[InfoParmLen];                // Competition class
 | ||||
|      char    Task[InfoParmLen];                // Competition task
 | ||||
|      char    Base[InfoParmLen];                // Base airfield
 | ||||
|      char     ICE[InfoParmLen];                // In Case of Emergency
 | ||||
| 
 | ||||
|    // char BTname[8];
 | ||||
|    // char  BTpin[4];
 | ||||
|    // char Pilot[16];
 | ||||
|    // char Copilot[16]
 | ||||
|    // char Category[16]
 | ||||
| 
 | ||||
|  | @ -102,14 +110,18 @@ class FlashParameters | |||
|     TimeCorr       =         0; // [sec]
 | ||||
|     GeoidSepar     =       470; // [0.1m]
 | ||||
| 
 | ||||
|     Pilot[0]    = 0; | ||||
|     Manuf[0]    = 0; | ||||
|     Model[0]    = 0; | ||||
|     Reg[0]      = 0; | ||||
|     Base[0]     = 0; | ||||
|     ICE[0]      = 0; | ||||
|     for(uint8_t Idx=0; Idx<InfoParmNum; Idx++) | ||||
|       InfoParmValue(Idx)[0] = 0; | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| // void WriteHeader(OGN_Packet &Packet)
 | ||||
| // { Packet.HeaderWord=0;
 | ||||
| //   Packet.Header.Address    = Parameters.Address;    // set address
 | ||||
| //   Packet.Header.AddrType   = Parameters.AddrType;   // address-type
 | ||||
| //   Packet.Header.Other=1;
 | ||||
| //   Packet.calcAddrParity(); }                        // parity of (part of) the header
 | ||||
| 
 | ||||
| #ifdef WITH_ESP32 | ||||
|   esp_err_t WriteToNVS(const char *Name="Parameters", const char *NameSpace="TRACKER") | ||||
|   { nvs_handle Handle; | ||||
|  | @ -194,6 +206,9 @@ class FlashParameters | |||
| #endif | ||||
| #ifdef WITH_RFM95 | ||||
|     Len+=Format_String(Line+Len, " RFM95"); | ||||
| #endif | ||||
| #ifdef WITH_SX1272 | ||||
|     Len+=Format_String(Line+Len, " SX1272"); | ||||
| #endif | ||||
|     Line[Len++]='/'; | ||||
|     Len+=Format_SignDec(Line+Len, (int16_t)getTxPower()); | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| #include <stdint.h> | ||||
| 
 | ||||
| #include "hal.h" | ||||
| 
 | ||||
| #include "proc.h" | ||||
| #include "ctrl.h" | ||||
| 
 | ||||
|  | @ -26,6 +25,7 @@ static LDPC_Decoder     Decoder;      // error corrector for the OGN Gallager co | |||
| 
 | ||||
| static OGN_PrioQueue<16> RelayQueue;  // received packets and candidates to be relayed
 | ||||
| 
 | ||||
| #ifdef DEBUG_PRINT | ||||
| static void PrintRelayQueue(uint8_t Idx)                    // for debug
 | ||||
| { uint8_t Len=0; | ||||
|   // Len+=Format_String(Line+Len, "");
 | ||||
|  | @ -34,27 +34,27 @@ static void PrintRelayQueue(uint8_t Idx)                    // for debug | |||
|   Line[Len++]='['; Len+=Format_Hex(Line+Len, Idx); Line[Len++]=']'; Line[Len++]=' '; | ||||
|   Len+=RelayQueue.Print(Line+Len); | ||||
|   Format_String(CONS_UART_Write, Line); | ||||
|   xSemaphoreGive(CONS_Mutex); | ||||
| } | ||||
|   xSemaphoreGive(CONS_Mutex); } | ||||
| #endif | ||||
| 
 | ||||
| static bool GetRelayPacket(OGN_TxPacket *Packet)      // prepare a packet to be relayed
 | ||||
| { if(RelayQueue.Sum==0) return 0; | ||||
|   XorShift32(RX_Random); | ||||
|   uint8_t Idx=RelayQueue.getRand(RX_Random); | ||||
|   if(RelayQueue.Packet[Idx].Rank==0) return 0; | ||||
|   memcpy(Packet->Packet.Byte(), RelayQueue[Idx]->Byte(), OGN_Packet::Bytes); | ||||
|   Packet->Packet.Header.RelayCount+=1; | ||||
|   Packet->Packet.Whiten(); Packet->calcFEC(); | ||||
| { if(RelayQueue.Sum==0) return 0;                     // if no packets in the relay queue
 | ||||
|   XorShift32(RX_Random);                              // produce a new random number
 | ||||
|   uint8_t Idx=RelayQueue.getRand(RX_Random);          // get weight-random packet from the relay queue
 | ||||
|   if(RelayQueue.Packet[Idx].Rank==0) return 0;        // should not happen ...
 | ||||
|   memcpy(Packet->Packet.Byte(), RelayQueue[Idx]->Byte(), OGN_Packet::Bytes); // copy the packet
 | ||||
|   Packet->Packet.Header.RelayCount+=1;                // increment the relay count (in fact we only do single relay)
 | ||||
|   Packet->Packet.Whiten(); Packet->calcFEC();         // whiten and calc. the FEC code => packet ready for transmission
 | ||||
|   // PrintRelayQueue(Idx);  // for debug
 | ||||
|   RelayQueue.decrRank(Idx); | ||||
|   RelayQueue.decrRank(Idx);                           // reduce the rank of the packet selected for relay
 | ||||
|   return 1; } | ||||
| 
 | ||||
| static void CleanRelayQueue(uint32_t Time, uint32_t Delay=20) | ||||
| { RelayQueue.cleanTime((Time-Delay)%60); } | ||||
| static void CleanRelayQueue(uint32_t Time, uint32_t Delay=20) // remove "old" packets from the relay queue
 | ||||
| { RelayQueue.cleanTime((Time-Delay)%60); }            // remove packets 20(default) seconds into the past
 | ||||
| 
 | ||||
| // ---------------------------------------------------------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| static void ReadStatus(OGN_TxPacket &StatPacket) | ||||
| static void ReadStatus(OGN_TxPacket &StatPacket)                            // read the device status and fill the status packet
 | ||||
| { | ||||
| 
 | ||||
| #ifdef WITH_STM32 | ||||
|  | @ -71,8 +71,8 @@ static void ReadStatus(OGN_TxPacket &StatPacket) | |||
|   uint16_t RxRate = RX_OGN_Count64+1; | ||||
|   uint8_t RxRateLog2=0; RxRate>>=1; while(RxRate) { RxRate>>=1; RxRateLog2++; } | ||||
|   StatPacket.Packet.Status.RxRate = RxRateLog2; | ||||
| 
 | ||||
|  { uint8_t Len=0; | ||||
|                                                                              // produce the POGNR sentence
 | ||||
|   { uint8_t Len=0; | ||||
|     Len+=Format_String(Line+Len, "$POGNR,");                                 // NMEA report: radio status
 | ||||
|     Len+=Format_UnsDec(Line+Len, RF_FreqPlan.Plan);                          // which frequency plan
 | ||||
|     Line[Len++]=','; | ||||
|  | @ -98,7 +98,7 @@ static void ReadStatus(OGN_TxPacket &StatPacket) | |||
| #ifdef WITH_SDLOG | ||||
|     if(Log_Free()>=128) | ||||
|     { xSemaphoreTake(Log_Mutex, portMAX_DELAY); | ||||
|       Format_String(Log_Write, Line, Len);                                     // send the NMEA out to the log file
 | ||||
|       Format_String(Log_Write, Line, Len, 0);                                     // send the NMEA out to the log file
 | ||||
|       xSemaphoreGive(Log_Mutex); } | ||||
| #endif | ||||
|   } | ||||
|  | @ -126,7 +126,7 @@ static void ProcessRxPacket(OGN_RxPacket *RxPacket, uint8_t RxPacketIdx) | |||
| #ifdef WITH_SDLOG | ||||
|     if(Log_Free()>=128) | ||||
|     { xSemaphoreTake(Log_Mutex, portMAX_DELAY); | ||||
|       Format_String(Log_Write, Line, Len); | ||||
|       Format_String(Log_Write, Line, Len, 0); | ||||
|       xSemaphoreGive(Log_Mutex); } | ||||
| #endif | ||||
| #ifdef WITH_PFLAA | ||||
|  | @ -190,9 +190,13 @@ void vTaskPROC(void* pvParameters) | |||
| #endif | ||||
|   RelayQueue.Clear(); | ||||
| 
 | ||||
|   OGN_TxPacket PosPacket;                                               // position packet
 | ||||
|   uint32_t     PosTime=0;                                               // [sec] when the position was recorded
 | ||||
|   OGN_TxPacket StatPacket;                                              // status report packet
 | ||||
|   static uint16_t AverSpeed=0;                                          // [0.1m/s] average speed (including vertical)
 | ||||
|   static bool     isMoving=0;                                           // is the aircraft moving ?
 | ||||
| 
 | ||||
|   static OGN_TxPacket PosPacket;                                        // position packet
 | ||||
|   static uint32_t     PosTime=0;                                        // [sec] when the position was recorded
 | ||||
|   static OGN_TxPacket StatPacket;                                       // status report packet
 | ||||
|   static OGN_TxPacket InfoPacket;                                       // information packet
 | ||||
| 
 | ||||
|   for( ; ; ) | ||||
|   { vTaskDelay(1); | ||||
|  | @ -240,7 +244,8 @@ void vTaskPROC(void* pvParameters) | |||
|     // GPS_Position *Position = GPS_getPosition();
 | ||||
|     if(Position) Position->EncodeStatus(StatPacket.Packet);             // encode GPS altitude and pressure
 | ||||
|     if( Position && Position->isReady && (!Position->Sent) && Position->isReady && Position->isValid() ) | ||||
|     { int16_t AverSpeed=GPS_AverageSpeed();                             // [0.1m/s] average speed, including the vertical speed
 | ||||
|     { AverSpeed=GPS_AverageSpeed();                                     // [0.1m/s] average speed, including the vertical speed
 | ||||
|       isMoving = AverSpeed>10; | ||||
|       RF_FreqPlan.setPlan(Position->Latitude, Position->Longitude);     // set the frequency plan according to the GPS position
 | ||||
| /*
 | ||||
| #ifdef DEBUG_PRINT | ||||
|  | @ -275,7 +280,7 @@ void vTaskPROC(void* pvParameters) | |||
|       xSemaphoreGive(CONS_Mutex); | ||||
| #endif | ||||
|       XorShift32(RX_Random); | ||||
|       if( (AverSpeed>10) || ((RX_Random&0x3)==0) )                      // send only some positions if the speed is less than 1m/s
 | ||||
|       if( isMoving || ((RX_Random&0x3)==0) )                            // send only some positions if the speed is less than 1m/s
 | ||||
|         RF_TxFIFO.Write();                                              // complete the write into the TxFIFO
 | ||||
|       Position->Sent=1; | ||||
| #ifdef WITH_FLASHLOG | ||||
|  | @ -312,6 +317,13 @@ void vTaskPROC(void* pvParameters) | |||
|     Format_String(CONS_UART_Write, Line); | ||||
|     xSemaphoreGive(CONS_Mutex); | ||||
| #endif | ||||
|     // Parameters.WriteHeader(InfoPacket.Packet);
 | ||||
|     InfoPacket.Packet.HeaderWord=0; | ||||
|     InfoPacket.Packet.Header.Address    = Parameters.Address;    // set address
 | ||||
|     InfoPacket.Packet.Header.AddrType   = Parameters.AddrType;   // address-type
 | ||||
|     InfoPacket.Packet.Header.Other=1; | ||||
|     InfoPacket.Packet.calcAddrParity();                          // parity of (part of) the header
 | ||||
| 
 | ||||
|     StatPacket.Packet.HeaderWord=0; | ||||
|     StatPacket.Packet.Header.Address    = Parameters.Address;    // set address
 | ||||
|     StatPacket.Packet.Header.AddrType   = Parameters.AddrType;   // address-type
 | ||||
|  |  | |||
|  | @ -79,8 +79,8 @@ static uint32_t ReceiveUntil(TickType_t End) | |||
|     vTaskDelay(1); } | ||||
|   return Count; } | ||||
| 
 | ||||
| static uint32_t ReceiveFor(TickType_t Ticks)                     // keep receiving packets for given period of time
 | ||||
| { return ReceiveUntil(xTaskGetTickCount()+Ticks); } | ||||
| // static uint32_t ReceiveFor(TickType_t Ticks)                     // keep receiving packets for given period of time
 | ||||
| // { return ReceiveUntil(xTaskGetTickCount()+Ticks); }
 | ||||
| 
 | ||||
| static uint8_t Transmit(uint8_t TxChan, const uint8_t *PacketByte, uint8_t Thresh, uint8_t MaxWait=7) | ||||
| { | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ | |||
| 
 | ||||
| // #define DEBUG_PRINT
 | ||||
| 
 | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) | ||||
| 
 | ||||
| #ifdef WITH_BMP180 | ||||
| #include "bmp180.h" | ||||
|  | @ -21,6 +21,10 @@ | |||
| #include "bmp280.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_BME280 | ||||
| #include "bme280.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_MS5607 | ||||
| #include "ms5607.h" | ||||
| #endif | ||||
|  | @ -63,6 +67,10 @@ static BMP180   Baro;                       // BMP180 barometer sensor | |||
| static BMP280   Baro;                       // BMP280 barometer sensor
 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_BME280 | ||||
| static BME280   Baro;                       // BMP280 barometer sensor with humidity sensor
 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_MS5607 | ||||
| static MS5607   Baro;                       // BMP280 barometer sensor
 | ||||
| #endif | ||||
|  | @ -81,7 +89,7 @@ static Delay<int32_t, 8>        PressDelay; // 4-second delay for long-term clim | |||
| static char Line[64];                       // line to prepare the barometer NMEA sentence
 | ||||
| 
 | ||||
| static uint8_t InitBaro() | ||||
| { xSemaphoreTake(I2C_Mutex, portMAX_DELAY); | ||||
| { // xSemaphoreTake(I2C_Mutex, portMAX_DELAY);
 | ||||
|   Baro.Bus=BARO_I2C; | ||||
|   uint8_t Err=Baro.CheckID(); | ||||
|   if(Err==0) Err=Baro.ReadCalib(); | ||||
|  | @ -89,11 +97,11 @@ static uint8_t InitBaro() | |||
|   if(Err==0) Err=Baro.AcquireRawTemperature(); | ||||
|   if(Err==0) { Baro.CalcTemperature(); AverPress=0; AverCount=0; } | ||||
| #endif | ||||
| #if defined(WITH_BMP280) || defined(WITH_MS5607) | ||||
| #if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) | ||||
|   if(Err==0) Err=Baro.Acquire(); | ||||
|   if(Err==0) { Baro.Calculate(); } | ||||
| #endif | ||||
|   xSemaphoreGive(I2C_Mutex); | ||||
|   // xSemaphoreGive(I2C_Mutex);
 | ||||
|   // if(Err) LED_BAT_On();
 | ||||
|   return Err==0 ? Baro.ADDR:0; } | ||||
| 
 | ||||
|  | @ -109,32 +117,41 @@ static void ProcBaro(void) | |||
| 
 | ||||
| #ifdef WITH_BMP180 | ||||
|     TickType_t Start=xTaskGetTickCount(); | ||||
|     xSemaphoreTake(I2C_Mutex, portMAX_DELAY); | ||||
|     // xSemaphoreTake(I2C_Mutex, portMAX_DELAY);
 | ||||
|     uint8_t Err=Baro.AcquireRawTemperature();                             // measure temperature
 | ||||
|     xSemaphoreGive(I2C_Mutex); | ||||
|     // xSemaphoreGive(I2C_Mutex);
 | ||||
|     if(Err==0) { Baro.CalcTemperature(); AverPress=0; AverCount=0; }      // clear the average
 | ||||
|           else { PipeCount=0; | ||||
|                  xSemaphoreTake(I2C_Mutex, portMAX_DELAY); | ||||
|                  // xSemaphoreTake(I2C_Mutex, portMAX_DELAY);
 | ||||
| 	         I2C_Restart(Baro.Bus); | ||||
|                  xSemaphoreGive(I2C_Mutex); | ||||
|                  // xSemaphoreGive(I2C_Mutex);
 | ||||
|                  vTaskDelay(20); | ||||
|                  InitBaro(); // try to recover I2C bus and baro
 | ||||
| 		 return; } | ||||
| 
 | ||||
|     for(uint8_t Idx=0; Idx<24; Idx++) | ||||
|     { xSemaphoreTake(I2C_Mutex, portMAX_DELAY); | ||||
|     for(uint8_t Idx=0; Idx<16; Idx++) | ||||
|     { // xSemaphoreTake(I2C_Mutex, portMAX_DELAY);
 | ||||
|       uint8_t Err=Baro.AcquireRawPressure();                              // take pressure measurement
 | ||||
|       xSemaphoreGive(I2C_Mutex); | ||||
|       // xSemaphoreGive(I2C_Mutex);
 | ||||
|       if(Err==0) { Baro.CalcPressure(); AverPress+=Baro.Pressure; AverCount++; } // sum-up average pressure
 | ||||
|       TickType_t Time=xTaskGetTickCount()-Start; if(Time>=200) break; }   // but no longer than 250ms to fit into 0.5 second slot
 | ||||
| 
 | ||||
|     if(AverCount==0) { PipeCount=0; return ; }                          // and we summed-up some measurements
 | ||||
|     AverPress = ( (AverPress<<2) + (AverCount>>1) )/AverCount;          // [0.25Pa]] make the average
 | ||||
| #ifdef DEBUG_PRINT | ||||
|     xSemaphoreTake(CONS_Mutex, portMAX_DELAY); | ||||
|     Format_String(CONS_UART_Write, "BMP180: "); | ||||
|     Format_UnsDec(CONS_UART_Write, (AverPress+2)/4, 3, 2); | ||||
|     Format_String(CONS_UART_Write, "hPa/"); | ||||
|     Format_UnsDec(CONS_UART_Write, (uint16_t)AverCount); | ||||
|     Format_String(CONS_UART_Write, "\n"); | ||||
|     xSemaphoreGive(CONS_Mutex); | ||||
| #endif | ||||
| #if defined(WITH_BMP280) || defined(WITH_MS5607) | ||||
|     xSemaphoreTake(I2C_Mutex, portMAX_DELAY); | ||||
| #endif | ||||
| #if defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) | ||||
|     // xSemaphoreTake(I2C_Mutex, portMAX_DELAY);
 | ||||
|     uint8_t Err=Baro.Acquire(); | ||||
|     xSemaphoreGive(I2C_Mutex); | ||||
|     // xSemaphoreGive(I2C_Mutex);
 | ||||
|     if(Err==0) { Baro.Calculate(); } | ||||
|           else { PipeCount=0; return; } | ||||
|     AverPress = Baro.Pressure;                                          // [0.25Pa]
 | ||||
|  | @ -207,6 +224,10 @@ static void ProcBaro(void) | |||
|     Line[Len++]=','; | ||||
|     Len+=Format_SignDec(Line+Len, ClimbRate,   3, 2);                // [m/s] climb rate
 | ||||
|     Line[Len++]=','; | ||||
| #ifdef WITH_BME280 | ||||
|     Len+=Format_SignDec(Line+Len, Baro.Humidity,3, 1);                // [%] relative humidity
 | ||||
|     Line[Len++]=','; | ||||
| #endif | ||||
|     Len+=NMEA_AppendCheckCRNL(Line, Len); | ||||
|     // if(CONS_UART_Free()>=128)
 | ||||
|     { xSemaphoreTake(CONS_Mutex, portMAX_DELAY); | ||||
|  | @ -215,7 +236,7 @@ static void ProcBaro(void) | |||
| #ifdef WITH_SDLOG | ||||
|     if(Log_Free()>=128) | ||||
|     { xSemaphoreTake(Log_Mutex, portMAX_DELAY); | ||||
|       Format_String(Log_Write, Line, Len);                             // send NMEA sentence to the log file
 | ||||
|       Format_String(Log_Write, Line, Len, 0);                             // send NMEA sentence to the log file
 | ||||
|       xSemaphoreGive(Log_Mutex); } | ||||
| #endif | ||||
| 
 | ||||
|  | @ -233,7 +254,7 @@ static void ProcBaro(void) | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif // WITH_BMP180/BMP280
 | ||||
| #endif // WITH_BMP180/BMP280/BME280
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -245,7 +266,7 @@ void vTaskSENS(void* pvParameters) | |||
| //   VarioSound(0);
 | ||||
| // #endif
 | ||||
| 
 | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) | ||||
|   BaroPipe.Clear  (4*90000); | ||||
|   BaroNoise.Set(12*16);                // guess the pressure noise level
 | ||||
| 
 | ||||
|  | @ -272,6 +293,12 @@ void vTaskSENS(void* pvParameters) | |||
|          else  Format_String(CONS_UART_Write, " ?!"); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_BME280 | ||||
|   Format_String(CONS_UART_Write, " BME280: "); | ||||
|   if(Detected) { Format_String(CONS_UART_Write, " @"); Format_Hex(CONS_UART_Write, Detected); } | ||||
|          else  Format_String(CONS_UART_Write, " ?!"); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WITH_MS5607 | ||||
|   Format_String(CONS_UART_Write, " MS5607: "); | ||||
|   if(Detected) { Format_String(CONS_UART_Write, " @"); Format_Hex(CONS_UART_Write, Detected); } | ||||
|  | @ -283,7 +310,7 @@ void vTaskSENS(void* pvParameters) | |||
| 
 | ||||
|   while(1) | ||||
|   { | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) | ||||
| #if defined(WITH_BMP180) || defined(WITH_BMP280) || defined(WITH_MS5607) || defined(WITH_BME280) | ||||
|     ProcBaro(); | ||||
| #else | ||||
|     vTaskDelay(1000); | ||||
|  |  | |||
|  | @ -246,6 +246,13 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20 | |||
| # | ||||
| CONFIG_PM_ENABLE= | ||||
| 
 | ||||
| # | ||||
| # ADC-Calibration | ||||
| # | ||||
| CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y | ||||
| CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y | ||||
| CONFIG_ADC_CAL_LUT_ENABLE=y | ||||
| 
 | ||||
| # | ||||
| # Ethernet | ||||
| # | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Pawel Jalocha
						Pawel Jalocha