1
0
forked from me/IronOS

Merge pull request #634 from Ralim/feat/BSP

Feature: Move board dependant code to be separate
This commit is contained in:
Ben V. Brown
2020-05-30 13:04:45 +10:00
committed by GitHub
119 changed files with 4135 additions and 3956 deletions

View File

@@ -1,4 +1,4 @@
FROM ubuntu:rolling
FROM ubuntu:20.04
LABEL maintainer="Ben V. Brown <ralim@ralimtek.com>"
WORKDIR /build

View File

@@ -0,0 +1,55 @@
#include "BSP_Flash.h"
#include "BSP_Power.h"
#include "BSP_QC.h"
#include "Defines.h"
#include "UnitSettings.h"
#include "stdint.h"
/*
* BSP.h -- Board Support
*
* This exposes functions that are expected to be implemented to add support for different hardware
*/
#ifndef BSP_BSP_H_
#define BSP_BSP_H_
#ifdef __cplusplus
extern "C" {
#endif
// Called first thing in main() to init the hardware
void preRToSInit();
// Called once the RToS has started for any extra work
void postRToSInit();
// Called to reset the hardware watchdog unit
void resetWatchdog();
// Accepts a output level of 0.. to use to control the tip output PWM
void setTipPWM(uint8_t pulse);
// Returns the Handle temp in C, X10
uint16_t getHandleTemperature();
// Returns the Tip temperature ADC reading in raw units
uint16_t getTipRawTemp(uint8_t refresh);
// Returns the main DC input voltage, using the adjustable divisor + sample flag
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample);
// Readers for the two buttons
// !! Returns 1 if held down, 0 if released
uint8_t getButtonA();
uint8_t getButtonB();
// This is a work around that will be called if I2C starts to bug out
// This should toggle the SCL line until SDA goes high to end the current transaction
void unstick_I2C();
// Reboot the IC when things go seriously wrong
void reboot();
// If the user has programmed in a bootup logo, draw it to the screen from flash
// Returns 1 if the logo was printed so that the unit waits for the timeout or button
uint8_t showBootLogoIfavailable();
void delay_ms(uint16_t count);
#ifdef __cplusplus
}
#endif
#endif /* BSP_BSP_H_ */

View File

@@ -0,0 +1,26 @@
/*
* BSP_Flash.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include "stdint.h"
#ifndef BSP_BSP_FLASH_H_
#define BSP_BSP_FLASH_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Wrappers to allow read/writing to a sector of flash that we use to store all of the user settings
*
* Should allow reading and writing to the flash
*/
//Erase the flash, then save the buffer. Returns 1 if worked
uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length);
void flash_read_buffer(uint8_t *buffer, const uint16_t length);
#ifdef __cplusplus
}
#endif
#endif /* BSP_BSP_FLASH_H_ */

View File

@@ -0,0 +1,27 @@
#include "stdint.h"
/*
* BSP_Power.h -- Board Support for Power control
*
* These functions are hooks used to allow for power control
*
*/
#ifndef BSP_POWER_H_
#define BSP_POWER_H_
#ifdef __cplusplus
extern "C" {
#endif
// Called once at startup, after RToS
// This can handle negotiations for QC/PD etc
void power_probe();
// Called periodically in the movement handling thread
// Can be used to check any details for the power system
void power_check();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,42 @@
/*
* BSP_QC.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef BSP_BSP_QC_H_
#define BSP_BSP_QC_H_
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
// Init GPIO for QC neg
void QC_Init_GPIO();
// Set the DP pin to 0.6V
void QC_DPlusZero_Six();
// Set the DM pin to 0.6V
void QC_DNegZero_Six();
// Set the DP pin to 3.3V
void QC_DPlusThree_Three();
// Set the DM pin to 3.3V
void QC_DNegThree_Three();
// Turn on weak pulldown on the DM pin
// This is used as a helper for some power banks
void QC_DM_PullDown();
// Turn off the pulldown
void QC_DM_No_PullDown();
// Turn on output drivers that were initally disabled to prevent spike through QC disable mode
void QC_Post_Probe_En();
// Check if DM was pulled down
// 1=Pulled down, 0 == pulled high
uint8_t QC_DM_PulledDown();
// Re-sync if required
void QC_resync();
#ifdef __cplusplus
}
#endif
#endif /* BSP_BSP_QC_H_ */

View File

@@ -0,0 +1,19 @@
/*
* Defines.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef BSP_DEFINES_H_
#define BSP_DEFINES_H_
enum Orientation {
ORIENTATION_LEFT_HAND = 0, ORIENTATION_RIGHT_HAND = 1, ORIENTATION_FLAT = 3
};
//It is assumed that all hardware implements an 8Hz update period at this time
#define PID_TIM_HZ (8)
#endif /* BSP_DEFINES_H_ */

View File

@@ -0,0 +1,256 @@
//BSP mapping functions
#include "BSP.h"
#include "Setup.h"
#include "history.hpp"
#include "Pins.h"
#include "main.hpp"
#include "history.hpp"
#include "I2C_Wrapper.hpp"
volatile uint16_t PWMSafetyTimer = 0;
volatile uint8_t pendingPWM = 0;
//2 second filter (ADC is PID_TIM_HZ Hz)
history<uint16_t, PID_TIM_HZ> rawTempFilter = { { 0 }, 0, 0 };
void resetWatchdog() {
HAL_IWDG_Refresh(&hiwdg);
}
uint16_t getHandleTemperature() {
// We return the current handle temperature in X10 C
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for
// example) STM32 = 4096 count @ 3.3V input -> But We oversample by 32/(2^2) =
// 8 times oversampling Therefore 32768 is the 3.3V input, so 0.1007080078125
// mV per count So we need to subtract an offset of 0.5V to center on 0C
// (4964.8 counts)
//
int32_t result = getADC(0);
result -= 4965; // remove 0.5V offset
// 10mV per C
// 99.29 counts per Deg C above 0C
result *= 100;
result /= 993;
return result;
}
uint16_t getTipInstantTemperature() {
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
uint16_t readings[8];
//Looking to reject the highest outlier readings.
//As on some hardware these samples can run into the op-amp recovery time
//Once this time is up the signal stabilises quickly, so no need to reject minimums
readings[0] = hadc1.Instance->JDR1;
readings[1] = hadc1.Instance->JDR2;
readings[2] = hadc1.Instance->JDR3;
readings[3] = hadc1.Instance->JDR4;
readings[4] = hadc2.Instance->JDR1;
readings[5] = hadc2.Instance->JDR2;
readings[6] = hadc2.Instance->JDR3;
readings[7] = hadc2.Instance->JDR4;
for (int i = 0; i < 8; i++) {
sum += readings[i];
}
return sum; // 8x over sample
}
uint16_t getTipRawTemp(uint8_t refresh) {
if (refresh) {
uint16_t lastSample = getTipInstantTemperature();
rawTempFilter.update(lastSample);
return lastSample;
} else {
return rawTempFilter.average();
}
}
uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) {
// ADC maximum is 32767 == 3.3V at input == 28.05V at VIN
// Therefore we can divide down from there
// Multiplying ADC max by 4 for additional calibration options,
// ideal term is 467
#ifdef MODEL_TS100
#define BATTFILTERDEPTH 32
#else
#define BATTFILTERDEPTH 8
#endif
static uint8_t preFillneeded = 10;
static uint32_t samples[BATTFILTERDEPTH];
static uint8_t index = 0;
if (preFillneeded) {
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
samples[i] = getADC(1);
preFillneeded--;
}
if (sample) {
samples[index] = getADC(1);
index = (index + 1) % BATTFILTERDEPTH;
}
uint32_t sum = 0;
for (uint8_t i = 0; i < BATTFILTERDEPTH; i++)
sum += samples[i];
sum /= BATTFILTERDEPTH;
return sum * 4 / divisor;
}
void setTipPWM(uint8_t pulse) {
PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is
// disabled if the PID task is not scheduled often enough.
pendingPWM = pulse;
}
// These are called by the HAL after the corresponding events from the system
// timers.
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
// Period has elapsed
if (htim->Instance == TIM2) {
// we want to turn on the output again
PWMSafetyTimer--;
// We decrement this safety value so that lockups in the
// scheduler will not cause the PWM to become locked in an
// active driving state.
// While we could assume this could never happen, its a small price for
// increased safety
htim2.Instance->CCR4 = pendingPWM;
if (htim2.Instance->CCR4 && PWMSafetyTimer) {
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
} else {
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
}
} else if (htim->Instance == TIM1) {
// STM uses this for internal functions as a counter for timeouts
HAL_IncTick();
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {
// This was a when the PWM for the output has timed out
if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
}
}
void unstick_I2C() {
GPIO_InitTypeDef GPIO_InitStruct;
int timeout = 100;
int timeout_cnt = 0;
// 1. Clear PE bit.
hi2c1.Instance->CR1 &= ~(0x0001);
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
// 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = SCL_Pin;
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
GPIO_InitStruct.Pin = SDA_Pin;
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) {
//Move clock to release I2C
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
timeout_cnt++;
if (timeout_cnt > timeout)
return;
}
// 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = SCL_Pin;
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SDA_Pin;
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET);
// 13. Set SWRST bit in I2Cx_CR1 register.
hi2c1.Instance->CR1 |= 0x8000;
asm("nop");
// 14. Clear SWRST bit in I2Cx_CR1 register.
hi2c1.Instance->CR1 &= ~0x8000;
asm("nop");
// 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
hi2c1.Instance->CR1 |= 0x0001;
// Call initialization function.
HAL_I2C_Init(&hi2c1);
}
uint8_t getButtonA() {
return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ?
1 : 0;
}
uint8_t getButtonB() {
return HAL_GPIO_ReadPin(KEY_B_GPIO_Port, KEY_B_Pin) == GPIO_PIN_RESET ?
1 : 0;
}
/*
* Catch the IRQ that says that the conversion is done on the temperature
* readings coming in Once these have come in we can unblock the PID so that it
* runs again
*/
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (hadc == &hadc1) {
if (pidTaskNotification) {
vTaskNotifyGiveFromISR(pidTaskNotification,
&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c __unused) {
FRToSI2C::CpltCallback();
}
void reboot() {
NVIC_SystemReset();
}
void delay_ms(uint16_t count) {
HAL_Delay(count);
}

View File

@@ -0,0 +1,142 @@
/*
* FRToSI2C.cpp
*
* Created on: 14Apr.,2018
* Author: Ralim
*/
#include <I2C_Wrapper.hpp>
#include "BSP.h"
#include "Setup.h"
#define I2CUSESDMA
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
void FRToSI2C::CpltCallback() {
hi2c1.State = HAL_I2C_STATE_READY; // Force state reset (even if tx error)
if (I2CSemaphore) {
xSemaphoreGiveFromISR(I2CSemaphore, NULL);
}
}
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) {
// no RToS, run blocking code
HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
pData, Size, 5000);
return true;
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
return false;
} else {
xSemaphoreGive(I2CSemaphore);
return true;
}
#else
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size,
5000)==HAL_OK){
xSemaphoreGive(I2CSemaphore);
return true;
}
xSemaphoreGive(I2CSemaphore);
return false;
#endif
} else {
return false;
}
}
}
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
Mem_Write(address, reg, &data, 1);
}
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
uint8_t tx_data[1];
Mem_Read(add, reg, tx_data, 1);
return tx_data[0];
}
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) {
// no RToS, run blocking code
HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
pData, Size, 5000);
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
}
xSemaphoreGive(I2CSemaphore);
#else
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData,
Size, 5000) != HAL_OK) {
}
xSemaphoreGive(I2CSemaphore);
#endif
} else {
}
}
}
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
if (I2CSemaphore == NULL) {
// no RToS, run blocking code
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
} else {
// RToS is active, run threading
// Get the mutex so we can use the I2C port
// Wait up to 1 second for the mutex
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
#ifdef I2CUSESDMA
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
!= HAL_OK) {
I2C_Unstick();
xSemaphoreGive(I2CSemaphore);
}
#else
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
xSemaphoreGive(I2CSemaphore);
#endif
} else {
}
}
}
bool FRToSI2C::probe(uint16_t DevAddress) {
uint8_t buffer[1];
if (Mem_Read(DevAddress, 0, buffer, 1)) {
//ACK'd
return true;
}
return false;
}
void FRToSI2C::I2C_Unstick() {
unstick_I2C();
}

