-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
733 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,15 @@ | ||
# HX1230Menu | ||
Menu system for HX1230 96x68 LCD screen in PlatformIO STM32 environment. | ||
|
||
# Menu items | ||
- Titles | ||
- Submenus (menu tree) | ||
- Toggle switches (binary variable, value is shown by graphics) | ||
- Push buttons (function call) | ||
- Sliders (int16 value with limits and step size) | ||
- Custom mode (execution loop activated through menu) | ||
|
||
![](media/menu1.jpg) | ||
![](media/menu2.jpg) | ||
![](media/menu3.jpg) | ||
![](media/menu4.jpg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "HX1230Menu", | ||
"keywords": "stm32, stm32cube, hx1230, menu system", | ||
"description": "Menu system for HX1230 96x68 LCD screen in PlatformIO STM32 environment.", | ||
"license": "BSD-3-Clause", | ||
"repository": | ||
{ | ||
"type": "git", | ||
"url": "https://github.com/RockerM4NHUN/HX1230Menu.git" | ||
}, | ||
"authors": | ||
{ | ||
"name": "ZOMBORI Dániel", | ||
"email": "[email protected]", | ||
"url": "https://github.com/RockerM4NHUN", | ||
"maintainer": true | ||
}, | ||
"version": "0.1.0", | ||
"frameworks": "stm32cube", | ||
"platforms": "stm32, ststm32" | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
|
||
#include "font.h" | ||
|
||
const uint8_t charset[] = { | ||
0x00,0x00,0x00, /*" ",0*/ | ||
0x00,0x5e,0x00, /*"!",1*/ | ||
0x00,0x06,0x00,0x06, /*""",2*/ | ||
0x14,0x7E,0x14,0x7E,0x14, /*"#",3*/ | ||
0x24,0x4A,0xFF,0x52,0x24, /*"$",4*/ | ||
0x4E,0x2A,0x7E,0x54,0x72, /*"%",5*/ | ||
0x34,0x4A,0x5A,0x24,0x50, /*"&",6*/ | ||
0x00,0x00,0x06,0x00, /*"'",7*/ | ||
0x3C,0x42,0x81, /*"(",8*/ | ||
0x81,0x42,0x3C, /*")",9*/ | ||
0x2A,0x1C,0x08,0x1C,0x2A, /*"*",10*/ | ||
0x08,0x08,0x3E,0x08,0x08, /*"+",11*/ | ||
0xC0,0x40,0x00, /*",",12*/ | ||
0x08,0x08,0x08,0x08, /*"-",13*/ | ||
0x00,0x40,0x00, /*".",14*/ | ||
0x40,0x30,0x0C,0x02, /*"/",15*/ | ||
0x3C,0x4A,0x52,0x3C, /*"0",16*/ | ||
0x44,0x7E,0x40, /*"1",17*/ | ||
0x64,0x52,0x4A,0x44, /*"2",18*/ | ||
0x24,0x42,0x4A,0x3C, /*"3",19*/ | ||
0x30,0x28,0x24,0x7E, /*"4",20*/ | ||
0x2E,0x4A,0x4A,0x32, /*"5",21*/ | ||
0x3C,0x52,0x52,0x24, /*"6",22*/ | ||
0x02,0x72,0x0A,0x06, /*"7",23*/ | ||
0x34,0x4A,0x4A,0x34, /*"8",24*/ | ||
0x24,0x4A,0x4A,0x3C, /*"9",25*/ | ||
0x00,0x24,0x00, /*":",26*/ | ||
0xC4,0x40,0x00, /*";",27*/ | ||
0x08,0x14,0x14,0x22, /*"<",28*/ | ||
0x14,0x14,0x14,0x14, /*"=",29*/ | ||
0x22,0x14,0x14,0x08, /*">",30*/ | ||
0x04,0x52,0x0A,0x04, /*"?",31*/ | ||
0x3C,0x42,0x5A,0x56,0x5C, /*"@",32*/ | ||
0x7C,0x12,0x12,0x7C, /*"A",33*/ | ||
0x7E,0x4A,0x4A,0x34, /*"B",34*/ | ||
0x3C,0x42,0x42,0x24, /*"C",35*/ | ||
0x7E,0x42,0x42,0x3C, /*"D",36*/ | ||
0x7E,0x4A,0x4A,0x42, /*"E",37*/ | ||
0x7E,0x0A,0x0A,0x02, /*"F",38*/ | ||
0x3C,0x42,0x52,0x34, /*"G",39*/ | ||
0x7E,0x08,0x08,0x7E, /*"H",40*/ | ||
0x42,0x7E,0x42,0x00, /*"I",41*/ | ||
0x20,0x40,0x40,0x3E, /*"J",42*/ | ||
0x7E,0x08,0x14,0x62, /*"K",43*/ | ||
0x7E,0x40,0x40,0x40, /*"L",44*/ | ||
0x7E,0x04,0x08,0x04,0x7E, /*"M",45*/ | ||
0x7E,0x08,0x10,0x7E, /*"N",46*/ | ||
0x3C,0x42,0x42,0x3C, /*"O",47*/ | ||
0x7E,0x12,0x12,0x0C, /*"P",48*/ | ||
0x3C,0x42,0x62,0xBC, /*"Q",49*/ | ||
0x7E,0x12,0x12,0x6C, /*"R",50*/ | ||
0x24,0x4A,0x52,0x24, /*"S",51*/ | ||
0x02,0x02,0x7E,0x02,0x02, /*"T",52*/ | ||
0x3E,0x40,0x40,0x3E, /*"U",53*/ | ||
0x1E,0x20,0x40,0x20,0x1E, /*"V",54*/ | ||
0x3E,0x40,0x38,0x40,0x3E, /*"W",55*/ | ||
0x66,0x18,0x18,0x66, /*"X",56*/ | ||
0x06,0x08,0x70,0x08,0x06, /*"Y",57*/ | ||
0x62,0x52,0x4A,0x46, /*"Z",58*/ | ||
|
||
0x00 | ||
}; | ||
|
||
const int8_t offsets[] = { | ||
0, 0, | ||
1,-1, | ||
2,-2, | ||
4,-1, | ||
5, 0, | ||
6, 1, | ||
7, 2, | ||
9, 1, | ||
10, 0, | ||
11, 1, | ||
12, 2, | ||
13, 1, | ||
15, 0, | ||
18,-1, | ||
27,-2, | ||
28,-3, | ||
33,-2, | ||
46,-1, | ||
53, 0, | ||
55, 1, | ||
56, 2, | ||
58, 3, | ||
127,-128 | ||
}; | ||
|
||
int8_t getOffset(uint8_t code){ | ||
uint8_t i = 0; | ||
while(offsets[i] <= code){ | ||
i += 2; | ||
} | ||
i -= 2; | ||
return offsets[i+1]; | ||
} | ||
|
||
/* if data is NULL only the length will be returned */ | ||
/* otherwise data is handled as a pointers mem address*/ | ||
/* returns the number of bytes length */ | ||
uint8_t getCharData(char ascii, const uint8_t** data){ | ||
if (ascii >= 'a' && ascii <= 'z'){ | ||
ascii = ascii - 'a' + 'A'; | ||
} else if (ascii > 'Z' || ascii < ' '){ | ||
ascii = '?'; | ||
} | ||
uint8_t code = ascii-' '; // normalize to charset code | ||
uint8_t offset = getOffset(code) + code * 4; // get offset in charset | ||
uint8_t length = getOffset(code+1) + (code + 1) * 4 - offset; | ||
if (data != 0){ | ||
*data = charset+offset; | ||
} | ||
return length; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
|
||
#ifndef _FONT_H_ | ||
#define _FONT_H_ | ||
|
||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
uint8_t getCharData(char, const uint8_t**); | ||
extern const uint8_t charset[]; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* _FONT_H_ */ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
#include "hx1230.h" | ||
#include "font.h" | ||
|
||
#define SPI_TIMEOUT 10 | ||
|
||
static SPI_HandleTypeDef* _hspi; | ||
|
||
static void WriteSingle(uint16_t data){ | ||
HAL_GPIO_WritePin(HX1230_nCE_GPIO_Port,HX1230_nCE_Pin,GPIO_PIN_RESET); | ||
|
||
HAL_SPI_Transmit(_hspi,(uint8_t*)&data,1,SPI_TIMEOUT); | ||
|
||
HAL_GPIO_WritePin(HX1230_nCE_GPIO_Port,HX1230_nCE_Pin,GPIO_PIN_SET); | ||
} | ||
|
||
void HX1230_Stream(const uint16_t* data, uint16_t length){ | ||
HAL_GPIO_WritePin(HX1230_nCE_GPIO_Port,HX1230_nCE_Pin,GPIO_PIN_RESET); | ||
|
||
// WARNING: why is length staying the same? Maybe SPI implementation works like this. | ||
// -> it is deliberatly converted "badly" | ||
HAL_SPI_Transmit(_hspi,(uint8_t*)data,length,SPI_TIMEOUT); | ||
|
||
HAL_GPIO_WritePin(HX1230_nCE_GPIO_Port,HX1230_nCE_Pin,GPIO_PIN_SET); | ||
} | ||
|
||
|
||
void HX1230_Init(SPI_HandleTypeDef * hspi){ | ||
_hspi = hspi; | ||
|
||
HAL_GPIO_WritePin(HX1230_nRST_GPIO_Port,HX1230_nRST_Pin,GPIO_PIN_RESET); | ||
HAL_GPIO_WritePin(HX1230_nCE_GPIO_Port,HX1230_nCE_Pin,GPIO_PIN_RESET); | ||
|
||
HAL_Delay(50); | ||
|
||
HAL_GPIO_WritePin(HX1230_nRST_GPIO_Port,HX1230_nRST_Pin,GPIO_PIN_SET); | ||
|
||
HAL_Delay(1); | ||
|
||
HAL_GPIO_WritePin(HX1230_nCE_GPIO_Port,HX1230_nCE_Pin,GPIO_PIN_SET); | ||
|
||
WriteSingle(HX1230_TURN_ON); | ||
WriteSingle(HX1230_INVERT_OFF); | ||
WriteSingle(HX1230_PIXEL_TEST_OFF); | ||
WriteSingle(HX1230_DISPLAY_ON); | ||
HX1230_Scan_Offset(0); | ||
HX1230_SetXY(0,0); | ||
} | ||
|
||
void HX1230_Command(uint8_t cmd){ | ||
WriteSingle(cmd); | ||
} | ||
|
||
void HX1230_Clear(){ | ||
uint16_t words[8] = {0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100}; | ||
HX1230_SetXY(0,0); | ||
for (int i = 0; i < HX1230_ROWS * 12; i++){ | ||
HX1230_Stream(words, 8); | ||
} | ||
HX1230_SetXY(0,0); | ||
} | ||
|
||
void HX1230_PixelTest(){ | ||
WriteSingle(HX1230_PIXEL_TEST_ON); | ||
HAL_Delay(1000); | ||
WriteSingle(HX1230_PIXEL_TEST_OFF); | ||
} | ||
|
||
void HX1230_SetXY(uint8_t x, uint8_t y){ | ||
|
||
if (x > 95){ | ||
x -= 96; | ||
} | ||
|
||
WriteSingle(0xB0 | (y & 0x07)); | ||
WriteSingle(0x10 | ((x >> 4) & 0x07)); | ||
WriteSingle(x & 0x0F); | ||
} | ||
|
||
void HX1230_SetX(uint8_t x){ | ||
|
||
if (x > 95){ | ||
x -= 96; | ||
} | ||
|
||
WriteSingle(0x10 | ((x >> 4) & 0x07)); | ||
WriteSingle(x & 0x0F); | ||
} | ||
|
||
void HX1230_SetY(uint8_t y){ | ||
WriteSingle(0xB0 | (y & 0x07)); | ||
} | ||
|
||
void HX1230_Scan_Offset(uint8_t y){ | ||
WriteSingle(0x40 | (y & 0x3F)); | ||
} | ||
|
||
void HX1230_Draw(const uint8_t* data, uint16_t length){ | ||
uint16_t words[length]; | ||
for(int i = 0; i < length; i++){ | ||
words[i] = 0x100 | data[i]; | ||
} | ||
|
||
HX1230_Stream(words, length); | ||
} | ||
|
||
/* Implementation only handles breaking between characters. */ | ||
uint16_t HX1230_Print(uint8_t x, uint8_t y, const char* text, uint16_t length){ | ||
HX1230_SetXY(x,y); | ||
const uint8_t* pdata; | ||
|
||
uint8_t row = y; | ||
uint8_t col = x; | ||
uint16_t slices = 0; | ||
|
||
for(uint16_t chari = 0; chari < length; chari++){ | ||
uint8_t width = getCharData(text[chari],&pdata); | ||
if (col + width > HX1230_COLS){ | ||
// Not fits in row | ||
row++; | ||
col = 0; | ||
|
||
if (row > HX1230_ROWS) return slices; | ||
|
||
HX1230_SetXY(0,row); | ||
slices = row * HX1230_COLS; | ||
|
||
// If last character is space don't display it | ||
if (text[chari] == ' ') continue; | ||
} | ||
|
||
slices += width; | ||
col += width; | ||
HX1230_Draw(pdata,width); | ||
|
||
// Spacer between characters | ||
if (col + 1 <= HX1230_COLS){ | ||
HX1230_Draw((uint8_t*)"",1); | ||
slices++; | ||
col++; | ||
} | ||
} | ||
|
||
return slices; | ||
} | ||
|
||
void HX1230_PrintField(uint8_t line, uint8_t colStart, uint8_t colEnd, const char* text, uint16_t length){ | ||
HX1230_SetXY(colStart,line); | ||
const uint8_t* pdata; | ||
|
||
uint8_t col = colStart; | ||
|
||
for(uint16_t chari = 0; chari < length; chari++){ | ||
uint8_t width = getCharData(text[chari],&pdata); | ||
if (col + width > colEnd){ | ||
// Not fits in row | ||
width = colEnd - col; | ||
HX1230_Draw(pdata,width); | ||
return; | ||
} | ||
|
||
col += width; | ||
HX1230_Draw(pdata,width); | ||
|
||
// Spacer between characters | ||
if (col + 1 <= colEnd){ | ||
col++; | ||
HX1230_Draw((uint8_t*)"",1); | ||
} | ||
} | ||
|
||
while(col++ < colEnd){ | ||
HX1230_Draw((uint8_t*)"",1); | ||
} | ||
} |
Oops, something went wrong.