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"]
|
||||
path = src/BME68x-Sensor-API
|
||||
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/portable/GCC/ARM_CM3",
|
||||
"${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": [
|
||||
"STM32L1",
|
||||
"STM32L152RC",
|
||||
"DEBUG",
|
||||
"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",
|
||||
"cppStandard": "c++17"
|
||||
}
|
||||
|
|
15
Makefile
15
Makefile
|
@ -2,17 +2,24 @@ TARGET := voc-sensor
|
|||
RTOS := freertos
|
||||
DEVICE := stm32l152rc
|
||||
|
||||
DEFS := BME68X_DO_NOT_USE_FPU
|
||||
DEFS += BME68X_DO_NOT_USE_FPU
|
||||
DEFS += FW_USE_RTOS
|
||||
|
||||
INCDIRS := \
|
||||
src/BME68x-Sensor-API \
|
||||
src/oled-driver/ \
|
||||
src/oled-driver/include \
|
||||
src \
|
||||
src/BME68x-Sensor-API
|
||||
|
||||
SOURCES := \
|
||||
src/BME68x-Sensor-API/bme68x.c \
|
||||
src/oled-driver/fonts/mono.cxx \
|
||||
src/oled-driver/src/Display.cxx \
|
||||
src/oled-driver/src/Image.cxx \
|
||||
src/oled-driver/src/Renderer.cxx \
|
||||
src/bmeSPI.cxx \
|
||||
src/main.cxx \
|
||||
src/handlers.cxx \
|
||||
src/BME68x-Sensor-API/bme68x.c
|
||||
src/main.cxx \
|
||||
|
||||
# Actual build engine
|
||||
include core/mk/include.mk
|
|
@ -13,7 +13,13 @@ void *operator new(std::size_t size)
|
|||
#if FW_USE_RTOS
|
||||
return pvPortMalloc(size);
|
||||
#else
|
||||
return reinterpret_cast<void *>(0xffffffff);
|
||||
#ifdef DEBUG
|
||||
__asm("bkpt");
|
||||
#else
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -26,11 +32,15 @@ void operator delete(void *ptr)
|
|||
{
|
||||
#if FW_USE_RTOS
|
||||
vPortFree(ptr);
|
||||
#else
|
||||
#ifdef DEBUG
|
||||
__asm("bkpt");
|
||||
#else
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void operator delete(void *ptr, unsigned int)
|
||||
|
@ -110,7 +120,7 @@ extern "C"
|
|||
|
||||
// some functions in cmath follow the compiler flag -fno-math-errno
|
||||
// but not so for std::pow...
|
||||
void __errno() {
|
||||
|
||||
void __errno()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -60,7 +60,7 @@
|
|||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||
#define configMAX_PRIORITIES ( 56 )
|
||||
#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 configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
@ -68,8 +68,10 @@
|
|||
#define configQUEUE_REGISTRY_SIZE 8
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
|
|
|
@ -58,8 +58,14 @@ void Error_Handler(void);
|
|||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define SPI_CS_Pin GPIO_PIN_12
|
||||
#define SPI_CS_GPIO_Port GPIOB
|
||||
#define VocSensorCS_Pin GPIO_PIN_0
|
||||
#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 END Private defines */
|
||||
|
|
|
@ -75,6 +75,7 @@ void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
|||
|
||||
/* Hook prototypes */
|
||||
void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName);
|
||||
void vApplicationMallocFailedHook(void);
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
__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 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
|
||||
* @param None
|
||||
|
|
|
@ -53,7 +53,10 @@ void MX_GPIO_Init(void)
|
|||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
/*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
|
||||
PC1 PC2 PC3 PC4
|
||||
|
@ -73,34 +76,41 @@ void MX_GPIO_Init(void)
|
|||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PA0 PA1 PA2 PA3
|
||||
PA4 PA5 PA6 PA7
|
||||
PA8 PA9 PA10 PA11
|
||||
PA12 PA15 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|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;
|
||||
/*Configure GPIO pin : PtPin */
|
||||
GPIO_InitStruct.Pin = VocSensorCS_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(VocSensorCS_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*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.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PB0 PB1 PB2 PB10
|
||||
PB11 PB3 PB4 PB5
|
||||
PB6 PB7 PB8 PB9 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
|
||||
|GPIO_PIN_11|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5
|
||||
|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
|
||||
/*Configure GPIO pins : PB0 PB1 PB2 PB3
|
||||
PB4 PB5 PB6 PB7
|
||||
PB8 PB9 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|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_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PtPin */
|
||||
GPIO_InitStruct.Pin = SPI_CS_Pin;
|
||||
/*Configure GPIO pins : PBPin PBPin PBPin */
|
||||
GPIO_InitStruct.Pin = DisplayDC_Pin|DisplayReset_Pin|DisplayCS_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
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 */
|
||||
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
|
||||
FREERTOS.FootprintOK=true
|
||||
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.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
|
||||
GPIO.groupedBy=
|
||||
KeepUserPlacement=false
|
||||
|
@ -38,15 +41,18 @@ Mcu.IP5=SYS
|
|||
Mcu.IPNb=6
|
||||
Mcu.Name=STM32L152RCTx
|
||||
Mcu.Package=LQFP64
|
||||
Mcu.Pin0=PB12
|
||||
Mcu.Pin1=PB13
|
||||
Mcu.Pin2=PB14
|
||||
Mcu.Pin3=PB15
|
||||
Mcu.Pin4=PA13
|
||||
Mcu.Pin5=PA14
|
||||
Mcu.Pin6=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.Pin7=VP_SYS_VS_tim2
|
||||
Mcu.PinsNb=8
|
||||
Mcu.Pin0=PA0-WKUP1
|
||||
Mcu.Pin1=PB10
|
||||
Mcu.Pin10=VP_SYS_VS_tim2
|
||||
Mcu.Pin2=PB11
|
||||
Mcu.Pin3=PB12
|
||||
Mcu.Pin4=PB13
|
||||
Mcu.Pin5=PB14
|
||||
Mcu.Pin6=PB15
|
||||
Mcu.Pin7=PA13
|
||||
Mcu.Pin8=PA14
|
||||
Mcu.Pin9=VP_FREERTOS_VS_CMSIS_V2
|
||||
Mcu.PinsNb=11
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32L152RCTx
|
||||
|
@ -71,13 +77,21 @@ NVIC.TIM2_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true
|
|||
NVIC.TimeBase=TIM2_IRQn
|
||||
NVIC.TimeBaseIP=TIM2
|
||||
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.Signal=SYS_JTMS-SWDIO
|
||||
PA14.Mode=Serial_Wire
|
||||
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.GPIO_Label=SPI_CS
|
||||
PB12.Locked=true
|
||||
PB12.GPIO_Label=DisplayCS
|
||||
PB12.Signal=GPIO_Output
|
||||
PB13.Mode=Full_Duplex_Master
|
||||
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 "gpio.h"
|
||||
#include "main.h"
|
||||
#include "semphr.h"
|
||||
#include "spi.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#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;
|
||||
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)
|
||||
{
|
||||
HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, state ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void waitForSpiFinished()
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
HAL_GPIO_WritePin(VocSensorCS_GPIO_Port, VocSensorCS_Pin,
|
||||
state ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
// SPI read function map
|
||||
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);
|
||||
HAL_SPI_Transmit_DMA(SPI_DEVICE, ®_addr, 1);
|
||||
waitForSpiFinished();
|
||||
|
@ -47,6 +55,8 @@ BME68X_INTF_RET_TYPE bme68x_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32
|
|||
waitForSpiFinished();
|
||||
setChipSelect(false);
|
||||
|
||||
xSemaphoreGive(spiMutex);
|
||||
|
||||
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;
|
||||
std::memcpy(&txBuffer[1], reg_data, len);
|
||||
|
||||
xSemaphoreTake(spiMutex, portMAX_DELAY);
|
||||
|
||||
setChipSelect(true);
|
||||
HAL_SPI_Transmit_DMA(SPI_DEVICE, const_cast<uint8_t *>(txBuffer), len + 1);
|
||||
waitForSpiFinished();
|
||||
setChipSelect(false);
|
||||
|
||||
xSemaphoreGive(spiMutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -153,10 +167,33 @@ void bmeRun()
|
|||
/* Check if res == BME68X_OK, report or handle if otherwise */
|
||||
for (uint8_t i = 0; i < n_fields; i++)
|
||||
{
|
||||
// printf("%u, %u, %d, %u, %u, %u, 0x%x, %d, %d\n", sampleCount,
|
||||
// time_ms,(bmeData[i].temperature / 100), bmeData[i].pressure, (bmeData[i].humidity /
|
||||
// 1000),bmeData[i].gas_resistance,
|
||||
// bmeData[i].status,data[i].gas_index,data[i].meas_index);
|
||||
renderer.clearAll();
|
||||
|
||||
snprintf(buffer, MaximumChars,
|
||||
"%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);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,13 @@ extern "C" void prvGetRegistersFromStack(uint32_t *pulFaultStackAddress)
|
|||
|
||||
/* 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);
|
||||
#ifdef DEBUG
|
||||
__asm("bkpt");
|
||||
#else
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void hard_fault_handler(void)
|
||||
|
@ -67,10 +71,13 @@ extern "C" void hard_fault_handler(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)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName)
|
||||
|
@ -78,8 +85,11 @@ extern "C" void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCH
|
|||
(void)pxTask;
|
||||
(void)pcTaskName;
|
||||
|
||||
// HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
|
||||
#ifdef DEBUG
|
||||
__asm("bkpt");
|
||||
#else
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
54
src/main.cxx
54
src/main.cxx
|
@ -1,33 +1,79 @@
|
|||
#include "main.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#include "SSD1306_SPI.hpp"
|
||||
#include "oled-driver/Display.hpp"
|
||||
#include "oled-driver/Renderer.hpp"
|
||||
|
||||
extern TaskHandle_t sensorHandle;
|
||||
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;
|
||||
vTaskNotifyGiveFromISR(sensorHandle, &higherPriorityTaskWoken);
|
||||
xSemaphoreGiveFromISR(spiBinary, &higherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(higherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void waitForSpiFinished()
|
||||
{
|
||||
xSemaphoreTake(spiBinary, portMAX_DELAY);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
extern "C" void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *)
|
||||
{
|
||||
notifySensorTask();
|
||||
notifySpiIsFinished();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
extern "C" void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *)
|
||||
{
|
||||
notifySensorTask();
|
||||
notifySpiIsFinished();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
extern "C" void sensorTask(void *)
|
||||
{
|
||||
initDisplay();
|
||||
|
||||
bmeRun();
|
||||
while (1)
|
||||
{
|
||||
|
|
1
src/oled-driver
Submodule
1
src/oled-driver
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit a224095e81a4728faa1311f0d717eb54959c6430
|
Loading…
Reference in a new issue