Changeset - f2c57ce0cd7b
[Not reviewed]
default
2 3 2
Ethan Zonca (ethanzonca) - 9 years ago 2017-01-24 10:20:42
e@ethanzonca.com
Refactor old pressure code and make optional. Fix high power output due to multiple Si446x power definitions
5 files changed with 59 insertions and 26 deletions:
0 comments (0 inline, 0 general)
Include/config.h
Show inline comments
 
//
 
// Depth Select Configuration
 
//
 
 
#ifndef CONFIG_H
 
#define CONFIG_H
 
 
 
// --------------------------------------------------------------------------
 
// Transmitter config (si446x.c)
 
// --------------------------------------------------------------------------
 
 
// Transmit power (0-0x7F, 0mW - 40mw?)
 
#define SI446x_POWER 0x02
 
 
#define TUNE_FREQUENCY 433000000UL
 
#define TUNE_FREQUENCY 433500000UL
 
 
// Internal macros
 
#define hal_init HAL_Init
 
 
 
// Uncomment if using legacy LPS25h pressure sensor
 
//#define LPS25H
 
 
 
// --------------------------------------------------------------------------
 
// ADC config (adc.c)
 
// --------------------------------------------------------------------------
 
 
// Temperature sensor offset (die temperature from ambient, esimate, in Celcius)
 
#define ADC_TEMPERATURE_OFFSET -10
 
 
 
// --------------------------------------------------------------------------
 
// AX.25 config (ax25.c)
 
// --------------------------------------------------------------------------
 
 
// TX delay in milliseconds
 
#define TX_DELAY      70
 
 
// Maximum packet delay
 
#define MAX_PACKET_LEN 512  // bytes
 
 
 
// --------------------------------------------------------------------------
 
// APRS config (aprs.c)
 
// --------------------------------------------------------------------------
 
 
#define SI446x_POWER 0x7f
 
 
// Set your callsign and SSID here. Common values for the SSID are
 
// (from http://zlhams.wikidot.com/aprs-ssidguide):
 
//
 
// - Balloons:  11
 
// - Cars:       9
 
// - Home:       0
 
// - IGate:      5
 
#define S_CALLSIGN      "S"
 
#define S_CALLSIGN_ID   1
 
 
// Destination callsign: APRS (with SSID=0) is usually okay.
 
#define D_CALLSIGN      ""
 
#define D_CALLSIGN_ID   0
 
 
// Digipeating paths:
 
// (read more about digipeating paths here: http://wa8lmf.net/DigiPaths/ )
 
// The recommended digi path for a balloon is WIDE2-1 or pathless. The default
 
// is pathless. Uncomment the following two lines for WIDE2-1 path:
 
//#define DIGI_PATH1      "WIDE2"
 
//#define DIGI_PATH1_TTL  1
 
 
// Transmit the APRS sentence every X milliseconds
 
#define APRS_TRANSMIT_PERIOD 1000
 
Include/lps25h.h
Show inline comments
 
file renamed from Include/pressure.h to Include/lps25h.h
 
#ifndef PRESSURE_H
 
#define PRESSURE_H
 
#ifndef LPS25H_H
 
#define LPS25H_H
 
 
#include "stm32f0xx_hal.h"
 
 
 
#define PIN_SENSORS_SDA GPIO_PIN_7
 
#define PIN_SENSORS_SCL GPIO_PIN_6
 
#define PORT_SENSORS GPIOB
 
 
#define PRESSURE_ADDRESS 0b10111000
 
#define PRESSURE_PRESS_REGH 0x2A
 
#define PRESSURE_PRESS_REGL 0x29
 
#define PRESSURE_PRESS_REGXL 0x28
 
#define PRESSURE_TEMP_REGH 0x2C
 
#define PRESSURE_TEMP_REGL 0x2B
 
#define PRESSURE_AUTOINC 0b10000000
 
 
#define PRESSURE_CTRL1_1HZ 	  0b00010000
 
#define PRESSURE_CTRL1_7HZ 	  0b00100000
 
#define PRESSURE_CTRL1_12_5HZ 0b00110000
 