View File

@@ -1,27 +1,13 @@
/*
* Hardware.h
* Pins.h
*
* Created on: 29Aug.,2017
* Author: Ben V. Brown
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef HARDWARE_H_
#define HARDWARE_H_
#include "Setup.h"
#include "stm32f1xx_hal.h"
#include "FreeRTOS.h"
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include "unit.h"
#ifndef BSP_MINIWARE_PINS_H_
#define BSP_MINIWARE_PINS_H_
#ifdef __cplusplus
extern "C" {
#endif
enum Orientation {
ORIENTATION_LEFT_HAND = 0, ORIENTATION_RIGHT_HAND = 1, ORIENTATION_FLAT = 3
};
#define PID_TIM_HZ (8)
#if defined(MODEL_TS100) + defined(MODEL_TS80) > 1
#error "Multiple models defined!"
#elif defined(MODEL_TS100) + defined(MODEL_TS80) == 0
@@ -94,55 +80,4 @@ enum Orientation {
#endif
/*
* Keep in a uint8_t range for the ID's
*/
#ifdef MODEL_TS100
enum TipType {
TS_B2 = 0,
TS_D24 = 1,
TS_BC2 = 2,
TS_C1 = 3,
Tip_MiniWare = 4,
HAKKO_BC2 = 4,
Tip_Hakko = 5,
Tip_Custom = 5,
};
#endif
#ifdef MODEL_TS80
enum TipType {
TS_B02 = 0, TS_D25 = 1, Tip_MiniWare = 2, Tip_Custom = 3,
};
#endif
extern uint16_t tipGainCalValue ;
uint16_t lookupTipDefaultCalValue(enum TipType tipID);
uint16_t getHandleTemperature();
uint16_t getTipRawTemp(uint8_t refresh);
uint16_t getInputVoltageX10(uint16_t divisor,uint8_t sample);
void setTipPWM(uint8_t pulse);
uint16_t ctoTipMeasurement(uint16_t temp);
uint16_t tipMeasurementToC(uint16_t raw);
uint16_t ftoTipMeasurement(uint16_t temp);
#ifdef ENABLED_FAHRENHEIT_SUPPORT
uint16_t tipMeasurementToF(uint16_t raw);
#endif
void seekQC(int16_t Vx10, uint16_t divisor);
void setCalibrationOffset(int16_t offSet);
void setTipType(enum TipType tipType, uint8_t manualCalGain);
uint32_t calculateTipR();
int16_t calculateMaxVoltage(uint8_t useHP);
void startQC(uint16_t divisor); // Tries to negotiate QC for highest voltage, must be run after
// RToS
// This will try for 12V, failing that 9V, failing that 5V
// If input is over 12V returns -1
// If the input is [5-12] Will return the value.
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) ;
void vApplicationIdleHook(void);
#ifdef __cplusplus
}
#endif
#endif /* HARDWARE_H_ */
#endif /* BSP_MINIWARE_PINS_H_ */

View File

@@ -0,0 +1,21 @@
#include "BSP.h"
#include "BSP_Power.h"
#include "QC3.h"
#include "Settings.h"
void power_probe() {
// If TS80 probe for QC
// If TS100 - noop
#ifdef MODEL_TS80
startQC(systemSettings.voltageDiv);
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
systemSettings.voltageDiv); // this will move the QC output to the preferred voltage to start with
#endif
}
void power_check() {
#ifdef MODEL_TS80
QC_resync();
#endif
}

View File

