diff --git a/.vscode/launch.json b/.vscode/launch.json index 0ceee6a..b9dd9f5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,8 +11,7 @@ "cwd": "${workspaceFolder}", "executable": "${workspaceFolder}/build/debug/voc-sensor.elf", "servertype": "stutil", - "device": "STM32F103CB", - "runToMain": true + "device": "STM32F103CB" } ] } \ No newline at end of file diff --git a/Makefile b/Makefile index 65acd3e..1ae51b7 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,11 @@ src \ SOURCES := \ src/BME68x-Sensor-API/bme68x.c \ -src/oled-driver/fonts/mono.cxx \ -src/oled-driver/src/Display.cxx \ +src/oled-driver/fonts/dfi.cxx \ +src/oled-driver/src/SSD1305.cxx \ +src/oled-driver/src/SSD1306.cxx \ +src/oled-driver/src/SSD1675a.cxx \ +src/oled-driver/src/SSD1680.cxx \ src/oled-driver/src/Image.cxx \ src/oled-driver/src/Renderer.cxx \ src/bmeSPI.cxx \ diff --git a/cubemx/Core/Inc/FreeRTOSConfig.h b/cubemx/Core/Inc/FreeRTOSConfig.h index fbf290f..e4685b2 100644 --- a/cubemx/Core/Inc/FreeRTOSConfig.h +++ b/cubemx/Core/Inc/FreeRTOSConfig.h @@ -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)6000) +#define configTOTAL_HEAP_SIZE ((size_t)20000) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 diff --git a/cubemx/Core/Inc/main.h b/cubemx/Core/Inc/main.h index 296d9ca..721cef8 100644 --- a/cubemx/Core/Inc/main.h +++ b/cubemx/Core/Inc/main.h @@ -60,6 +60,10 @@ void Error_Handler(void); /* Private defines -----------------------------------------------------------*/ #define VocSensorCS_Pin GPIO_PIN_0 #define VocSensorCS_GPIO_Port GPIOA +#define EINK_BUSY_Pin GPIO_PIN_5 +#define EINK_BUSY_GPIO_Port GPIOA +#define EINK_RS_Pin GPIO_PIN_2 +#define EINK_RS_GPIO_Port GPIOB #define DisplayDC_Pin GPIO_PIN_10 #define DisplayDC_GPIO_Port GPIOB #define DisplayReset_Pin GPIO_PIN_11 diff --git a/cubemx/Core/Src/gpio.c b/cubemx/Core/Src/gpio.c index 9640da8..866196b 100644 --- a/cubemx/Core/Src/gpio.c +++ b/cubemx/Core/Src/gpio.c @@ -56,7 +56,7 @@ void MX_GPIO_Init(void) 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); + HAL_GPIO_WritePin(GPIOB, EINK_RS_Pin|DisplayDC_Pin|DisplayReset_Pin|DisplayCS_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : PC13 PC14 PC15 PC0 PC1 PC2 PC3 PC4 @@ -84,29 +84,33 @@ void MX_GPIO_Init(void) HAL_GPIO_Init(VocSensorCS_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : PA1 PA2 PA3 PA4 - PA5 PA6 PA7 PA8 - PA9 PA10 PA11 PA12 - PA15 */ + 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_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 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; + /*Configure GPIO pin : PtPin */ + GPIO_InitStruct.Pin = EINK_BUSY_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(EINK_BUSY_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : PB0 PB1 PB3 PB4 + PB5 PB6 PB7 PB8 + PB9 */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|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 pins : PBPin PBPin PBPin */ - GPIO_InitStruct.Pin = DisplayDC_Pin|DisplayReset_Pin|DisplayCS_Pin; + /*Configure GPIO pins : PBPin PBPin PBPin PBPin */ + GPIO_InitStruct.Pin = EINK_RS_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; diff --git a/cubemx/voc-sensor.ioc b/cubemx/voc-sensor.ioc index d1c2a82..c928f34 100644 --- a/cubemx/voc-sensor.ioc +++ b/cubemx/voc-sensor.ioc @@ -26,7 +26,7 @@ FREERTOS.IPParameters=Tasks01,configCHECK_FOR_STACK_OVERFLOW,FootprintOK,HEAP_NU 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.configTOTAL_HEAP_SIZE=20000 FREERTOS.configUSE_MALLOC_FAILED_HOOK=1 File.Version=6 GPIO.groupedBy= @@ -42,17 +42,19 @@ Mcu.IPNb=6 Mcu.Name=STM32L152RCTx Mcu.Package=LQFP64 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.Pin1=PA5 +Mcu.Pin10=PA14 +Mcu.Pin11=VP_FREERTOS_VS_CMSIS_V2 +Mcu.Pin12=VP_SYS_VS_tim2 +Mcu.Pin2=PB2 +Mcu.Pin3=PB10 +Mcu.Pin4=PB11 +Mcu.Pin5=PB12 +Mcu.Pin6=PB13 +Mcu.Pin7=PB14 +Mcu.Pin8=PB15 +Mcu.Pin9=PA13 +Mcu.PinsNb=13 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32L152RCTx @@ -84,6 +86,10 @@ PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire PA14.Signal=SYS_JTCK-SWCLK +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=EINK_BUSY +PA5.Locked=true +PA5.Signal=GPIO_Input PB10.GPIOParameters=GPIO_Label PB10.GPIO_Label=DisplayDC PB10.Signal=GPIO_Output @@ -105,6 +111,10 @@ PB15.GPIOParameters=GPIO_Speed PB15.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM PB15.Mode=Full_Duplex_Master PB15.Signal=SPI2_MOSI +PB2.GPIOParameters=GPIO_Label +PB2.GPIO_Label=EINK_RS +PB2.Locked=true +PB2.Signal=GPIO_Output PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true ProjectManager.BackupPrevious=false diff --git a/src/SSDSpiInterface.hpp b/src/SSDSpiInterface.hpp index a0c6218..45ccdd6 100644 --- a/src/SSDSpiInterface.hpp +++ b/src/SSDSpiInterface.hpp @@ -6,9 +6,6 @@ #include "oled-driver/SSDInterface.hpp" -constexpr size_t OledWidth = 128; -constexpr size_t OledPages = 4; - constexpr auto UsedSpiPeripherie = &hspi2; extern QueueHandle_t spiMutex; @@ -19,12 +16,22 @@ extern void waitForSpiFinished(); class SSDSpiInterface : public SSDInterface { public: + void waitUntilIdle() override + { + while (!readBusyPin()) + { + vTaskDelay(pdMS_TO_TICKS(10)); + } + } + + //-------------------------------------------------------------------------------------------------- void writeCommand(uint8_t cmd) override { xSemaphoreTake(spiMutex, portMAX_DELAY); setCommandPin(); setChipSelect(true); + // vTaskDelay(1); HAL_SPI_Transmit_DMA(UsedSpiPeripherie, &cmd, 1); waitForSpiFinished(); setChipSelect(false); @@ -39,6 +46,7 @@ public: setDataPin(); setChipSelect(true); + // vTaskDelay(1); HAL_SPI_Transmit_DMA(UsedSpiPeripherie, &data, 1); waitForSpiFinished(); setChipSelect(false); @@ -49,8 +57,8 @@ public: //-------------------------------------------------------------------------------------------------- void writeData(const uint8_t *data, unsigned int length) override { - if (length > OledWidth * OledPages) - return; + // if (length > OledWidth * OledPages) + // return; xSemaphoreTake(spiMutex, portMAX_DELAY); @@ -82,4 +90,10 @@ private: HAL_GPIO_WritePin(DisplayCS_GPIO_Port, DisplayCS_Pin, state ? GPIO_PIN_RESET : GPIO_PIN_SET); } + + //-------------------------------------------------------------------------------------------------- + bool readBusyPin() + { + return HAL_GPIO_ReadPin(EINK_BUSY_GPIO_Port, EINK_BUSY_Pin) == GPIO_PIN_SET; + } }; diff --git a/src/bmeSPI.cxx b/src/bmeSPI.cxx index dd7b28e..b6bacd8 100644 --- a/src/bmeSPI.cxx +++ b/src/bmeSPI.cxx @@ -320,6 +320,8 @@ void writeStateToEeprom() extern "C" void sensorTask(void *) { initDisplay(); + vTaskSuspend(nullptr); + bmeSensorInit(); readStateFromEeprom(); diff --git a/src/main.cxx b/src/main.cxx index c56ec2e..731c3e0 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -5,13 +5,19 @@ // #include "BSEC/bsec_integration.h" #include "SSDSpiInterface.hpp" -#include "oled-driver/Renderer.hpp" +#include "oled-driver/DualRenderer.hpp" #include "oled-driver/SSD1306.hpp" +#include "oled-driver/fonts/dfi.hpp" + +#include "oled-driver/SSD1680.hpp" // oled display SSDSpiInterface ssdSpiInterface; + +SSD1680 test(ssdSpiInterface); + SSD1306 display(ssdSpiInterface); -Renderer renderer(OledWidth, OledPages, display); +DualRenderer renderer(296, 152, test); QueueHandle_t spiMutex = xSemaphoreCreateMutex(); QueueHandle_t spiBinary = xSemaphoreCreateBinary(); @@ -20,10 +26,100 @@ QueueHandle_t spiBinary = xSemaphoreCreateBinary(); 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)); + HAL_GPIO_WritePin(EINK_RS_GPIO_Port, EINK_RS_Pin, GPIO_PIN_RESET); + vTaskDelay(pdMS_TO_TICKS(100)); + // HAL_GPIO_WritePin(DisplayReset_GPIO_Port, DisplayReset_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(EINK_RS_GPIO_Port, EINK_RS_Pin, GPIO_PIN_SET); + vTaskDelay(pdMS_TO_TICKS(100)); + + test.selectLut(SSD1680::LutSelection::Red); + test.init(); + renderer.black.setFont(fontDfi); + + renderer.black.clearAll(); + renderer.red.clearAll(); + + if (true) + { + test.selectLut(SSD1680::LutSelection::None); + test.init(); + renderer.dualRender(); + test.deepSleep(1); + return; + } + + constexpr auto aL = Renderer::Alignment::Left; + constexpr auto aC = Renderer::Alignment::Center; + constexpr auto aR = Renderer::Alignment::Right; + + size_t page = 0; + size_t maxNumberPixels = 0; + size_t result = 0; + + bool scroll = false; + + if (!scroll) + { + renderer.black.print({0, page}, "9", aL, 2); + renderer.black.print({20, page}, "Neustädter See", aL, 2); + renderer.black.print({296, page}, "jetzt", aR, 2); + page += 2; + } + + renderer.black.print({0, page}, "1", aL, 2); + renderer.black.print({20, page}, "Sudenburg", aL, 2); + renderer.black.print({296, page}, "1min", aR, 2); + page += 2; + + renderer.black.print({0, page}, "10", aL, 2); + renderer.black.print({20, page}, "Barleber See", aL, 2); + renderer.black.print({296, page}, "2min", aR, 2); + page += 2; + + renderer.black.print({0, page}, "1", aL, 2); + renderer.black.print({20, page}, "Kannenstieg", aL, 2); + result = renderer.black.print({296, page}, "5min", aR, 2); + maxNumberPixels = std::max(maxNumberPixels, result); + page += 2; + + renderer.black.print({0, page}, "9", aL, 2); + renderer.black.print({20, page}, "Reform", aL, 2); + result = renderer.black.print({296, page}, "55min", aR, 2); + maxNumberPixels = std::max(maxNumberPixels, result); + page += 2; + + renderer.black.print({0, page}, "10", aL, 2); + renderer.black.print({20, page}, "Rothensee", aL, 2); + result = renderer.black.print({296, page}, "107min", aR, 2); + maxNumberPixels = std::max(maxNumberPixels, result); + page += 2; + + renderer.red.print({0, page}, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", aL, 2); + + page = scroll ? 2 : 3; + + const auto PositionX = 296 - maxNumberPixels - 4; + result = renderer.black.print({PositionX, page}, ")", aR, 2); + auto result2 = renderer.red.print({PositionX - result, page}, "-8", aR, 2); + renderer.black.print({PositionX - result - result2, page}, "(", aR, 2); + page += 2; + + result = renderer.black.print({PositionX, page}, ")", aR, 2); + result2 = renderer.red.print({PositionX - result, page}, "+2", aR, 2); + renderer.black.print({PositionX - result - result2, page}, "(", aR, 2); + page += 2; + + result = renderer.black.print({PositionX, page}, ")", aR, 2); + result2 = renderer.red.print({PositionX - result, page}, "+22", aR, 2); + renderer.black.print({PositionX - result - result2, page}, "(", aR, 2); + page += 2; + + renderer.dualRender(); + + test.deepSleep(1); + + /* display.setDisplayState(SSD1306::DisplayState::Off); display.setMultiplexRatio(OledPages * 8 - 1); display.setComPinConfig(false, false); @@ -39,6 +135,7 @@ void initDisplay() display.setColumnAddress(0, OledWidth - 1); // columns from 0 to 127 display.setDisplayState(SSD1306::DisplayState::On); + */ } //-------------------------------------------------------------------------------------------------- diff --git a/src/oled-driver b/src/oled-driver index 95f315a..2be1664 160000 --- a/src/oled-driver +++ b/src/oled-driver @@ -1 +1 @@ -Subproject commit 95f315a0764640e542031c3307565e5b11f902ff +Subproject commit 2be16647b4431014c75ae8d0f46dbfb24772d2ad