#define PRESSURE_CTRL1_25HZ   0b01000000
 
 
#define PRESSURE_CTRL1_PWRUP 0b10000000
 
 
void pressure_init(void);
 
void pressure_read(void);
 
void pressure_updatevalues(void);
 
void lps25h_init(void);
 
void lps25h_read(void);
 
void lps25h_updatevalues(void);
 
 
int32_t pressure_gettemp(void);
 
int32_t pressure_getpressure(void);
 
int32_t lps25h_get_temperature(void);
 
int32_t lps25h_get_pressure(void);
 
 
I2C_HandleTypeDef* pressure_get_i2c_handle(void);
 
I2C_HandleTypeDef* lps25h_get_i2c_handle(void);
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Libraries/aprs/aprs.c
Show inline comments
 
@@ -3,50 +3,53 @@
 
 *
 
 * This file is part of FeatherHAB.
 
 *
 
 * FeatherHab is free software: you can redistribute it and/or modify
 
 * it under the terms of the GNU Affero General Public License as published by
 
 * the Free Software Foundation, either version 3 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * FeatherHab is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU Affero General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU Affero General Public License
 
 * along with FeatherHAB. If not, see <http://www.gnu.org/licenses/>.
 
 * 
 
 * Ethan Zonca
 
 *
 
 */
 

	
 
#include <string.h>
 
#include <stdlib.h>
 

	
 
#include "config.h"
 
//#include "pressure.h"
 
#include "bme280.h"
 
#ifdef LPS25H
 
	#include "lps25h.h"
 
#else
 
	#include "bme280.h"
 
#endif
 
#include "aprs.h"
 
#include "gps.h"
 
//#include "gps.h"
 
//#include "adc.h"
 
#include "ax25.h"
 
#include "system/adc.h"
 

	
 

	
 
int32_t meters_to_feet(int32_t m)
 
{
 
  // 10000 ft = 3048 m
 
  return (float)m / 0.3048;
 
}
 

	
 
void aprs_send(void)
 