@@ -0,0 +1,74 @@
/*
* QC.c
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include "BSP.h"
#include "Pins.h"
#include "QC3.h"
#include "Settings.h"
#include "stm32f1xx_hal.h"
void QC_DPlusZero_Six() {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+
}
void QC_DNegZero_Six() {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}
void QC_DPlusThree_Three() {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET); // pull up D+
}
void QC_DNegThree_Three() {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
}
void QC_DM_PullDown() {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Pin = GPIO_PIN_11;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void QC_DM_No_PullDown() {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_11;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void QC_Init_GPIO() {
// Setup any GPIO into the right states for QC
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// Turn off output mode on pins that we can
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void QC_Post_Probe_En() {
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
uint8_t QC_DM_PulledDown() { return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET ? 1 : 0; }
void QC_resync() {
#ifdef MODEL_TS80
seekQC((systemSettings.cutoutSetting) ? 120 : 90,
systemSettings.voltageDiv); // Run the QC seek again if we have drifted too much
#endif
}

View File

@@ -0,0 +1,12 @@
# BSP section for STM32F103 based Miniware products
This folder contains the hardware abstractions required for the TS100, TS80 and probably TS80P soldering irons.
## Main abstractions
* Hardware Init
* -> Should contain all bootstrap to bring the hardware up to an operating point
* -> Two functions are required, a pre and post FreeRToS call
* I2C read/write
* Set PWM for the tip
* Links between IRQ's on the system and the calls in the rest of the firmware

View File

@@ -5,6 +5,7 @@
* Author: Ben V. Brown
*/
#include "Setup.h"
#include "Pins.h"
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
@@ -32,12 +33,8 @@ static void MX_ADC2_Init(void);
void Setup_HAL() {
SystemClock_Config();
#ifndef LOCAL_BUILD
__HAL_AFIO_REMAP_SWJ_DISABLE()
;
#else
__HAL_AFIO_REMAP_SWJ_NOJTAG();
#endif
MX_GPIO_Init();
MX_DMA_Init();
@@ -49,8 +46,8 @@ void Setup_HAL() {
MX_IWDG_Init();
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t*) ADCReadings, 64); // start DMA of normal readings
HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings
HAL_ADCEx_InjectedStart(&hadc2); // enable injected readings
HAL_ADCEx_InjectedStart(&hadc1); // enable injected readings
HAL_ADCEx_InjectedStart(&hadc2); // enable injected readings
}
// channel 0 -> temperature sensor, 1-> VIN
@@ -336,7 +333,7 @@ static void MX_TIM2_Init(void) {
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 255 + 13;//13 -> Delay of 5ms
sConfigOC.Pulse = 255 + 13; //13 -> Delay of 5ms
//255 is the largest time period of the drive signal, and then offset ADC sample to be a bit delayed after this
/*
* It takes 4 milliseconds for output to be stable after PWM turns off.

View File

@@ -11,7 +11,7 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <hardware.h>
#include "stm32f1xx_hal.h"
extern ADC_HandleTypeDef hadc1;
@@ -29,7 +29,7 @@ extern TIM_HandleTypeDef htim3;
void Setup_HAL();
uint16_t getADC(uint8_t channel);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim); //Since the hal header file does not define this one
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); //Since the hal header file does not define this one
#ifdef __cplusplus
}

View File

@@ -0,0 +1,18 @@
/*
* UnitSettings.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef BSP_MINIWARE_UNITSETTINGS_H_
#define BSP_MINIWARE_UNITSETTINGS_H_
//On the TS80, the LIS accel is mounted backwards
#ifdef MODEL_TS80
#define LIS_ORI_FLIP
#endif
#endif /* BSP_MINIWARE_UNITSETTINGS_H_ */

View File

@@ -0,0 +1,49 @@
/*
* flash.c
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include "BSP_Flash.h"
#include "BSP.h"
#include "string.h"
#include "stm32f1xx_hal.h"
/*Flash start OR'ed with the maximum amount of flash - 1024 bytes*/
/*We use the last 1024 byte page*/
#define FLASH_ADDR (0x8000000 |0xFC00)
uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
FLASH_EraseInitTypeDef pEraseInit;
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
pEraseInit.Banks = FLASH_BANK_1;
pEraseInit.NbPages = 1;
pEraseInit.PageAddress = FLASH_ADDR;
uint32_t failingAddress = 0;
resetWatchdog();
__HAL_FLASH_CLEAR_FLAG(
FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);
HAL_FLASH_Unlock();
HAL_Delay(10);
resetWatchdog();
HAL_FLASHEx_Erase(&pEraseInit, &failingAddress);
//^ Erase the page of flash (1024 bytes on this stm32)
// erased the chunk
// now we program it
uint16_t *data = (uint16_t*) buffer;
HAL_FLASH_Unlock();
for (uint8_t i = 0; i < (length / 2); i++) {
resetWatchdog();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_ADDR + (i * 2),
data[i]);
}
HAL_FLASH_Lock();
return 1;
}
void flash_read_buffer(uint8_t *buffer, const uint16_t length) {
uint16_t *data = (uint16_t*) buffer;
for (uint8_t i = 0; i < (length / 2); i++) {
data[i] = *((uint16_t*) (FLASH_ADDR + (i * 2)));
}
}

View File

@@ -0,0 +1,27 @@
/*
* logo.c
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include "BSP.h"
#include "OLED.hpp"
// Second last page of flash set aside for logo image.
#define FLASH_LOGOADDR (0x8000000 | 0xF800)
// Logo header signature.
#define LOGO_HEADER_VALUE 0xF00DAA55
uint8_t showBootLogoIfavailable() {
// Do not show logo data if signature is not found.
if (LOGO_HEADER_VALUE
!= *(reinterpret_cast<const uint32_t*>(FLASH_LOGOADDR))) {
return 0;
}
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (FLASH_LOGOADDR + 4));
OLED::refresh();
return 1;
}

View File

@@ -0,0 +1,13 @@
#include "BSP.h"
#include "FreeRTOS.h"
#include "QC3.h"
#include "Settings.h"
#include "cmsis_os.h"
#include "main.hpp"
#include "power.hpp"
#include "stdlib.h"
#include "task.h"
void postRToSInit() {
// Any after RTos setup
}

View File

@@ -0,0 +1,22 @@
/*
* preRTOS.c
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include <I2C_Wrapper.hpp>
#include "BSP.h"
#include "Setup.h"
#include "Pins.h"
void preRToSInit() {
/* Reset of all peripherals, Initializes the Flash interface and the Systick.
*/
HAL_Init();
Setup_HAL(); // Setup all the HAL objects
FRToSI2C::init();
HAL_Delay(50);
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(50);
}

View File

