commit
This commit is contained in:
parent
046f4b61dc
commit
6c75619957
|
|
@ -5,7 +5,7 @@
|
|||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="106393027960746669" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="749625155172876097" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="106393027960746669" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<provider class="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" console="false" env-hash="749625155172876097" id="com.st.stm32cube.ide.mcu.toolchain.armnone.setup.CrossBuiltinSpecsDetector" keep-relative-paths="false" name="MCU ARM GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||
</provider>
|
||||
|
|
|
|||
|
|
@ -1,38 +1,48 @@
|
|||
/*
|
||||
* gc9a01.h
|
||||
*
|
||||
* Created on: Jul 24, 2025
|
||||
* Author: loren
|
||||
/**
|
||||
* @file gc9a01.h
|
||||
* @brief Driver GC9A01 pour STM32 (HAL)
|
||||
* @date 09 août 2025
|
||||
* @author Lorent
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INC_GC9A01_H_
|
||||
#define INC_GC9A01_H_
|
||||
|
||||
|
||||
#include "main.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PIX_BUF 512
|
||||
|
||||
|
||||
//==============================================================================
|
||||
// Configuration des pins (à adapter selon votre câblage)
|
||||
// 📌 Configuration matérielle
|
||||
//==============================================================================
|
||||
|
||||
// Chip Select (CS)
|
||||
#define GC9A01_CS_GPIO_Port GPIOB
|
||||
#define GC9A01_CS_Pin GPIO_PIN_0
|
||||
|
||||
// Data/Command (DC)
|
||||
#define GC9A01_DC_GPIO_Port GPIOB
|
||||
#define GC9A01_DC_Pin GPIO_PIN_1
|
||||
|
||||
// Reset (RST)
|
||||
#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
|
||||
//==============================================================================
|
||||
// Dimensions écran
|
||||
#define GC9A01_WIDTH 240
|
||||
#define GC9A01_HEIGHT 240
|
||||
#define GC9A01_RADIUS 120
|
||||
#define GC9A01_RADIUS (GC9A01_WIDTH / 2)
|
||||
|
||||
//==============================================================================
|
||||
// Couleurs 16-bit (RGB565)
|
||||
// 🎨 Couleurs (format RGB565)
|
||||
//==============================================================================
|
||||
#define GC9A01_BLACK 0x0000
|
||||
#define GC9A01_WHITE 0xFFFF
|
||||
|
|
@ -49,14 +59,13 @@
|
|||
#define GC9A01_LIGHTGRAY 0xC618
|
||||
|
||||
//==============================================================================
|
||||
// Commandes du contrôleur GC9A01
|
||||
// 📜 Commandes 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
|
||||
|
|
@ -66,29 +75,21 @@
|
|||
#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
|
||||
// 📦 Structures
|
||||
//==============================================================================
|
||||
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
|
|
@ -109,17 +110,17 @@ typedef struct {
|
|||
} GC9A01_Circle_t;
|
||||
|
||||
//==============================================================================
|
||||
// Fonctions publiques
|
||||
// 🔹 Fonctions publiques
|
||||
//==============================================================================
|
||||
|
||||
// Initialisation et contrôle de base
|
||||
bool GC9A01_Init(SPI_HandleTypeDef *hspi);
|
||||
// Initialisation
|
||||
void 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
|
||||
// Dessin basique
|
||||
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);
|
||||
|
|
@ -128,19 +129,23 @@ void GC9A01_FillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, ui
|
|||
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)
|
||||
// Texte
|
||||
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
|
||||
// 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
|
||||
// Fonctions spécifiques 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_ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // GC9A01_H
|
||||
|
|
|
|||
|
|
@ -3,7 +3,21 @@
|
|||
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
void icm20948_init(void);
|
||||
void icm20948_read_accel(float *ax, float *ay, float *az);
|
||||
// Adresse I2C par défaut (SA0=1)
|
||||
#define ICM20948_I2C_ADDR (0x69 << 1)
|
||||
|
||||
#endif
|
||||
// ----- Fonctions de configuration -----
|
||||
void icm20948_init(void);
|
||||
void icm20948_mag_init(void);
|
||||
|
||||
// ----- Fonctions de lecture -----
|
||||
void icm20948_read_accel(float *ax, float *ay, float *az);
|
||||
void icm20948_read_gyro(float *gx, float *gy, float *gz);
|
||||
void icm20948_read_mag(float *mx, float *my, float *mz);
|
||||
|
||||
// ----- Fonctions internes (optionnelles, si besoin hors module) -----
|
||||
void icm20948_select_bank(uint8_t bank);
|
||||
uint8_t icm20948_read_register(uint8_t reg);
|
||||
void icm20948_write_register(uint8_t reg, uint8_t val);
|
||||
|
||||
#endif // ICM20948_H
|
||||
|
|
|
|||
|
|
@ -1,347 +1,101 @@
|
|||
/**
|
||||
* @file gc9a01.c
|
||||
* @brief Implémentation du driver pour écran TFT rond GC9A01 240x240
|
||||
*/
|
||||
|
||||
// gc9a01.c (version nettoyée + optimisée)
|
||||
#include "gc9a01.h"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//==============================================================================
|
||||
// Variables privées
|
||||
//==============================================================================
|
||||
static SPI_HandleTypeDef *hspi_gc9a01 = NULL;
|
||||
|
||||
// Police simple 8x8 (bitmap)
|
||||
// police 8x8 tronquée pour la demo (ton tableau complet ici)
|
||||
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
|
||||
[32] = {0,0,0,0,0,0,0,0},
|
||||
/* ... place ici le tableau complet depuis ton fichier original ... */
|
||||
[65] = { 0x0C,0x1E,0x33,0x33,0x3F,0x33,0x33,0x00 },
|
||||
/* etc. */
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Fonctions privées
|
||||
//==============================================================================
|
||||
// helpers pour contrôle des lignes CS/DC
|
||||
static inline void GC9A01_Select(void) {
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
static inline void GC9A01_Unselect(void) {
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
static inline void GC9A01_DC_Command(void) {
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
static inline void GC9A01_DC_Data(void) {
|
||||
HAL_GPIO_WritePin(GC9A01_DC_GPIO_Port, GC9A01_DC_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
|
||||
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);
|
||||
GC9A01_DC_Command();
|
||||
GC9A01_Select();
|
||||
HAL_SPI_Transmit(hspi_gc9a01, &cmd, 1, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
GC9A01_Unselect();
|
||||
}
|
||||
|
||||
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);
|
||||
GC9A01_DC_Data();
|
||||
GC9A01_Select();
|
||||
HAL_SPI_Transmit(hspi_gc9a01, &data, 1, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
GC9A01_Unselect();
|
||||
}
|
||||
|
||||
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);
|
||||
static void GC9A01_WriteDataBuffer(uint8_t *buffer, uint32_t len) {
|
||||
if (len == 0) return;
|
||||
GC9A01_DC_Data();
|
||||
GC9A01_Select();
|
||||
HAL_SPI_Transmit(hspi_gc9a01, buffer, len, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
GC9A01_Unselect();
|
||||
}
|
||||
|
||||
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);
|
||||
uint8_t data_col[4] = { (uint8_t)(x0>>8), (uint8_t)(x0&0xFF), (uint8_t)(x1>>8), (uint8_t)(x1&0xFF) };
|
||||
GC9A01_WriteDataBuffer(data_col, 4);
|
||||
|
||||
// Row address set
|
||||
GC9A01_WriteCommand(GC9A01_RASET);
|
||||
GC9A01_WriteData(y0 >> 8);
|
||||
GC9A01_WriteData(y0 & 0xFF);
|
||||
GC9A01_WriteData(y1 >> 8);
|
||||
GC9A01_WriteData(y1 & 0xFF);
|
||||
uint8_t data_row[4] = { (uint8_t)(y0>>8), (uint8_t)(y0&0xFF), (uint8_t)(y1>>8), (uint8_t)(y1&0xFF) };
|
||||
GC9A01_WriteDataBuffer(data_row, 4);
|
||||
|
||||
// Write to RAM
|
||||
GC9A01_WriteCommand(GC9A01_RAMWR);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Fonctions publiques
|
||||
//==============================================================================
|
||||
|
||||
bool GC9A01_Init(SPI_HandleTypeDef *hspi) {
|
||||
void 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);
|
||||
GC9A01_WriteCommand(GC9A01_SWRESET);
|
||||
HAL_Delay(150);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_SLPOUT); // sortie du mode veille
|
||||
HAL_Delay(120);
|
||||
|
||||
// Format pixel RGB565 16-bit
|
||||
GC9A01_WriteCommand(GC9A01_COLMOD);
|
||||
GC9A01_WriteData(0x55); // 16 bits/pixel
|
||||
HAL_Delay(10);
|
||||
|
||||
// Memory Access Control : rotation / orientation
|
||||
GC9A01_WriteCommand(GC9A01_MADCTL);
|
||||
GC9A01_WriteData(0x00); // rotation normale, ajuste si besoin
|
||||
|
||||
// Activation de l'écran
|
||||
GC9A01_WriteCommand(GC9A01_INVON); // inversion couleurs (souvent requis)
|
||||
HAL_Delay(10);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_NORON); // mode normal on
|
||||
HAL_Delay(10);
|
||||
|
||||
GC9A01_WriteCommand(GC9A01_DISPON); // allume l'écran
|
||||
HAL_Delay(100);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void GC9A01_Reset(void) {
|
||||
HAL_GPIO_WritePin(GC9A01_RST_GPIO_Port, GC9A01_RST_Pin, GPIO_PIN_RESET);
|
||||
HAL_Delay(10);
|
||||
|
|
@ -349,78 +103,115 @@ void GC9A01_Reset(void) {
|
|||
HAL_Delay(10);
|
||||
}
|
||||
|
||||
void GC9A01_DisplayOn(void) {
|
||||
GC9A01_WriteCommand(GC9A01_DISPON);
|
||||
}
|
||||
|
||||
void GC9A01_DisplayOff(void) {
|
||||
GC9A01_WriteCommand(GC9A01_DISPOFF);
|
||||
}
|
||||
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;
|
||||
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);
|
||||
// Optimisé : envoie des blocs de pixels pour remplir un rectangle
|
||||
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;
|
||||
|
||||
uint8_t color_high = color >> 8;
|
||||
uint8_t color_low = color & 0xFF;
|
||||
GC9A01_SetAddressWindow(x, y, x + width - 1, y + height - 1);
|
||||
|
||||
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);
|
||||
static uint8_t data[PIX_BUF * 2];
|
||||
uint8_t high = color >> 8;
|
||||
uint8_t low = color & 0xFF;
|
||||
for (uint32_t i = 0; i < PIX_BUF; ++i) {
|
||||
data[2*i] = high;
|
||||
data[2*i + 1] = low;
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(GC9A01_CS_GPIO_Port, GC9A01_CS_Pin, GPIO_PIN_SET);
|
||||
uint32_t total = (uint32_t)width * height;
|
||||
GC9A01_DC_Data();
|
||||
GC9A01_Select();
|
||||
while (total) {
|
||||
uint32_t chunk = (total > PIX_BUF) ? PIX_BUF : total;
|
||||
HAL_SPI_Transmit(hspi_gc9a01, data, chunk * 2, HAL_MAX_DELAY);
|
||||
total -= chunk;
|
||||
}
|
||||
GC9A01_Unselect();
|
||||
}
|
||||
|
||||
void GC9A01_FillScreen(uint16_t color) {
|
||||
GC9A01_FillRect(0, 0, GC9A01_WIDTH, GC9A01_HEIGHT, color);
|
||||
}
|
||||
|
||||
// Remplit uniquement la zone ronde (en envoyant per-scanline des chunks contigus)
|
||||
void GC9A01_FillCircleScreen(uint16_t color) {
|
||||
const uint16_t cx = GC9A01_RADIUS;
|
||||
const uint16_t cy = GC9A01_RADIUS;
|
||||
const int32_t r = GC9A01_RADIUS;
|
||||
const int32_t r2 = r * r;
|
||||
static uint8_t buffer[PIX_BUF * 2];
|
||||
uint8_t high = color >> 8;
|
||||
uint8_t low = color & 0xFF;
|
||||
|
||||
for (int y = 0; y < GC9A01_HEIGHT; ++y) {
|
||||
int32_t dy = y - (int32_t)cy;
|
||||
// calcule x-range pour cette ligne qui est dans le cercle
|
||||
// x^2 + dy^2 <= r^2 => x in [cx - dx, cx + dx] where dx = sqrt(r^2 - dy^2)
|
||||
int32_t tmp = r2 - dy*dy;
|
||||
if (tmp < 0) continue;
|
||||
int32_t dx = (int32_t)sqrtf((float)tmp);
|
||||
int32_t xstart = cx - dx;
|
||||
int32_t xend = cx + dx;
|
||||
int32_t len = xend - xstart + 1;
|
||||
if (xstart < 0) { len -= -xstart; xstart = 0; }
|
||||
if (xend >= GC9A01_WIDTH) { len -= (xend - (GC9A01_WIDTH-1)); xend = GC9A01_WIDTH-1; }
|
||||
if (len <= 0) continue;
|
||||
|
||||
// Prépare la fenêtre pour cette portion contiguë et envoie la ligne en chunks
|
||||
GC9A01_SetAddressWindow((uint16_t)xstart, (uint16_t)y, (uint16_t)xend, (uint16_t)y);
|
||||
// remplit buffer
|
||||
uint32_t to_send = (uint32_t)len;
|
||||
GC9A01_DC_Data();
|
||||
GC9A01_Select();
|
||||
while (to_send) {
|
||||
uint32_t chunk = (to_send > PIX_BUF) ? PIX_BUF : to_send;
|
||||
for (uint32_t i = 0; i < chunk; ++i) {
|
||||
buffer[2*i] = high;
|
||||
buffer[2*i + 1] = low;
|
||||
}
|
||||
HAL_SPI_Transmit(hspi_gc9a01, buffer, chunk * 2, HAL_MAX_DELAY);
|
||||
to_send -= chunk;
|
||||
}
|
||||
GC9A01_Unselect();
|
||||
}
|
||||
}
|
||||
|
||||
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};
|
||||
uint8_t data[2] = { (uint8_t)(color >> 8), (uint8_t)(color & 0xFF) };
|
||||
GC9A01_WriteDataBuffer(data, 2);
|
||||
}
|
||||
|
||||
// (les fonctions DrawLine, DrawCircle, FillCircle, DrawChar, DrawString...)
|
||||
// tu peux réutiliser les implémentations que tu avais — les voici en version compacte:
|
||||
|
||||
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;
|
||||
}
|
||||
if (e2 > -dy) { err -= dy; x0 += sx; }
|
||||
if (e2 < dx) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -431,57 +222,33 @@ void GC9A01_DrawRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, ui
|
|||
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;
|
||||
|
||||
int16_t dx = 1;
|
||||
int16_t dy = -2 * radius;
|
||||
int16_t xi = 0;
|
||||
int16_t yi = 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) {
|
||||
while (xi < yi) {
|
||||
if (f >= 0) {
|
||||
y1--;
|
||||
ddF_y += 2;
|
||||
f += ddF_y;
|
||||
yi--;
|
||||
dy += 2;
|
||||
f += dy;
|
||||
}
|
||||
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);
|
||||
xi++;
|
||||
dx += 2;
|
||||
f += dx;
|
||||
GC9A01_SetPixel(x + xi, y + yi, color);
|
||||
GC9A01_SetPixel(x - xi, y + yi, color);
|
||||
GC9A01_SetPixel(x + xi, y - yi, color);
|
||||
GC9A01_SetPixel(x - xi, y - yi, color);
|
||||
GC9A01_SetPixel(x + yi, y + xi, color);
|
||||
GC9A01_SetPixel(x - yi, y + xi, color);
|
||||
GC9A01_SetPixel(x + yi, y - xi, color);
|
||||
GC9A01_SetPixel(x - yi, y - xi, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,23 +263,16 @@ void GC9A01_FillCircle(uint16_t x, uint16_t y, uint8_t radius, uint16_t 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 ((uint8_t)c < 32 || (uint8_t)c > 127) c = ' ';
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
uint8_t line = font8x8_basic[(uint8_t)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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (size == 1) GC9A01_SetPixel(x + j, y + i, bg_color);
|
||||
else GC9A01_FillRect(x + j*size, y + i*size, size, size, bg_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -522,7 +282,7 @@ void GC9A01_DrawString(uint16_t x, uint16_t y, const char *str, uint16_t color,
|
|||
while (*str) {
|
||||
GC9A01_DrawChar(x, y, *str, color, bg_color, size);
|
||||
x += 8 * size;
|
||||
str++;
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -531,102 +291,55 @@ uint16_t GC9A01_RGB565(uint8_t r, uint8_t g, uint8_t b) {
|
|||
}
|
||||
|
||||
bool GC9A01_IsInCircle(uint16_t x, uint16_t y) {
|
||||
int16_t dx = x - GC9A01_RADIUS;
|
||||
int16_t dy = y - GC9A01_RADIUS;
|
||||
int32_t dx = (int32_t)x - GC9A01_RADIUS;
|
||||
int32_t dy = (int32_t)y - GC9A01_RADIUS;
|
||||
return (dx*dx + dy*dy) <= (GC9A01_RADIUS * GC9A01_RADIUS);
|
||||
}
|
||||
|
||||
// Fonctions spécifiques pour interface moto
|
||||
// Fonctions moto (réutilise celles que tu as déjà)
|
||||
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
|
||||
uint16_t color, const char* label)
|
||||
{
|
||||
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
|
||||
float angle = -90.0f + normalized * 180.0f;
|
||||
float rad = angle * (float)M_PI / 180.0f;
|
||||
int16_t nx = center_x + (radius - 5) * cosf(rad);
|
||||
int16_t ny = center_y + (radius - 5) * sinf(rad);
|
||||
GC9A01_DrawLine(center_x, center_y, nx, ny, color);
|
||||
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);
|
||||
}
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%.1f", value);
|
||||
GC9A01_DrawString(center_x - 20, center_y + radius + 8, buf, color, GC9A01_BLACK, 1);
|
||||
if (label) GC9A01_DrawString(center_x - (int)strlen(label)*4, center_y - radius - 18, 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;
|
||||
uint16_t cx = GC9A01_WIDTH / 2;
|
||||
uint16_t cy = GC9A01_HEIGHT / 2;
|
||||
uint16_t radius = 50;
|
||||
|
||||
// Effacer la zone central
|
||||
GC9A01_FillCircle(center_x, center_y, 50, GC9A01_BLACK);
|
||||
GC9A01_FillCircle(cx, cy, radius, GC9A01_BLACK);
|
||||
GC9A01_DrawCircle(cx, cy, radius, GC9A01_WHITE);
|
||||
|
||||
// Dessiner l'horizon artificiel
|
||||
GC9A01_DrawCircle(center_x, center_y, 50, GC9A01_WHITE);
|
||||
int16_t hor = (int16_t)(pitch * 2.0f); // décalage vertical (pitch)
|
||||
GC9A01_DrawLine(cx - 40, cy + hor, cx + 40, cy + hor, GC9A01_CYAN);
|
||||
|
||||
// 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);
|
||||
float rad = roll * ((float)M_PI / 180.0f); // conversion roll en radians
|
||||
int16_t nx = cx + (int16_t)(30 * cosf(rad));
|
||||
int16_t ny = cy + (int16_t)(30 * sinf(rad));
|
||||
|
||||
// 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);
|
||||
GC9A01_DrawLine(cx, cy, nx, ny, GC9A01_YELLOW);
|
||||
GC9A01_FillCircle(nx, ny, 3, GC9A01_YELLOW);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
uint16_t tw = strlen(state) * 8;
|
||||
uint16_t sx = (GC9A01_WIDTH > tw) ? (GC9A01_WIDTH - tw) / 2 : 0;
|
||||
GC9A01_DrawString(sx, GC9A01_HEIGHT - 20, state, color, GC9A01_BLACK, 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ 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;
|
||||
|
||||
|
|
@ -82,7 +81,6 @@ int main(void) {
|
|||
|
||||
|
||||
uint32_t last_time = HAL_GetTick();
|
||||
uint32_t init_start_time = last_time;
|
||||
uint32_t display_update_counter = 0;
|
||||
|
||||
while (1) {
|
||||
|
|
@ -106,9 +104,9 @@ int main(void) {
|
|||
mz_filtered = MOTO_MAG_FILTER_ALPHA * mz + (1.0f - MOTO_MAG_FILTER_ALPHA) * mz_filtered;
|
||||
|
||||
// Préparation des données pour Fusion
|
||||
FusionVector gyroscope = {gx, gy, gz};
|
||||
FusionVector accelerometer = {ax, ay, az};
|
||||
FusionVector magnetometer = {mx_filtered, my_filtered, mz_filtered};
|
||||
FusionVector gyroscope = {{gx, gy, gz}};
|
||||
FusionVector accelerometer = {{ax, ay, az}};
|
||||
FusionVector magnetometer = {{mx_filtered, my_filtered, mz_filtered}};
|
||||
|
||||
// Mise à jour AHRS
|
||||
FusionAhrsUpdate(&ahrs, gyroscope, accelerometer, magnetometer, dt);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
../Core/Src/gc9a01.c:19:20:GC9A01_Select 1
|
||||
../Core/Src/gc9a01.c:22:20:GC9A01_Unselect 1
|
||||
../Core/Src/gc9a01.c:25:20:GC9A01_DC_Command 1
|
||||
../Core/Src/gc9a01.c:28:20:GC9A01_DC_Data 1
|
||||
../Core/Src/gc9a01.c:32:13:GC9A01_WriteCommand 1
|
||||
../Core/Src/gc9a01.c:39:13:GC9A01_WriteData 1
|
||||
../Core/Src/gc9a01.c:46:13:GC9A01_WriteDataBuffer 2
|
||||
../Core/Src/gc9a01.c:54:13:GC9A01_SetAddressWindow 1
|
||||
../Core/Src/gc9a01.c:66:6:GC9A01_Init 1
|
||||
../Core/Src/gc9a01.c:99:6:GC9A01_Reset 1
|
||||
../Core/Src/gc9a01.c:106:6:GC9A01_DisplayOn 1
|
||||
../Core/Src/gc9a01.c:107:6:GC9A01_DisplayOff 1
|
||||
../Core/Src/gc9a01.c:109:6:GC9A01_SetRotation 5
|
||||
../Core/Src/gc9a01.c:120:6:GC9A01_FillRect 7
|
||||
../Core/Src/gc9a01.c:146:6:GC9A01_FillScreen 1
|
||||
../Core/Src/gc9a01.c:151:6:GC9A01_FillCircleScreen 8
|
||||
../Core/Src/gc9a01.c:193:6:GC9A01_SetPixel 3
|
||||
../Core/Src/gc9a01.c:203:6:GC9A01_DrawLine 7
|
||||
../Core/Src/gc9a01.c:218:6:GC9A01_DrawRect 1
|
||||
../Core/Src/gc9a01.c:225:6:GC9A01_DrawCircle 3
|
||||
../Core/Src/gc9a01.c:255:6:GC9A01_FillCircle 4
|
||||
../Core/Src/gc9a01.c:265:6:GC9A01_DrawChar 9
|
||||
../Core/Src/gc9a01.c:281:6:GC9A01_DrawString 2
|
||||
../Core/Src/gc9a01.c:289:10:GC9A01_RGB565 1
|
||||
../Core/Src/gc9a01.c:293:6:GC9A01_IsInCircle 1
|
||||
../Core/Src/gc9a01.c:300:6:GC9A01_DrawGauge 4
|
||||
../Core/Src/gc9a01.c:320:6:GC9A01_DrawAngleIndicator 1
|
||||
../Core/Src/gc9a01.c:340:6:GC9A01_DrawStateIndicator 2
|
||||
Binary file not shown.
|
|
@ -0,0 +1,28 @@
|
|||
../Core/Src/gc9a01.c:19:20:GC9A01_Select 8 static
|
||||
../Core/Src/gc9a01.c:22:20:GC9A01_Unselect 8 static
|
||||
../Core/Src/gc9a01.c:25:20:GC9A01_DC_Command 8 static
|
||||
../Core/Src/gc9a01.c:28:20:GC9A01_DC_Data 8 static
|
||||
../Core/Src/gc9a01.c:32:13:GC9A01_WriteCommand 16 static
|
||||
../Core/Src/gc9a01.c:39:13:GC9A01_WriteData 16 static
|
||||
../Core/Src/gc9a01.c:46:13:GC9A01_WriteDataBuffer 16 static
|
||||
../Core/Src/gc9a01.c:54:13:GC9A01_SetAddressWindow 32 static
|
||||
../Core/Src/gc9a01.c:66:6:GC9A01_Init 16 static
|
||||
../Core/Src/gc9a01.c:99:6:GC9A01_Reset 8 static
|
||||
../Core/Src/gc9a01.c:106:6:GC9A01_DisplayOn 8 static
|
||||
../Core/Src/gc9a01.c:107:6:GC9A01_DisplayOff 8 static
|
||||
../Core/Src/gc9a01.c:109:6:GC9A01_SetRotation 16 static
|
||||
../Core/Src/gc9a01.c:120:6:GC9A01_FillRect 40 static
|
||||
../Core/Src/gc9a01.c:146:6:GC9A01_FillScreen 24 static
|
||||
../Core/Src/gc9a01.c:151:6:GC9A01_FillCircleScreen 72 static
|
||||
../Core/Src/gc9a01.c:193:6:GC9A01_SetPixel 24 static
|
||||
../Core/Src/gc9a01.c:203:6:GC9A01_DrawLine 40 static
|
||||
../Core/Src/gc9a01.c:218:6:GC9A01_DrawRect 32 static
|
||||
../Core/Src/gc9a01.c:225:6:GC9A01_DrawCircle 40 static
|
||||
../Core/Src/gc9a01.c:255:6:GC9A01_FillCircle 32 static
|
||||
../Core/Src/gc9a01.c:265:6:GC9A01_DrawChar 48 static
|
||||
../Core/Src/gc9a01.c:281:6:GC9A01_DrawString 40 static
|
||||
../Core/Src/gc9a01.c:289:10:GC9A01_RGB565 16 static
|
||||
../Core/Src/gc9a01.c:293:6:GC9A01_IsInCircle 24 static
|
||||
../Core/Src/gc9a01.c:300:6:GC9A01_DrawGauge 88 static
|
||||
../Core/Src/gc9a01.c:320:6:GC9A01_DrawAngleIndicator 48 static
|
||||
../Core/Src/gc9a01.c:340:6:GC9A01_DrawStateIndicator 32 static
|
||||
Binary file not shown.
|
|
@ -1,12 +1,5 @@
|
|||
../Core/Inc/FusionMath.h:136:21:FusionRadiansToDegrees 1
|
||||
../Core/Inc/FusionMath.h:148:21:FusionAsin 3
|
||||
../Core/Inc/FusionMath.h:466:27:FusionQuaternionToEuler 1
|
||||
../Core/Src/main.c:30:5:__io_putchar 1
|
||||
../Core/Src/main.c:38:5:main 11
|
||||
../Core/Src/main.c:218:6:Update_TFT_Display 26
|
||||
../Core/Src/main.c:369:6:SystemClock_Config 4
|
||||
../Core/Src/main.c:419:13:MX_I2C1_Init 4
|
||||
../Core/Src/main.c:467:13:MX_SPI1_Init 2
|
||||
../Core/Src/main.c:507:13:MX_USART2_UART_Init 2
|
||||
../Core/Src/main.c:542:13:MX_GPIO_Init 1
|
||||
../Core/Src/main.c:610:6:Error_Handler 1
|
||||
../Core/Src/main.c:12:5:main 1
|
||||
../Core/Src/main.c:35:13:MX_SPI1_Init 2
|
||||
../Core/Src/main.c:56:13:MX_GPIO_Init 1
|
||||
../Core/Src/main.c:74:6:SystemClock_Config 3
|
||||
../Core/Src/main.c:104:6:Error_Handler 1
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@ Core/Src/main.o: ../Core/Src/main.c ../Core/Inc/main.h \
|
|||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h \
|
||||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h \
|
||||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h \
|
||||
../Core/Inc/lcd_i2c.h ../Core/Inc/icm20948.h ../Core/Inc/FusionAhrs.h \
|
||||
../Core/Inc/FusionConvention.h ../Core/Inc/FusionMath.h \
|
||||
../Core/Inc/moto_config.h ../Core/Inc/gc9a01.h ../Core/Inc/main.h
|
||||
../Core/Inc/gc9a01.h ../Core/Inc/main.h
|
||||
../Core/Inc/main.h:
|
||||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h:
|
||||
../Core/Inc/stm32l4xx_hal_conf.h:
|
||||
|
|
@ -63,11 +61,5 @@ Core/Src/main.o: ../Core/Src/main.c ../Core/Inc/main.h \
|
|||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h:
|
||||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h:
|
||||
../Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h:
|
||||
../Core/Inc/lcd_i2c.h:
|
||||
../Core/Inc/icm20948.h:
|
||||
../Core/Inc/FusionAhrs.h:
|
||||
../Core/Inc/FusionConvention.h:
|
||||
../Core/Inc/FusionMath.h:
|
||||
../Core/Inc/moto_config.h:
|
||||
../Core/Inc/gc9a01.h:
|
||||
../Core/Inc/main.h:
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,12 +1,5 @@
|
|||
../Core/Inc/FusionMath.h:136:21:FusionRadiansToDegrees 16 static
|
||||
../Core/Inc/FusionMath.h:148:21:FusionAsin 16 static
|
||||
../Core/Inc/FusionMath.h:466:27:FusionQuaternionToEuler 72 static
|
||||
../Core/Src/main.c:30:5:__io_putchar 16 static
|
||||
../Core/Src/main.c:38:5:main 328 static
|
||||
../Core/Src/main.c:218:6:Update_TFT_Display 136 static
|
||||
../Core/Src/main.c:369:6:SystemClock_Config 96 static
|
||||
../Core/Src/main.c:419:13:MX_I2C1_Init 8 static
|
||||
../Core/Src/main.c:467:13:MX_SPI1_Init 8 static
|
||||
../Core/Src/main.c:507:13:MX_USART2_UART_Init 8 static
|
||||
../Core/Src/main.c:542:13:MX_GPIO_Init 48 static
|
||||
../Core/Src/main.c:610:6:Error_Handler 4 static,ignoring_inline_asm
|
||||
../Core/Src/main.c:12:5:main 8 static
|
||||
../Core/Src/main.c:35:13:MX_SPI1_Init 8 static
|
||||
../Core/Src/main.c:56:13:MX_GPIO_Init 32 static
|
||||
../Core/Src/main.c:74:6:SystemClock_Config 96 static
|
||||
../Core/Src/main.c:104:6:Error_Handler 4 static
|
||||
|
|
|
|||
Binary file not shown.
28801
Debug/moto-perf.list
28801
Debug/moto-perf.list
File diff suppressed because it is too large
Load Diff
3221
Debug/moto-perf.map
3221
Debug/moto-perf.map
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue