Changeset - 2ee6c8e67f32
[Not reviewed]
Include/burn.h
Show inline comments
 
#ifndef BURN_H
 
#define BURN_H
 
#include "stm32f0xx_hal.h"
 
 
 
 
// Number of burn outputs
 
#define NUM_BURNS 3
 
 
 
enum burn
 
{
 
	BURN_NONE = 0,
 
	BURN_1,
 
	BURN_2,
 
};
 
 
 
enum burn_status
 
{
 
	BURN_IDLE = 0,
 
	BURN_BURNING,
 
};
 
 
 
void burn_queue(uint8_t burn_id, uint8_t delaytime, uint8_t resttime);
 
void burn_process(void);
 
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/config.h
Show inline comments
 
//
 
// Depth Select Configuration
 
//
 
 
#ifndef CONFIG_H
 
#define CONFIG_H
 
 
 
// --------------------------------------------------------------------------
 
// Transmitter config (si446x.c)
 
// --------------------------------------------------------------------------
 
 
 
#define TUNE_FREQUENCY 433000000UL
 
 
// Internal macros
 
#define hal_init HAL_Init
 
 
 
 
 
// --------------------------------------------------------------------------
 
// 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
 
 
 
 
 
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/error.h
Show inline comments
 
#ifndef ERROR_H
 
#define ERROR_H
 
#include "stm32f0xx_hal.h"
 
 
// Each error message has an enum entry
 
// If adding errors, remember to define a message for each in error.c
 
enum error_number
 
{
 
	ERR_RS485_PARSE = 0,
 
	ERR_GPS_OFF = 0,
 
	ERR_GPS_CHECKSUM,
 
};
 
 
 
void error_assert(uint8_t errno);
 
void error_assert_info(uint8_t errno, char* details);
 
uint8_t error_check(uint8_t errno);
 
uint8_t error_occurred(void);
 
uint8_t error_count(void);
 
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/gps.h
Show inline comments
 
#ifndef GPS_H_
 
#define GPS_H_
 

	
 
#include <stdint.h>
 

	
 

	
 
typedef struct _gps_data
 
{
 
    uint32_t pdop;
 
    uint8_t sats_in_solution;
 
    int32_t speed;
 
    int32_t heading;
 

	
 
    int32_t latitude;
 
    int32_t longitude;
 
    int32_t altitude;
 

	
 
    uint8_t month;
 
    uint8_t day;
 
    uint8_t hour;
 
    uint8_t minute;
 
    uint8_t second;
 

	
 
    uint8_t valid;
 
    uint8_t fixtype;
 

	
 
} gps_data_t;
 

	
 

	
 
void gps_update_data(void);
 

	
 
uint8_t gps_check_nav(void);
 

	
 

	
 
void gps_poweron(void);
 
void gps_poweroff(void);
 

	
 
void gps_acquirefix(void);
 
uint8_t gps_getstate(void);
 

	
 
gps_data_t* gps_getdata(void);
 
uint8_t gps_ison(void);
 

	
 
#endif /* GPS_H_ */
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/pressure.h
Show inline comments
 
#ifndef PRESSURE_H
 
#define PRESSURE_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);
 
 
int32_t pressure_gettemp(void);
 
int32_t pressure_getpressure(void);
 
 
I2C_HandleTypeDef* pressure_get_i2c_handle(void);
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/adc.h
Show inline comments
 
#ifndef SYSTEM_ADC_H_
 
#define SYSTEM_ADC_H_
 
 
void adc_init(void);
 
DMA_HandleTypeDef* adc__hdma_gethandle(void);
 
uint8_t adc_get_vbatt(void);
 
 
 
 
#endif /* SYSTEM_ADC_H_ */
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/flash.h
Show inline comments
 
#ifndef flash_h
 
#define flash_h
 
 
 
 
// Flash Structure
 
typedef struct
 
{
 
  uint16_t Blank;
 
  uint32_t readings[128];
 
 
}flash_t;
 
extern flash_t Flash;
 
 
 
// Flash States
 
enum flash_type
 
{
 
  Flash_blank         = 1,
 
  Flash_good_cksum    = 2,
 
  Flash_bad_cksum     = 3,
 
  Flash_error         = 4,
 
  Flash_default_value = 5,
 
  Flash_write         = 6
 
};
 
 
 
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
 
 
#define PageSize        ((uint16_t)0x400)
 
//#define ENDADDR          0x0801FFFF // Medium density
 
#define ENDADDR         0x0807FFFF // High density
 
 
 
//------------------------------------------------------------------------------
 
// Prototypes
 
//------------------------------------------------------------------------------
 
void init_FLASH(void);
 
void flash_load(uint8_t flash_test);
 
void flash_erase(void);
 
void flash_read(void);
 
void flash_write(void);
 
void flash_checksum(void);
 
 
 
#endif // flash_h
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/gpio.h
Show inline comments
 