{
 
  struct s_address addresses[] = { 
 
    {D_CALLSIGN, D_CALLSIGN_ID},  // Destination callsign
 
    {"", S_CALLSIGN_ID},  // Source callsign (-11 = balloon, -9 = car)
 
		//{S_CALLSIGN, S_CALLSIGN_ID},
 
#ifdef DIGI_PATH1
 
    {DIGI_PATH1, DIGI_PATH1_TTL}, // Digi1 (first digi in the chain)
 
#endif
 
#ifdef DIGI_PATH2
 
@@ -59,53 +62,69 @@ void aprs_send(void)
 
  // emz: modified this to get the size of the first address rather than the size of the struct itself, which fails
 
  ax25_send_header(addresses, sizeof(addresses)/sizeof(addresses[0]));
 
  ax25_send_byte(',');
 

	
 
  char tmpBuffer[128];
 
  tmpBuffer[0] = ',';
 
  tmpBuffer[1] = '\0';
 

	
 
  // Latitude
 
  snprintf(tmpBuffer, 128, "%ld,", gps_getdata()->latitude);
 
  ax25_send_string(tmpBuffer);
 
  
 
  // Longitude
 
  snprintf(tmpBuffer, 128, "%ld,", gps_getdata()->longitude);
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Speed
 
  snprintf(tmpBuffer, 128, "%d,", gps_getdata()->speed);
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Altitude
 
  snprintf(tmpBuffer, 128, "%d,", gps_getdata()->altitude);
 
  ax25_send_string(tmpBuffer);
 

	
 

	
 
#ifdef LPS25H
 
  // Pressure
 
  snprintf(tmpBuffer, 128, "%d,", bme280_get_pressure());
 
  snprintf(tmpBuffer, 128, "%d,", lps25h_get_pressure());
 
  ax25_send_string(tmpBuffer);
 
  
 
  // Temperature
 
  snprintf(tmpBuffer, 128, "%d,", bme280_get_temperature());
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Humidity
 
  snprintf(tmpBuffer, 128, "0,");
 
  ax25_send_string(tmpBuffer);
 

	
 
#else
 
  // Pressure
 
  snprintf(tmpBuffer, 128, "%d,", bme280_get_pressure());
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Temperature
 
  snprintf(tmpBuffer, 128, "%d,", bme280_get_temperature());
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Humidity
 
  snprintf(tmpBuffer, 128, "%d,", bme280_get_humidity());
 
  ax25_send_string(tmpBuffer);
 
#endif
 

	
 
  // HDOP
 
  snprintf(tmpBuffer, 128, "%u,", gps_getdata()->pdop);
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Heading
 
  snprintf(tmpBuffer, 128, "%u,", gps_getdata()->heading);
 
  ax25_send_string(tmpBuffer);
 

	
 
  // Vbatt
 
  snprintf(tmpBuffer, 128, "%u,", adc_get_vbatt());
 
  ax25_send_string(tmpBuffer);
 

	
 
  ax25_send_footer();
 
  ax25_flush_frame();
 
}
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
Source/lps25h.c
Show inline comments
 
file renamed from Source/pressure.c to Source/lps25h.c
 
//
 
// Sensors: Reads pressure and e-compass sensors over I2C and stores readings in queryable internal data structures
 
//
 
 
#include "pressure.h"
 
#include "lps25h.h"
 
#include "stm32f0xx_hal.h"
 
 
 
#include "config.h"
 
 
 
// Static variables
 
static I2C_HandleTypeDef hi2c1;
 
 
static int32_t pressure_hPa = 0;
 
static int32_t temp_celsius = 0;
 
 
static uint8_t sensors_pressurebuf[8]; // Buffer for i2c rx pressure data
 
static uint8_t sensors_pressure_freshdata = 0; // If pressure sensor has fresh data
 
 
 
// Initialize pressure sensor and E-compass
 
void pressure_init(void)
 
void lps25h_init(void)
 
{
 
	GPIO_InitTypeDef GPIO_InitStruct;
 
 
	// I2C Pins
 
    GPIO_InitStruct.Pin = PIN_SENSORS_SCL|PIN_SENSORS_SDA;
 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 
    GPIO_InitStruct.Pull = GPIO_PULLUP;
 
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 
    GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
 
    HAL_GPIO_Init(PORT_SENSORS, &GPIO_InitStruct);
 
 
    // Initialize I2C peripheral
 
    __I2C1_CLK_ENABLE();
 
    hi2c1.Instance = I2C1;
 
    hi2c1.Init.Timing = 0x00108EFB;
 
    hi2c1.Init.OwnAddress1 = 0x0;
 
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
 
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
 
    hi2c1.Init.OwnAddress2 = 0;
 
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
 
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
 
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
 
    volatile HAL_StatusTypeDef res = HAL_I2C_Init(&hi2c1);
 
 
    // Configure Analog filter
 
    res =  HAL_I2CEx_AnalogFilter_Config(&hi2c1, I2C_ANALOGFILTER_ENABLED);
 
 
	// Enable I2C interrupt
 
    HAL_NVIC_SetPriority(I2C1_IRQn, 7, 4);
 
    HAL_NVIC_EnableIRQ(I2C1_IRQn);
 
 
    // Blocking initialization of sensors
 
 
	// Power on the pressure sensor and configure //////////////////////////////////////////////////
 
	uint8_t temp[2];
 
	temp[0] = PRESSURE_CTRL1_PWRUP | PRESSURE_CTRL1_7HZ;
 
	HAL_Delay(10);
 
	res = HAL_I2C_Mem_Write(&hi2c1, PRESSURE_ADDRESS, 0x20, 1, temp, 1, 500);
 
}
 
 
 
// Initiate interrupt-based read of engineering sensors
 
void pressure_read(void)
 
void lps25h_read(void)
 
{
 
	// Start reading pressure sensor
 
	HAL_Delay(10);
 
	volatile  HAL_StatusTypeDef res = HAL_I2C_Mem_Read(&hi2c1, PRESSURE_ADDRESS, PRESSURE_PRESS_REGXL | PRESSURE_AUTOINC, 1, sensors_pressurebuf, 5, 500);
 
 
	// Consume fresh data flag
 
	sensors_pressure_freshdata = 0;
 
 
	// Convert received bytes to pressure in hPa
 
	pressure_hPa = sensors_pressurebuf[0]<<8 | sensors_pressurebuf[1]<<16 | sensors_pressurebuf[2]<<24;
 
	pressure_hPa >>= 8; // Sign extend
 
	pressure_hPa /= 4096; // convert to hPa
 
 
	// Convert received bytes to temperature in Celsius
 
	int16_t temp_out = (sensors_pressurebuf[3] | sensors_pressurebuf[4]<<8);
 
	if(!temp_out)
 
		temp_celsius = 42;
 
	else
 
		temp_celsius = 42.5 + temp_out / 480.0;
 
 
}
 
 
 
// Get current temperature in Celsius
 
int32_t pressure_gettemp(void)
 
int32_t lps25h_get_temperature(void)
 
{
 
	return temp_celsius;
 
}
 
 
 
// Get current pressure in hPa
 
int32_t pressure_getpressure(void)
 
int32_t lps25h_get_pressure(void)
 
{
 
	return pressure_hPa;
 
}
 
 
 
 
inline I2C_HandleTypeDef* pressure_get_i2c_handle(void)
 
inline I2C_HandleTypeDef* lps25h_get_i2c_handle(void)
 
{
 
	return &hi2c1;
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/main.c
Show inline comments
 
@@ -3,85 +3,99 @@
 
 *
 
 * This file is part of FeatherHAB.
 
 *
 
 * FeatherHab is free software: you can redistribute it and/or modify
 
 * it under the terms of the GNU Affero General Public License as published by
 
 * the Free Software Foundation, either version 3 of the License, or
 
 * (at your option) any later version.
 
 *
 
 * FeatherHab is distributed in the hope that it will be useful,
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 * GNU Affero General Public License for more details.
 
 *
 
 * You should have received a copy of the GNU Affero General Public License
 
 * along with FeatherHAB. If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 * Ethan Zonca
 
 *
 
 */
 
 
#include "stm32f0xx_hal.h"
 
 
#include "config.h"
 
#include "error.h"
 
//#include "pressure.h"
 
#include "bme280.h"
 
 
#ifdef LPS25H
 
	#include "lps25h.h"
 
#else
 
	#include "bme280.h"
 
#endif
 
#include "gps.h"
 
 
#include "system/gpio.h"
 
#include "system/sysclk.h"
 
#include "system/watchdog.h"
 
#include "system/uart.h"
 
#include "system/adc.h"
 
 
#include "si446x/si446x.h"
 
#include "aprs/aprs.h"
 
#include "aprs/afsk.h"
 
 
 
int main(void)
 
{
 
  hal_init();
 
  sysclock_init();
 
  gpio_init();
 
  adc_init();
 
  afsk_init();
 
  si446x_init();
 
  si446x_init();
 
  gps_poweron();
 
//  pressure_init();
 
  bme280_init();
 
 
  #ifdef LPS25H
 
    lps25h_init();
 
  #else
 
    bme280_init();
 
  #endif
 
 
  // Software timers
 
  uint32_t last_transmission = HAL_GetTick();
 
  uint32_t last_led = HAL_GetTick();
 
 
  while (1)
 
  {
 
	  // Blink LEDs
 
	  if(HAL_GetTick() - last_transmission > 700)
 
	  {
 
		  gps_update_data(); // Will always return at 1hz rate (default measurement rate)
 
		  //pressure_read();
 
		  bme280_update();
 
 
		  #ifdef LPS25H
 
		  	  lps25h_read();
 
		  #else
 
		  	  bme280_update();
 
		  #endif
 
 
		  while(afsk_busy()); // ensure previous message finished
 
		  aprs_send();
 
 
		  last_transmission = HAL_GetTick();
 
	  }
 
 
	  if(HAL_GetTick() - last_led > 100)
 
	  {
 
		  HAL_GPIO_TogglePin(LED_POWER);
 
		  last_led = HAL_GetTick();
 
	  }
 
 
	  if(afsk_request_cwoff())
 
		  si446x_cw_off();
 
 
	  // High-frequency function calls
 
	  watchdog_feed();
 
  }
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
0 comments (0 inline, 0 general)