@@ -1,4 +1,4 @@
#include <hardware.h>
#include "Pins.h"
#include "stm32f1xx_hal.h"
#include "Setup.h"
/**

View File

@@ -0,0 +1,115 @@
/*
* Buttons.c
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include <Buttons.hpp>
#include "FreeRTOS.h"
#include "task.h"
#include "gui.hpp"
uint32_t lastButtonTime = 0;
ButtonState getButtonState() {
/*
* Read in the buttons and then determine if a state change needs to occur
*/
/*
* If the previous state was 00 Then we want to latch the new state if
* different & update time
* If the previous state was !00 Then we want to search if we trigger long
* press (buttons still down), or if release we trigger press
* (downtime>filter)
*/
static uint8_t previousState = 0;
static uint32_t previousStateChange = 0;
const uint16_t timeout = 40;
uint8_t currentState;
currentState = (getButtonA()) << 0;
currentState |= (getButtonB()) << 1;
if (currentState)
lastButtonTime = xTaskGetTickCount();
if (currentState == previousState) {
if (currentState == 0)
return BUTTON_NONE;
if ((xTaskGetTickCount() - previousStateChange) > timeout) {
// User has been holding the button down
// We want to send a button is held message
if (currentState == 0x01)
return BUTTON_F_LONG;
else if (currentState == 0x02)
return BUTTON_B_LONG;
else
return BUTTON_NONE; // Both being held case, we dont long hold this
} else
return BUTTON_NONE;
} else {
// A change in button state has occurred
ButtonState retVal = BUTTON_NONE;
if (currentState) {
// User has pressed a button down (nothing done on down)
if (currentState != previousState) {
// There has been a change in the button states
// If there is a rising edge on one of the buttons from double press we
// want to mask that out As users are having issues with not release
// both at once
if (previousState == 0x03)
currentState = 0x03;
}
} else {
// User has released buttons
// If they previously had the buttons down we want to check if they were <
// long hold and trigger a press
if ((xTaskGetTickCount() - previousStateChange) < timeout) {
// The user didn't hold the button for long
// So we send button press
if (previousState == 0x01)
retVal = BUTTON_F_SHORT;
else if (previousState == 0x02)
retVal = BUTTON_B_SHORT;
else
retVal = BUTTON_BOTH; // Both being held case
}
}
previousState = currentState;
previousStateChange = xTaskGetTickCount();
return retVal;
}
return BUTTON_NONE;
}
void waitForButtonPress() {
// we are just lazy and sleep until user confirms button press
// This also eats the button press event!
ButtonState buttons = getButtonState();
while (buttons) {
buttons = getButtonState();
GUIDelay();
}
while (!buttons) {
buttons = getButtonState();
GUIDelay();
}
}
void waitForButtonPressOrTimeout(uint32_t timeout) {
timeout += xTaskGetTickCount();
// calculate the exit point
ButtonState buttons = getButtonState();
while (buttons) {
buttons = getButtonState();
GUIDelay();
if (xTaskGetTickCount() > timeout)
return;
}
while (!buttons) {
buttons = getButtonState();
GUIDelay();
if (xTaskGetTickCount() > timeout)
return;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Buttons.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#include "BSP.h"
#ifndef INC_BUTTONS_H_
#define INC_BUTTONS_H_
extern uint32_t lastButtonTime;
enum ButtonState {
BUTTON_NONE = 0, /* No buttons pressed / < filter time*/
BUTTON_F_SHORT = 1, /* User has pressed the front button*/
BUTTON_B_SHORT = 2, /* User has pressed the back button*/
BUTTON_F_LONG = 4, /* User is holding the front button*/
BUTTON_B_LONG = 8, /* User is holding the back button*/
BUTTON_BOTH = 16, /* User has pressed both buttons*/
/*
* Note:
* Pressed means press + release, we trigger on a full \__/ pulse
* holding means it has gone low, and been low for longer than filter time
*/
};
//Returns what buttons are pressed (if any)
ButtonState getButtonState();
//Helpers
void waitForButtonPressOrTimeout(uint32_t timeout);
void waitForButtonPress();
#endif /* INC_BUTTONS_H_ */

View File

@@ -12,8 +12,8 @@
#include "Translation.h"
#define FONT_12_WIDTH 12
// FONTS ARE NO LONGER HERE, MOVED TO PYTHON AUTO GEN
// THE MAIN FONTS ARE NO LONGER HERE, MOVED TO PYTHON AUTO GEN
// THESE ARE ONLY THE SYMBOL FONTS
const uint8_t ExtraFontChars[] = {
//width = 12

View File

@@ -7,14 +7,21 @@
#ifndef FRTOSI2C_HPP_
#define FRTOSI2C_HPP_
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
/*
* Wrapper class to work with the device I2C bus
*
* This provides mutex protection of the peripheral
* Also allows hardware to use DMA should it want to
*
*
*/
class FRToSI2C {
public:
static void init(I2C_HandleTypeDef *i2chandle) {
i2c = i2chandle;
static void init() {
I2CSemaphore = nullptr;
}
@@ -25,18 +32,19 @@ public:
static void CpltCallback(); //Normal Tx Callback
static void Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
uint8_t *pData, uint16_t Size);
static void Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
uint8_t *pData, uint16_t Size);
//Returns true if device ACK's being addressed
static bool probe(uint16_t DevAddress);
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
static void I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg);
private:
static I2C_HandleTypeDef *i2c;
static void I2C1_ClearBusyFlagErratum();
static void I2C_Unstick();
static SemaphoreHandle_t I2CSemaphore;
static StaticSemaphore_t xSemaphoreBuffer;
};

View File

@@ -0,0 +1,52 @@
/*
* LIS2DH12.cpp
*
* Created on: 27Feb.,2018
* Author: Ralim
*/
#include <array>
#include "LIS2DH12.hpp"
#include "cmsis_os.h"
typedef struct {
const uint8_t reg;
const uint8_t value;
} LIS_REG;
static const LIS_REG i2c_registers[] = { { LIS_CTRL_REG1, 0x17 }, // 25Hz
{ LIS_CTRL_REG2, 0b00001000 }, // Highpass filter off
{ LIS_CTRL_REG3, 0b01100000 }, // Setup interrupt pins
{ LIS_CTRL_REG4, 0b00001000 }, // Block update mode off, HR on
{ LIS_CTRL_REG5, 0b00000010 }, { LIS_CTRL_REG6, 0b01100010 },
//Basically setup the unit to run, and enable 4D orientation detection
{ LIS_INT2_CFG, 0b01111110 }, //setup for movement detection
{ LIS_INT2_THS, 0x28 }, { LIS_INT2_DURATION, 64 }, {
LIS_INT1_CFG, 0b01111110 }, { LIS_INT1_THS, 0x28 }, {
LIS_INT1_DURATION, 64 } };
void LIS2DH12::initalize() {
for (size_t index = 0;
index < (sizeof(i2c_registers) / sizeof(i2c_registers[0]));
index++) {
FRToSI2C::I2C_RegisterWrite(LIS2DH_I2C_ADDRESS,
i2c_registers[index].reg, i2c_registers[index].value);
}
}
void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
std::array<int16_t, 3> sensorData;
FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8,
reinterpret_cast<uint8_t*>(sensorData.begin()),
sensorData.size() * sizeof(int16_t));
x = sensorData[0];
y = sensorData[1];
z = sensorData[2];
}
bool LIS2DH12::detect() {
return FRToSI2C::probe(LIS2DH_I2C_ADDRESS);
}

