Browse Source

Use eInk

eink
MG-95 11 months ago
parent
commit
20bc94beed
  1. 3
      .vscode/launch.json
  2. 7
      Makefile
  3. 2
      cubemx/Core/Inc/FreeRTOSConfig.h
  4. 4
      cubemx/Core/Inc/main.h
  5. 34
      cubemx/Core/Src/gpio.c
  6. 34
      cubemx/voc-sensor.ioc
  7. 24
      src/SSDSpiInterface.hpp
  8. 2
      src/bmeSPI.cxx
  9. 107
      src/main.cxx
  10. 2
      src/oled-driver

3
.vscode/launch.json vendored

@ -11,8 +11,7 @@
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/debug/voc-sensor.elf",
"servertype": "stutil",
"device": "STM32F103CB",
"runToMain": true
"device": "STM32F103CB"
}
]
}

7
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 \

2
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

4
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

34
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;

34
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

24
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;
}
};

2
src/bmeSPI.cxx

@ -320,6 +320,8 @@ void writeStateToEeprom()
extern "C" void sensorTask(void *)
{
initDisplay();
vTaskSuspend(nullptr);
bmeSensorInit();
readStateFromEeprom();

107
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);
*/
}
//--------------------------------------------------------------------------------------------------

2
src/oled-driver

@ -1 +1 @@
Subproject commit 95f315a0764640e542031c3307565e5b11f902ff
Subproject commit 2be16647b4431014c75ae8d0f46dbfb24772d2ad
Loading…
Cancel
Save