This commit is contained in:
2025-07-29 18:40:23 +02:00
parent 79bfa20ac7
commit 509b840b3f
84 changed files with 8838 additions and 279 deletions
+146
View File
@@ -0,0 +1,146 @@
/*
* gc9a01.h
*
* Created on: Jul 24, 2025
* Author: loren
*/
#ifndef INC_GC9A01_H_
#define INC_GC9A01_H_
#include "main.h"
#include <stdint.h>
#include <stdbool.h>
//==============================================================================
// Configuration des pins (à adapter selon votre câblage)
//==============================================================================
#define GC9A01_CS_GPIO_Port GPIOB
#define GC9A01_CS_Pin GPIO_PIN_0
#define GC9A01_DC_GPIO_Port GPIOB
#define GC9A01_DC_Pin GPIO_PIN_1
#define GC9A01_RST_GPIO_Port GPIOB
#define GC9A01_RST_Pin GPIO_PIN_2
// SCK et MOSI sont sur SPI1 par défaut
//==============================================================================
// Constantes de l'écran
//==============================================================================
#define GC9A01_WIDTH 240
#define GC9A01_HEIGHT 240
#define GC9A01_RADIUS 120
//==============================================================================
// Couleurs 16-bit (RGB565)
//==============================================================================
#define GC9A01_BLACK 0x0000
#define GC9A01_WHITE 0xFFFF
#define GC9A01_RED 0xF800
#define GC9A01_GREEN 0x07E0
#define GC9A01_BLUE 0x001F
#define GC9A01_CYAN 0x07FF
#define GC9A01_MAGENTA 0xF81F
#define GC9A01_YELLOW 0xFFE0
#define GC9A01_ORANGE 0xFD20
#define GC9A01_DARKGREEN 0x03E0
#define GC9A01_DARKBLUE 0x0010
#define GC9A01_GRAY 0x8410
#define GC9A01_LIGHTGRAY 0xC618
//==============================================================================
// Commandes du contrôleur GC9A01
//==============================================================================
#define GC9A01_SWRESET 0x01
#define GC9A01_RDDID 0x04
#define GC9A01_RDDST 0x09
#define GC9A01_SLPIN 0x10
#define GC9A01_SLPOUT 0x11
#define GC9A01_PTLON 0x12
#define GC9A01_NORON 0x13
#define GC9A01_INVOFF 0x20
#define GC9A01_INVON 0x21
#define GC9A01_DISPOFF 0x28
#define GC9A01_DISPON 0x29
#define GC9A01_CASET 0x2A
#define GC9A01_RASET 0x2B
#define GC9A01_RAMWR 0x2C
#define GC9A01_RAMRD 0x2E
#define GC9A01_PTLAR 0x30
#define GC9A01_COLMOD 0x3A
#define GC9A01_MADCTL 0x36
#define GC9A01_DFUNCTR 0xB6
#define GC9A01_PWCTR1 0xC1
#define GC9A01_PWCTR2 0xC3
#define GC9A01_PWCTR3 0xC4
#define GC9A01_PWCTR4 0xC9
#define GC9A01_RDID1 0xDA
#define GC9A01_RDID2 0xDB
#define GC9A01_RDID3 0xDC
#define GC9A01_FRAMERATE 0xE8
#define GC9A01_SPI2DATA 0xE9
#define GC9A01_INREGEN2 0xEF
#define GC9A01_GAMMA1 0xF0
#define GC9A01_GAMMA2 0xF1
#define GC9A01_GAMMA3 0xF2
#define GC9A01_GAMMA4 0xF3
//==============================================================================
// Structures
//==============================================================================
typedef struct {
uint16_t x;
uint16_t y;
} GC9A01_Point_t;
typedef struct {
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} GC9A01_Rect_t;
typedef struct {
uint16_t x;
uint16_t y;
uint8_t radius;
uint16_t color;
} GC9A01_Circle_t;
//==============================================================================
// Fonctions publiques
//==============================================================================
// Initialisation et contrôle de base
bool GC9A01_Init(SPI_HandleTypeDef *hspi);
void GC9A01_Reset(void);
void GC9A01_DisplayOn(void);
void GC9A01_DisplayOff(void);
void GC9A01_SetRotation(uint8_t rotation);
// Fonctions de dessin de base
void GC9A01_FillScreen(uint16_t color);
void GC9A01_SetPixel(uint16_t x, uint16_t y, uint16_t color);
void GC9A01_DrawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
void GC9A01_DrawRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color);
void GC9A01_FillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color);
void GC9A01_DrawCircle(uint16_t x, uint16_t y, uint8_t radius, uint16_t color);
void GC9A01_FillCircle(uint16_t x, uint16_t y, uint8_t radius, uint16_t color);
// Fonctions de texte (simple)
void GC9A01_DrawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg_color, uint8_t size);
void GC9A01_DrawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color, uint8_t size);
// Fonctions utilitaires
uint16_t GC9A01_RGB565(uint8_t r, uint8_t g, uint8_t b);
bool GC9A01_IsInCircle(uint16_t x, uint16_t y);
// 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);
void GC9A01_DrawAngleIndicator(float roll, float pitch);
void GC9A01_DrawStateIndicator(const char* state, uint16_t color);
#endif /* INC_GC9A01_H_ */
+1 -1
View File
@@ -74,7 +74,7 @@
/*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
/*#define HAL_SPI_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_SWPMI_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */
+632
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
}
+68
View File
@@ -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