View File

@@ -7,17 +7,17 @@
#ifndef LIS2DH12_HPP_
#define LIS2DH12_HPP_
#include "stm32f1xx_hal.h"
#include "FRToSI2C.hpp"
#include "I2C_Wrapper.hpp"
#include "LIS2DH12_defines.hpp"
#include "hardware.h"
#include "BSP.h"
class LIS2DH12 {
public:
static bool detect();
static void initalize();
//1 = rh, 2,=lh, 8=flat
static Orientation getOrientation() {
#ifdef MODEL_TS80
#ifdef LIS_ORI_FLIP
uint8_t val = (FRToSI2C::I2C_RegisterRead(LIS2DH_I2C_ADDRESS,
LIS_INT2_SRC) >> 2);
if (val == 8)

View File

@@ -30,28 +30,31 @@ static const MMA_REG i2c_registers[] = { { CTRL_REG2, 0 }, //Normal mode
{ CTRL_REG1, 0x19 } // ODR=12 Hz, Active mode
};
void MMA8652FC::initalize() {
size_t index = 0;
//send all the init commands to the unit
FRToSI2C::I2C_RegisterWrite(MMA8652FC_I2C_ADDRESS,i2c_registers[index].reg, i2c_registers[index].val);
FRToSI2C::I2C_RegisterWrite(MMA8652FC_I2C_ADDRESS, i2c_registers[index].reg,
i2c_registers[index].val);
index++;
FRToSI2C::I2C_RegisterWrite(MMA8652FC_I2C_ADDRESS,i2c_registers[index].reg, i2c_registers[index].val);
FRToSI2C::I2C_RegisterWrite(MMA8652FC_I2C_ADDRESS, i2c_registers[index].reg,
i2c_registers[index].val);
index++;
HAL_Delay(2); // ~1ms delay
delay_ms(2); // ~1ms delay
while (index < (sizeof(i2c_registers) / sizeof(i2c_registers[0]))) {
FRToSI2C::I2C_RegisterWrite(MMA8652FC_I2C_ADDRESS,i2c_registers[index].reg, i2c_registers[index].val);
FRToSI2C::I2C_RegisterWrite(MMA8652FC_I2C_ADDRESS,
i2c_registers[index].reg, i2c_registers[index].val);
index++;
}
}
Orientation MMA8652FC::getOrientation() {
//First read the PL_STATUS register
uint8_t plStatus = FRToSI2C::I2C_RegisterRead(MMA8652FC_I2C_ADDRESS,PL_STATUS_REG);
uint8_t plStatus = FRToSI2C::I2C_RegisterRead(MMA8652FC_I2C_ADDRESS,
PL_STATUS_REG);
if ((plStatus & 0b10000000) == 0b10000000) {
plStatus >>= 1; //We don't need the up/down bit
plStatus &= 0x03; //mask to the two lower bits
@@ -65,14 +68,21 @@ Orientation MMA8652FC::getOrientation() {
return ORIENTATION_FLAT;
}
void MMA8652FC::getAxisReadings(int16_t& x, int16_t& y, int16_t& z) {
void MMA8652FC::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
std::array<int16_t, 3> sensorData;
FRToSI2C::Mem_Read(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG, I2C_MEMADD_SIZE_8BIT,
reinterpret_cast<uint8_t*>(sensorData.begin()),
sensorData.size() * sizeof(int16_t));
FRToSI2C::Mem_Read(MMA8652FC_I2C_ADDRESS, OUT_X_MSB_REG,
reinterpret_cast<uint8_t*>(sensorData.begin()),
sensorData.size() * sizeof(int16_t));
x = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(&sensorData[0])));
y = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(&sensorData[1])));
z = static_cast<int16_t>(__builtin_bswap16(*reinterpret_cast<uint16_t*>(&sensorData[2])));
x = static_cast<int16_t>(__builtin_bswap16(
*reinterpret_cast<uint16_t*>(&sensorData[0])));
y = static_cast<int16_t>(__builtin_bswap16(
*reinterpret_cast<uint16_t*>(&sensorData[1])));
z = static_cast<int16_t>(__builtin_bswap16(
*reinterpret_cast<uint16_t*>(&sensorData[2])));
}
bool MMA8652FC::detect() {
return FRToSI2C::probe(MMA8652FC_I2C_ADDRESS);
}

View File

@@ -0,0 +1,27 @@
/*
* MMA8652FC.h
*
* Created on: 31Aug.,2017
* Author: Ben V. Brown
*/
#ifndef MMA8652FC_HPP_
#define MMA8652FC_HPP_
#include "MMA8652FC_defines.h"
#include "I2C_Wrapper.hpp"
#include "BSP.h"
class MMA8652FC {
public:
//Returns true if this accelerometer is detected
static bool detect();
//Init any internal state
static void initalize();
static Orientation getOrientation(); // Reads the I2C register and returns the orientation (true == left)
static void getAxisReadings(int16_t &x, int16_t &y, int16_t &z);
private:
};
#endif /* MMA8652FC_HPP_ */

View File