#ifndef GPIO_H
 
#define GPIO_H
 
 
 
/// LEDs 1-2 ///////////////////////
 
#define PIN_LED_POWER GPIO_PIN_0
 
#define PORT_LED_POWER GPIOB
 
#define LED_POWER  PORT_LED_POWER , PIN_LED_POWER
 
////////////////////////////////////
 
 
 
#define GPS_NOTEN_PORT GPIOA
 
#define GPS_NOTEN_PIN GPIO_PIN_1
 
#define GPS_NOTEN GPS_NOTEN_PORT , GPS_NOTEN_PIN
 
 
 
void gpio_init(void);
 
void gpio_schedule_shutdown(void);
 
void gpio_process_shutdown(void);
 
 
#endif
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/stm32f0xx_hal_conf.h
Show inline comments
 
@@ -169,96 +169,98 @@
 
#endif /* HAL_COMP_MODULE_ENABLED */
 
 
#ifdef HAL_CRC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_crc.h"
 
#endif /* HAL_CRC_MODULE_ENABLED */
 
 
#ifdef HAL_DAC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_dac.h"
 
#endif /* HAL_DAC_MODULE_ENABLED */
 
 
#ifdef HAL_FLASH_MODULE_ENABLED
 
 #include "stm32f0xx_hal_flash.h"
 
#endif /* HAL_FLASH_MODULE_ENABLED */
 
 
#ifdef HAL_I2C_MODULE_ENABLED
 
 #include "stm32f0xx_hal_i2c.h"
 
#endif /* HAL_I2C_MODULE_ENABLED */
 
 
#ifdef HAL_I2S_MODULE_ENABLED
 
 #include "stm32f0xx_hal_i2s.h"
 
#endif /* HAL_I2S_MODULE_ENABLED */
 
 
#ifdef HAL_IRDA_MODULE_ENABLED
 
 #include "stm32f0xx_hal_irda.h"
 
#endif /* HAL_IRDA_MODULE_ENABLED */
 
 
#ifdef HAL_IWDG_MODULE_ENABLED
 
 #include "stm32f0xx_hal_iwdg.h"
 
#endif /* HAL_IWDG_MODULE_ENABLED */
 
 
#ifdef HAL_PCD_MODULE_ENABLED
 
 #include "stm32f0xx_hal_pcd.h"
 
#endif /* HAL_PCD_MODULE_ENABLED */
 
 
#ifdef HAL_PWR_MODULE_ENABLED
 
 #include "stm32f0xx_hal_pwr.h"
 
#endif /* HAL_PWR_MODULE_ENABLED */
 
 
#ifdef HAL_RTC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_rtc.h"
 
#endif /* HAL_RTC_MODULE_ENABLED */
 
 
#ifdef HAL_SMARTCARD_MODULE_ENABLED
 
 #include "stm32f0xx_hal_smartcard.h"
 
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
 
 
#ifdef HAL_SMBUS_MODULE_ENABLED
 
 #include "stm32f0xx_hal_smbus.h"
 
#endif /* HAL_SMBUS_MODULE_ENABLED */
 
 
#ifdef HAL_SPI_MODULE_ENABLED
 
 #include "stm32f0xx_hal_spi.h"
 
#endif /* HAL_SPI_MODULE_ENABLED */
 
 
#ifdef HAL_TIM_MODULE_ENABLED
 
 #include "stm32f0xx_hal_tim.h"
 
#endif /* HAL_TIM_MODULE_ENABLED */
 
 
#ifdef HAL_TSC_MODULE_ENABLED
 
 #include "stm32f0xx_hal_tsc.h"
 
#endif /* HAL_TSC_MODULE_ENABLED */
 
 
#ifdef HAL_UART_MODULE_ENABLED
 
 #include "stm32f0xx_hal_uart.h"
 
#endif /* HAL_UART_MODULE_ENABLED */
 
 
#ifdef HAL_USART_MODULE_ENABLED
 
 #include "stm32f0xx_hal_usart.h"
 
#endif /* HAL_USART_MODULE_ENABLED */
 
 
#ifdef HAL_WWDG_MODULE_ENABLED
 
 #include "stm32f0xx_hal_wwdg.h"
 
#endif /* HAL_WWDG_MODULE_ENABLED */
 
 
/* Exported macro ------------------------------------------------------------*/
 
#ifdef  USE_FULL_ASSERT
 
/**
 
  * @brief  The assert_param macro is used for function's parameters check.
 
  * @param  expr: If expr is false, it calls assert_failed function
 
  *         which reports the name of the source file and the source
 
  *         line number of the call that failed. 
 
  *         If expr is true, it returns no value.
 
  * @retval None
 
  */
 
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
 
/* Exported functions ------------------------------------------------------- */
 
  void assert_failed(uint8_t* file, uint32_t line);
 
#else
 
  #define assert_param(expr) ((void)0)
 
#endif /* USE_FULL_ASSERT */    
 
    
 
#ifdef __cplusplus
 
}
 
#endif
 
 
#endif /* __STM32F0xx_HAL_CONF_H */
 
 
 // vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/stm32f0xx_it.h
Show inline comments
 
#ifndef __STM32F0xx_IT_H
 
#define __STM32F0xx_IT_H
 
 
#ifdef __cplusplus
 
 extern "C" {
 
#endif 
 
 
void SysTick_Handler(void);
 
 
#ifdef __cplusplus
 
}
 
#endif
 
 
#endif /* __STM32F0xx_IT_H */
 
 
 // vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/sysclk.h
Show inline comments
 
#ifndef SYSCLK_H
 
#define SYSCLK_H
 
 
void sysclock_init(void);
 
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/uart.h
Show inline comments
 
#ifndef __usart_H
 
#define __usart_H
 
 
#include "stm32f0xx_hal.h"
 
 
void uart_init(void);
 
void uart_deinit(void);
 
UART_HandleTypeDef* uart_gethandle(void);
 
DMA_HandleTypeDef* uart_get_txdma_handle(void);
 
DMA_HandleTypeDef* uart_get_rxdma_handle(void);
 
 
#endif 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Include/system/watchdog.h
Show inline comments
 
#ifndef WATCHDOG_H
 
#define WATCHDOG_H
 
 
void watchdog_init(void);
 
void watchdog_feed(void);
 
 
#endif
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/error.c
Show inline comments
 
//
 
// Error: Provides a simple interface for asserting and checking errors
 
//
 
 
#include "error.h"
 
#include "stm32f0xx_hal.h"
 
 
#include <stdio.h>
 
 
 
volatile uint32_t err_reg;
 
volatile uint8_t num_errors_asserted = 0;
 
 
// Moderately detailed messages corresponding to each error enum
 
char *  error_message[] =
 
{
 
		"RS485 parse fail",
 
		"GPS off",
 
		"GPS checksum",
 
 
};
 
 
// Set the passed error flag
 
void error_assert(uint8_t errno)
 
{
 
	// Errno invalid: exceeds bit length of error register
 
	if(errno >= 32)
 
		return;
 
 
	// Set error flag
 
	err_reg |= (1<<errno);
 
 
	// Count how many errors have occurred
 
	num_errors_asserted++;
 
 
	// Dispatch error message over IRdA and/or debug port
 
#ifdef DEBUG_ERROUT_ENABLE
 
	char outbuf[256];
 
	snprintf(outbuf, 256, "Error: %s (no details)\r\n", error_message[errno]);
 
	usb_send(outbuf);
 
	ir_efs_send(outbuf);
 
#endif
 
}
 
 
// Set the passed error flag with details about the error
 
void error_assert_info(uint8_t errno, char* details)
 
{
 
	// Errno invalid: exceeds bit length of error register
 
	if(errno >= 32)
 
		return;
 
 
	// Set error flag
 
	err_reg |= (1<<errno);
 
 
	// Count how many errors have occurred
 
	num_errors_asserted++;
 
 
	// Dispatch error message over IRdA and/or debug port
 
#ifdef DEBUG_ERROUT_ENABLE
 
	char outbuf[256];
 
	snprintf(outbuf, 256, "Error: %s (%s)\r\n", error_message[errno], details);
 
	usb_send(outbuf);
 
	ir_efs_send(outbuf);
 
#endif
 
}
 
 
// Check if the passed error flag has been asserted
 
uint8_t error_check(uint8_t errno)
 
{
 
	return (err_reg & (1<<errno)) > 0;
 
}
 
 
// Return 1 if any error has occurred
 
uint8_t error_occurred(void)
 
{
 
	return err_reg > 0;
 
}
 
 
// Return the number of errors that have occurred
 
uint8_t error_count(void)
 
