299 lines
9.8 KiB
C++
299 lines
9.8 KiB
C++
#include "../2025_include_user/OledMenuDriver.h"
|
||
|
||
#define OLED_I2C_ADDR (0x3C) // 7-bit地址,不需要 <<1
|
||
#define SYSTEM_CORE_CLOCK_HZ 80000000U
|
||
|
||
u8g2_t MenuDriver::u8g2 = {};
|
||
|
||
uint8_t u8x8_gpio_and_delay_mspm0(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
|
||
switch (msg) {
|
||
case U8X8_MSG_GPIO_AND_DELAY_INIT:
|
||
delay_cycles(32000); //1ms
|
||
break;
|
||
case U8X8_MSG_DELAY_MILLI:
|
||
for (uint8_t i = 0; i < arg_int; i++) {
|
||
delay_cycles(32000);
|
||
}
|
||
|
||
break;
|
||
case U8X8_MSG_GPIO_DC:
|
||
break;
|
||
case U8X8_MSG_GPIO_RESET: /**
|
||
if (arg_int)
|
||
{
|
||
DL_GPIO_setPins(GPIO_OLED_PORT, GPIO_OLED_RST_OLED_PIN);
|
||
}
|
||
else
|
||
{
|
||
DL_GPIO_clearPins(GPIO_OLED_PORT, GPIO_OLED_RST_OLED_PIN);
|
||
}**/
|
||
break;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
|
||
uint8_t u8x8_byte_mspm0_hw_i2c(u8x8_t *u8g2, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
|
||
/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
|
||
/* add extra byte for the i2c address */
|
||
static uint8_t buffer[34];
|
||
static volatile uint8_t buf_idx, g_u8TxCount;
|
||
uint8_t *data;
|
||
switch (msg) {
|
||
case U8X8_MSG_BYTE_SEND:
|
||
data = (uint8_t *) arg_ptr;
|
||
while (arg_int > 0) {
|
||
buffer[buf_idx++] = *data;
|
||
data++;
|
||
arg_int--;
|
||
}
|
||
break;
|
||
|
||
case U8X8_MSG_BYTE_INIT:
|
||
/* add your custom code to init i2c subsystem */
|
||
|
||
break;
|
||
case U8X8_MSG_BYTE_SET_DC:
|
||
/* ignored for i2c */
|
||
break;
|
||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||
buf_idx = 0;
|
||
break;
|
||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||
/*
|
||
* Fill FIFO with data.
|
||
*/
|
||
g_u8TxCount = DL_I2C_fillControllerTXFIFO(I2C_0_INST, &buffer[0], buf_idx);
|
||
|
||
/* Wait for I2C to be Idle */
|
||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||
|
||
/* Send the packet to the controller.
|
||
* This function will send Start + Stop automatically.
|
||
*/
|
||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_I2C_ADDR,
|
||
DL_I2C_CONTROLLER_DIRECTION_TX, buf_idx);
|
||
|
||
while (g_u8TxCount < buf_idx) {
|
||
while (DL_I2C_isControllerTXFIFOFull(I2C_0_INST) == true);
|
||
DL_I2C_transmitControllerData(I2C_0_INST, buffer[g_u8TxCount]);
|
||
g_u8TxCount++;
|
||
}
|
||
|
||
/* Poll until the Controller writes all bytes */
|
||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||
|
||
/* Trap if there was an error */
|
||
if (DL_I2C_getControllerStatus(I2C_0_INST) &
|
||
DL_I2C_CONTROLLER_STATUS_ERROR) {
|
||
while (1);
|
||
}
|
||
|
||
/* Wait for I2C to be Idle */
|
||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||
|
||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||
|
||
break;
|
||
|
||
default:
|
||
return 0;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
void MenuDriver::oled_init() {
|
||
u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_mspm0_hw_i2c, u8x8_gpio_and_delay_mspm0);
|
||
u8g2_InitDisplay(&u8g2);
|
||
u8g2_SetPowerSave(&u8g2, 0);
|
||
u8g2_ClearBuffer(&u8g2);
|
||
}
|
||
|
||
void MenuDriver::ssd1306_transmit_cmd(uint8_t cmd) {
|
||
uint8_t temp[2] = {0x00, cmd};
|
||
|
||
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
|
||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||
|
||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||
|
||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||
}
|
||
|
||
void MenuDriver::ssd1306_transmit_data(uint8_t data, const uint8_t mode) {
|
||
if (!mode)
|
||
data = ~data;
|
||
uint8_t temp[2] = {0x40, data};
|
||
|
||
DL_I2C_fillControllerTXFIFO(I2C_0_INST, temp, 2);
|
||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||
|
||
DL_I2C_startControllerTransfer(I2C_0_INST, OLED_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 2);
|
||
while (DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
||
while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE));
|
||
|
||
DL_I2C_flushControllerTXFIFO(I2C_0_INST);
|
||
}
|
||
|
||
void MenuDriver::ssd1306_set_cursor(unsigned char _x, unsigned char _y) {
|
||
ssd1306_transmit_cmd(0xB0 | _y);
|
||
ssd1306_transmit_cmd(0x10 | ((_x & 0xF0) >> 4));
|
||
ssd1306_transmit_cmd(0x00 | (_x & 0x0F));
|
||
}
|
||
|
||
void MenuDriver::ssd1306_fill(unsigned char _data) {
|
||
for (uint8_t page = 0; page < 8; ++page) {
|
||
ssd1306_set_cursor(0, page);
|
||
for (uint8_t col = 0; col < 128; ++col) {
|
||
ssd1306_transmit_data(_data, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
void MenuDriver::screenOn() {
|
||
ssd1306_transmit_cmd(0X8D);
|
||
ssd1306_transmit_cmd(0X14);
|
||
ssd1306_transmit_cmd(0XAF);
|
||
}
|
||
|
||
void MenuDriver::screenOff() {
|
||
ssd1306_transmit_cmd(0X8D);
|
||
ssd1306_transmit_cmd(0X10);
|
||
ssd1306_transmit_cmd(0XAE);
|
||
}
|
||
|
||
void *MenuDriver::getCanvasBuffer() {
|
||
return u8g2_GetBufferPtr(&u8g2);
|
||
}
|
||
|
||
uint8_t MenuDriver::getBufferTileHeight() {
|
||
return u8g2_GetBufferTileHeight(&u8g2);
|
||
}
|
||
|
||
uint8_t MenuDriver::getBufferTileWidth() {
|
||
return u8g2_GetBufferTileWidth(&u8g2);
|
||
}
|
||
|
||
void MenuDriver::canvasUpdate() {
|
||
u8g2_SendBuffer(&u8g2);
|
||
}
|
||
|
||
void MenuDriver::canvasClear() {
|
||
u8g2_ClearBuffer(&u8g2);
|
||
}
|
||
|
||
void MenuDriver::setFont(const uint8_t *_font) {
|
||
u8g2_SetFontMode(&u8g2, 1);
|
||
u8g2_SetFontDirection(&u8g2, 0);
|
||
u8g2_SetFont(&u8g2, _font);
|
||
}
|
||
|
||
void MenuDriver::setFont(const uint8_t *_font, uint8_t _font_mode, uint8_t _font_direction) {
|
||
u8g2_SetFontMode(&u8g2, _font_mode);
|
||
u8g2_SetFontDirection(&u8g2, _font_direction);
|
||
u8g2_SetFont(&u8g2, _font);
|
||
}
|
||
|
||
uint8_t MenuDriver::getFontWidth(const char *_text) {
|
||
return u8g2_GetUTF8Width(&u8g2, _text);
|
||
}
|
||
|
||
uint8_t MenuDriver::getFontHeight() {
|
||
return u8g2_GetMaxCharHeight(&u8g2);
|
||
}
|
||
|
||
void MenuDriver::setDrawType(uint8_t _type) {
|
||
u8g2_SetDrawColor(&u8g2, _type);
|
||
}
|
||
|
||
void MenuDriver::drawPixel(float _x, float _y) {
|
||
u8g2_DrawPixel(&u8g2, (int16_t) round(_x), (int16_t) round(_y));
|
||
}
|
||
|
||
void MenuDriver::draw(float _x, float _y, const char *_text) {
|
||
setFont(u8g2_font_wqy14_t_chinese3);
|
||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||
}
|
||
|
||
void MenuDriver::draw(float _x, float _y, const char *_text, uint8_t _font_mode, uint8_t _font_direction) {
|
||
setFont(u8g2_font_wqy14_t_chinese3, _font_mode, _font_direction);
|
||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||
}
|
||
|
||
void MenuDriver::draw(float _x, float _y, const char *_text, const uint8_t *_font, uint8_t _font_mode,
|
||
uint8_t _font_direction) {
|
||
setFont(_font, _font_mode, _font_direction);
|
||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||
}
|
||
|
||
void MenuDriver::drawEnglish(float _x, float _y, const char *_text) {
|
||
setFont(u8g2_font_wqy14_t_chinese3);
|
||
u8g2_DrawStr(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||
}
|
||
|
||
void MenuDriver::drawChinese(float _x, float _y, const char *_text) {
|
||
setFont(u8g2_font_wqy14_t_chinese3);
|
||
u8g2_DrawUTF8(&u8g2, (int16_t) round(_x), (int16_t) round(_y), _text);
|
||
}
|
||
|
||
void MenuDriver::drawVDottedLine(float _x, float _y, float _h) {
|
||
for (unsigned char i = 0; i < (unsigned char) round(_h); i++) {
|
||
if (i % 8 == 0 || (i - 1) % 8 == 0 || (i - 2) % 8 == 0)
|
||
continue;
|
||
u8g2_DrawPixel(&u8g2, (int16_t) round(_x), (int16_t) round(_y) + i);
|
||
}
|
||
}
|
||
|
||
void MenuDriver::drawHDottedLine(float _x, float _y, float _l) {
|
||
for (unsigned char i = 0; i < _l; i++) {
|
||
if (i % 8 == 0 || (i - 1) % 8 == 0 || (i - 2) % 8 == 0)
|
||
continue;
|
||
u8g2_DrawPixel(&u8g2, (int16_t) round(_x) + i, (int16_t) round(_y));
|
||
}
|
||
}
|
||
|
||
void MenuDriver::drawVLine(float _x, float _y, float _h) {
|
||
u8g2_DrawVLine(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_h));
|
||
}
|
||
|
||
void MenuDriver::drawHLine(float _x, float _y, float _l) {
|
||
u8g2_DrawHLine(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_l));
|
||
}
|
||
|
||
void MenuDriver::drawBMP(float _x, float _y, float _w, float _h, const uint8_t *_bitMap) {
|
||
u8g2_DrawXBMP(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h), _bitMap);
|
||
}
|
||
|
||
void MenuDriver::drawBox(float _x, float _y, float _w, float _h) {
|
||
u8g2_DrawBox(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h));
|
||
}
|
||
|
||
void MenuDriver::drawRBox(float _x, float _y, float _w, float _h, float _r) {
|
||
u8g2_DrawRBox(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h),
|
||
(int16_t) round(_r));
|
||
}
|
||
|
||
void MenuDriver::drawFrame(float _x, float _y, float _w, float _h) {
|
||
u8g2_DrawFrame(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h));
|
||
}
|
||
|
||
void MenuDriver::drawRFrame(float _x, float _y, float _w, float _h, float _r) {
|
||
u8g2_DrawRFrame(&u8g2, (int16_t) round(_x), (int16_t) round(_y), (int16_t) round(_w), (int16_t) round(_h),
|
||
(int16_t) round(_r));
|
||
}
|
||
|
||
void MenuDriver::drawCheckMark(float x, float y, float w, float h) {
|
||
float x0 = x + w * 0.1f;
|
||
float y0 = y + h * 0.5f;
|
||
|
||
float x1 = x + w * 0.4f;
|
||
float y1 = y + h * 0.8f;
|
||
|
||
float x2 = x + w * 0.9f;
|
||
float y2 = y + h * 0.2f;
|
||
|
||
u8g2_DrawLine(&u8g2, (int16_t) round(x0), (int16_t) round(y0), (int16_t) round(x1), (int16_t) round(y1));
|
||
u8g2_DrawLine(&u8g2, (int16_t) round(x1), (int16_t) round(y1), (int16_t) round(x2), (int16_t) round(y2));
|
||
} |