@@ -63,7 +63,6 @@ uint8_t OLED_Setup_Array[] = {
const uint8_t REFRESH_COMMANDS[17] = { 0x80, 0xAF, 0x80, 0x21, 0x80, 0x20, 0x80,
0x7F, 0x80, 0xC0, 0x80, 0x22, 0x80, 0x00, 0x80, 0x01, 0x40 };
/*
* Animation timing function that follows a bezier curve.
* @param t A given percentage value [0..<100]
@@ -95,10 +94,6 @@ void OLED::initialize() {
displayOffset = 0;
memcpy(&screenBuffer[0], &REFRESH_COMMANDS[0], sizeof(REFRESH_COMMANDS));
HAL_Delay(50);
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(50);
// Set the display to be ON once the settings block is sent and send the
// initialisation data to the OLED.
@@ -195,11 +190,14 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
offset = progress;
memmove(&firstStripPtr[oldStart], &firstStripPtr[oldPrevious], OLED_WIDTH - progress);
memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious], OLED_WIDTH - progress);
memmove(&firstStripPtr[oldStart], &firstStripPtr[oldPrevious],
OLED_WIDTH - progress);
memmove(&secondStripPtr[oldStart], &secondStripPtr[oldPrevious],
OLED_WIDTH - progress);
memmove(&firstStripPtr[newStart], &firstBackStripPtr[newEnd], progress);
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd], progress);
memmove(&secondStripPtr[newStart], &secondBackStripPtr[newEnd],
progress);
refresh();
osDelay(40);
@@ -275,7 +273,7 @@ uint8_t OLED::getFont() {
inline void stripLeaderZeros(char *buffer, uint8_t places) {
//Removing the leading zero's by swapping them to SymbolSpace
// Stop 1 short so that we dont blank entire number if its zero
for (int i = 0; i < (places-1); i++) {
for (int i = 0; i < (places - 1); i++) {
if (buffer[i] == 2) {
buffer[i] = SymbolSpace[0];
} else {

View File

@@ -9,11 +9,10 @@
#ifndef OLED_HPP_
#define OLED_HPP_
#include <hardware.h>
#include "stm32f1xx_hal.h"
#include <BSP.h>
#include <stdbool.h>
#include <string.h>
#include "FRToSI2C.hpp"
#include "I2C_Wrapper.hpp"
#include "Font.h"
#ifdef __cplusplus
extern "C" {
@@ -31,8 +30,7 @@ class OLED {
public:
enum DisplayState : bool {
OFF = false,
ON = true
OFF = false, ON = true
};
static void initialize(); // Startup the I2C coms (brings screen out of reset etc)
@@ -40,7 +38,7 @@ public:
// Draw the buffer out to the LCD using the DMA Channel
static void refresh() {
FRToSI2C::Transmit( DEVICEADDR_OLED, screenBuffer,
FRAMEBUFFER_START + (OLED_WIDTH * 2));
FRAMEBUFFER_START + (OLED_WIDTH * 2));
//DMA tx time is ~ 20mS Ensure after calling this you delay for at least 25ms
//or we need to goto double buffering
}
@@ -52,13 +50,13 @@ public:
static void setRotation(bool leftHanded); // Set the rotation for the screen
// Get the current rotation of the LCD
static bool getRotation() {
static bool getRotation() {
return inLeftHandedMode;
}
static int16_t getCursorX() {
return cursor_x;
}
static void print(const char* string);// Draw a string to the current location, with current font
static void print(const char *string);// Draw a string to the current location, with current font
// Set the cursor location by pixels
static void setCursor(int16_t x, int16_t y) {
cursor_x = x;
@@ -71,11 +69,12 @@ public:
}
static void setFont(uint8_t fontNumber); // (Future) Set the font that is being used
static uint8_t getFont();
static void drawImage(const uint8_t* buffer, uint8_t x, uint8_t width) {
static void drawImage(const uint8_t *buffer, uint8_t x, uint8_t width) {
drawArea(x, 0, width, 16, buffer);
}
// Draws an image to the buffer, at x offset from top to bottom (fixed height renders)
static void printNumber(uint16_t number, uint8_t places,bool noLeaderZeros=true);
static void printNumber(uint16_t number, uint8_t places,
bool noLeaderZeros = true);
// Draws a number at the current cursor location
// Clears the buffer
static void clearScreen() {
@@ -92,9 +91,9 @@ public:
static void debugNumber(int32_t val);
static void drawSymbol(uint8_t symbolID);//Used for drawing symbols of a predictable width
static void drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height,
const uint8_t* ptr); //Draw an area, but y must be aligned on 0/8 offset
static void drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height,
const uint8_t* ptr); //Draw an area, but y must be aligned on 0/8 offset
const uint8_t *ptr); //Draw an area, but y must be aligned on 0/8 offset
static void drawAreaSwapped(int16_t x, int8_t y, uint8_t wide,
uint8_t height, const uint8_t *ptr); //Draw an area, but y must be aligned on 0/8 offset
static void fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height,
const uint8_t value); //Fill an area, but y must be aligned on 0/8 offset
static void drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
@@ -106,9 +105,9 @@ public:
private:
static void drawChar(char c); // Draw a character to a specific location
static void setFramebuffer(uint8_t *buffer);
static const uint8_t* currentFont;// Pointer to the current font used for rendering to the buffer
static uint8_t* firstStripPtr; // Pointers to the strips to allow for buffer having extra content
static uint8_t* secondStripPtr; //Pointers to the strips
static const uint8_t *currentFont; // Pointer to the current font used for rendering to the buffer
static uint8_t *firstStripPtr; // Pointers to the strips to allow for buffer having extra content
static uint8_t *secondStripPtr; //Pointers to the strips
static bool inLeftHandedMode; // Whether the screen is in left or not (used for offsets in GRAM)
static DisplayState displayState;
static uint8_t fontWidth, fontHeight;

View File

@@ -0,0 +1,10 @@
# Drivers
Drivers are the classes used to represent physical hardware on the board in a more abstract way, that are more complex than just an IO
* OLED Display
* Accelerometers
* Button handling logic
* Tip thermo response modelling
All drivers should be written with minimal hardware assumptions, and defer hardware related logic to the BSP folder where possible

View File

@@ -7,7 +7,7 @@
#include "TipThermoModel.h"
#include "Settings.h"
#include "hardware.h"
#include "BSP.h"
#include "../../configuration.h"
/*

View File

@@ -8,7 +8,7 @@
#ifndef SRC_TIPTHERMOMODEL_H_
#define SRC_TIPTHERMOMODEL_H_
#include "stdint.h"
#include "hardware.h"
#include "BSP.h"
#include "unit.h"
class TipThermoModel {
public:

View File

@@ -0,0 +1,28 @@
/*
* FreeRTOSHooks.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef INC_FREERTOSHOOKS_H_
#define INC_FREERTOSHOOKS_H_
#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "unit.h"
#ifdef __cplusplus
extern "C" {
#endif
// RToS
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize);
void vApplicationIdleHook(void);
#ifdef __cplusplus
}
#endif
#endif /* INC_FREERTOSHOOKS_H_ */

View File

@@ -1,27 +0,0 @@
/*
* MMA8652FC.h
*
* Created on: 31Aug.,2017
* Author: Ben V. Brown
*/
#ifndef MMA8652FC_HPP_
#define MMA8652FC_HPP_
#include "stm32f1xx_hal.h"
#include "MMA8652FC_defines.h"
#include "FRToSI2C.hpp"
#include "hardware.h"
class MMA8652FC {
public:
static void initalize(); // Initalize the system
static Orientation getOrientation();// Reads the I2C register and returns the orientation (true == left)
static void getAxisReadings(int16_t& x, int16_t& y, int16_t& z);
private:
};
#endif /* MMA8652FC_HPP_ */

View File

@@ -0,0 +1,21 @@
/*
* QC3.h
*
* Created on: 29 May 2020
* Author: Ralim
*/
#ifndef INC_QC3_H_
#define INC_QC3_H_
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
void seekQC(int16_t Vx10, uint16_t divisor);
void startQC(uint16_t divisor); // Tries to negotiate QC for highest voltage, must be run after
#ifdef __cplusplus
}
#endif
#endif /* INC_QC3_H_ */

