commit
This commit is contained in:
@@ -0,0 +1,632 @@
|
||||
/**
|
||||
* @file gc9a01.c
|
||||
* @brief Implémentation du driver pour écran TFT rond GC9A01 240x240
|
||||
*/
|
||||
|
||||
#include "gc9a01.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
//==============================================================================
|
||||
// Variables privées
|
||||
//==============================================================================
|
||||
static SPI_HandleTypeDef *hspi_gc9a01 = NULL;
|
||||
|
||||
// Police simple 8x8 (bitmap)
|
||||
static const uint8_t font8x8_basic[128][8] = {
|
||||
// A partir du caractère ' ' (32)
|
||||
[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // space
|
||||
[33] = { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // !
|
||||
[34] = { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // "
|
||||
[35] = { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // #
|
||||
[36] = { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // $
|
||||
[37] = { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // %
|
||||
[38] = { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // &
|
||||
[39] = { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // '
|
||||
[40] = { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // (
|
||||
[41] = { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // )
|
||||
[42] = { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // *
|
||||
[43] = { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // +
|
||||
[44] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x06, 0x00}, // ,
|
||||
[45] = { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // -
|
||||
[46] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // .
|
||||
[47] = { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // /
|
||||
[48] = { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // 0
|
||||
[49] = { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // 1
|
||||
[50] = { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // 2
|
||||
[51] = { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // 3
|
||||
[52] = { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // 4
|
||||
[53] = { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // 5
|
||||
[54] = { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // 6
|
||||
[55] = { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // 7
|
||||
[56] = { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // 8
|
||||
[57] = { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // 9
|
||||
[58] = { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // :
|
||||
[65] = { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // A
|
||||
[66] = { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // B
|
||||
[67] = { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // C
|
||||
[68] = { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // D
|
||||
[69] = { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // E
|
||||
[70] = { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // F
|
||||
[71] = { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // G
|
||||
[72] = { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // H
|
||||
[73] = { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // I
|
||||
[74] = { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // J
|
||||
[75] = { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // K
|
||||
[76] = { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // L
|
||||
[77] = { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // M
|
||||
[78] = { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // N
|
||||
[79] = { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // O
|
||||
[80] = { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // P
|
||||
[81] = { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // Q
|
||||
[82] = { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // R
|
||||
[83] = { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // S
|
||||
[84] = { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // T
|
||||
[85] = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U
|
||||
[86] = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // V
|
||||
[87] = { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // W
|
||||
[88] = { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // X
|
||||
[89] = { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // Y
|
||||
[90] = { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // Z
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Fonctions privées
|
||||
//==============================================================================
|
||||
|
||||
static void GC9A01_WriteCommand(uint8_t cmd) {
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_RESET);
|
||||
HAL_SPI_Transmit(hspi_gc9a01, &cmd, 1, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
static void GC9A01_WriteData(uint8_t data) {
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_RESET);
|
||||
HAL_SPI_Transmit(hspi_gc9a01, &data, 1, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
static void GC9A01_WriteDataBuffer(uint8_t *buffer, uint16_t len) {
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_RESET);
|
||||
HAL_SPI_Transmit(hspi_gc9a01, buffer, len, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
static void GC9A01_SetAddressWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
// Column address set
|
||||
GC9A01_WriteCommand(GC9A01_CASET);
|
||||
GC9A01_WriteData(x0 >> 8);
|
||||
GC9A01_WriteData(x0 & 0xFF);
|
||||
GC9A01_WriteData(x1 >> 8);
|
||||
GC9A01_WriteData(x1 & 0xFF);
|
||||
|
||||
// Row address set
|
||||
GC9A01_WriteCommand(GC9A01_RASET);
|
||||
GC9A01_WriteData(y0 >> 8);
|
||||
GC9A01_WriteData(y0 & 0xFF);
|
||||
GC9A01_WriteData(y1 >> 8);
|
||||
GC9A01_WriteData(y1 & 0xFF);
|
||||
|
||||
// Write to RAM
|
||||
GC9A01_WriteCommand(GC9A01_RAMWR);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Fonctions publiques
|
||||
//==============================================================================
|
||||
|
||||
bool GC9A01_Init(SPI_HandleTypeDef *hspi) {
|
||||
hspi_gc9a01 = hspi;
|
||||
|
||||
// Reset de l'écran
|
||||
GC9A01_Reset();
|
||||
HAL_Delay(100);
|
||||
|
||||
// Séquence d'initialisation GC9A01
|
||||
GC9A01_WriteCommand(GC9A01_INREGEN2);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_SPI2DATA);
|
||||
|
||||
GC9A01_WriteCommand(0xEB);
|
||||
GC9A01_WriteData(0x14);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_INREGEN2);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_SPI2DATA);
|
||||
|
||||
GC9A01_WriteCommand(0x84);
|
||||
GC9A01_WriteData(0x40);
|
||||
|
||||
GC9A01_WriteCommand(0x85);
|
||||
GC9A01_WriteData(0xFF);
|
||||
|
||||
GC9A01_WriteCommand(0x86);
|
||||
GC9A01_WriteData(0xFF);
|
||||
|
||||
GC9A01_WriteCommand(0x87);
|
||||
GC9A01_WriteData(0xFF);
|
||||
|
||||
GC9A01_WriteCommand(0x88);
|
||||
GC9A01_WriteData(0x0A);
|
||||
|
||||
GC9A01_WriteCommand(0x89);
|
||||
GC9A01_WriteData(0x21);
|
||||
|
||||
GC9A01_WriteCommand(0x8A);
|
||||
GC9A01_WriteData(0x00);
|
||||
|
||||
GC9A01_WriteCommand(0x8B);
|
||||
GC9A01_WriteData(0x80);
|
||||
|
||||
GC9A01_WriteCommand(0x8C);
|
||||
GC9A01_WriteData(0x01);
|
||||
|
||||
GC9A01_WriteCommand(0x8D);
|
||||
GC9A01_WriteData(0x01);
|
||||
|
||||
GC9A01_WriteCommand(0x8E);
|
||||
GC9A01_WriteData(0xFF);
|
||||
|
||||
GC9A01_WriteCommand(0x8F);
|
||||
GC9A01_WriteData(0xFF);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_DFUNCTR);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x20);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_MADCTL);
|
||||
GC9A01_WriteData(0x08);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_COLMOD);
|
||||
GC9A01_WriteData(0x05);
|
||||
|
||||
GC9A01_WriteCommand(0x90);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x08);
|
||||
|
||||
GC9A01_WriteCommand(0xBD);
|
||||
GC9A01_WriteData(0x06);
|
||||
|
||||
GC9A01_WriteCommand(0xBC);
|
||||
GC9A01_WriteData(0x00);
|
||||
|
||||
GC9A01_WriteCommand(0xFF);
|
||||
GC9A01_WriteData(0x60);
|
||||
GC9A01_WriteData(0x01);
|
||||
GC9A01_WriteData(0x04);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_PWCTR2);
|
||||
GC9A01_WriteData(0x13);
|
||||
GC9A01_WriteCommand(GC9A01_PWCTR3);
|
||||
GC9A01_WriteData(0x13);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_PWCTR4);
|
||||
GC9A01_WriteData(0x22);
|
||||
|
||||
GC9A01_WriteCommand(0xBE);
|
||||
GC9A01_WriteData(0x11);
|
||||
|
||||
GC9A01_WriteCommand(0xE1);
|
||||
GC9A01_WriteData(0x10);
|
||||
GC9A01_WriteData(0x0E);
|
||||
|
||||
GC9A01_WriteCommand(0xDF);
|
||||
GC9A01_WriteData(0x21);
|
||||
GC9A01_WriteData(0x0c);
|
||||
GC9A01_WriteData(0x02);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_GAMMA1);
|
||||
GC9A01_WriteData(0x45);
|
||||
GC9A01_WriteData(0x09);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x26);
|
||||
GC9A01_WriteData(0x2A);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_GAMMA2);
|
||||
GC9A01_WriteData(0x43);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x72);
|
||||
GC9A01_WriteData(0x36);
|
||||
GC9A01_WriteData(0x37);
|
||||
GC9A01_WriteData(0x6F);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_GAMMA3);
|
||||
GC9A01_WriteData(0x45);
|
||||
GC9A01_WriteData(0x09);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x26);
|
||||
GC9A01_WriteData(0x2A);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_GAMMA4);
|
||||
GC9A01_WriteData(0x43);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x72);
|
||||
GC9A01_WriteData(0x36);
|
||||
GC9A01_WriteData(0x37);
|
||||
GC9A01_WriteData(0x6F);
|
||||
|
||||
GC9A01_WriteCommand(0xED);
|
||||
GC9A01_WriteData(0x1B);
|
||||
GC9A01_WriteData(0x0B);
|
||||
|
||||
GC9A01_WriteCommand(0xAE);
|
||||
GC9A01_WriteData(0x77);
|
||||
|
||||
GC9A01_WriteCommand(0xCD);
|
||||
GC9A01_WriteData(0x63);
|
||||
|
||||
GC9A01_WriteCommand(0x70);
|
||||
GC9A01_WriteData(0x07);
|
||||
GC9A01_WriteData(0x07);
|
||||
GC9A01_WriteData(0x04);
|
||||
GC9A01_WriteData(0x0E);
|
||||
GC9A01_WriteData(0x0F);
|
||||
GC9A01_WriteData(0x71);
|
||||
GC9A01_WriteData(0xEF);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x70);
|
||||
|
||||
GC9A01_WriteCommand(0x63);
|
||||
GC9A01_WriteData(0x18);
|
||||
GC9A01_WriteData(0x11);
|
||||
GC9A01_WriteData(0x71);
|
||||
GC9A01_WriteData(0xF1);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x18);
|
||||
GC9A01_WriteData(0x13);
|
||||
GC9A01_WriteData(0x71);
|
||||
GC9A01_WriteData(0xF3);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x70);
|
||||
|
||||
GC9A01_WriteCommand(0x64);
|
||||
GC9A01_WriteData(0x28);
|
||||
GC9A01_WriteData(0x29);
|
||||
GC9A01_WriteData(0xF1);
|
||||
GC9A01_WriteData(0x01);
|
||||
GC9A01_WriteData(0xF1);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x07);
|
||||
|
||||
GC9A01_WriteCommand(0x66);
|
||||
GC9A01_WriteData(0x3C);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0xCD);
|
||||
GC9A01_WriteData(0x67);
|
||||
GC9A01_WriteData(0x45);
|
||||
GC9A01_WriteData(0x45);
|
||||
GC9A01_WriteData(0x10);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x00);
|
||||
|
||||
GC9A01_WriteCommand(0x67);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x3C);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x01);
|
||||
GC9A01_WriteData(0x54);
|
||||
GC9A01_WriteData(0x10);
|
||||
GC9A01_WriteData(0x32);
|
||||
GC9A01_WriteData(0x98);
|
||||
|
||||
GC9A01_WriteCommand(0x74);
|
||||
GC9A01_WriteData(0x10);
|
||||
GC9A01_WriteData(0x85);
|
||||
GC9A01_WriteData(0x80);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x00);
|
||||
GC9A01_WriteData(0x4E);
|
||||
GC9A01_WriteData(0x00);
|
||||
|
||||
GC9A01_WriteCommand(0x98);
|
||||
GC9A01_WriteData(0x3e);
|
||||
GC9A01_WriteData(0x07);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_SLPOUT);
|
||||
HAL_Delay(120);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_DISPON);
|
||||
HAL_Delay(20);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GC9A01_Reset(void) {
|
||||
HAL_GPIO_WritePin(GC9A01_RST_GPIO_Port, GC9A01_RST_Pin, GPIO_PIN_RESET);
|
||||
HAL_Delay(10);
|
||||
HAL_GPIO_WritePin(GC9A01_RST_GPIO_Port, GC9A01_RST_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(10);
|
||||
}
|
||||
|
||||
void GC9A01_DisplayOn(void) {
|
||||
GC9A01_WriteCommand(GC9A01_DISPON);
|
||||
}
|
||||
|
||||
void GC9A01_DisplayOff(void) {
|
||||
GC9A01_WriteCommand(GC9A01_DISPOFF);
|
||||
}
|
||||
|
||||
void GC9A01_SetRotation(uint8_t rotation) {
|
||||
GC9A01_WriteCommand(GC9A01_MADCTL);
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
GC9A01_WriteData(0x08);
|
||||
break;
|
||||
case 1:
|
||||
GC9A01_WriteData(0x68);
|
||||
break;
|
||||
case 2:
|
||||
GC9A01_WriteData(0xC8);
|
||||
break;
|
||||
case 3:
|
||||
GC9A01_WriteData(0xA8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GC9A01_FillScreen(uint16_t color) {
|
||||
GC9A01_SetAddressWindow(0, 0, GC9A01_WIDTH-1, GC9A01_HEIGHT-1);
|
||||
|
||||
uint8_t color_high = color >> 8;
|
||||
uint8_t color_low = color & 0xFF;
|
||||
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
for (uint32_t i = 0; i < GC9A01_WIDTH * GC9A01_HEIGHT; i++) {
|
||||
uint8_t data[2] = {color_high, color_low};
|
||||
HAL_SPI_Transmit(hspi_gc9a01, data, 2, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void GC9A01_SetPixel(uint16_t x, uint16_t y, uint16_t color) {
|
||||
if (x >= GC9A01_WIDTH || y >= GC9A01_HEIGHT) return;
|
||||
|
||||
GC9A01_SetAddressWindow(x, y, x, y);
|
||||
uint8_t data[2] = {color >> 8, color & 0xFF};
|
||||
GC9A01_WriteDataBuffer(data, 2);
|
||||
}
|
||||
|
||||
void GC9A01_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color) {
|
||||
int16_t dx = abs(x1 - x0);
|
||||
int16_t dy = abs(y1 - y0);
|
||||
int16_t sx = (x0 < x1) ? 1 : -1;
|
||||
int16_t sy = (y0 < y1) ? 1 : -1;
|
||||
int16_t err = dx - dy;
|
||||
|
||||
while (1) {
|
||||
GC9A01_SetPixel(x0, y0, color);
|
||||
|
||||
if (x0 == x1 && y0 == y1) break;
|
||||
|
||||
int16_t e2 = 2 * err;
|
||||
if (e2 > -dy) {
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dx) {
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GC9A01_DrawRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) {
|
||||
GC9A01_DrawLine(x, y, x + width - 1, y, color);
|
||||
GC9A01_DrawLine(x + width - 1, y, x + width - 1, y + height - 1, color);
|
||||
GC9A01_DrawLine(x + width - 1, y + height - 1, x, y + height - 1, color);
|
||||
GC9A01_DrawLine(x, y + height - 1, x, y, color);
|
||||
}
|
||||
|
||||
void GC9A01_FillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) {
|
||||
if (x >= GC9A01_WIDTH || y >= GC9A01_HEIGHT) return;
|
||||
if (x + width > GC9A01_WIDTH) width = GC9A01_WIDTH - x;
|
||||
if (y + height > GC9A01_HEIGHT) height = GC9A01_HEIGHT - y;
|
||||
|
||||
GC9A01_SetAddressWindow(x, y, x + width - 1, y + height - 1);
|
||||
|
||||
uint8_t color_high = color >> 8;
|
||||
uint8_t color_low = color & 0xFF;
|
||||
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
for (uint32_t i = 0; i < width * height; i++) {
|
||||
uint8_t data[2] = {color_high, color_low};
|
||||
HAL_SPI_Transmit(hspi_gc9a01, data, 2, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
void GC9A01_DrawCircle(uint16_t x, uint16_t y, uint8_t radius, uint16_t color) {
|
||||
int16_t f = 1 - radius;
|
||||
int16_t ddF_x = 1;
|
||||
int16_t ddF_y = -2 * radius;
|
||||
int16_t x1 = 0;
|
||||
int16_t y1 = radius;
|
||||
|
||||
GC9A01_SetPixel(x, y + radius, color);
|
||||
GC9A01_SetPixel(x, y - radius, color);
|
||||
GC9A01_SetPixel(x + radius, y, color);
|
||||
GC9A01_SetPixel(x - radius, y, color);
|
||||
|
||||
while (x1 < y1) {
|
||||
if (f >= 0) {
|
||||
y1--;
|
||||
ddF_y += 2;
|
||||
f += ddF_y;
|
||||
}
|
||||
x1++;
|
||||
ddF_x += 2;
|
||||
f += ddF_x;
|
||||
|
||||
GC9A01_SetPixel(x + x1, y + y1, color);
|
||||
GC9A01_SetPixel(x - x1, y + y1, color);
|
||||
GC9A01_SetPixel(x + x1, y - y1, color);
|
||||
GC9A01_SetPixel(x - x1, y - y1, color);
|
||||
GC9A01_SetPixel(x + y1, y + x1, color);
|
||||
GC9A01_SetPixel(x - y1, y + x1, color);
|
||||
GC9A01_SetPixel(x + y1, y - x1, color);
|
||||
GC9A01_SetPixel(x - y1, y - x1, color);
|
||||
}
|
||||
}
|
||||
|
||||
void GC9A01_FillCircle(uint16_t x, uint16_t y, uint8_t radius, uint16_t color) {
|
||||
for (int16_t dy = -radius; dy <= radius; dy++) {
|
||||
for (int16_t dx = -radius; dx <= radius; dx++) {
|
||||
if (dx*dx + dy*dy <= radius*radius) {
|
||||
GC9A01_SetPixel(x + dx, y + dy, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GC9A01_DrawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg_color, uint8_t size) {
|
||||
if (c < 32 || c > 127) c = '?';
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint8_t line = font8x8_basic[c][i];
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (line & (1 << j)) {
|
||||
if (size == 1) {
|
||||
GC9A01_SetPixel(x + j, y + i, color);
|
||||
} else {
|
||||
GC9A01_FillRect(x + j * size, y + i * size, size, size, color);
|
||||
}
|
||||
} else if (bg_color != color) {
|
||||
if (size == 1) {
|
||||
GC9A01_SetPixel(x + j, y + i, bg_color);
|
||||
} else {
|
||||
GC9A01_FillRect(x + j * size, y + i * size, size, size, bg_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GC9A01_DrawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color, uint8_t size) {
|
||||
while (*str) {
|
||||
GC9A01_DrawChar(x, y, *str, color, bg_color, size);
|
||||
x += 8 * size;
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t GC9A01_RGB565(uint8_t r, uint8_t g, uint8_t b) {
|
||||
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||
}
|
||||
|
||||
bool GC9A01_IsInCircle(uint16_t x, uint16_t y) {
|
||||
int16_t dx = x - GC9A01_RADIUS;
|
||||
int16_t dy = y - GC9A01_RADIUS;
|
||||
return (dx*dx + dy*dy) <= (GC9A01_RADIUS * GC9A01_RADIUS);
|
||||
}
|
||||
|
||||
// Fonctions spécifiques pour interface moto
|
||||
void GC9A01_DrawGauge(uint16_t center_x, uint16_t center_y, uint8_t radius,
|
||||
float value, float min_val, float max_val,
|
||||
uint16_t color, const char* label) {
|
||||
|
||||
// Dessiner le cercle extérieur
|
||||
GC9A01_DrawCircle(center_x, center_y, radius, GC9A01_WHITE);
|
||||
|
||||
// Calculer l'angle (de -90° à +90°, soit 180° total)
|
||||
float normalized = (value - min_val) / (max_val - min_val);
|
||||
if (normalized < 0) normalized = 0;
|
||||
if (normalized > 1) normalized = 1;
|
||||
|
||||
float angle = -90.0f + (normalized * 180.0f); // -90° à +90°
|
||||
float rad = angle * M_PI / 180.0f;
|
||||
|
||||
// Dessiner l'aiguille
|
||||
int16_t needle_x = center_x + (radius - 5) * cos(rad);
|
||||
int16_t needle_y = center_y + (radius - 5) * sin(rad);
|
||||
GC9A01_DrawLine(center_x, center_y, needle_x, needle_y, color);
|
||||
|
||||
// Dessiner le centre
|
||||
GC9A01_FillCircle(center_x, center_y, 3, color);
|
||||
|
||||
// Afficher la valeur
|
||||
char value_str[10];
|
||||
snprintf(value_str, sizeof(value_str), "%.1f", value);
|
||||
GC9A01_DrawString(center_x - 20, center_y + radius + 10, value_str, color, GC9A01_BLACK, 1);
|
||||
|
||||
// Afficher le label
|
||||
if (label) {
|
||||
GC9A01_DrawString(center_x - strlen(label) * 4, center_y - radius - 20, label, GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void GC9A01_DrawAngleIndicator(float roll, float pitch) {
|
||||
uint16_t center_x = GC9A01_WIDTH / 2;
|
||||
uint16_t center_y = GC9A01_HEIGHT / 2;
|
||||
|
||||
// Effacer la zone central
|
||||
GC9A01_FillCircle(center_x, center_y, 50, GC9A01_BLACK);
|
||||
|
||||
// Dessiner l'horizon artificiel
|
||||
GC9A01_DrawCircle(center_x, center_y, 50, GC9A01_WHITE);
|
||||
|
||||
// Ligne d'horizon (basée sur le pitch)
|
||||
int16_t horizon_offset = (int16_t)(pitch * 2); // Facteur d'échelle
|
||||
GC9A01_DrawLine(center_x - 40, center_y + horizon_offset,
|
||||
center_x + 40, center_y + horizon_offset, GC9A01_CYAN);
|
||||
|
||||
// Indicateur de roulis (triangle au centre)
|
||||
float roll_rad = roll * M_PI / 180.0f;
|
||||
int16_t tri_x = center_x + 20 * sin(roll_rad);
|
||||
int16_t tri_y = center_y - 20 * cos(roll_rad);
|
||||
|
||||
GC9A01_DrawLine(center_x, center_y, tri_x, tri_y, GC9A01_RED);
|
||||
GC9A01_FillCircle(tri_x, tri_y, 3, GC9A01_RED);
|
||||
|
||||
// Afficher les valeurs numériques
|
||||
char roll_str[10], pitch_str[10];
|
||||
snprintf(roll_str, sizeof(roll_str), "R:%.1f", roll);
|
||||
snprintf(pitch_str, sizeof(pitch_str), "P:%.1f", pitch);
|
||||
|
||||
GC9A01_DrawString(10, 10, roll_str, GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
GC9A01_DrawString(10, 25, pitch_str, GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
}
|
||||
|
||||
void GC9A01_DrawStateIndicator(const char* state, uint16_t color) {
|
||||
// Effacer la zone du bas
|
||||
GC9A01_FillRect(0, GC9A01_HEIGHT - 30, GC9A01_WIDTH, 30, GC9A01_BLACK);
|
||||
|
||||
// Centrer le texte
|
||||
uint16_t text_width = strlen(state) * 8;
|
||||
uint16_t start_x = (GC9A01_WIDTH - text_width) / 2;
|
||||
|
||||
GC9A01_DrawString(start_x, GC9A01_HEIGHT - 20, state, color, GC9A01_BLACK, 1);
|
||||
}A01_WriteData(0x09);
|
||||
GC9A01_WriteData(0x07);
|
||||
GC9A01_WriteData(0x08);
|
||||
GC9A01_WriteData(0x03);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_FRAMERATE);
|
||||
GC9A01_WriteData(0x34);
|
||||
|
||||
GC9A01_WriteCommand(0x62);
|
||||
GC9A01_WriteData(0x18);
|
||||
GC9A01_WriteData(0x0D);
|
||||
GC9A01_WriteData(0x71);
|
||||
GC9A01_WriteData(0xED);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x70);
|
||||
GC9A01_WriteData(0x18);
|
||||
GC9A01_WriteData(0x0F);
|
||||
GC9
|
||||
+312
-5
@@ -5,18 +5,27 @@
|
||||
#include "icm20948.h"
|
||||
#include "FusionAhrs.h"
|
||||
#include "moto_config.h"
|
||||
#include "gc9a01.h"
|
||||
|
||||
|
||||
I2C_HandleTypeDef hi2c1;
|
||||
SPI_HandleTypeDef hspi1;
|
||||
UART_HandleTypeDef huart2;
|
||||
|
||||
FusionAhrs ahrs;
|
||||
MotoData_t moto_data;
|
||||
MotoStats_t moto_stats = {0};
|
||||
|
||||
SPI_HandleTypeDef hspi1; // Pour l'écran TFT
|
||||
uint32_t display_mode = 0; // Mode d'affichage (0=angles, 1=jauges, 2=horizon)
|
||||
uint32_t mode_change_time = 0;
|
||||
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_I2C1_Init(void);
|
||||
static void MX_USART2_UART_Init(void);
|
||||
static void MX_SPI1_Init(void);
|
||||
void Update_TFT_Display(void);
|
||||
|
||||
int __io_putchar(int ch) {
|
||||
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
@@ -32,6 +41,7 @@ int main(void) {
|
||||
MX_GPIO_Init();
|
||||
MX_I2C1_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_SPI1_Init();
|
||||
|
||||
// Initialisation de l'écran
|
||||
lcd_init();
|
||||
@@ -40,6 +50,16 @@ int main(void) {
|
||||
lcd_print("MOTO IMU SYSTEM");
|
||||
HAL_Delay(1000);
|
||||
|
||||
if (!GC9A01_Init(&hspi1)) {
|
||||
printf("Erreur initialisation écran TFT\r\n");
|
||||
} else {
|
||||
printf("Écran TFT initialisé\r\n");
|
||||
GC9A01_FillScreen(GC9A01_BLACK);
|
||||
GC9A01_DrawString(60, 120, "MOTO IMU", GC9A01_GREEN, GC9A01_BLACK, 2);
|
||||
HAL_Delay(2000);
|
||||
GC9A01_FillScreen(GC9A01_BLACK);
|
||||
}
|
||||
|
||||
// Initialisation de l'IMU
|
||||
icm20948_init();
|
||||
|
||||
@@ -109,7 +129,7 @@ int main(void) {
|
||||
Moto_UpdateStats(&moto_stats, &moto_data, gx, gy, gz);
|
||||
|
||||
// Mise à jour de l'affichage (toutes les 5 itérations = ~50ms)
|
||||
display_update_counter++;
|
||||
/*display_update_counter++;
|
||||
if (display_update_counter >= 5) {
|
||||
char buffer[21];
|
||||
|
||||
@@ -120,7 +140,24 @@ int main(void) {
|
||||
}
|
||||
|
||||
display_update_counter = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
// Mise à jour de l'affichage (toutes les 5 itérations = ~50ms)
|
||||
display_update_counter++;
|
||||
if (display_update_counter >= 5) {
|
||||
// Affichage LCD existant (gardé pour debug/backup)
|
||||
char buffer[21];
|
||||
for (int line = 0; line < 4; line++) {
|
||||
Moto_FormatDisplay(&moto_data, line, buffer);
|
||||
lcd_set_cursor(line, 0);
|
||||
lcd_print(buffer);
|
||||
}
|
||||
|
||||
// Nouvel affichage TFT
|
||||
Update_TFT_Display();
|
||||
|
||||
display_update_counter = 0;
|
||||
}
|
||||
|
||||
// LED d'état
|
||||
switch (moto_data.state) {
|
||||
@@ -172,10 +209,163 @@ int main(void) {
|
||||
}
|
||||
|
||||
// Petite pause pour éviter la surcharge du processeur
|
||||
HAL_Delay(20);
|
||||
HAL_Delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fonction de mise à jour de l'affichage TFT (à ajouter avant main())
|
||||
void Update_TFT_Display(void) {
|
||||
float roll = moto_data.roll_filtered;
|
||||
float pitch = moto_data.pitch_filtered;
|
||||
float yaw = moto_data.yaw_filtered;
|
||||
|
||||
// Changement de mode d'affichage toutes les 5 secondes
|
||||
uint32_t current_time = HAL_GetTick();
|
||||
if (current_time - mode_change_time > 5000) {
|
||||
display_mode = (display_mode + 1) % 3;
|
||||
mode_change_time = current_time;
|
||||
GC9A01_FillScreen(GC9A01_BLACK); // Effacer l'écran
|
||||
}
|
||||
|
||||
switch (display_mode) {
|
||||
case 0: // Mode angles numériques
|
||||
{
|
||||
// Titre
|
||||
GC9A01_DrawString(80, 10, "MOTO IMU", GC9A01_WHITE, GC9A01_BLACK, 2);
|
||||
|
||||
// Angles
|
||||
char buffer[20];
|
||||
snprintf(buffer, sizeof(buffer), "Roll: %6.1f°", roll);
|
||||
uint16_t roll_color = (fabsf(roll) > 30) ? GC9A01_RED : GC9A01_GREEN;
|
||||
GC9A01_DrawString(20, 50, buffer, roll_color, GC9A01_BLACK, 1);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "Pitch: %5.1f°", pitch);
|
||||
uint16_t pitch_color = (fabsf(pitch) > 15) ? GC9A01_ORANGE : GC9A01_GREEN;
|
||||
GC9A01_DrawString(20, 70, buffer, pitch_color, GC9A01_BLACK, 1);
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "Yaw: %7.1f°", yaw);
|
||||
GC9A01_DrawString(20, 90, buffer, GC9A01_CYAN, GC9A01_BLACK, 1);
|
||||
|
||||
// État de la moto
|
||||
const char* state_str = Moto_GetStateString(moto_data.state);
|
||||
uint16_t state_color;
|
||||
switch (moto_data.state) {
|
||||
case MOTO_STATE_NORMAL:
|
||||
state_color = GC9A01_GREEN;
|
||||
break;
|
||||
case MOTO_STATE_WARNING:
|
||||
state_color = GC9A01_YELLOW;
|
||||
break;
|
||||
case MOTO_STATE_DANGER:
|
||||
case MOTO_STATE_POSSIBLE_CRASH:
|
||||
state_color = GC9A01_RED;
|
||||
break;
|
||||
case MOTO_STATE_WHEELIE:
|
||||
case MOTO_STATE_STOPPIE:
|
||||
state_color = GC9A01_MAGENTA;
|
||||
break;
|
||||
case MOTO_STATE_RAPID_TURN:
|
||||
state_color = GC9A01_ORANGE;
|
||||
break;
|
||||
default:
|
||||
state_color = GC9A01_WHITE;
|
||||
break;
|
||||
}
|
||||
|
||||
GC9A01_DrawString(20, 120, "Etat:", GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
GC9A01_DrawString(20, 135, state_str, state_color, GC9A01_BLACK, 1);
|
||||
|
||||
// Indicateur d'initialisation
|
||||
if (moto_data.is_initializing) {
|
||||
GC9A01_DrawString(50, 180, "INIT...", GC9A01_YELLOW, GC9A01_BLACK, 2);
|
||||
}
|
||||
|
||||
// Statistiques
|
||||
char stats_buffer[30];
|
||||
snprintf(stats_buffer, sizeof(stats_buffer), "Samples: %lu", moto_stats.total_samples);
|
||||
GC9A01_DrawString(10, 210, stats_buffer, GC9A01_GRAY, GC9A01_BLACK, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // Mode jauges
|
||||
{
|
||||
GC9A01_DrawString(90, 5, "JAUGES", GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
|
||||
// Jauge de roulis (gauche)
|
||||
uint16_t roll_color = (fabsf(roll) > 30) ? GC9A01_RED :
|
||||
(fabsf(roll) > 15) ? GC9A01_YELLOW : GC9A01_GREEN;
|
||||
GC9A01_DrawGauge(60, 80, 40, roll, -45.0f, 45.0f, roll_color, "ROLL");
|
||||
|
||||
// Jauge de tangage (droite)
|
||||
uint16_t pitch_color = (fabsf(pitch) > 20) ? GC9A01_RED :
|
||||
(fabsf(pitch) > 10) ? GC9A01_YELLOW : GC9A01_GREEN;
|
||||
GC9A01_DrawGauge(180, 80, 40, pitch, -30.0f, 30.0f, pitch_color, "PITCH");
|
||||
|
||||
// Boussole pour le yaw (en bas)
|
||||
GC9A01_DrawCircle(120, 180, 35, GC9A01_WHITE);
|
||||
float yaw_rad = yaw * M_PI / 180.0f;
|
||||
int16_t yaw_x = 120 + 30 * sin(yaw_rad);
|
||||
int16_t yaw_y = 180 - 30 * cos(yaw_rad);
|
||||
GC9A01_DrawLine(120, 180, yaw_x, yaw_y, GC9A01_CYAN);
|
||||
GC9A01_FillCircle(yaw_x, yaw_y, 3, GC9A01_CYAN);
|
||||
GC9A01_DrawString(105, 220, "YAW", GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
|
||||
// État en bas
|
||||
GC9A01_DrawStateIndicator(Moto_GetStateString(moto_data.state),
|
||||
(moto_data.state == MOTO_STATE_NORMAL) ? GC9A01_GREEN : GC9A01_RED);
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: // Mode horizon artificiel
|
||||
{
|
||||
GC9A01_DrawString(70, 5, "HORIZON", GC9A01_WHITE, GC9A01_BLACK, 1);
|
||||
|
||||
// Horizon artificiel principal
|
||||
GC9A01_DrawAngleIndicator(roll, pitch);
|
||||
|
||||
// Informations complémentaires autour
|
||||
char info_buffer[15];
|
||||
|
||||
// Yaw en haut à droite
|
||||
snprintf(info_buffer, sizeof(info_buffer), "Y:%.0f°", yaw);
|
||||
GC9A01_DrawString(180, 25, info_buffer, GC9A01_CYAN, GC9A01_BLACK, 1);
|
||||
|
||||
// Indicateurs de seuils
|
||||
if (fabsf(roll) > 30) {
|
||||
GC9A01_DrawString(10, 200, "ROULIS!", GC9A01_RED, GC9A01_BLACK, 1);
|
||||
}
|
||||
if (fabsf(pitch) > 20) {
|
||||
GC9A01_DrawString(170, 200, "TANGAGE!", GC9A01_RED, GC9A01_BLACK, 1);
|
||||
}
|
||||
|
||||
// Grille d'aide (lignes de référence)
|
||||
for (int i = -40; i <= 40; i += 20) {
|
||||
if (i != 0) {
|
||||
uint16_t y_pos = 120 + i;
|
||||
if (y_pos > 70 && y_pos < 170) {
|
||||
GC9A01_DrawLine(70, y_pos, 90, y_pos, GC9A01_GRAY);
|
||||
GC9A01_DrawLine(150, y_pos, 170, y_pos, GC9A01_GRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// État actuel
|
||||
GC9A01_DrawStateIndicator(Moto_GetStateString(moto_data.state),
|
||||
(moto_data.state == MOTO_STATE_NORMAL) ? GC9A01_GREEN : GC9A01_RED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
@@ -221,8 +411,21 @@ void SystemClock_Config(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_I2C1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 0 */
|
||||
|
||||
/* USER CODE END I2C1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 1 */
|
||||
|
||||
/* USER CODE END I2C1_Init 1 */
|
||||
hi2c1.Instance = I2C1;
|
||||
hi2c1.Init.Timing = 0x10D19CE4;
|
||||
hi2c1.Init.OwnAddress1 = 0;
|
||||
@@ -237,19 +440,80 @@ static void MX_I2C1_Init(void)
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Analogue filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Digital filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN I2C1_Init 2 */
|
||||
|
||||
/* USER CODE END I2C1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_SPI1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 0 */
|
||||
|
||||
/* USER CODE END SPI1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 1 */
|
||||
|
||||
/* USER CODE END SPI1_Init 1 */
|
||||
/* SPI1 parameter configuration*/
|
||||
hspi1.Instance = SPI1;
|
||||
hspi1.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi1.Init.CRCPolynomial = 7;
|
||||
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
|
||||
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
|
||||
if (HAL_SPI_Init(&hspi1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_USART2_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART2_Init 0 */
|
||||
|
||||
/* USER CODE END USART2_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART2_Init 1 */
|
||||
|
||||
/* USER CODE END USART2_Init 1 */
|
||||
huart2.Instance = USART2;
|
||||
huart2.Init.BaudRate = 115200;
|
||||
huart2.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
@@ -264,11 +528,23 @@ static void MX_USART2_UART_Init(void)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART2_Init 2 */
|
||||
|
||||
/* USER CODE END USART2_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_GPIO_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
/* USER CODE BEGIN MX_GPIO_Init_1 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_1 */
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
@@ -280,7 +556,10 @@ static void MX_GPIO_Init(void)
|
||||
HAL_GPIO_WritePin(GPIOA, SMPS_EN_Pin|SMPS_V1_Pin|SMPS_SW_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_2, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1|LD4_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : B1_Pin */
|
||||
GPIO_InitStruct.Pin = B1_Pin;
|
||||
@@ -301,23 +580,51 @@ static void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(SMPS_PG_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PB0 PB1 PB2 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : LD4_Pin */
|
||||
GPIO_InitStruct.Pin = LD4_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(LD4_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
|
||||
+15
-15
@@ -75,12 +75,12 @@ void Moto_FilterAngles(MotoData_t *data) {
|
||||
|
||||
const char* Moto_GetStateString(MotoState_t state) {
|
||||
switch (state) {
|
||||
case MOTO_STATE_NORMAL: return "NORMAL";
|
||||
case MOTO_STATE_WARNING: return "ATTENTION";
|
||||
case MOTO_STATE_DANGER: return "DANGER";
|
||||
case MOTO_STATE_WHEELIE: return "WHEELIE";
|
||||
case MOTO_STATE_STOPPIE: return "STOPPIE";
|
||||
case MOTO_STATE_RAPID_TURN: return "VIRAGE RAPIDE";
|
||||
case MOTO_STATE_NORMAL: return "NORMAL ";
|
||||
case MOTO_STATE_WARNING: return "ATTENTION ";
|
||||
case MOTO_STATE_DANGER: return "DANGER ";
|
||||
case MOTO_STATE_WHEELIE: return "WHEELIE ";
|
||||
case MOTO_STATE_STOPPIE: return "STOPPIE ";
|
||||
case MOTO_STATE_RAPID_TURN: return "VIRAGE RAPIDE ";
|
||||
case MOTO_STATE_POSSIBLE_CRASH: return "CHUTE POSSIBLE";
|
||||
default: return "INCONNU";
|
||||
}
|
||||
@@ -150,34 +150,34 @@ void Moto_FormatDisplay(const MotoData_t *data, int line, char *buffer) {
|
||||
|
||||
case 3:
|
||||
if (data->is_initializing) {
|
||||
snprintf(buffer, 21, "--- INIT EN COURS ---");
|
||||
snprintf(buffer, 21, "---- INIT EN COURS ----");
|
||||
} else {
|
||||
switch (data->state) {
|
||||
case MOTO_STATE_NORMAL:
|
||||
snprintf(buffer, 21, "--- EQUILIBRE ---");
|
||||
snprintf(buffer, 21, "---- EQUILIBRE ----");
|
||||
break;
|
||||
case MOTO_STATE_WARNING:
|
||||
if (data->roll > 0) {
|
||||
snprintf(buffer, 21, "INCLIN. DROITE >>>");
|
||||
snprintf(buffer, 21, "INCLIN. DROITE >>>");
|
||||
} else {
|
||||
snprintf(buffer, 21, "<<< INCLIN. GAUCHE");
|
||||
snprintf(buffer, 21, "<<< INCLIN. GAUCHE");
|
||||
}
|
||||
break;
|
||||
case MOTO_STATE_DANGER:
|
||||
case MOTO_STATE_POSSIBLE_CRASH:
|
||||
snprintf(buffer, 21, "!!! ATTENTION !!!");
|
||||
snprintf(buffer, 21, "!!! ATTENTION !!! ");
|
||||
break;
|
||||
case MOTO_STATE_WHEELIE:
|
||||
snprintf(buffer, 21, "^^^ WHEELIE ^^^");
|
||||
snprintf(buffer, 21, "^^^ WHEELIE ^^^ ");
|
||||
break;
|
||||
case MOTO_STATE_STOPPIE:
|
||||
snprintf(buffer, 21, "vvv STOPPIE vvv");
|
||||
snprintf(buffer, 21, "vvv STOPPIE vvv ");
|
||||
break;
|
||||
case MOTO_STATE_RAPID_TURN:
|
||||
snprintf(buffer, 21, ">>> VIRAGE <<<");
|
||||
snprintf(buffer, 21, ">>> VIRAGE <<< ");
|
||||
break;
|
||||
default:
|
||||
snprintf(buffer, 21, "--- INCONNU ---");
|
||||
snprintf(buffer, 21, "--- INCONNU --- ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,74 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PA1 ------> SPI1_SCK
|
||||
PA11 ------> SPI1_MISO
|
||||
PA12 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hspi: SPI handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
|
||||
{
|
||||
if(hspi->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA1 ------> SPI1_SCK
|
||||
PA11 ------> SPI1_MISO
|
||||
PA12 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_11|GPIO_PIN_12);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
|
||||
Reference in New Issue
Block a user