{
 
	return num_errors_asserted;
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/gps.c
Show inline comments
 
//
 
// GPS: communicate with ublox GPS module via ubx protocol
 
//
 

	
 
#include "stm32f0xx_hal.h"
 

	
 
#include "config.h"
 
#include "error.h"
 
#include "system/gpio.h"
 
#include "system/uart.h"
 
#include "gps.h"
 

	
 

	
 
volatile gps_data_t position;
 
uint8_t gpson = 0;
 

	
 

	
 
// Private methods
 
static void gps_ubx_checksum(uint8_t* data, uint8_t len, uint8_t* cka, uint8_t* ckb);
 
static uint8_t _gps_verify_checksum(uint8_t* data, uint8_t len);
 

	
 

	
 
// Poll for fix data from the GPS and update the internal structure
 
void gps_update_data(void)
 
{
 
	// Error!
 
	if(!gpson)
 
	{
 
//		led_blink(5);
 
		error_assert(ERR_GPS_OFF);
 
		return;
 
	}
 

	
 
    // Construct the request to the GPS
 
    uint8_t request[8] = {0xB5, 0x62, 0x01, 0x07, 0x00, 0x00, 0xFF, 0xFF};
 

	
 

	
 
    volatile uint8_t check_a = 0;
 
    volatile uint8_t check_b = 0;
 
    for(uint8_t i = 2; i<6; i++)
 
    {
 
    	check_a += request[i];
 
    	check_b += check_a;
 
    }
 
    request[6] = check_a;
 
    request[7] = check_b;
 

	
 
    volatile uint8_t flushed = uart_gethandle()->Instance->RDR;
 
    HAL_UART_Transmit(uart_gethandle(), request, 8, 100);
 

	
 

	
 

	
 
    // Get the message back from the GPS
 
    uint8_t buf[100];
 
    for(uint8_t i=0; i<100; i++)
 
    	buf[i] = 0xaa;
 
    volatile HAL_StatusTypeDef res = HAL_UART_Receive(uart_gethandle(), buf, 100, 3000);
 

	
 
    // Check 60 bytes minus SYNC and CHECKSUM (4 bytes)
 
//    if( !_gps_verify_checksum(&buf[2], 96) )
 
//        led_blink(2);
 

	
 
    if( !_gps_verify_checksum(&buf[2], 96) )
 
    {
 
		error_assert(ERR_GPS_CHECKSUM);
 
    }
 

	
 
    //volatile uint32_t gpstime_ms = (buf[6+0] << 24) | (buf[6+1] << 16) | buf[6+2] << 8) | (buf[6+3]);
 

	
 
    position.month = buf[6+6];
 
    position.day = buf[6+7];
 
    position.hour = buf[6+8];
 
    position.minute = buf[6+9];
 
    position.second = buf[6+10];
 
    position.valid = buf[6+11] & 0b1111;
 
    position.fixtype = buf[6+20];
 

	
 
    position.sats_in_solution = buf[6+23];
 

	
 
    position.longitude = (buf[6+24] << 0) | (buf[6+25] << 8) | (buf[6+26] << 16) | (buf[6+27] << 24); // degrees
 
    position.latitude =  (buf[6+28] << 0) | (buf[6+29] << 8) | (buf[6+30] << 16) | (buf[6+31] << 24); // degrees
 

	
 
    position.altitude = (buf[6+36] << 0) | (buf[6+37] << 8) | (buf[6+38] << 16) | (buf[6+39] << 24); // mm above sealevel
 
    position.altitude /= 1000; // mm => m
 

	
 
    position.speed = (buf[6+60] << 0) | (buf[6+61] << 8) | (buf[6+62] << 16) | (buf[6+63] << 24); // mm/second
 
    position.speed /= 10; // mm/s -> cm/s
 
    
 
    position.pdop = (buf[6+76] << 0) | (buf[6+77] << 8);
 
    position.pdop /= 100; // scale to dop units
 

	
 
    position.heading = (buf[6+64] << 0) | (buf[6+65] << 8) | (buf[6+66] << 16) | (buf[6+67] << 24);
 
    position.heading /= 100000; // 1e-5
 

	
 
//    // Return the value if GPSfixOK is set in 'flags'
 
//    if( buf[17] & 0x01 )
 
//        *lock = buf[16];
 
//    else
 
//        *lock = 0;
 

	
 
}
 

	
 

	
 
// Verify the checksum for the given data and length.
 
static uint8_t _gps_verify_checksum(uint8_t* data, uint8_t len)
 
{
 
    uint8_t a, b;
 
    gps_ubx_checksum(data, len, &a, &b);
 
    if( a != *(data + len) || b != *(data + len + 1))
 
        return 0;
 
    else
 
        return 1;
 
}
 

	
 

	
 
// Calculate a UBX checksum using 8-bit Fletcher (RFC1145)
 
static void gps_ubx_checksum(uint8_t* data, uint8_t len, uint8_t* cka, uint8_t* ckb)
 
{
 
    *cka = 0;
 
    *ckb = 0;
 
    for( uint8_t i = 0; i < len; i++ )
 
    {
 
        *cka += *data;
 
        *ckb += *cka;
 
        data++;
 
    }
 
}
 

	
 

	
 
// Power on GPS module and initialize UART
 
void gps_poweron(void)
 
{
 
    // NOTE: pchannel
 
    HAL_GPIO_WritePin(GPS_NOTEN, 0);
 
    uart_init();
 

	
 
	// Disable messages
 
	uint8_t setGGA[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XFF, 0X23};
 
	HAL_UART_Transmit(uart_gethandle(), setGGA, sizeof(setGGA)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t ackbuffer[10];
 
	for(uint8_t i=0; i<10; i++)
 
		ackbuffer[i] = 0xaa;
 
	HAL_UART_Receive(uart_gethandle(), ackbuffer, 10, 100);
 

	
 
	uint8_t setZDA[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X08, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X07, 0X5B};
 
	HAL_UART_Transmit(uart_gethandle(), setZDA, sizeof(setZDA)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setGLL[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X2A};
 
	HAL_UART_Transmit(uart_gethandle(), setGLL, sizeof(setGLL)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setGSA[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X02, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X31};
 
	HAL_UART_Transmit(uart_gethandle(), setGSA, sizeof(setGSA)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setGSV[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X03, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X02, 0X38};
 
	HAL_UART_Transmit(uart_gethandle(), setGSV, sizeof(setGSV)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setRMC[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X04, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X03, 0X3F};
 
	HAL_UART_Transmit(uart_gethandle(), setRMC, sizeof(setRMC)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setVTG[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X05, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X04, 0X46};
 
	HAL_UART_Transmit(uart_gethandle(), setVTG, sizeof(setRMC)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 

	
 
//    // Disable GLONASS mode
 
//    uint8_t disable_glonass[20] = {0xB5, 0x62, 0x06, 0x3E, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x01, 0x06, 0x08, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB2};
 
//    HAL_UART_Transmit(uart_gethandle(), disable_glonass, sizeof(disable_glonass)/sizeof(uint8_t), 100);
 
//	HAL_Delay(100);
 
//
 
//    // Enable power saving
 
//    uint8_t enable_powersave[10] = {0xB5, 0x62, 0x06, 0x11, 0x02, 0x00, 0x08, 0x01, 0x22, 0x92};
 
//    HAL_UART_Transmit(uart_gethandle(), enable_powersave, sizeof(enable_powersave)/sizeof(uint8_t), 100);
 
//	HAL_Delay(100);
 
//
 
//
 
//    // Set dynamic model 6 (<1g airborne platform)
 
//    uint8_t airborne_model[] = { 0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC };
 
//    HAL_UART_Transmit(uart_gethandle(), airborne_model, sizeof(airborne_model)/sizeof(uint8_t), 100);
 
//	HAL_Delay(100);
 
//
 
//
 

	
 

	
 

	
 
    // Begin DMA reception
 
    //HAL_UART_Receive_DMA(uart_gethandle(), nmeaBuffer, NMEABUFFER_SIZE);
 

	
 
    gpson = 1;
 
}
 

	
 

	
 
// Power off GPS module
 
void gps_poweroff(void)
 
{
 
    // NOTE: pchannel
 
//	position.hour = 0;
 
//	position.minute = 0;
 
//	position.second = 0;
 
//	position.altitude = 0;
 
//	position.latitude = 0;
 
//	position.longitude = 0;
 
//	position.day = 0;
 
//	position.month = 0;
 
//	position.fixtype = 0;
 
//	position.valid = 0;
 
	position.pdop = 0;
 
	position.sats_in_solution = 0;
 
//	position.speed = 0;
 

	
 
    uart_deinit();
 
    HAL_GPIO_WritePin(GPS_NOTEN, 1);
 
    gpson = 0;
 
}
 

	
 
gps_data_t* gps_getdata(void)
 
{
 
    return &position;
 
}
 

	
 
uint8_t gps_ison(void)
 
{
 
    return gpson;
 
}
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
Source/main.c
Show inline comments
 
/*
 
 * FeatherHAB
 
 *
 
 * 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 "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();
 
 
  // 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();
 
		  aprs_send();
 
		  //while(afsk_busy());
 
 
		  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();
 
	  watchdog_feed();
 
  }
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/pressure.c
Show inline comments
 
@@ -14,96 +14,98 @@ 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)
 
{
 
	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)
 
{
 
	// 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)
 
{
 
	return temp_celsius;
 
}
 
 
 
// Get current pressure in hPa
 
int32_t pressure_getpressure(void)
 
{
 
	return pressure_hPa;
 
}
 
 
 
 
inline I2C_HandleTypeDef* pressure_get_i2c_handle(void)
 
{
 
	return &hi2c1;
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/system/_sbrk.c
Show inline comments
 
//
 
// sbrk: basic implementation of _sbrk for sprintf and other stdlib functions
 
//
 

	
 
#include <sys/stat.h>
 

	
 
caddr_t _sbrk(int incr)
 
{
 
extern char end asm("end");
 
static char *heap_end;
 
char *prev_heap_end;
 

	
 
if (heap_end == 0) {
 
heap_end = &end;
 
}
 

	
 
prev_heap_end = heap_end;
 

	
 
heap_end += incr;
 

	
 
return (caddr_t)prev_heap_end;
 
}
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/system/adc.c
Show inline comments
 
@@ -2,96 +2,98 @@
 
 * FeatherHAB
 
 *
 
 * 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 "system/adc.h"
 
 
ADC_HandleTypeDef hadc;
 
DMA_HandleTypeDef hdma_adc;
 
 
#define ADC_BUF_LEN 1
 
uint16_t adc_buffer[ADC_BUF_LEN];
 
 
 
void adc_init(void)
 
{
 
 
    __ADC1_CLK_ENABLE();
 
 
	GPIO_InitTypeDef GPIO_InitStruct;
 
    GPIO_InitStruct.Pin = GPIO_PIN_6;
 
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 
    GPIO_InitStruct.Pull = GPIO_NOPULL;
 
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 
 
	ADC_ChannelConfTypeDef sConfig;
 
	hadc.Instance = ADC1;
 
	hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC;
 
	hadc.Init.Resolution = ADC_RESOLUTION12b;
 
	hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 
	hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
 
	hadc.Init.EOCSelection = EOC_SEQ_CONV;
 
	hadc.Init.LowPowerAutoWait = DISABLE;
 
	hadc.Init.LowPowerAutoPowerOff = DISABLE;
 
	hadc.Init.ContinuousConvMode = ENABLE;
 
	hadc.Init.DiscontinuousConvMode = DISABLE;
 
	hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 
	hadc.Init.DMAContinuousRequests = ENABLE;
 
	hadc.Init.Overrun = OVR_DATA_OVERWRITTEN;
 
	HAL_ADC_Init(&hadc);
 
 
	sConfig.Channel = ADC_CHANNEL_6;
 
	sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
 
	sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
 
	HAL_ADC_ConfigChannel(&hadc, &sConfig);
 
 
 
	__DMA1_CLK_ENABLE();
 
		HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
 
	HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
 
    hdma_adc.Instance = DMA1_Channel1;
 
    hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
 
    hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
 
    hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
 
    hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 
    hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
 
    hdma_adc.Init.Mode = DMA_CIRCULAR;
 
    hdma_adc.Init.Priority = DMA_PRIORITY_LOW;
 
    HAL_DMA_Init(&hdma_adc);
 
 
    __HAL_LINKDMA(&hadc,DMA_Handle,hdma_adc);
 
 
 
    HAL_ADC_Start_DMA(&hadc, adc_buffer, ADC_BUF_LEN);
 
 
 
}
 
 
uint8_t adc_get_vbatt(void)
 
{
 
	return adc_buffer[0] / 62.5; // tenths of volts ish
 
}
 
 
DMA_HandleTypeDef* adc__hdma_gethandle(void)
 
{
 
	return &hdma_adc;
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/system/flash.c
Show inline comments
 
@@ -137,96 +137,98 @@ void flash_write(void)
 
 
	size = sizeof(Flash)-1; // in Bytes
 
	flash_adr = ENDADDR-size;
 
	Struct_ptr = (uint16_t *)&Flash;
 
 
	if(size%2==0)
 
		length = size/2;
 
	else
 
		length = size/2+1;
 
 
	for(i=0;i<length;i++)
 
	{
 
		Data = *Struct_ptr;
 
		FLASH_ProgramHalfWord(flash_adr,Data);
 
		Struct_ptr +=1;
 
		flash_adr +=2;
 
	}
 
 
	FLASH_Lock();
 
	taskEXIT_CRITICAL();
 
}
 
 
 
//------------------------------------------------------------------------------
 
// Function Name  : flash_checksum
 
// Description    :
 
// Input          : None
 
// Output         : None
 
// Return         : None
 
//------------------------------------------------------------------------------
 
void flash_checksum(void)
 
{
 
	uint8_t cksum0=0,cksum1=0;
 
	uint16_t  i,size,checksum;
 
	uint32_t flash_adr;
 
	uint8_t  *flash_ptr;
 
 
	taskENTER_CRITICAL();
 
	FLASH_Unlock();
 
 
	size = sizeof(Flash)-1; // in Bytes
 
	flash_adr = ENDADDR-size;
 
	flash_ptr = (uint8_t *)flash_adr;
 
 
	for(i=1; i < size; i++)
 
	{
 
		cksum0 += *flash_ptr++;
 
		cksum1 += cksum0;
 
	}
 
	checksum = MAKEWORD(cksum1,cksum0);
 
	flash_adr -= 2;
 
	FLASH_ProgramHalfWord(flash_adr,checksum);
 
 
	FLASH_Lock();
 
	taskEXIT_CRITICAL();
 
}
 
 
 
//------------------------------------------------------------------------------
 
// Function Name  : flash_erase
 
// Description    : Erase flash_values that are stored
 
// Input          : None
 
// Output         : None
 
// Return         : None
 
//------------------------------------------------------------------------------
 
void flash_erase(void)
 
{
 
	FLASH_Status FLASHStatus;
 
	uint32_t StartAddr;
 
	uint32_t end_addr;
 
	uint32_t NbrOfPage;
 
	uint32_t EraseCounter;
 
 
	taskENTER_CRITICAL();
 
 
	FLASHStatus = FLASH_COMPLETE;
 
	end_addr = ENDADDR;
 
	NbrOfPage = abs( (sizeof(Flash)-1)/0x400 )+1;   // Number of pages to be erased
 
	StartAddr = (end_addr+1) - (0x400*NbrOfPage);   // Starting address to be erased
 
 
	// Unlock the Flash Program Erase controller
 
	FLASH_Unlock();
 
 
	// Clear All pending flags
 
	FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
 
 
	// Erase the FLASH pages
 
	for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
 
		FLASHStatus = FLASH_ErasePage(StartAddr + (PageSize * EraseCounter));
 
 
	FLASH_Lock();
 
 
	taskEXIT_CRITICAL();
 
}
 
*/
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/system/gpio.c
Show inline comments
 
/*
 
 * FeatherHAB
 
 *
 
 * 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 "config.h"
 
#include "system/gpio.h"
 
#include "stm32f0xx_hal.h"
 
 
 
// Private variables
 
static uint8_t shutdown_triggered = 0;
 
static uint32_t shutdown_triggered_time = 0;
 
 
 
// Initialize GPIOs
 
void gpio_init(void)
 
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
 
 
  // Enable clocks
 
  __GPIOC_CLK_ENABLE();
 
  __GPIOF_CLK_ENABLE();
 
  __GPIOA_CLK_ENABLE();
 
  __GPIOB_CLK_ENABLE();
 
 
  // LEDs 1/2
 
  GPIO_InitStruct.Pin = PIN_LED_POWER;
 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
  HAL_GPIO_Init(PORT_LED_POWER, &GPIO_InitStruct);
 
 
  GPIO_InitStruct.Pin = GPS_NOTEN_PIN;
 
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 
  GPIO_InitStruct.Pull = GPIO_NOPULL;
 
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
  HAL_GPIO_Init(GPS_NOTEN_PORT, &GPIO_InitStruct);
 
  HAL_GPIO_WritePin(GPS_NOTEN, 1); // yes, keep the chip disabled
 
 
 
  // Toggle the power LED
 
  HAL_GPIO_TogglePin(LED_POWER);
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
 
Source/system/interrupts.c
Show inline comments
 
//
 
// Interrupts: ISRs for all global interrupts
 
//
 
 
#include <system/gpio.h>
 
#include <system/stm32f0xx_it.h>
 
#include "stm32f0xx_hal.h"
 
#include "stm32f0xx.h"
 
#include "system/gpio.h"
 
#include "aprs/afsk.h"
 
#include "pressure.h"
 
#include "system/adc.h"
 
 
// Systick
 
void SysTick_Handler(void)
 
{
 
  HAL_IncTick();
 
  HAL_SYSTICK_IRQHandler();
 
}
 
 
 
void TIM1_CC_IRQHandler(void)
 
{
 
  HAL_TIM_IRQHandler(afsk_timer_gethandle());
 
}
 
 
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
 
{
 
  HAL_TIM_IRQHandler(afsk_timer_gethandle());
 
}
 
 
 
// Handle I2C interrupts
 
void I2C1_IRQHandler(void)
 
{
 
	if (pressure_get_i2c_handle()->Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {
 
		HAL_I2C_ER_IRQHandler(pressure_get_i2c_handle());
 
	} else {
 
		HAL_I2C_EV_IRQHandler(pressure_get_i2c_handle());
 
	}
 
}
 
 
void DMA1_Channel1_IRQHandler(void)
 
{
 
  HAL_DMA_IRQHandler(adc__hdma_gethandle());
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/system/sysclk.c
Show inline comments
 
//
 
// sysclk: Initialize and start system clocks
 
//
 
 
#include "config.h"
 
#include "system/sysclk.h"
 
#include "stm32f0xx_hal.h"
 
 
 
// Initialize system clocks and systick
 
void sysclock_init(void)
 
{
 
	/*
 
	RCC_OscInitTypeDef RCC_OscInitStruct;
 
	RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
	RCC_PeriphCLKInitTypeDef PeriphClkInit;
 
 
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 
	RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
 
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 
	RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
 
	RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV2;
 
	HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
 
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
 
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
 
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
	HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
 
 
	PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
 
	PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
 
	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
 
 
	HAL_RCC_MCOConfig(RCC_MCO, RCC_MCOSOURCE_SYSCLK, RCC_MCO_DIV1);
 
 
	__SYSCFG_CLK_ENABLE();
 
 
	// Enable SysTick interrupt
 
	HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
 
	*/
 
 
 
	  RCC_OscInitTypeDef RCC_OscInitStruct;
 
	  RCC_ClkInitTypeDef RCC_ClkInitStruct;
 
	  RCC_PeriphCLKInitTypeDef PeriphClkInit;
 
 
	    /**Initializes the CPU, AHB and APB busses clocks
 
	    */
 
	  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 
	  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 
	  RCC_OscInitStruct.HSICalibrationValue = 16;
 
	  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 
	  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 
	  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
 
	  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
 
	  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
 
	    /**Initializes the CPU, AHB and APB busses clocks
 
	    */
 
	  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 
	                              |RCC_CLOCKTYPE_PCLK1;
 
	  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 
	  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
 
	  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
 
	  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
 
 
	  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
 
	  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
 
	  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
 
	    /**Configure the Systick interrupt time
 
	    */
 
	  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
 
	    /**Configure the Systick
 
	    */
 
	  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
 
	  /* SysTick_IRQn interrupt configuration */
 
	  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
 
Source/system/uart.c
Show inline comments
 
@@ -24,96 +24,98 @@ void uart_init(void)
 
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
    GPIO_InitStruct.Pull = GPIO_NOPULL; //GPIO_PULLUP;
 
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
 
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 
    // Init UART periph
 
    huart1.Instance = USART1;
 
    huart1.Init.BaudRate = 9600;
 
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
 
    huart1.Init.StopBits = UART_STOPBITS_1;
 
    huart1.Init.Parity = UART_PARITY_NONE;
 
    huart1.Init.Mode = UART_MODE_TX_RX;
 
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 
    //huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 
    huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;
 
    huart1.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
 
    huart1.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
 
    HAL_UART_Init(&huart1);
 
 
    HAL_Delay(100);
 
	uint8_t switch_baud[] = "$PUBX,41,1,0003,0001,115200,0*1E\r\n";
 
	HAL_UART_Transmit(uart_gethandle(), switch_baud, sizeof(switch_baud)/sizeof(uint8_t), 1000);
 
 
    HAL_UART_DeInit(&huart1);
 
    huart1.Init.BaudRate = 115200;
 
    HAL_UART_Init(&huart1);
 
 
 
//
 
//    __DMA1_CLK_ENABLE();
 
//
 
//  // Init UART DMA
 
//    hdma_usart1_rx.Instance = DMA1_Channel3;
 
//    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 
//    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 
//    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
 
//    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 
//    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 
//    hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
 
//    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
 
//    HAL_DMA_Init(&hdma_usart1_rx);
 
//
 
//    __HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx);
 
//
 
//    hdma_usart1_tx.Instance = DMA1_Channel2;
 
//    hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 
//    hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 
//    hdma_usart1_tx.Init.MemInc = DMA_MINC_DISABLE;
 
//    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 
//    hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 
//    hdma_usart1_tx.Init.Mode = DMA_NORMAL;
 
//    hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
 
//    HAL_DMA_Init(&hdma_usart1_tx);
 
//
 
//    __HAL_LINKDMA(&huart1,hdmatx,hdma_usart1_tx);
 
//
 
////    HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
 
////    HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
 
 
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
 
    //HAL_NVIC_EnableIRQ(USART1_IRQn);
 
    HAL_NVIC_DisableIRQ(USART1_IRQn);
 
 
    uart_initted = 1;
 
}
 
 
void uart_deinit(void)
 
{
 
    if(uart_initted == 1)
 
    {
 
        //HAL_DMA_DeInit(&hdma_usart1_rx);
 
        //HAL_DMA_DeInit(&hdma_usart1_tx);
 
        HAL_UART_DeInit(&huart1);
 
        __HAL_RCC_USART1_CLK_DISABLE();
 
 
        uart_initted = 0;
 
    }
 
}
 
 
UART_HandleTypeDef* uart_gethandle(void)
 
{
 
    return &huart1;
 
} 
 
 
DMA_HandleTypeDef* uart_get_txdma_handle(void)
 
{
 
    return &hdma_usart1_tx;
 
}
 
DMA_HandleTypeDef* uart_get_rxdma_handle(void)
 
{
 
    return &hdma_usart1_rx;
 
}
 
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
Source/system/watchdog.c
Show inline comments
 
//
 
// Watchdog: configure and initialize the watchdog peripheral
 
//
 
 
#include "stm32f0xx_hal.h"
 
 
#include "config.h"
 
#include "system/watchdog.h"
 
 
#ifdef WATCHDOG_ENABLE
 
static IWDG_HandleTypeDef hiwdg;
 
#endif
 
 
void watchdog_init(void)
 
{
 
#ifdef WATCHDOG_ENABLE
 
    hiwdg.Instance = IWDG;
 
    hiwdg.Init.Prescaler = IWDG_PRESCALER_4;
 
    hiwdg.Init.Window = 4095;
 
    hiwdg.Init.Reload = 4095;
 
    HAL_IWDG_Init(&hiwdg);
 
	watchdog_feed();
 
	HAL_IWDG_Start(&hiwdg);
 
 
#endif
 
}
 
 
void watchdog_feed(void)
 
{
 
#ifdef WATCHDOG_ENABLE
 
	HAL_IWDG_Refresh(&hiwdg);
 
#endif
 
}
 
 
// vim:softtabstop=4 shiftwidth=4 expandtab
0 comments (0 inline, 0 general)