View File

@@ -42,7 +42,7 @@ typedef struct {
uint8_t temperatureInF :1; // Should the temp be in F or C (true is F)
#endif
uint8_t descriptionScrollSpeed :1; // Description scroll speed
uint8_t KeepAwakePulse; // Keep Awake pulse power in 0.1 watts (10 = 1Watt)
uint8_t KeepAwakePulse; // Keep Awake pulse power in 0.1 watts (10 = 1Watt)
uint16_t voltageDiv; // Voltage divisor factor
uint16_t BoostTemp; // Boost mode set point for the iron
@@ -70,5 +70,5 @@ void saveSettings();
bool restoreSettings();
uint8_t lookupVoltageLevel(uint8_t level);
void resetSettings();
bool showBootLogoIfavailable();
#endif /* SETTINGS_H_ */

View File

@@ -7,8 +7,8 @@
#ifndef TRANSLATION_H_
#define TRANSLATION_H_
#include "stm32f1xx_hal.h"
#include "unit.h"
#include "stdint.h"
enum ShortNameType {
SHORT_NAME_SINGLE_LINE = 1, SHORT_NAME_DOUBLE_LINE = 2,
};

View File

@@ -9,13 +9,12 @@
#define GUI_HPP_
#include "Translation.h"
#include "Settings.h"
#include "hardware.h"
#include "BSP.h"
#define PRESS_ACCEL_STEP 3
#define PRESS_ACCEL_INTERVAL_MIN 10
#define PRESS_ACCEL_INTERVAL_MAX 30
//GUI holds the menu structure and all its methods for the menu itself
//Declarations for all the methods for the settings menu (at end of this file)
@@ -33,6 +32,7 @@ typedef struct {
} menuitem;
void enterSettingsMenu();
void GUIDelay();
extern const menuitem rootSettingsMenu[];
#endif /* GUI_HPP_ */

View File

@@ -1,31 +1,12 @@
#ifndef __MAIN_H
#define __MAIN_H
#include <MMA8652FC.hpp>
#include "OLED.hpp"
#include "Setup.h"
extern uint8_t PCBVersion;
extern uint32_t currentTempTargetDegC;
extern bool settingsWereReset;
enum ButtonState {
BUTTON_NONE = 0, /* No buttons pressed / < filter time*/
BUTTON_F_SHORT = 1, /* User has pressed the front button*/
BUTTON_B_SHORT = 2, /* User has pressed the back button*/
BUTTON_F_LONG = 4, /* User is holding the front button*/
BUTTON_B_LONG = 8, /* User is holding the back button*/
BUTTON_BOTH = 16, /* User has pressed both buttons*/
/*
* Note:
* Pressed means press + release, we trigger on a full \__/ pulse
* holding means it has gone low, and been low for longer than filter time
*/
};
ButtonState getButtonState();
void waitForButtonPressOrTimeout(uint32_t timeout);
void waitForButtonPress();
void GUIDelay();
#ifdef __cplusplus
extern "C" {
#endif
@@ -40,6 +21,13 @@ void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
void vApplicationStackOverflowHook(xTaskHandle *pxTask,
signed portCHAR *pcTaskName);
//Threads
void startGUITask(void const *argument);
void startPIDTask(void const *argument);
void startMOVTask(void const *argument);
extern TaskHandle_t pidTaskNotification;
extern uint8_t accelInit;
extern uint32_t lastMovementTime;
#ifdef __cplusplus
}
#endif

View File

@@ -7,7 +7,7 @@
#include "stdint.h"
#include <history.hpp>
#include "hardware.h"
#include "BSP.h"
#include "expMovingAverage.h"
#ifndef POWER_HPP_
#define POWER_HPP_

Some files were not shown because too many files have changed in this diff Show More