Add OLED display support
This commit is contained in:
parent
6ec7d1b8bb
commit
548549f067
14 changed files with 322 additions and 68 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
||||||
[submodule "src/BME68x-Sensor-API"]
|
[submodule "src/BME68x-Sensor-API"]
|
||||||
path = src/BME68x-Sensor-API
|
path = src/BME68x-Sensor-API
|
||||||
url = https://github.com/BoschSensortec/BME68x-Sensor-API.git
|
url = https://github.com/BoschSensortec/BME68x-Sensor-API.git
|
||||||
|
[submodule "src/oled-driver"]
|
||||||
|
path = src/oled-driver
|
||||||
|
url = git@github.com:MG-5/oled-driver.git
|
||||||
|
|
13
.vscode/c_cpp_properties.json
vendored
13
.vscode/c_cpp_properties.json
vendored
|
@ -11,15 +11,18 @@
|
||||||
"${workspaceFolder}/cubemx/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2",
|
"${workspaceFolder}/cubemx/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2",
|
||||||
"${workspaceFolder}/cubemx/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3",
|
"${workspaceFolder}/cubemx/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3",
|
||||||
"${workspaceFolder}/cubemx/Drivers/CMSIS/Device/ST/STM32L1xx/Include",
|
"${workspaceFolder}/cubemx/Drivers/CMSIS/Device/ST/STM32L1xx/Include",
|
||||||
"${workspaceFolder}/cubemx/Drivers/CMSIS/Include"
|
"${workspaceFolder}/cubemx/Drivers/CMSIS/Include",
|
||||||
|
"${workspaceFolder}/src",
|
||||||
|
"${workspaceFolder}/src/oled-driver/include",
|
||||||
|
"${workspaceFolder}/src/oled-driver"
|
||||||
],
|
],
|
||||||
"defines": [
|
"defines": [
|
||||||
"STM32L1",
|
"DEBUG",
|
||||||
"STM32L152RC",
|
|
||||||
"STM32L152xC",
|
"STM32L152xC",
|
||||||
"BME68X_DO_NOT_USE_FPU"
|
"BME68X_DO_NOT_USE_FPU",
|
||||||
|
"FW_USE_RTOS"
|
||||||
],
|
],
|
||||||
"compilerPath": "arm-none-eabi-gcc",
|
"compilerPath": "/usr/bin/arm-none-eabi-gcc",
|
||||||
"cStandard": "c11",
|
"cStandard": "c11",
|
||||||
"cppStandard": "c++17"
|
"cppStandard": "c++17"
|
||||||
}
|
}
|
||||||
|
|
25
Makefile
25
Makefile
|
@ -2,17 +2,24 @@ TARGET := voc-sensor
|
||||||
RTOS := freertos
|
RTOS := freertos
|
||||||
DEVICE := stm32l152rc
|
DEVICE := stm32l152rc
|
||||||
|
|
||||||
DEFS := BME68X_DO_NOT_USE_FPU
|
DEFS += BME68X_DO_NOT_USE_FPU
|
||||||
|
DEFS += FW_USE_RTOS
|
||||||
|
|
||||||
INCDIRS := \
|
INCDIRS := \
|
||||||
src \
|
src/BME68x-Sensor-API \
|
||||||
src/BME68x-Sensor-API
|
src/oled-driver/ \
|
||||||
|
src/oled-driver/include \
|
||||||
|
src \
|
||||||
|
|
||||||
SOURCES := \
|
SOURCES := \
|
||||||
src/bmeSPI.cxx \
|
src/BME68x-Sensor-API/bme68x.c \
|
||||||
src/main.cxx \
|
src/oled-driver/fonts/mono.cxx \
|
||||||
src/handlers.cxx \
|
src/oled-driver/src/Display.cxx \
|
||||||
src/BME68x-Sensor-API/bme68x.c
|
src/oled-driver/src/Image.cxx \
|
||||||
|
src/oled-driver/src/Renderer.cxx \
|
||||||
|
src/bmeSPI.cxx \
|
||||||
|
src/handlers.cxx \
|
||||||
|
src/main.cxx \
|
||||||
|
|
||||||
# Actual build engine
|
# Actual build engine
|
||||||
include core/mk/include.mk
|
include core/mk/include.mk
|
|
@ -13,7 +13,13 @@ void *operator new(std::size_t size)
|
||||||
#if FW_USE_RTOS
|
#if FW_USE_RTOS
|
||||||
return pvPortMalloc(size);
|
return pvPortMalloc(size);
|
||||||
#else
|
#else
|
||||||
return reinterpret_cast<void *>(0xffffffff);
|
#ifdef DEBUG
|
||||||
|
__asm("bkpt");
|
||||||
|
#else
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,11 +32,15 @@ void operator delete(void *ptr)
|
||||||
{
|
{
|
||||||
#if FW_USE_RTOS
|
#if FW_USE_RTOS
|
||||||
vPortFree(ptr);
|
vPortFree(ptr);
|
||||||
|
#else
|
||||||
|
#ifdef DEBUG
|
||||||
|
__asm("bkpt");
|
||||||
#else
|
#else
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void *ptr, unsigned int)
|
void operator delete(void *ptr, unsigned int)
|
||||||
|
@ -110,7 +120,7 @@ extern "C"
|
||||||
|
|
||||||
// some functions in cmath follow the compiler flag -fno-math-errno
|
// some functions in cmath follow the compiler flag -fno-math-errno
|
||||||
// but not so for std::pow...
|
// but not so for std::pow...
|
||||||
void __errno() {
|
void __errno()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -60,7 +60,7 @@
|
||||||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||||
#define configMAX_PRIORITIES ( 56 )
|
#define configMAX_PRIORITIES ( 56 )
|
||||||
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
|
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
|
||||||
#define configTOTAL_HEAP_SIZE ((size_t)3072)
|
#define configTOTAL_HEAP_SIZE ((size_t)6000)
|
||||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||||
#define configUSE_TRACE_FACILITY 1
|
#define configUSE_TRACE_FACILITY 1
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
@ -68,8 +68,10 @@
|
||||||
#define configQUEUE_REGISTRY_SIZE 8
|
#define configQUEUE_REGISTRY_SIZE 8
|
||||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
#define configUSE_RECURSIVE_MUTEXES 1
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||||
#define configUSE_COUNTING_SEMAPHORES 1
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||||
|
|
||||||
/* Co-routine definitions. */
|
/* Co-routine definitions. */
|
||||||
#define configUSE_CO_ROUTINES 0
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
|
|
@ -58,8 +58,14 @@ void Error_Handler(void);
|
||||||
/* USER CODE END EFP */
|
/* USER CODE END EFP */
|
||||||
|
|
||||||
/* Private defines -----------------------------------------------------------*/
|
/* Private defines -----------------------------------------------------------*/
|
||||||
#define SPI_CS_Pin GPIO_PIN_12
|
#define VocSensorCS_Pin GPIO_PIN_0
|
||||||
#define SPI_CS_GPIO_Port GPIOB
|
#define VocSensorCS_GPIO_Port GPIOA
|
||||||
|
#define DisplayDC_Pin GPIO_PIN_10
|
||||||
|
#define DisplayDC_GPIO_Port GPIOB
|
||||||
|
#define DisplayReset_Pin GPIO_PIN_11
|
||||||
|
#define DisplayReset_GPIO_Port GPIOB
|
||||||
|
#define DisplayCS_Pin GPIO_PIN_12
|
||||||
|
#define DisplayCS_GPIO_Port GPIOB
|
||||||
/* USER CODE BEGIN Private defines */
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
/* USER CODE END Private defines */
|
/* USER CODE END Private defines */
|
||||||
|
|
|
@ -75,6 +75,7 @@ void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||||
|
|
||||||
/* Hook prototypes */
|
/* Hook prototypes */
|
||||||
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName);
|
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName);
|
||||||
|
void vApplicationMallocFailedHook(void);
|
||||||
|
|
||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
__weak void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
|
__weak void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName)
|
||||||
|
@ -85,6 +86,22 @@ __weak void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTask
|
||||||
}
|
}
|
||||||
/* USER CODE END 4 */
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 5 */
|
||||||
|
__weak void vApplicationMallocFailedHook(void)
|
||||||
|
{
|
||||||
|
/* vApplicationMallocFailedHook() will only be called if
|
||||||
|
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
|
||||||
|
function that will get called if a call to pvPortMalloc() fails.
|
||||||
|
pvPortMalloc() is called internally by the kernel whenever a task, queue,
|
||||||
|
timer or semaphore is created. It is also called by various parts of the
|
||||||
|
demo application. If heap_1.c or heap_2.c are used, then the size of the
|
||||||
|
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
|
||||||
|
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
|
||||||
|
to query the size of free heap space that remains (although it does not
|
||||||
|
provide information on how the remaining heap might be fragmented). */
|
||||||
|
}
|
||||||
|
/* USER CODE END 5 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief FreeRTOS initialization
|
* @brief FreeRTOS initialization
|
||||||
* @param None
|
* @param None
|
||||||
|
|
|
@ -53,7 +53,10 @@ void MX_GPIO_Init(void)
|
||||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET);
|
HAL_GPIO_WritePin(VocSensorCS_GPIO_Port, VocSensorCS_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
|
/*Configure GPIO pin Output Level */
|
||||||
|
HAL_GPIO_WritePin(GPIOB, DisplayDC_Pin|DisplayReset_Pin|DisplayCS_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
/*Configure GPIO pins : PC13 PC14 PC15 PC0
|
/*Configure GPIO pins : PC13 PC14 PC15 PC0
|
||||||
PC1 PC2 PC3 PC4
|
PC1 PC2 PC3 PC4
|
||||||
|
@ -73,34 +76,41 @@ void MX_GPIO_Init(void)
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pins : PA0 PA1 PA2 PA3
|
/*Configure GPIO pin : PtPin */
|
||||||
PA4 PA5 PA6 PA7
|
GPIO_InitStruct.Pin = VocSensorCS_Pin;
|
||||||
PA8 PA9 PA10 PA11
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
PA12 PA15 */
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
|
HAL_GPIO_Init(VocSensorCS_GPIO_Port, &GPIO_InitStruct);
|
||||||
|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|
|
||||||
|GPIO_PIN_12|GPIO_PIN_15;
|
/*Configure GPIO pins : PA1 PA2 PA3 PA4
|
||||||
|
PA5 PA6 PA7 PA8
|
||||||
|
PA9 PA10 PA11 PA12
|
||||||
|
PA15 */
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4
|
||||||
|
|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|
||||||
|
|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12
|
||||||
|
|GPIO_PIN_15;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pins : PB0 PB1 PB2 PB10
|
/*Configure GPIO pins : PB0 PB1 PB2 PB3
|
||||||
PB11 PB3 PB4 PB5
|
PB4 PB5 PB6 PB7
|
||||||
PB6 PB7 PB8 PB9 */
|
PB8 PB9 */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|
||||||
|GPIO_PIN_11|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
|
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
|
||||||
|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
|
|GPIO_PIN_8|GPIO_PIN_9;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pin : PtPin */
|
/*Configure GPIO pins : PBPin PBPin PBPin */
|
||||||
GPIO_InitStruct.Pin = SPI_CS_Pin;
|
GPIO_InitStruct.Pin = DisplayDC_Pin|DisplayReset_Pin|DisplayCS_Pin;
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||||
HAL_GPIO_Init(SPI_CS_GPIO_Port, &GPIO_InitStruct);
|
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
/*Configure GPIO pin : PD2 */
|
/*Configure GPIO pin : PD2 */
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||||
|
|
|
@ -22,9 +22,12 @@ Dma.SPI2_TX.1.Priority=DMA_PRIORITY_LOW
|
||||||
Dma.SPI2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
|
Dma.SPI2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
|
||||||
FREERTOS.FootprintOK=true
|
FREERTOS.FootprintOK=true
|
||||||
FREERTOS.HEAP_NUMBER=1
|
FREERTOS.HEAP_NUMBER=1
|
||||||
FREERTOS.IPParameters=Tasks01,configCHECK_FOR_STACK_OVERFLOW,FootprintOK,HEAP_NUMBER
|
FREERTOS.IPParameters=Tasks01,configCHECK_FOR_STACK_OVERFLOW,FootprintOK,HEAP_NUMBER,configRECORD_STACK_HIGH_ADDRESS,configUSE_MALLOC_FAILED_HOOK,configTOTAL_HEAP_SIZE
|
||||||
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;sensor,24,512,sensorTask,As external,NULL,Dynamic,NULL,NULL
|
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;sensor,24,512,sensorTask,As external,NULL,Dynamic,NULL,NULL
|
||||||
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
|
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
|
||||||
|
FREERTOS.configRECORD_STACK_HIGH_ADDRESS=1
|
||||||
|
FREERTOS.configTOTAL_HEAP_SIZE=6000
|
||||||
|
FREERTOS.configUSE_MALLOC_FAILED_HOOK=1
|
||||||
File.Version=6
|
File.Version=6
|
||||||
GPIO.groupedBy=
|
GPIO.groupedBy=
|
||||||
KeepUserPlacement=false
|
KeepUserPlacement=false
|
||||||
|
@ -38,15 +41,18 @@ Mcu.IP5=SYS
|
||||||
Mcu.IPNb=6
|
Mcu.IPNb=6
|
||||||
Mcu.Name=STM32L152RCTx
|
Mcu.Name=STM32L152RCTx
|
||||||
Mcu.Package=LQFP64
|
Mcu.Package=LQFP64
|
||||||
Mcu.Pin0=PB12
|
Mcu.Pin0=PA0-WKUP1
|
||||||
Mcu.Pin1=PB13
|
Mcu.Pin1=PB10
|
||||||
Mcu.Pin2=PB14
|
Mcu.Pin10=VP_SYS_VS_tim2
|
||||||
Mcu.Pin3=PB15
|
Mcu.Pin2=PB11
|
||||||
Mcu.Pin4=PA13
|
Mcu.Pin3=PB12
|
||||||
Mcu.Pin5=PA14
|
Mcu.Pin4=PB13
|
||||||
Mcu.Pin6=VP_FREERTOS_VS_CMSIS_V2
|
Mcu.Pin5=PB14
|
||||||
Mcu.Pin7=VP_SYS_VS_tim2
|
Mcu.Pin6=PB15
|
||||||
Mcu.PinsNb=8
|
Mcu.Pin7=PA13
|
||||||
|
Mcu.Pin8=PA14
|
||||||
|
Mcu.Pin9=VP_FREERTOS_VS_CMSIS_V2
|
||||||
|
Mcu.PinsNb=11
|
||||||
Mcu.ThirdPartyNb=0
|
Mcu.ThirdPartyNb=0
|
||||||
Mcu.UserConstants=
|
Mcu.UserConstants=
|
||||||
Mcu.UserName=STM32L152RCTx
|
Mcu.UserName=STM32L152RCTx
|
||||||
|
@ -71,13 +77,21 @@ NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true
|
||||||
NVIC.TimeBase=TIM2_IRQn
|
NVIC.TimeBase=TIM2_IRQn
|
||||||
NVIC.TimeBaseIP=TIM2
|
NVIC.TimeBaseIP=TIM2
|
||||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||||
|
PA0-WKUP1.GPIOParameters=GPIO_Label
|
||||||
|
PA0-WKUP1.GPIO_Label=VocSensorCS
|
||||||
|
PA0-WKUP1.Signal=GPIO_Output
|
||||||
PA13.Mode=Serial_Wire
|
PA13.Mode=Serial_Wire
|
||||||
PA13.Signal=SYS_JTMS-SWDIO
|
PA13.Signal=SYS_JTMS-SWDIO
|
||||||
PA14.Mode=Serial_Wire
|
PA14.Mode=Serial_Wire
|
||||||
PA14.Signal=SYS_JTCK-SWCLK
|
PA14.Signal=SYS_JTCK-SWCLK
|
||||||
|
PB10.GPIOParameters=GPIO_Label
|
||||||
|
PB10.GPIO_Label=DisplayDC
|
||||||
|
PB10.Signal=GPIO_Output
|
||||||
|
PB11.GPIOParameters=GPIO_Label
|
||||||
|
PB11.GPIO_Label=DisplayReset
|
||||||
|
PB11.Signal=GPIO_Output
|
||||||
PB12.GPIOParameters=GPIO_Label
|
PB12.GPIOParameters=GPIO_Label
|
||||||
PB12.GPIO_Label=SPI_CS
|
PB12.GPIO_Label=DisplayCS
|
||||||
PB12.Locked=true
|
|
||||||
PB12.Signal=GPIO_Output
|
PB12.Signal=GPIO_Output
|
||||||
PB13.Mode=Full_Duplex_Master
|
PB13.Mode=Full_Duplex_Master
|
||||||
PB13.Signal=SPI2_SCK
|
PB13.Signal=SPI2_SCK
|
||||||
|
|
88
src/SSD1306_SPI.hpp
Normal file
88
src/SSD1306_SPI.hpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "spi.h"
|
||||||
|
|
||||||
|
#include "oled-driver/SSD1306Interface.hpp"
|
||||||
|
|
||||||
|
constexpr size_t OledWidth = 128;
|
||||||
|
constexpr size_t OledPages = 4;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
constexpr auto DisplaySpiPeripherie = &hspi2;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
extern QueueHandle_t spiMutex;
|
||||||
|
extern void waitForSpiFinished();
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
//! SPI interface to a SSD1305/6 display controller.
|
||||||
|
class SSD1306_SPI : public SSD1306Interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void writeCommand(uint8_t cmd) override
|
||||||
|
{
|
||||||
|
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
setCommandPin();
|
||||||
|
setChipSelect(true);
|
||||||
|
HAL_SPI_Transmit_DMA(DisplaySpiPeripherie, &cmd, 1);
|
||||||
|
waitForSpiFinished();
|
||||||
|
setChipSelect(false);
|
||||||
|
|
||||||
|
xSemaphoreGive(spiMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void writeData(uint8_t data) override
|
||||||
|
{
|
||||||
|
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
setDataPin();
|
||||||
|
setChipSelect(true);
|
||||||
|
HAL_SPI_Transmit_DMA(DisplaySpiPeripherie, &data, 1);
|
||||||
|
waitForSpiFinished();
|
||||||
|
setChipSelect(false);
|
||||||
|
|
||||||
|
xSemaphoreGive(spiMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void writeData(const uint8_t *data, unsigned int length) override
|
||||||
|
{
|
||||||
|
if (length > OledWidth * OledPages)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||||
|
|
||||||
|
setDataPin();
|
||||||
|
setChipSelect(true);
|
||||||
|
HAL_SPI_Transmit_DMA(DisplaySpiPeripherie, const_cast<uint8_t *>(data), length);
|
||||||
|
waitForSpiFinished();
|
||||||
|
setChipSelect(false);
|
||||||
|
|
||||||
|
xSemaphoreGive(spiMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
private:
|
||||||
|
void setDataPin()
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(DisplayDC_GPIO_Port, DisplayDC_Pin, GPIO_PIN_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void setCommandPin()
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(DisplayDC_GPIO_Port, DisplayDC_Pin, GPIO_PIN_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void setChipSelect(bool state)
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(DisplayCS_GPIO_Port, DisplayCS_Pin,
|
||||||
|
state ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,11 +1,21 @@
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "semphr.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "BME68x-Sensor-API/bme68x.h"
|
#include "BME68x-Sensor-API/bme68x.h"
|
||||||
|
#include "oled-driver/Renderer.hpp"
|
||||||
|
|
||||||
|
extern QueueHandle_t spiMutex;
|
||||||
|
extern void waitForSpiFinished();
|
||||||
|
extern Renderer renderer;
|
||||||
|
|
||||||
|
constexpr auto MaximumChars = 22 * 4;
|
||||||
|
char buffer[MaximumChars];
|
||||||
|
|
||||||
constexpr auto SPI_DEVICE = &hspi2;
|
constexpr auto SPI_DEVICE = &hspi2;
|
||||||
uint8_t txBuffer[512];
|
uint8_t txBuffer[512];
|
||||||
|
@ -29,17 +39,15 @@ uint16_t dur_prof[10] = {100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
|
||||||
|
|
||||||
void setChipSelect(bool state)
|
void setChipSelect(bool state)
|
||||||
{
|
{
|
||||||
HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
HAL_GPIO_WritePin(VocSensorCS_GPIO_Port, VocSensorCS_Pin,
|
||||||
}
|
state ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||||
|
|
||||||
void waitForSpiFinished()
|
|
||||||
{
|
|
||||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPI read function map
|
// SPI read function map
|
||||||
BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *)
|
BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *)
|
||||||
{
|
{
|
||||||
|
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||||
|
|
||||||
setChipSelect(true);
|
setChipSelect(true);
|
||||||
HAL_SPI_Transmit_DMA(SPI_DEVICE, ®_addr, 1);
|
HAL_SPI_Transmit_DMA(SPI_DEVICE, ®_addr, 1);
|
||||||
waitForSpiFinished();
|
waitForSpiFinished();
|
||||||
|
@ -47,6 +55,8 @@ BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32
|
||||||
waitForSpiFinished();
|
waitForSpiFinished();
|
||||||
setChipSelect(false);
|
setChipSelect(false);
|
||||||
|
|
||||||
|
xSemaphoreGive(spiMutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,11 +70,15 @@ BME68X_INTF_RET_TYPE bme68x_spi_write(uint8_t reg_addr, const uint8_t *reg_data,
|
||||||
txBuffer[0] = reg_addr;
|
txBuffer[0] = reg_addr;
|
||||||
std::memcpy(&txBuffer[1], reg_data, len);
|
std::memcpy(&txBuffer[1], reg_data, len);
|
||||||
|
|
||||||
|
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||||
|
|
||||||
setChipSelect(true);
|
setChipSelect(true);
|
||||||
HAL_SPI_Transmit_DMA(SPI_DEVICE, const_cast<uint8_t *>(txBuffer), len + 1);
|
HAL_SPI_Transmit_DMA(SPI_DEVICE, const_cast<uint8_t *>(txBuffer), len + 1);
|
||||||
waitForSpiFinished();
|
waitForSpiFinished();
|
||||||
setChipSelect(false);
|
setChipSelect(false);
|
||||||
|
|
||||||
|
xSemaphoreGive(spiMutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,10 +167,33 @@ void bmeRun()
|
||||||
/* Check if res == BME68X_OK, report or handle if otherwise */
|
/* Check if res == BME68X_OK, report or handle if otherwise */
|
||||||
for (uint8_t i = 0; i < n_fields; i++)
|
for (uint8_t i = 0; i < n_fields; i++)
|
||||||
{
|
{
|
||||||
// printf("%u, %u, %d, %u, %u, %u, 0x%x, %d, %d\n", sampleCount,
|
renderer.clearAll();
|
||||||
// time_ms,(bmeData[i].temperature / 100), bmeData[i].pressure, (bmeData[i].humidity /
|
|
||||||
// 1000),bmeData[i].gas_resistance,
|
snprintf(buffer, MaximumChars,
|
||||||
// bmeData[i].status,data[i].gas_index,data[i].meas_index);
|
"%d°C, %luhPa, %lu%%\n%lukOhm, status: 0x%x\ngas_index: %d\nmeas_index: %d",
|
||||||
|
bmeData[i].temperature / 100, //
|
||||||
|
bmeData[i].pressure / 100, //
|
||||||
|
bmeData[i].humidity / 1000, //
|
||||||
|
bmeData[i].gas_resistance / 1000, //
|
||||||
|
bmeData[i].status, //
|
||||||
|
bmeData[i].gas_index, //
|
||||||
|
bmeData[i].meas_index);
|
||||||
|
|
||||||
|
renderer.print({0, 0}, buffer);
|
||||||
|
renderer.render();
|
||||||
|
/*
|
||||||
|
snprintf(buffer, MaximumChars, "sampleCount: %u\n, time_ms: %u\n \
|
||||||
|
temperature; %d°C\n \
|
||||||
|
pressure: %u\n \
|
||||||
|
humidity: %u\n \
|
||||||
|
gas_resistance: %u\n \
|
||||||
|
// status: 0x%x\n \
|
||||||
|
//gas_index: %d\n \
|
||||||
|
meas_index: %d\n",
|
||||||
|
sampleCount, time_ms, (bmeData[i].temperature / 100), bmeData[i].pressure,
|
||||||
|
(bmeData[i].humidity / 1000), bmeData[i].gas_resistance, bmeData[i].status,
|
||||||
|
bmeData[i].gas_index, bmeData[i].meas_index);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,15 @@ extern "C" void prvGetRegistersFromStack(uint32_t *pulFaultStackAddress)
|
||||||
(void)pc;
|
(void)pc;
|
||||||
(void)psr;
|
(void)psr;
|
||||||
|
|
||||||
/* When the following line is hit, the variables contain the register values. */
|
/* When the following line is hit, the variables contain the register values. */
|
||||||
// HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
|
// HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
|
||||||
|
#ifdef DEBUG
|
||||||
|
__asm("bkpt");
|
||||||
|
#else
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void hard_fault_handler(void)
|
extern "C" void hard_fault_handler(void)
|
||||||
|
@ -67,10 +71,13 @@ extern "C" void hard_fault_handler(void)
|
||||||
|
|
||||||
extern "C" void vApplicationMallocFailedHook(void)
|
extern "C" void vApplicationMallocFailedHook(void)
|
||||||
{
|
{
|
||||||
// HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
|
#ifdef DEBUG
|
||||||
|
__asm("bkpt");
|
||||||
|
#else
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName)
|
extern "C" void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName)
|
||||||
|
@ -78,8 +85,11 @@ extern "C" void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCH
|
||||||
(void)pxTask;
|
(void)pxTask;
|
||||||
(void)pcTaskName;
|
(void)pcTaskName;
|
||||||
|
|
||||||
// HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
|
#ifdef DEBUG
|
||||||
|
__asm("bkpt");
|
||||||
|
#else
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
54
src/main.cxx
54
src/main.cxx
|
@ -1,33 +1,79 @@
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
|
#include "SSD1306_SPI.hpp"
|
||||||
|
#include "oled-driver/Display.hpp"
|
||||||
|
#include "oled-driver/Renderer.hpp"
|
||||||
|
|
||||||
extern TaskHandle_t sensorHandle;
|
extern TaskHandle_t sensorHandle;
|
||||||
extern void bmeRun();
|
extern void bmeRun();
|
||||||
|
|
||||||
|
// oled display
|
||||||
|
SSD1306_SPI ssdSpiInterface;
|
||||||
|
Display display(ssdSpiInterface);
|
||||||
|
Renderer renderer(128, 4, display);
|
||||||
|
|
||||||
|
QueueHandle_t spiMutex = xSemaphoreCreateMutex();
|
||||||
|
QueueHandle_t spiBinary = xSemaphoreCreateBinary();
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void notifySensorTask()
|
void initDisplay()
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(DisplayReset_GPIO_Port, DisplayReset_Pin, GPIO_PIN_RESET);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
HAL_GPIO_WritePin(DisplayReset_GPIO_Port, DisplayReset_Pin, GPIO_PIN_SET);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1));
|
||||||
|
|
||||||
|
display.setDisplayState(Display::DisplayState::Off);
|
||||||
|
display.setMultiplexRatio(OledPages * 8 - 1);
|
||||||
|
display.setComPinConfig(false, false);
|
||||||
|
display.setContrastControl(0xFF);
|
||||||
|
display.setDisplayClockDivide(0, 0x8);
|
||||||
|
display.setSegmentRemap(true);
|
||||||
|
display.setComOutputMode(Display::ComMode::Remap);
|
||||||
|
display.setPrechargingPeriod(1, 0xF);
|
||||||
|
display.setChargePump(true);
|
||||||
|
|
||||||
|
display.setMemoryAddressingMode(Display::AddressingMode::Horizontal);
|
||||||
|
display.setPageAddress(0, OledPages - 1); // pages from 0 to 3
|
||||||
|
display.setColumnAddress(0, OledWidth - 1); // columns from 0 to 127
|
||||||
|
|
||||||
|
display.setDisplayState(Display::DisplayState::On);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void notifySpiIsFinished()
|
||||||
{
|
{
|
||||||
auto higherPriorityTaskWoken = pdFALSE;
|
auto higherPriorityTaskWoken = pdFALSE;
|
||||||
vTaskNotifyGiveFromISR(sensorHandle, &higherPriorityTaskWoken);
|
xSemaphoreGiveFromISR(spiBinary, &higherPriorityTaskWoken);
|
||||||
portYIELD_FROM_ISR(higherPriorityTaskWoken);
|
portYIELD_FROM_ISR(higherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void waitForSpiFinished()
|
||||||
|
{
|
||||||
|
xSemaphoreTake(spiBinary, portMAX_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
extern "C" void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *)
|
extern "C" void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *)
|
||||||
{
|
{
|
||||||
notifySensorTask();
|
notifySpiIsFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
extern "C" void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *)
|
extern "C" void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *)
|
||||||
{
|
{
|
||||||
notifySensorTask();
|
notifySpiIsFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
extern "C" void sensorTask(void *)
|
extern "C" void sensorTask(void *)
|
||||||
{
|
{
|
||||||
|
initDisplay();
|
||||||
|
|
||||||
bmeRun();
|
bmeRun();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
1
src/oled-driver
Submodule
1
src/oled-driver
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit a224095e81a4728faa1311f0d717eb54959c6430
|
Loading…
Reference in a new issue