TiSmartCar/example/2025_source_user/OledMenuDriver.cpp
Boen_Shi 8be2866433 feat(base): 初始化 MSPM0 开发环境
- 添加头文件和配置文件支持
- 更新.gitignore忽略编译和IDE相关文件
- 添加基础的bsp代码
2026-07-16 14:45:26 +08:00

299 lines
9.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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));
}