Первая рабочая программа с рисовальщиком. Тач откалиброван
This commit is contained in:
224
Core/Src/App/Paint/appPaint.c
Normal file
224
Core/Src/App/Paint/appPaint.c
Normal file
@@ -0,0 +1,224 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
|
||||
/* BSP LCD driver */
|
||||
#include "stm32_adafruit_lcd.h"
|
||||
|
||||
/* BSP TS driver */
|
||||
#include "stm32_adafruit_ts.h"
|
||||
|
||||
//=============================================================================
|
||||
/* Setting section (please set the necessary things in this section) */
|
||||
|
||||
/* Touchscreen calibrate at starting
|
||||
- 0: off (for the touchscreen, use the TS_CINDEX values in stm32_adafruit_ts.h)
|
||||
- 1: on (the touchscreen must be calibrated at startup)
|
||||
- 2: on and printf (the touchscreen must be calibrated at startup and printf the cindex values)
|
||||
- 3: on and displays the TS_CINDEX values on the screen */
|
||||
#define TS_CALBIBRATE 0
|
||||
|
||||
/* If TS_CALBIBRATE == 3 -> Text line size */
|
||||
#define TS_CALIBTEXTSIZE 12
|
||||
|
||||
//=============================================================================
|
||||
#ifdef osCMSIS
|
||||
#define Delay(t) osDelay(t)
|
||||
#define GetTime() osKernelSysTick()
|
||||
#else
|
||||
#define Delay(t) HAL_Delay(t)
|
||||
#define GetTime() HAL_GetTick()
|
||||
#endif
|
||||
|
||||
#if TS_CALBIBRATE == 0
|
||||
#define ts_calib()
|
||||
#elif TS_CALBIBRATE > 0
|
||||
|
||||
#include "ts.h"
|
||||
|
||||
#define CALIBDELAY 500
|
||||
#define CALIBBOXSIZE 6
|
||||
#define CALIBBOXPOS 15
|
||||
#define TOUCHDELAY 50
|
||||
|
||||
extern TS_DrvTypeDef *ts_drv;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void touchcalib_drawBox(int32_t x, int32_t y, uint16_t cl)
|
||||
{
|
||||
BSP_LCD_SetTextColor(cl);
|
||||
BSP_LCD_DrawRect(x - CALIBBOXSIZE / 2, y - CALIBBOXSIZE / 2, CALIBBOXSIZE, CALIBBOXSIZE);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Touchscreen calibration function */
|
||||
void ts_calib(void)
|
||||
{
|
||||
uint16_t tx, ty;
|
||||
ts_three_points tc, dc; /* touchscreen and display corrdinates */
|
||||
#if TS_CALBIBRATE == 2
|
||||
ts_cindex ci;
|
||||
#elif TS_CALBIBRATE == 3
|
||||
ts_cindex ci;
|
||||
static char s[16];
|
||||
#endif
|
||||
|
||||
dc.x0 = 20;
|
||||
dc.y0 = 20;
|
||||
dc.x1 = BSP_LCD_GetXSize() >> 1;
|
||||
dc.x2 = BSP_LCD_GetXSize() - 1 - 20;
|
||||
dc.y1 = BSP_LCD_GetYSize() - 1 - 20;
|
||||
dc.y2 = BSP_LCD_GetYSize() >> 1;
|
||||
|
||||
touchcalib_drawBox(dc.x0, dc.y0, LCD_COLOR_YELLOW);
|
||||
Delay(CALIBDELAY);
|
||||
while(!ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
ts_drv->GetXY(0, &tx, &ty);
|
||||
tc.x0 = tx; tc.y0 = ty;
|
||||
|
||||
while(ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
|
||||
touchcalib_drawBox(dc.x0, dc.y0, LCD_COLOR_GRAY);
|
||||
touchcalib_drawBox(dc.x1, dc.y1, LCD_COLOR_YELLOW);
|
||||
Delay(CALIBDELAY);
|
||||
while(!ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
ts_drv->GetXY(0, &tx, &ty);
|
||||
tc.x1 = tx; tc.y1 = ty;
|
||||
while(ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
|
||||
touchcalib_drawBox(dc.x1, dc.y1, LCD_COLOR_GRAY);
|
||||
touchcalib_drawBox(dc.x2, dc.y2, LCD_COLOR_YELLOW);
|
||||
Delay(CALIBDELAY);
|
||||
while(!ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
ts_drv->GetXY(0, &tx, &ty);
|
||||
tc.x2 = tx; tc.y2 = ty;
|
||||
while(ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
|
||||
#if TS_CALBIBRATE == 1
|
||||
BSP_TS_CalibCalc(&tc, &dc, NULL);
|
||||
#elif TS_CALBIBRATE == 2
|
||||
BSP_TS_CalibCalc(&tc, &dc, &ci);
|
||||
BSP_TS_SetCindex(&ci);
|
||||
printf("\r\n#define TS_CINDEX {%d, %d, %d, %d, %d, %d, %d}\r\n", (int)ci[0], (int)ci[1], (int)ci[2], (int)ci[3], (int)ci[4], (int)ci[5], (int)ci[6]);
|
||||
#elif TS_CALBIBRATE == 3
|
||||
BSP_TS_CalibCalc(&tc, &dc, &ci);
|
||||
BSP_TS_SetCindex(&ci);
|
||||
BSP_LCD_DisplayStringAt(10, 0, (uint8_t *)"#define TS_CINDEX", LEFT_MODE);
|
||||
for(uint32_t i=0; i<7; i++)
|
||||
{
|
||||
sprintf(s, "%d", (int)ci[i]);
|
||||
BSP_LCD_DisplayStringAt(10, (i+1)*TS_CALIBTEXTSIZE, (uint8_t *)s, LEFT_MODE);
|
||||
}
|
||||
Delay(CALIBDELAY);
|
||||
while(!ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
while(ts_drv->DetectTouch(0))
|
||||
Delay(TOUCHDELAY);
|
||||
#endif
|
||||
Delay(CALIBDELAY);
|
||||
BSP_LCD_Clear(LCD_COLOR_BLACK);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void mainApp(void)
|
||||
{
|
||||
TS_StateTypeDef ts;
|
||||
uint16_t boxsize;
|
||||
uint16_t oldcolor, currentcolor;
|
||||
|
||||
BSP_LCD_Init();
|
||||
BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
|
||||
BSP_LCD_Clear(LCD_COLOR_BLACK);
|
||||
ts_calib();
|
||||
boxsize = BSP_LCD_GetXSize() / 6;
|
||||
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_RED);
|
||||
BSP_LCD_FillRect(0, 0, boxsize, boxsize);
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_YELLOW);
|
||||
BSP_LCD_FillRect(boxsize, 0, boxsize, boxsize);
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_GREEN);
|
||||
BSP_LCD_FillRect(boxsize * 2, 0, boxsize, boxsize);
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_CYAN);
|
||||
BSP_LCD_FillRect(boxsize * 3, 0, boxsize, boxsize);
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_BLUE);
|
||||
BSP_LCD_FillRect(boxsize * 4, 0, boxsize, boxsize);
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_MAGENTA);
|
||||
BSP_LCD_FillRect(boxsize * 5, 0, boxsize, boxsize);
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
|
||||
|
||||
BSP_LCD_DrawRect(0, 0, boxsize, boxsize);
|
||||
currentcolor = LCD_COLOR_RED;
|
||||
|
||||
while(1)
|
||||
{
|
||||
BSP_TS_GetState(&ts);
|
||||
if(ts.TouchDetected)
|
||||
{
|
||||
if(ts.Y < boxsize)
|
||||
{
|
||||
BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
|
||||
if (ts.X < boxsize)
|
||||
{
|
||||
currentcolor = LCD_COLOR_RED;
|
||||
BSP_LCD_DrawRect(0, 0, boxsize, boxsize);
|
||||
}
|
||||
else if (ts.X < boxsize * 2)
|
||||
{
|
||||
currentcolor = LCD_COLOR_YELLOW;
|
||||
BSP_LCD_DrawRect(boxsize, 0, boxsize, boxsize);
|
||||
}
|
||||
else if (ts.X < boxsize * 3)
|
||||
{
|
||||
currentcolor = LCD_COLOR_GREEN;
|
||||
BSP_LCD_DrawRect(boxsize*2, 0, boxsize, boxsize);
|
||||
}
|
||||
else if (ts.X < boxsize * 4)
|
||||
{
|
||||
currentcolor = LCD_COLOR_CYAN;
|
||||
BSP_LCD_DrawRect(boxsize*3, 0, boxsize, boxsize);
|
||||
}
|
||||
else if (ts.X < boxsize * 5)
|
||||
{
|
||||
currentcolor = LCD_COLOR_BLUE;
|
||||
BSP_LCD_DrawRect(boxsize*4, 0, boxsize, boxsize);
|
||||
}
|
||||
else if (ts.X < boxsize * 6)
|
||||
{
|
||||
currentcolor = LCD_COLOR_MAGENTA;
|
||||
BSP_LCD_DrawRect(boxsize*5, 0, boxsize, boxsize);
|
||||
}
|
||||
|
||||
if (oldcolor != currentcolor)
|
||||
{
|
||||
BSP_LCD_SetTextColor(oldcolor);
|
||||
if (oldcolor == LCD_COLOR_RED)
|
||||
BSP_LCD_FillRect(0, 0, boxsize, boxsize);
|
||||
else if (oldcolor == LCD_COLOR_YELLOW)
|
||||
BSP_LCD_FillRect(boxsize, 0, boxsize, boxsize);
|
||||
else if (oldcolor == LCD_COLOR_GREEN)
|
||||
BSP_LCD_FillRect(boxsize * 2, 0, boxsize, boxsize);
|
||||
else if (oldcolor == LCD_COLOR_CYAN)
|
||||
BSP_LCD_FillRect(boxsize * 3, 0, boxsize, boxsize);
|
||||
else if (oldcolor == LCD_COLOR_BLUE)
|
||||
BSP_LCD_FillRect(boxsize * 4, 0, boxsize, boxsize);
|
||||
else if (oldcolor == LCD_COLOR_MAGENTA)
|
||||
BSP_LCD_FillRect(boxsize * 5, 0, boxsize, boxsize);
|
||||
}
|
||||
|
||||
oldcolor = currentcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
BSP_LCD_DrawPixel(ts.X, ts.Y, currentcolor);
|
||||
}
|
||||
}
|
||||
Delay(1);
|
||||
}
|
||||
}
|
||||
1464
Core/Src/Lcd/Fonts/font12.c
Normal file
1464
Core/Src/Lcd/Fonts/font12.c
Normal file
File diff suppressed because it is too large
Load Diff
1844
Core/Src/Lcd/Fonts/font16.c
Normal file
1844
Core/Src/Lcd/Fonts/font16.c
Normal file
File diff suppressed because it is too large
Load Diff
2223
Core/Src/Lcd/Fonts/font20.c
Normal file
2223
Core/Src/Lcd/Fonts/font20.c
Normal file
File diff suppressed because it is too large
Load Diff
2600
Core/Src/Lcd/Fonts/font24.c
Normal file
2600
Core/Src/Lcd/Fonts/font24.c
Normal file
File diff suppressed because it is too large
Load Diff
1084
Core/Src/Lcd/Fonts/font8.c
Normal file
1084
Core/Src/Lcd/Fonts/font8.c
Normal file
File diff suppressed because it is too large
Load Diff
134
Core/Src/Lcd/Fonts/fonts.h
Normal file
134
Core/Src/Lcd/Fonts/fonts.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file fonts.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 18-February-2014
|
||||
* @brief Header for fonts.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __FONTS_H
|
||||
#define __FONTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/** @addtogroup Utilities
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32_EVAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup Common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup FONTS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FONTS_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
typedef struct _tFont
|
||||
{
|
||||
const uint8_t *table;
|
||||
uint16_t Width;
|
||||
uint16_t Height;
|
||||
|
||||
} sFONT;
|
||||
|
||||
extern sFONT Font24;
|
||||
extern sFONT Font20;
|
||||
extern sFONT Font16;
|
||||
extern sFONT Font12;
|
||||
extern sFONT Font8;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FONTS_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
#define LINE(x) ((x) * (((sFONT *)BSP_LCD_GetFont())->Height))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FONTS_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FONTS_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FONTS_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
42
Core/Src/Lcd/bmp.h
Normal file
42
Core/Src/Lcd/bmp.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* bmp.h
|
||||
*
|
||||
* Created on: 2019. febr. 17.
|
||||
* Author: Benjami
|
||||
*/
|
||||
|
||||
#ifndef __BMP_H_
|
||||
#define __BMP_H_
|
||||
|
||||
typedef struct __attribute__((packed)) tagBITMAPFILEHEADER {
|
||||
uint16_t bfType;
|
||||
uint32_t bfSize;
|
||||
uint16_t bfReserved1;
|
||||
uint16_t bfReserved2;
|
||||
uint32_t bfOffBits;
|
||||
} BITMAPFILEHEADER; // size is 14 bytes
|
||||
|
||||
typedef struct __attribute__((packed)) tagBITMAPINFOHEADER {
|
||||
uint32_t biSize;
|
||||
uint32_t biWidth;
|
||||
uint32_t biHeight;
|
||||
uint16_t biPlanes;
|
||||
uint16_t biBitCount;
|
||||
uint32_t biCompression;
|
||||
uint32_t biSizeImage;
|
||||
uint32_t biXPelsPerMeter;
|
||||
uint32_t biYPelsPerMeter;
|
||||
uint32_t biClrUsed;
|
||||
uint32_t biClrImportant;
|
||||
} BITMAPINFOHEADER; // size is 40 bytes
|
||||
|
||||
typedef struct __attribute__((packed)) tagBITMAPSTRUCT {
|
||||
// offset 0, size 14
|
||||
BITMAPFILEHEADER fileHeader;
|
||||
// offset 14, size 40
|
||||
BITMAPINFOHEADER infoHeader;
|
||||
// offset 54, size X * Y words
|
||||
uint16_t data[];
|
||||
} BITMAPSTRUCT;
|
||||
|
||||
#endif /* __BMP_H_ */
|
||||
699
Core/Src/Lcd/ili9488.c
Normal file
699
Core/Src/Lcd/ili9488.c
Normal file
@@ -0,0 +1,699 @@
|
||||
#include "main.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_io.h"
|
||||
#include "ili9488.h"
|
||||
|
||||
void ili9488_Init(void);
|
||||
uint32_t ili9488_ReadID(void);
|
||||
void ili9488_DisplayOn(void);
|
||||
void ili9488_DisplayOff(void);
|
||||
void ili9488_SetCursor(uint16_t Xpos, uint16_t Ypos);
|
||||
void ili9488_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code);
|
||||
uint16_t ili9488_ReadPixel(uint16_t Xpos, uint16_t Ypos);
|
||||
void ili9488_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
|
||||
void ili9488_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length);
|
||||
void ili9488_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length);
|
||||
uint16_t ili9488_GetLcdPixelWidth(void);
|
||||
uint16_t ili9488_GetLcdPixelHeight(void);
|
||||
void ili9488_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp);
|
||||
void ili9488_DrawRGBImage(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t *pData);
|
||||
void ili9488_ReadRGBImage(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t *pData);
|
||||
void ili9488_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t RGBCode);
|
||||
void ili9488_Scroll(int16_t Scroll, uint16_t TopFix, uint16_t BottonFix);
|
||||
void ili9488_UserCommand(uint16_t Command, uint8_t * pData, uint32_t Size, uint8_t Mode);
|
||||
|
||||
LCD_DrvTypeDef ili9488_drv =
|
||||
{
|
||||
ili9488_Init,
|
||||
ili9488_ReadID,
|
||||
ili9488_DisplayOn,
|
||||
ili9488_DisplayOff,
|
||||
ili9488_SetCursor,
|
||||
ili9488_WritePixel,
|
||||
ili9488_ReadPixel,
|
||||
ili9488_SetDisplayWindow,
|
||||
ili9488_DrawHLine,
|
||||
ili9488_DrawVLine,
|
||||
ili9488_GetLcdPixelWidth,
|
||||
ili9488_GetLcdPixelHeight,
|
||||
ili9488_DrawBitmap,
|
||||
ili9488_DrawRGBImage,
|
||||
ili9488_FillRect,
|
||||
ili9488_ReadRGBImage,
|
||||
ili9488_Scroll,
|
||||
ili9488_UserCommand
|
||||
};
|
||||
|
||||
LCD_DrvTypeDef *lcd_drv = &ili9488_drv;
|
||||
|
||||
/* transaction data */
|
||||
#define TRANSDATAMAXSIZE 4
|
||||
union
|
||||
{
|
||||
char c[TRANSDATAMAXSIZE];
|
||||
uint8_t d8[TRANSDATAMAXSIZE];
|
||||
uint16_t d16[TRANSDATAMAXSIZE / 2];
|
||||
}transdata;
|
||||
|
||||
#define ILI9488_NOP 0x00
|
||||
#define ILI9488_SWRESET 0x01
|
||||
#define ILI9488_RDDID 0x04
|
||||
#define ILI9488_RDDST 0x09
|
||||
|
||||
#define ILI9488_SLPIN 0x10
|
||||
#define ILI9488_SLPOUT 0x11
|
||||
#define ILI9488_PTLON 0x12
|
||||
#define ILI9488_NORON 0x13
|
||||
|
||||
#define ILI9488_RDMODE 0x0A
|
||||
#define ILI9488_RDMADCTL 0x0B
|
||||
#define ILI9488_RDPIXFMT 0x0C
|
||||
#define ILI9488_RDIMGFMT 0x0D
|
||||
#define ILI9488_RDSELFDIAG 0x0F
|
||||
|
||||
#define ILI9488_INVOFF 0x20
|
||||
#define ILI9488_INVON 0x21
|
||||
#define ILI9488_GAMMASET 0x26
|
||||
#define ILI9488_DISPOFF 0x28
|
||||
#define ILI9488_DISPON 0x29
|
||||
|
||||
#define ILI9488_CASET 0x2A
|
||||
#define ILI9488_PASET 0x2B
|
||||
#define ILI9488_RAMWR 0x2C
|
||||
#define ILI9488_RAMRD 0x2E
|
||||
|
||||
#define ILI9488_PTLAR 0x30
|
||||
#define ILI9488_VSCRDEF 0x33
|
||||
#define ILI9488_MADCTL 0x36
|
||||
#define ILI9488_VSCRSADD 0x37
|
||||
#define ILI9488_PIXFMT 0x3A
|
||||
#define ILI9488_RAMWRCONT 0x3C
|
||||
#define ILI9488_RAMRDCONT 0x3E
|
||||
|
||||
#define ILI9488_IMCTR 0xB0
|
||||
#define ILI9488_FRMCTR1 0xB1
|
||||
#define ILI9488_FRMCTR2 0xB2
|
||||
#define ILI9488_FRMCTR3 0xB3
|
||||
#define ILI9488_INVCTR 0xB4
|
||||
#define ILI9488_DFUNCTR 0xB6
|
||||
|
||||
#define ILI9488_PWCTR1 0xC0
|
||||
#define ILI9488_PWCTR2 0xC1
|
||||
#define ILI9488_PWCTR3 0xC2
|
||||
#define ILI9488_PWCTR4 0xC3
|
||||
#define ILI9488_PWCTR5 0xC4
|
||||
#define ILI9488_VMCTR1 0xC5
|
||||
#define ILI9488_VMCTR2 0xC7
|
||||
|
||||
#define ILI9488_RDID1 0xDA
|
||||
#define ILI9488_RDID2 0xDB
|
||||
#define ILI9488_RDID3 0xDC
|
||||
#define ILI9488_RDID4 0xDD
|
||||
|
||||
#define ILI9488_GMCTRP1 0xE0
|
||||
#define ILI9488_GMCTRN1 0xE1
|
||||
#define ILI9488_IMGFUNCT 0xE9
|
||||
|
||||
#define ILI9488_ADJCTR3 0xF7
|
||||
|
||||
#define ILI9488_MAD_RGB 0x00
|
||||
#define ILI9488_MAD_BGR 0x08
|
||||
#define ILI9488_MAD_VREFRORD 0x10
|
||||
#define ILI9488_MAD_HREFRORD 0x04
|
||||
|
||||
#define ILI9488_MAD_VERTICAL 0x20
|
||||
#define ILI9488_MAD_X_LEFT 0x00
|
||||
#define ILI9488_MAD_X_RIGHT 0x40
|
||||
#define ILI9488_MAD_Y_UP 0x80
|
||||
#define ILI9488_MAD_Y_DOWN 0x00
|
||||
|
||||
#if ILI9488_COLORMODE == 0
|
||||
#define ILI9488_MAD_COLORMODE ILI9488_MAD_RGB
|
||||
#elif ILI9488_COLORMODE == 1
|
||||
#define ILI9488_MAD_COLORMODE ILI9488_MAD_BGR
|
||||
#endif
|
||||
|
||||
#define ILI9488_SETWINDOW(x1, x2, y1, y2) \
|
||||
{ transdata.d16[0] = x1; transdata.d16[1] = x2; LCD_IO_WriteCmd8MultipleData16(ILI9488_CASET, (uint16_t *)&transdata, 2); \
|
||||
transdata.d16[0] = y1; transdata.d16[1] = y2; LCD_IO_WriteCmd8MultipleData16(ILI9488_PASET, (uint16_t *)&transdata, 2); }
|
||||
|
||||
#define ILI9488_SETCURSOR(x, y) \
|
||||
{ transdata.d16[0] = x; transdata.d16[1] = transdata.d16[0]; LCD_IO_WriteCmd8MultipleData16(ILI9488_CASET, (uint16_t *)&transdata, 2); \
|
||||
transdata.d16[0] = y; transdata.d16[1] = transdata.d16[0]; LCD_IO_WriteCmd8MultipleData16(ILI9488_PASET, (uint16_t *)&transdata, 2); }
|
||||
|
||||
/* the drawing directions of the 4 orientations */
|
||||
#if ILI9488_ORIENTATION == 0
|
||||
#define ILI9488_MAX_X (ILI9488_LCD_PIXEL_WIDTH - 1)
|
||||
#define ILI9488_MAX_Y (ILI9488_LCD_PIXEL_HEIGHT - 1)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_UP (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_RIGHT | ILI9488_MAD_Y_UP)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_DOWN (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_RIGHT | ILI9488_MAD_Y_DOWN)
|
||||
#elif ILI9488_ORIENTATION == 1
|
||||
#define ILI9488_MAX_X (ILI9488_LCD_PIXEL_HEIGHT - 1)
|
||||
#define ILI9488_MAX_Y (ILI9488_LCD_PIXEL_WIDTH - 1)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_UP (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_RIGHT | ILI9488_MAD_Y_DOWN | ILI9488_MAD_VERTICAL)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_DOWN (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_LEFT | ILI9488_MAD_Y_DOWN | ILI9488_MAD_VERTICAL)
|
||||
#elif ILI9488_ORIENTATION == 2
|
||||
#define ILI9488_MAX_X (ILI9488_LCD_PIXEL_WIDTH - 1)
|
||||
#define ILI9488_MAX_Y (ILI9488_LCD_PIXEL_HEIGHT - 1)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_UP (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_LEFT | ILI9488_MAD_Y_DOWN)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_DOWN (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_LEFT | ILI9488_MAD_Y_UP)
|
||||
#elif ILI9488_ORIENTATION == 3
|
||||
#define ILI9488_MAX_X (ILI9488_LCD_PIXEL_HEIGHT - 1)
|
||||
#define ILI9488_MAX_Y (ILI9488_LCD_PIXEL_WIDTH - 1)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_UP (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_LEFT | ILI9488_MAD_Y_UP | ILI9488_MAD_VERTICAL)
|
||||
#define ILI9488_MAD_DATA_RIGHT_THEN_DOWN (ILI9488_MAD_COLORMODE | ILI9488_MAD_X_RIGHT | ILI9488_MAD_Y_UP | ILI9488_MAD_VERTICAL)
|
||||
#endif
|
||||
|
||||
#if ILI9488_INTERFACE == 0 || ILI9488_INTERFACE == 1
|
||||
static uint16_t yStart, yEnd;
|
||||
|
||||
#define SETWINDOW(x1, x2, y1, y2) ILI9488_SETWINDOW(x1, x2, y1, y2)
|
||||
#define SETCURSOR(x, y) ILI9488_SETCURSOR(x, y)
|
||||
|
||||
#elif ILI9488_INTERFACE == 2
|
||||
#if ILI9488_ORIENTATION == 0
|
||||
#define SETWINDOW(x1, x2, y1, y2) ILI9488_SETWINDOW(ILI9488_MAX_X - (x2), ILI9488_MAX_X - (x1), y1, y2)
|
||||
#define SETCURSOR(x, y) ILI9488_SETCURSOR(ILI9488_MAX_X - (x), y)
|
||||
#elif ILI9488_ORIENTATION == 1
|
||||
#define SETWINDOW(x1, x2, y1, y2) ILI9488_SETWINDOW(x1, x2, y1, y2)
|
||||
#define SETCURSOR(x, y) ILI9488_SETCURSOR(x, y)
|
||||
#elif ILI9488_ORIENTATION == 2
|
||||
#define SETWINDOW(x1, x2, y1, y2) ILI9488_SETWINDOW(x1, x2, ILI9488_MAX_Y - (y2), ILI9488_MAX_Y - (y1))
|
||||
#define SETCURSOR(x, y) ILI9488_SETCURSOR(x, ILI9488_MAX_Y - (y))
|
||||
#elif ILI9488_ORIENTATION == 3
|
||||
#define SETWINDOW(x1, x2, y1, y2) ILI9488_SETWINDOW(ILI9488_MAX_X - (x2), ILI9488_MAX_X - (x1), ILI9488_MAX_Y - (y2), ILI9488_MAX_Y - (y1))
|
||||
#define SETCURSOR(x, y) ILI9488_SETCURSOR(ILI9488_MAX_X - (x), ILI9488_MAX_Y - (y))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LCD_REVERSE16
|
||||
#define LCD_REVERSE16 0
|
||||
#endif
|
||||
|
||||
#define ILI9488_LCD_INITIALIZED 0x01
|
||||
#define ILI9488_IO_INITIALIZED 0x02
|
||||
static uint8_t Is_ili9488_Initialized = 0;
|
||||
|
||||
const uint8_t EntryRightThenUp = ILI9488_MAD_DATA_RIGHT_THEN_UP;
|
||||
const uint8_t EntryRightThenDown = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
|
||||
/* the last set drawing direction is stored here */
|
||||
uint8_t LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Pixel draw and read functions */
|
||||
|
||||
#if ILI9488_WRITEBITDEPTH == ILI9488_READBITDEPTH
|
||||
/* 16/16 and 24/24 bit, no need to change bitdepth data */
|
||||
#define SetWriteDir()
|
||||
#define SetReadDir()
|
||||
#else /* #if ILI9488_WRITEBITDEPTH == ILI9488_READBITDEPTH */
|
||||
uint8_t lastdir = 0;
|
||||
#if ILI9488_WRITEBITDEPTH == 16
|
||||
/* 16/24 bit */
|
||||
#define SetWriteDir() { \
|
||||
if(lastdir != 0) \
|
||||
{ \
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PIXFMT, "\55", 1); \
|
||||
lastdir = 0; \
|
||||
} }
|
||||
#define SetReadDir() { \
|
||||
if(lastdir == 0) \
|
||||
{ \
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PIXFMT, "\66", 1); \
|
||||
lastdir = 1; \
|
||||
} }
|
||||
#elif ILI9488_WRITEBITDEPTH == 24
|
||||
/* 24/16 bit */
|
||||
#define SetWriteDir() { \
|
||||
if(lastdir != 0) \
|
||||
{ \
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PIXFMT, "\66", 1); \
|
||||
lastdir = 0; \
|
||||
} }
|
||||
#define SetReadDir() { \
|
||||
if(lastdir == 0) \
|
||||
{ \
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PIXFMT, "\55", 1); \
|
||||
lastdir = 1; \
|
||||
} }
|
||||
#endif /* #elif ILI9488_WRITEBITDEPTH == 24 */
|
||||
#endif /* #else ILI9488_WRITEBITDEPTH == ILI9488_READBITDEPTH */
|
||||
|
||||
#if ILI9488_WRITEBITDEPTH == 16
|
||||
#if LCD_REVERSE16 == 0
|
||||
#define LCD_IO_DrawFill(Color, Size) { \
|
||||
SetWriteDir(); \
|
||||
LCD_IO_WriteCmd8DataFill16(ILI9488_RAMWR, Color, Size); } /* Fill 16 bit pixel(s) */
|
||||
#define LCD_IO_DrawBitmap(pData, Size) { \
|
||||
SetWriteDir(); \
|
||||
LCD_IO_WriteCmd8MultipleData16(ILI9488_RAMWR, pData, Size); } /* Draw 16 bit bitmap */
|
||||
#elif LCD_REVERSE16 == 1
|
||||
#define LCD_IO_DrawFill(Color, Size) { \
|
||||
SetWriteDir(); \
|
||||
LCD_IO_WriteCmd8DataFill16r(ILI9488_RAMWR, Color, Size); } /* Fill 16 bit pixel(s) */
|
||||
#define LCD_IO_DrawBitmap(pData, Size) { \
|
||||
SetWriteDir(); \
|
||||
LCD_IO_WriteCmd8MultipleData16r(ILI9488_RAMWR, pData, Size); } /* Draw 16 bit bitmap */
|
||||
#endif /* #else LCD_REVERSE16 == 0 */
|
||||
#elif ILI9488_WRITEBITDEPTH == 24
|
||||
#define LCD_IO_DrawFill(Color, Size) { \
|
||||
SetWriteDir(); \
|
||||
LCD_IO_WriteCmd8DataFill16to24(ILI9488_RAMWR, Color, Size); } /* Fill 24 bit pixel(s) from 16 bit color code */
|
||||
#define LCD_IO_DrawBitmap(pData, Size) { \
|
||||
SetWriteDir(); \
|
||||
LCD_IO_WriteCmd8MultipleData16to24(ILI9488_RAMWR, pData, Size); } /* Draw 24 bit Lcd bitmap from 16 bit bitmap data */
|
||||
#endif /* #elif ILI9488_WRITEBITDEPTH == 24 */
|
||||
|
||||
#if ILI9488_READBITDEPTH == 16
|
||||
#if LCD_REVERSE16 == 0
|
||||
#define LCD_IO_ReadBitmap(pData, Size) { \
|
||||
SetReadDir(); \
|
||||
LCD_IO_ReadCmd8MultipleData16(ILI9488_RAMRD, pData, Size, 1); } /* Read 16 bit LCD */
|
||||
#elif LCD_REVERSE16 == 1
|
||||
#define LCD_IO_ReadBitmap(pData, Size) { \
|
||||
SetReadDir(); \
|
||||
LCD_IO_ReadCmd8MultipleData16r(ILI9488_RAMRD, pData, Size, 1); } /* Read 16 bit LCD */
|
||||
#endif /* #else LCD_REVERSE16 == 0 */
|
||||
#elif ILI9488_READBITDEPTH == 24
|
||||
#define LCD_IO_ReadBitmap(pData, Size) { \
|
||||
SetReadDir(); \
|
||||
LCD_IO_ReadCmd8MultipleData24to16(ILI9488_RAMRD, pData, Size, 1); } /* Read 24 bit Lcd and convert to 16 bit bitmap */
|
||||
#endif /* #elif ILI9488_READBITDEPTH == 24 */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ili9488_Init(void)
|
||||
{
|
||||
if((Is_ili9488_Initialized & ILI9488_LCD_INITIALIZED) == 0)
|
||||
{
|
||||
Is_ili9488_Initialized |= ILI9488_LCD_INITIALIZED;
|
||||
if((Is_ili9488_Initialized & ILI9488_IO_INITIALIZED) == 0)
|
||||
LCD_IO_Init();
|
||||
Is_ili9488_Initialized |= ILI9488_IO_INITIALIZED;
|
||||
}
|
||||
|
||||
LCD_Delay(105);
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_SWRESET, NULL, 0);
|
||||
LCD_Delay(5);
|
||||
// positive gamma control
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_GMCTRP1, (uint8_t *)"\x00\x01\x02\x04\x14\x09\x3F\x57\x4D\x05\x0B\x09\x1A\x1D\x0F", 15);
|
||||
// negative gamma control
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_GMCTRN1, (uint8_t *)"\x00\x1D\x20\x02\x0E\x03\x35\x12\x47\x02\x0D\x0C\x38\x39\x0F", 15);
|
||||
// Power Control 1 (Vreg1out, Verg2out)
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PWCTR1, (uint8_t *)"\x17\x15", 2);
|
||||
LCD_Delay(5);
|
||||
// Power Control 2 (VGH,VGL)
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PWCTR2, (uint8_t *)"\x41", 1);
|
||||
LCD_Delay(5);
|
||||
// Power Control 3 (Vcom)
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_VMCTR1, (uint8_t *)"\x00\x12\x80", 3);
|
||||
LCD_Delay(5);
|
||||
#if ILI9488_WRITEBITDEPTH == 16
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PIXFMT, (uint8_t *)"\x55", 1); // Interface Pixel Format (16 bit)
|
||||
#elif ILI9488_WRITEBITDEPTH == 24
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_PIXFMT, (uint8_t *)"\x66", 1); // Interface Pixel Format (24 bit)
|
||||
#endif
|
||||
#if ILI9488_INTERFACE == 0
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_IMCTR, (uint8_t *)"\x80", 1); // Interface Mode Control (SDO NOT USE)
|
||||
#elif ILI9488_INTERFACE == 1
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_IMCTR, (uint8_t *)"\x00", 1); // Interface Mode Control (SDO USE)
|
||||
#endif
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_FRMCTR1, (uint8_t *)"\xA0", 1); // Frame rate (60Hz)
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_INVCTR, (uint8_t *)"\x02", 1); // Display Inversion Control (2-dot)
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_DFUNCTR, (uint8_t *)"\x02\x02", 2); // Display Function Control RGB/MCU Interface Control
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_IMGFUNCT, (uint8_t *)"\x01", 1); // Set Image Functio (Disable 24 bit data)
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_ADJCTR3, (uint8_t *)"\xA9\x51\x2C\x82", 4); // Adjust Control (D7 stream, loose)
|
||||
LCD_Delay(5);
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_SLPOUT, NULL, 0); // Exit Sleep
|
||||
LCD_Delay(120);
|
||||
#if ILI9488_INITCLEAR == 1
|
||||
ili9488_FillRect(0, 0, ILI9488_MAX_X + 1, ILI9488_MAX_Y + 1, 0x0000);
|
||||
LCD_Delay(1);
|
||||
#endif
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_DISPON, NULL, 0); // Display on
|
||||
LCD_Delay(5);
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Enables the Display.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_DisplayOn(void)
|
||||
{
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_SLPOUT, NULL, 0); // Exit Sleep
|
||||
LCD_IO_Bl_OnOff(1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Disables the Display.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_DisplayOff(void)
|
||||
{
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_SLPIN, NULL, 0); // Sleep
|
||||
LCD_IO_Bl_OnOff(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Get the LCD pixel Width.
|
||||
* @param None
|
||||
* @retval The Lcd Pixel Width
|
||||
*/
|
||||
uint16_t ili9488_GetLcdPixelWidth(void)
|
||||
{
|
||||
return ILI9488_MAX_X + 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Get the LCD pixel Height.
|
||||
* @param None
|
||||
* @retval The Lcd Pixel Height
|
||||
*/
|
||||
uint16_t ili9488_GetLcdPixelHeight(void)
|
||||
{
|
||||
return ILI9488_MAX_Y + 1;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Get the ILI9488 ID.
|
||||
* @param None
|
||||
* @retval The ILI9488 ID
|
||||
*/
|
||||
uint32_t ili9488_ReadID(void)
|
||||
{
|
||||
uint32_t id = 0;
|
||||
|
||||
if(Is_ili9488_Initialized == 0)
|
||||
{
|
||||
ili9488_Init();
|
||||
}
|
||||
LCD_IO_ReadCmd8MultipleData8(0x04, (uint8_t *)&id, 3, 1);
|
||||
return id;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Set Cursor position.
|
||||
* @param Xpos: specifies the X position.
|
||||
* @param Ypos: specifies the Y position.
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_SetCursor(uint16_t Xpos, uint16_t Ypos)
|
||||
{
|
||||
SETCURSOR(Xpos, Ypos);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Write pixel.
|
||||
* @param Xpos: specifies the X position.
|
||||
* @param Ypos: specifies the Y position.
|
||||
* @param RGBCode: the RGB pixel color
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_WritePixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGBCode)
|
||||
{
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
SETCURSOR(Xpos, Ypos);
|
||||
LCD_IO_DrawFill(RGBCode, 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Read pixel.
|
||||
* @param None
|
||||
* @retval the RGB pixel color
|
||||
*/
|
||||
uint16_t ili9488_ReadPixel(uint16_t Xpos, uint16_t Ypos)
|
||||
{
|
||||
uint16_t ret;
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
SETCURSOR(Xpos, Ypos);
|
||||
LCD_IO_ReadBitmap(&ret, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Sets a display window
|
||||
* @param Xpos: specifies the X bottom left position.
|
||||
* @param Ypos: specifies the Y bottom left position.
|
||||
* @param Height: display window height.
|
||||
* @param Width: display window width.
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_SetDisplayWindow(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)
|
||||
{
|
||||
#if ILI9488_INTERFACE == 0 || ILI9488_INTERFACE == 1
|
||||
yStart = Ypos; yEnd = Ypos + Height - 1;
|
||||
#endif
|
||||
SETWINDOW(Xpos, Xpos + Width - 1, Ypos, Ypos + Height - 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Draw vertical line.
|
||||
* @param RGBCode: Specifies the RGB color
|
||||
* @param Xpos: specifies the X position.
|
||||
* @param Ypos: specifies the Y position.
|
||||
* @param Length: specifies the Line length.
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_DrawHLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length)
|
||||
{
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
ili9488_FillRect(Xpos, Ypos, Length, 1, RGBCode);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Draw vertical line.
|
||||
* @param RGBCode: Specifies the RGB color
|
||||
* @param Xpos: specifies the X position.
|
||||
* @param Ypos: specifies the Y position.
|
||||
* @param Length: specifies the Line length.
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_DrawVLine(uint16_t RGBCode, uint16_t Xpos, uint16_t Ypos, uint16_t Length)
|
||||
{
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
ili9488_FillRect(Xpos, Ypos, 1, Length, RGBCode);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Draw Filled rectangle
|
||||
* @param Xpos: specifies the X position.
|
||||
* @param Ypos: specifies the Y position.
|
||||
* @param Xsize: specifies the X size
|
||||
* @param Ysize: specifies the Y size
|
||||
* @param RGBCode: specifies the RGB color
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t RGBCode)
|
||||
{
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
ili9488_SetDisplayWindow(Xpos, Ypos, Xsize, Ysize);
|
||||
LCD_IO_DrawFill(RGBCode, Xsize * Ysize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Displays a 16bit bitmap picture..
|
||||
* @param BmpAddress: Bmp picture address.
|
||||
* @param Xpos: Bmp X position in the LCD
|
||||
* @param Ypos: Bmp Y position in the LCD
|
||||
* @retval None
|
||||
* @brief Draw direction: right then up
|
||||
*/
|
||||
void ili9488_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pbmp)
|
||||
{
|
||||
uint32_t index = 0, size = 0;
|
||||
/* Read bitmap size */
|
||||
Ypos += pbmp[22] + (pbmp[23] << 8) - 1;
|
||||
size = *(volatile uint16_t *) (pbmp + 2);
|
||||
size |= (*(volatile uint16_t *) (pbmp + 4)) << 16;
|
||||
/* Get bitmap data address offset */
|
||||
index = *(volatile uint16_t *) (pbmp + 10);
|
||||
index |= (*(volatile uint16_t *) (pbmp + 12)) << 16;
|
||||
size = (size - index)/2;
|
||||
pbmp += index;
|
||||
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_UP)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_UP;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenUp, 1);
|
||||
}
|
||||
#if ILI9488_INTERFACE == 0 || ILI9488_INTERFACE == 1
|
||||
transdata.d16[0] = ILI9488_MAX_Y - yEnd;
|
||||
transdata.d16[1] = ILI9488_MAX_Y - yStart;
|
||||
LCD_IO_WriteCmd8MultipleData16(ILI9488_PASET, &transdata, 2);
|
||||
LCD_IO_DrawBitmap(pbmp, size);
|
||||
#elif ILI9488_INTERFACE == 2
|
||||
LCD_IO_DrawBitmap(pbmp, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Displays 16bit/pixel picture..
|
||||
* @param pdata: picture address.
|
||||
* @param Xpos: Image X position in the LCD
|
||||
* @param Ypos: Image Y position in the LCD
|
||||
* @param Xsize: Image X size in the LCD
|
||||
* @param Ysize: Image Y size in the LCD
|
||||
* @retval None
|
||||
* @brief Draw direction: right then down
|
||||
*/
|
||||
void ili9488_DrawRGBImage(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t *pData)
|
||||
{
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
ili9488_SetDisplayWindow(Xpos, Ypos, Xsize, Ysize);
|
||||
LCD_IO_DrawBitmap(pData, Xsize * Ysize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Read 16bit/pixel vitmap from Lcd..
|
||||
* @param pdata: picture address.
|
||||
* @param Xpos: Image X position in the LCD
|
||||
* @param Ypos: Image Y position in the LCD
|
||||
* @param Xsize: Image X size in the LCD
|
||||
* @param Ysize: Image Y size in the LCD
|
||||
* @retval None
|
||||
* @brief Draw direction: right then down
|
||||
*/
|
||||
void ili9488_ReadRGBImage(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t *pData)
|
||||
{
|
||||
if(LastEntry != ILI9488_MAD_DATA_RIGHT_THEN_DOWN)
|
||||
{
|
||||
LastEntry = ILI9488_MAD_DATA_RIGHT_THEN_DOWN;
|
||||
LCD_IO_WriteCmd8MultipleData8(ILI9488_MADCTL, &EntryRightThenDown, 1);
|
||||
}
|
||||
ili9488_SetDisplayWindow(Xpos, Ypos, Xsize, Ysize);
|
||||
LCD_IO_ReadBitmap(pData, Xsize * Ysize);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Set display scroll parameters
|
||||
* @param Scroll : Scroll size [pixel]
|
||||
* @param TopFix : Top fix size [pixel]
|
||||
* @param BottonFix : Botton fix size [pixel]
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_Scroll(int16_t Scroll, uint16_t TopFix, uint16_t BottonFix)
|
||||
{
|
||||
static uint16_t scrparam[4] = {0, 0, 0, 0};
|
||||
#if (ILI9488_ORIENTATION == 0)
|
||||
if((TopFix != scrparam[1]) || (BottonFix != scrparam[3]))
|
||||
{
|
||||
scrparam[1] = TopFix;
|
||||
scrparam[3] = BottonFix;
|
||||
scrparam[2] = ILI9488_LCD_PIXEL_HEIGHT - TopFix - BottonFix;
|
||||
LCD_IO_WriteCmd8MultipleData16(ILI9488_VSCRDEF, &scrparam[1], 3);
|
||||
}
|
||||
Scroll = (0 - Scroll) % scrparam[2];
|
||||
if(Scroll < 0)
|
||||
Scroll = scrparam[2] + Scroll + scrparam[1];
|
||||
else
|
||||
Scroll = Scroll + scrparam[1];
|
||||
#elif (ILI9488_ORIENTATION == 1)
|
||||
if((TopFix != scrparam[1]) || (BottonFix != scrparam[3]))
|
||||
{
|
||||
scrparam[1] = TopFix;
|
||||
scrparam[3] = BottonFix;
|
||||
scrparam[2] = ILI9488_LCD_PIXEL_HEIGHT - TopFix - BottonFix;
|
||||
LCD_IO_WriteCmd8MultipleData16(ILI9488_VSCRDEF, &scrparam[1], 3);
|
||||
}
|
||||
Scroll = (0 - Scroll) % scrparam[2];
|
||||
if(Scroll < 0)
|
||||
Scroll = scrparam[2] + Scroll + scrparam[1];
|
||||
else
|
||||
Scroll = Scroll + scrparam[1];
|
||||
#elif (ILI9488_ORIENTATION == 2)
|
||||
if((TopFix != scrparam[3]) || (BottonFix != scrparam[1]))
|
||||
{
|
||||
scrparam[3] = TopFix;
|
||||
scrparam[1] = BottonFix;
|
||||
scrparam[2] = ILI9488_LCD_PIXEL_HEIGHT - TopFix - BottonFix;
|
||||
LCD_IO_WriteCmd8MultipleData16(ILI9488_VSCRDEF, &scrparam[1], 3);
|
||||
}
|
||||
Scroll %= scrparam[2];
|
||||
if(Scroll < 0)
|
||||
Scroll = scrparam[2] + Scroll + scrparam[1];
|
||||
else
|
||||
Scroll = Scroll + scrparam[1];
|
||||
#elif (ILI9488_ORIENTATION == 3)
|
||||
if((TopFix != scrparam[3]) || (BottonFix != scrparam[1]))
|
||||
{
|
||||
scrparam[3] = TopFix;
|
||||
scrparam[1] = BottonFix;
|
||||
scrparam[2] = ILI9488_LCD_PIXEL_HEIGHT - TopFix - BottonFix;
|
||||
LCD_IO_WriteCmd8MultipleData16(ILI9488_VSCRDEF, &scrparam[1], 3);
|
||||
}
|
||||
Scroll %= scrparam[2];
|
||||
if(Scroll < 0)
|
||||
Scroll = scrparam[2] + Scroll + scrparam[1];
|
||||
else
|
||||
Scroll = Scroll + scrparam[1];
|
||||
#endif
|
||||
if(Scroll != scrparam[0])
|
||||
{
|
||||
scrparam[0] = Scroll;
|
||||
LCD_IO_WriteCmd8DataFill16(ILI9488_VSCRSADD, scrparam[0], 1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief User command
|
||||
* @param Command : Lcd command
|
||||
* @param pData : data pointer
|
||||
* @param Size : data number
|
||||
* @param Mode : 0=write 8bits datas, 1=0=write 16bits datas, 2=read 8bits datas, 3=read 16bits datas
|
||||
* @retval None
|
||||
*/
|
||||
void ili9488_UserCommand(uint16_t Command, uint8_t* pData, uint32_t Size, uint8_t Mode)
|
||||
{
|
||||
if(Mode == 0)
|
||||
LCD_IO_WriteCmd8MultipleData8((uint8_t)Command, pData, Size);
|
||||
else if(Mode == 1)
|
||||
LCD_IO_WriteCmd8MultipleData16((uint8_t)Command, pData, Size);
|
||||
else if(Mode == 2)
|
||||
LCD_IO_ReadCmd8MultipleData8((uint8_t)Command, pData, Size, 1);
|
||||
else if(Mode == 3)
|
||||
LCD_IO_ReadCmd8MultipleData16((uint8_t)Command, pData, Size, 1);
|
||||
}
|
||||
32
Core/Src/Lcd/ili9488.h
Normal file
32
Core/Src/Lcd/ili9488.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* LCD interface type
|
||||
- 0: SPI half duplex (the mosi pin is bidirectional mode)
|
||||
- 1: SPI full duplex (write = mosi pin, read = miso pin)
|
||||
- 2: paralell 8 bit interface */
|
||||
#define ILI9488_INTERFACE 1
|
||||
|
||||
/* Orientation:
|
||||
- 0: 320x480 micro-sd in the top (portrait)
|
||||
- 1: 480x320 micro-sd in the left (landscape)
|
||||
- 2: 320x480 micro-sd in the bottom (portrait)
|
||||
- 3: 480x320 micro-sd in the right (landscape) */
|
||||
#define ILI9488_ORIENTATION 2
|
||||
|
||||
/* To clear the screen before display turning on ?
|
||||
- 0: does not clear
|
||||
- 1: clear */
|
||||
#define ILI9488_INITCLEAR 1
|
||||
|
||||
/* Color order
|
||||
- 0: RGB
|
||||
- 1: BGR */
|
||||
#define ILI9488_COLORMODE 1
|
||||
|
||||
/* Draw and read bitdeph (16: RGB565, 24: RGB888)
|
||||
note: my SPI ILI9488 LCD can only work in 24/24 bit depth
|
||||
my paralell 8 bit ILI9488 LCD can work in 16/16, 16/24, 24/16, 24/24 bit depth */
|
||||
#define ILI9488_WRITEBITDEPTH 24
|
||||
#define ILI9488_READBITDEPTH 24
|
||||
|
||||
/* ILI9488 Size (physical resolution in default orientation) */
|
||||
#define ILI9488_LCD_PIXEL_WIDTH 320
|
||||
#define ILI9488_LCD_PIXEL_HEIGHT 480
|
||||
101
Core/Src/Lcd/lcd.h
Normal file
101
Core/Src/Lcd/lcd.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file lcd.h
|
||||
* @author MCD Application Team
|
||||
* @version V4.0.1
|
||||
* @date 21-July-2015
|
||||
* @brief This file contains all the functions prototypes for the LCD driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modify:
|
||||
- ReadID return type: uint16_t to uint32_t (there is a display that has a 24-bit ID)
|
||||
- Add the LCD_REVERSE16 macro (so that dma can be used on the fsmc 8-bit interface for bitmap drawing)
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LCD_H
|
||||
#define __LCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
/* Setting section (please set the necessary things in this section) */
|
||||
|
||||
/* 16bit/pixel data byte order
|
||||
- 0: no change (default)
|
||||
- 1: change
|
||||
note: Enter a value of 1 only if you use an 8-bit fmsc IO driver and want to use DMA to draw bitmap images.
|
||||
The filling operation is DMA capable even with a value of 0.
|
||||
attention: the byte order should also be in reverse order in memory blocks containing images,
|
||||
because the displayed image will be incorrect. This is necessary because DMA can only write to the
|
||||
fsmc 8-bit peripheral in ascending byte order, but the LCD display requires reverse pixel byte order. */
|
||||
#define LCD_REVERSE16 0
|
||||
|
||||
//=============================================================================
|
||||
/* Interface section */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*Init)(void);
|
||||
uint32_t (*ReadID)(void);
|
||||
void (*DisplayOn)(void);
|
||||
void (*DisplayOff)(void);
|
||||
void (*SetCursor)(uint16_t, uint16_t);
|
||||
void (*WritePixel)(uint16_t, uint16_t, uint16_t);
|
||||
uint16_t (*ReadPixel)(uint16_t, uint16_t);
|
||||
|
||||
void (*SetDisplayWindow)(uint16_t, uint16_t, uint16_t, uint16_t);
|
||||
void (*DrawHLine)(uint16_t, uint16_t, uint16_t, uint16_t);
|
||||
void (*DrawVLine)(uint16_t, uint16_t, uint16_t, uint16_t);
|
||||
|
||||
uint16_t (*GetLcdPixelWidth)(void);
|
||||
uint16_t (*GetLcdPixelHeight)(void);
|
||||
void (*DrawBitmap)(uint16_t, uint16_t, uint8_t*);
|
||||
void (*DrawRGBImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint16_t*);
|
||||
void (*FillRect)(uint16_t, uint16_t, uint16_t, uint16_t, uint16_t);
|
||||
void (*ReadRGBImage)(uint16_t, uint16_t, uint16_t, uint16_t, uint16_t*);
|
||||
void (*Scroll)(int16_t, uint16_t, uint16_t);
|
||||
void (*UserCommand)(uint16_t, uint8_t*, uint32_t, uint8_t);
|
||||
}LCD_DrvTypeDef;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LCD_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
119
Core/Src/Lcd/lcd_io.h
Normal file
119
Core/Src/Lcd/lcd_io.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* lcd_io.h
|
||||
*
|
||||
* Created on: 2022.11
|
||||
* Author: Benjami
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __LCD_IO_H
|
||||
#define __LCD_IO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lcd.h"
|
||||
|
||||
//=============================================================================
|
||||
/* Interface section */
|
||||
|
||||
/* Mode bits */
|
||||
#define LCD_IO_CMD8 (1 << 0)
|
||||
#define LCD_IO_CMD16 (1 << 1)
|
||||
|
||||
#define LCD_IO_WRITE (1 << 2)
|
||||
#define LCD_IO_READ (1 << 3)
|
||||
|
||||
#define LCD_IO_DATA8 (1 << 4)
|
||||
#define LCD_IO_DATA16 (1 << 5)
|
||||
#define LCD_IO_DATA24TO16 (1 << 6) /* at read */
|
||||
#define LCD_IO_DATA16TO24 (1 << 6) /* at write */
|
||||
|
||||
#define LCD_IO_MULTIDATA (1 << 7)
|
||||
#define LCD_IO_FILL (1 << 8)
|
||||
|
||||
#define LCD_IO_REVERSE16 (1 << 9)
|
||||
/* LCD_IO_REVERSE16 only FMC/FSMC 8 bit IO interface
|
||||
note: DMA on the 8-bit FMC interface is only possible in low byte->high byte order.
|
||||
The displays, on the other hand, request it in order high byte->low byte.
|
||||
If we still want to use DMA, the color codes must be stored in reverse byte order in the bitmap memory.
|
||||
With this switch, we can signal LCD_IO to do a color code transaction in reverse order,
|
||||
so it can also use DMA for bitmap drawing. */
|
||||
|
||||
/* Link function for LCD peripheral */
|
||||
void LCD_Delay (uint32_t delay);
|
||||
void LCD_IO_Init(void);
|
||||
void LCD_IO_Bl_OnOff(uint8_t Bl);
|
||||
void LCD_IO_Transaction(uint16_t Cmd, uint8_t *pData, uint32_t Size, uint32_t DummySize, uint32_t Mode);
|
||||
|
||||
/* 8 bit write commands */
|
||||
#define LCD_IO_WriteCmd8DataFill16(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_FILL)
|
||||
#define LCD_IO_WriteCmd8DataFill16to24(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16TO24 | LCD_IO_FILL)
|
||||
#define LCD_IO_WriteCmd8MultipleData8(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA8 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_WriteCmd8MultipleData16(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_WriteCmd8MultipleData16to24(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16TO24 | LCD_IO_MULTIDATA)
|
||||
|
||||
/* 16 bit write commands */
|
||||
#define LCD_IO_WriteCmd16DataFill16(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_FILL)
|
||||
#define LCD_IO_WriteCmd16DataFill16to24(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA16TO24 | LCD_IO_FILL)
|
||||
#define LCD_IO_WriteCmd16MultipleData8(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA8 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_WriteCmd16MultipleData16(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_WriteCmd16MultipleData16to24(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA16TO24 | LCD_IO_MULTIDATA)
|
||||
|
||||
/* 8 bit read commands */
|
||||
#define LCD_IO_ReadCmd8MultipleData8(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD8 | LCD_IO_READ | LCD_IO_DATA8 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_ReadCmd8MultipleData16(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD8 | LCD_IO_READ | LCD_IO_DATA16 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_ReadCmd8MultipleData24to16(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD8 | LCD_IO_READ | LCD_IO_DATA24TO16 | LCD_IO_MULTIDATA)
|
||||
|
||||
/* 16 bit read commands */
|
||||
#define LCD_IO_ReadCmd16MultipleData8(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD16 | LCD_IO_READ | LCD_IO_DATA8 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_ReadCmd16MultipleData16(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD16 | LCD_IO_READ | LCD_IO_DATA16 | LCD_IO_MULTIDATA)
|
||||
#define LCD_IO_ReadCmd16MultipleData24to16(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD16 | LCD_IO_READ | LCD_IO_DATA24TO16 | LCD_IO_MULTIDATA)
|
||||
|
||||
/* 8 and 16 bit write and read commands with reverse byte order 16 bit data (only 16bitdepth pixel data in FSMC 8 bit io interface) */
|
||||
/* 8 bit write commands */
|
||||
#define LCD_IO_WriteCmd8DataFill16r(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_FILL | LCD_IO_REVERSE16)
|
||||
#define LCD_IO_WriteCmd8DataFill16to24r(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16TO24 | LCD_IO_FILL | LCD_IO_REVERSE16)
|
||||
#define LCD_IO_WriteCmd8MultipleData16r(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_MULTIDATA | LCD_IO_REVERSE16)
|
||||
#define LCD_IO_WriteCmd8MultipleData16to24r(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD8 | LCD_IO_WRITE | LCD_IO_DATA16TO24 | LCD_IO_MULTIDATA | LCD_IO_REVERSE16)
|
||||
|
||||
/* 16 bit write commands */
|
||||
#define LCD_IO_WriteCmd16DataFill16r(Cmd, Data, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)&Data, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_FILL | LCD_IO_REVERSE16)
|
||||
#define LCD_IO_WriteCmd16MultipleData16r(Cmd, pData, Size) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, 0, LCD_IO_CMD16 | LCD_IO_WRITE | LCD_IO_DATA16 | LCD_IO_MULTIDATA | LCD_IO_REVERSE16)
|
||||
|
||||
/* 8 bit read commands */
|
||||
#define LCD_IO_ReadCmd8MultipleData16r(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD8 | LCD_IO_READ | LCD_IO_DATA16 | LCD_IO_MULTIDATA | LCD_IO_REVERSE16)
|
||||
|
||||
/* 16 bit read commands */
|
||||
#define LCD_IO_ReadCmd16MultipleData16r(Cmd, pData, Size, DummySize) \
|
||||
LCD_IO_Transaction((uint16_t)Cmd, (uint8_t *)pData, Size, DummySize, LCD_IO_CMD16 | LCD_IO_READ | LCD_IO_DATA16 | LCD_IO_MULTIDATA | LCD_IO_REVERSE16)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SRC_LCD_LCD_IO_H_ */
|
||||
946
Core/Src/Lcd/lcd_io_spi_hal.c
Normal file
946
Core/Src/Lcd/lcd_io_spi_hal.c
Normal file
@@ -0,0 +1,946 @@
|
||||
/*
|
||||
* SPI HAL LCD driver for all stm32 family
|
||||
* author: Roberto Benjami
|
||||
* v.2023.04
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "lcd.h"
|
||||
#include "lcd_io.h"
|
||||
#include "lcd_io_spi_hal.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#define DMA_MINSIZE 0x0010
|
||||
#define DMA_MAXSIZE 0xFFFE
|
||||
/* note:
|
||||
- DMA_MINSIZE: if the transacion Size < DMA_MINSIZE -> not use the DMA for transaction
|
||||
- DMA_MAXSIZE: if the transacion Size > DMA_MAXSIZE -> multiple DMA transactions (because DMA transaction size register is 16bit) */
|
||||
|
||||
#define LCD_SPI_TIMEOUT HAL_MAX_DELAY
|
||||
/* note:
|
||||
- LCD_SPI_TIMEOUT: HAL_SPI_Transmit and HAL_SPI_Receive timeout value */
|
||||
|
||||
/* SPI clock pin default state */
|
||||
#define LCD_SPI_DEFSTATE 0
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Bitdepth convert macros */
|
||||
#if LCD_RGB24_ORDER == 0
|
||||
#define RGB565TO888(c16) ((c16 & 0xF800) << 8) | ((c16 & 0x07E0) << 5) | ((c16 & 0x001F) << 3)
|
||||
#define RGB888TO565(c24) ((c24 & 0XF80000) >> 8 | (c24 & 0xFC00) >> 5 | (c24 & 0xF8 ) >> 3)
|
||||
#elif LCD_RGB24_ORDER == 1
|
||||
#define RGB565TO888(c16) ((c16 & 0xF800) >> 8) | ((c16 & 0x07E0) << 5) | ((c16 & 0x001F) << 19)
|
||||
#define RGB888TO565(c24) ((c24 & 0XF80000) >> 19 | (c24 & 0xFC00) >> 5 | (c24 & 0xF8 ) << 8)
|
||||
#endif
|
||||
|
||||
/* processor family dependent things */
|
||||
#if defined(STM32C0)
|
||||
#include "stm32c0xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32F0)
|
||||
#include "stm32f0xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32F1)
|
||||
#include "stm32f1xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) hlcdspi.Instance->CR1 &= ~SPI_CR1_DFF
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) hlcdspi.Instance->CR1 |= SPI_CR1_DFF
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32F2)
|
||||
#include "stm32f2xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) hlcdspi.Instance->CR1 &= ~SPI_CR1_DFF
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) hlcdspi.Instance->CR1 |= SPI_CR1_DFF
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32F3)
|
||||
#include "stm32f3xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32F4)
|
||||
#include "stm32f4xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) hlcdspi.Instance->CR1 &= ~SPI_CR1_DFF
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) hlcdspi.Instance->CR1 |= SPI_CR1_DFF
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32F7)
|
||||
#include "stm32f7xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32H5)
|
||||
#include "stm32h5xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_DSIZE, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_DSIZE, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_MBR, br << SPI_CFG1_MBR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXP) dummy = hlcdspi.Instance->RXDR
|
||||
#elif defined(STM32H7)
|
||||
#include "stm32h7xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_DSIZE, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_DSIZE, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_MBR, br << SPI_CFG1_MBR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXP) dummy = hlcdspi.Instance->RXDR
|
||||
#elif defined(STM32G0)
|
||||
#include "stm32g0xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32G4)
|
||||
#include "stm32g4xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32L0)
|
||||
#include "stm32l0xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) hlcdspi.Instance->CR1 &= ~SPI_CR1_DFF
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) hlcdspi.Instance->CR1 |= SPI_CR1_DFF
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32L1)
|
||||
#include "stm32l1xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) hlcdspi.Instance->CR1 &= ~SPI_CR1_DFF
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) hlcdspi.Instance->CR1 |= SPI_CR1_DFF
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32L4)
|
||||
#include "stm32l4xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32L5)
|
||||
#include "stm32l5xx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32WB)
|
||||
#include "stm32wbxx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#elif defined(STM32WBA)
|
||||
#include "stm32wbaxx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_DSIZE, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_DSIZE, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CFG1, SPI_CFG1_MBR, br << SPI_CFG1_MBR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXP) dummy = hlcdspi.Instance->RXDR
|
||||
#elif defined(STM32WL)
|
||||
#include "stm32wlxx_ll_gpio.h"
|
||||
#define LCD_SPI_SETDATASIZE_8BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_8BIT)
|
||||
#define LCD_SPI_SETDATASIZE_16BIT(hlcdspi) MODIFY_REG(hlcdspi.Instance->CR2, SPI_CR2_DS, SPI_DATASIZE_16BIT)
|
||||
#define LCD_SPI_SETBAUDRATE(hlcdspi, br) MODIFY_REG(hlcdspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#define LCD_SPI_RXFIFOCLEAR(hlcdspi, dummy) while(hlcdspi.Instance->SR & SPI_SR_RXNE) dummy = hlcdspi.Instance->DR
|
||||
#else
|
||||
#error unknown processor family
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
extern SPI_HandleTypeDef LCD_SPI_HANDLE;
|
||||
|
||||
#if LCD_RGB24_BUFFSIZE < DMA_MINSIZE
|
||||
#undef LCD_RGB24_BUFFSIZE
|
||||
#define LCD_RGB24_BUFFSIZE 0
|
||||
#else
|
||||
uint8_t lcd_rgb24_buffer[LCD_RGB24_BUFFSIZE * 3 + 1];
|
||||
#endif /* #else LCD_RGB24_DMA_BUFFERSIZE < DMA_MINSIZE */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if LCD_SPI_MODE == 0
|
||||
/* Transmit only mode */
|
||||
|
||||
#define LcdDirRead()
|
||||
#define LcdDirWrite()
|
||||
|
||||
#elif (LCD_SPI_MODE == 1) || (LCD_SPI_MODE == 2)
|
||||
/* Half duplex and full duplex mode */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Switch from SPI write mode to SPI read mode, read the dummy bits, modify the SPI speed */
|
||||
void LcdDirRead(uint32_t DummySize)
|
||||
{
|
||||
uint32_t RxDummy __attribute__((unused));
|
||||
__HAL_SPI_DISABLE(&LCD_SPI_HANDLE); /* stop SPI */
|
||||
#if LCD_SPI_MODE == 1
|
||||
SPI_1LINE_RX(&LCD_SPI_HANDLE); /* if half duplex -> change MOSI data direction */
|
||||
#endif
|
||||
LL_GPIO_SetPinMode(LCD_SCK_GPIO_Port, LCD_SCK_Pin, LL_GPIO_MODE_OUTPUT); /* GPIO mode = output */
|
||||
while(DummySize--)
|
||||
{ /* Dummy pulses */
|
||||
HAL_GPIO_WritePin(LCD_SCK_GPIO_Port, LCD_SCK_Pin, 1 - LCD_SPI_DEFSTATE);
|
||||
HAL_GPIO_WritePin(LCD_SCK_GPIO_Port, LCD_SCK_Pin, LCD_SPI_DEFSTATE);
|
||||
}
|
||||
LL_GPIO_SetPinMode(LCD_SCK_GPIO_Port, LCD_SCK_Pin, LL_GPIO_MODE_ALTERNATE); /* GPIO mode = alternative */
|
||||
#if defined(LCD_SPI_SPD_WRITE) && defined(LCD_SPI_SPD_READ) && (LCD_SPI_SPD_WRITE != LCD_SPI_SPD_READ)
|
||||
LCD_SPI_SETBAUDRATE(LCD_SPI_HANDLE, LCD_SPI_SPD_READ); /* speed change */
|
||||
#endif
|
||||
LCD_SPI_RXFIFOCLEAR(LCD_SPI_HANDLE, RxDummy); /* RX fifo clear */
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Switch from SPI read mode to SPI write mode, modify the SPI speed */
|
||||
void LcdDirWrite(void)
|
||||
{
|
||||
__HAL_SPI_DISABLE(&LCD_SPI_HANDLE); /* stop SPI */
|
||||
#if defined(LCD_SPI_SPD_WRITE) && defined(LCD_SPI_SPD_READ) && (LCD_SPI_SPD_WRITE != LCD_SPI_SPD_READ)
|
||||
LCD_SPI_SETBAUDRATE(LCD_SPI_HANDLE, LCD_SPI_SPD_WRITE); /* speed change */
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* LCD_SPI_MODE */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Set SPI 8bit mode without HAL_SPI_Init */
|
||||
static inline void LcdSpiMode8(void)
|
||||
{
|
||||
LCD_SPI_SETDATASIZE_8BIT(LCD_SPI_HANDLE);
|
||||
LCD_SPI_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
}
|
||||
|
||||
/* Set SPI 16bit mode without HAL_SPI_Init */
|
||||
static inline void LcdSpiMode16(void)
|
||||
{
|
||||
LCD_SPI_SETDATASIZE_16BIT(LCD_SPI_HANDLE);
|
||||
LCD_SPI_HANDLE.Init.DataSize = SPI_DATASIZE_16BIT;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if LCD_DMA_TX == 0 && LCD_DMA_RX == 0
|
||||
/* DMA off mode */
|
||||
|
||||
#define LcdTransInit()
|
||||
#define LcdTransStart()
|
||||
#define LcdTransEnd()
|
||||
|
||||
uint32_t LCD_IO_DmaBusy(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* #if LCD_DMA_TX == 0 && LCD_DMA_RX == 0 */
|
||||
/* DMA on mode */
|
||||
|
||||
#define DMA_STATUS_FREE 0
|
||||
#define DMA_STATUS_FILL (1 << 0)
|
||||
#define DMA_STATUS_MULTIDATA (1 << 1)
|
||||
#define DMA_STATUS_8BIT (1 << 2)
|
||||
#define DMA_STATUS_16BIT (1 << 3)
|
||||
#define DMA_STATUS_24BIT (1 << 4)
|
||||
|
||||
struct
|
||||
{
|
||||
volatile uint32_t status; /* DMA status (0=free, other: see the DMA_STATUS... macros) */
|
||||
uint32_t size; /* all transactions data size */
|
||||
uint32_t trsize; /* actual DMA transaction data size */
|
||||
uint32_t maxtrsize; /* max size / one DMA transaction */
|
||||
uint32_t ptr; /* data pointer for DMA */
|
||||
uint16_t data; /* fill operation data for DMA */
|
||||
}volatile dmastatus;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef osCMSIS
|
||||
/* DMA mode on, Freertos off mode */
|
||||
|
||||
#define LcdTransInit()
|
||||
|
||||
#if LCD_DMA_ENDWAIT == 0
|
||||
#define LcdTransStart() {while(dmastatus.status);}
|
||||
#define LcdDmaWaitEnd(d)
|
||||
#elif LCD_DMA_ENDWAIT == 1
|
||||
#define LcdTransStart() {while(dmastatus.status);}
|
||||
#define LcdDmaWaitEnd(d) {if(d) while(dmastatus.status);}
|
||||
#elif LCD_DMA_ENDWAIT == 2
|
||||
#define LcdTransStart()
|
||||
#define LcdDmaWaitEnd(d) {while(dmastatus.status);}
|
||||
#endif /* #elif LCD_DMA_ENDWAIT == 2 */
|
||||
|
||||
#define LcdTransEnd()
|
||||
|
||||
#define LcdDmaTransEnd() {dmastatus.status = 0;}
|
||||
|
||||
#else /* #ifndef osCMSIS */
|
||||
/* Freertos mode */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#if osCMSIS < 0x20000
|
||||
/* DMA on, Freertos 1 mode */
|
||||
|
||||
osSemaphoreId LcdSemIdHandle;
|
||||
osSemaphoreDef(LcdSemId);
|
||||
#define LcdSemNew0 LcdSemIdHandle = osSemaphoreCreate(osSemaphore(LcdSemId), 1); osSemaphoreWait(LcdSemIdHandle, 0)
|
||||
#define LcdSemNew1 LcdSemIdHandle = osSemaphoreCreate(osSemaphore(LcdSemId), 1)
|
||||
#define LcdSemWait osSemaphoreWait(LcdSemIdHandle, osWaitForever)
|
||||
#define LcdSemSet osSemaphoreRelease(LcdSemIdHandle)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#else /* #if osCMSIS < 0x20000 */
|
||||
/* DMA on, Freertos 2 mode */
|
||||
|
||||
osSemaphoreId_t LcdSemId;
|
||||
#define LcdSemNew0 LcdSemId = osSemaphoreNew(1, 0, 0)
|
||||
#define LcdSemNew1 LcdSemId = osSemaphoreNew(1, 1, 0)
|
||||
#define LcdSemWait osSemaphoreAcquire(LcdSemId, osWaitForever)
|
||||
#define LcdSemSet osSemaphoreRelease(LcdSemId)
|
||||
|
||||
#endif /* #else osCMSIS < 0x20000 */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* DMA on, Freertos 1 and 2 mode */
|
||||
|
||||
#if LCD_DMA_ENDWAIT == 0
|
||||
#define LcdTransInit() {LcdSemNew1;}
|
||||
#define LcdTransStart() {LcdSemWait;}
|
||||
#define LcdTransEnd() {LcdSemSet;}
|
||||
#define LcdDmaWaitEnd(d)
|
||||
#elif LCD_DMA_ENDWAIT == 1
|
||||
#define LcdTransInit() {LcdSemNew1;}
|
||||
#define LcdTransStart() {LcdSemWait;}
|
||||
#define LcdTransEnd() {LcdSemSet;}
|
||||
#define LcdDmaWaitEnd(d) {if(d) {LcdSemWait; LcdSemSet;}}
|
||||
#elif LCD_DMA_ENDWAIT == 2
|
||||
#define LcdTransInit() {LcdSemNew0;}
|
||||
#define LcdTransStart()
|
||||
#define LcdTransEnd()
|
||||
#define LcdDmaWaitEnd(d) {LcdSemWait;}
|
||||
#endif /* elif LCD_DMA_ENDWAIT == 2 */
|
||||
|
||||
#define LcdDmaTransEnd() {dmastatus.status = 0; LcdSemSet;}
|
||||
|
||||
#endif /* #else osCMSIS */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Get the DMA operation status (0=DMA is free, 1=DMA is busy) */
|
||||
uint32_t LCD_IO_DmaBusy(void)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
if(dmastatus.status != DMA_STATUS_FREE)
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* #else LCD_DMA_TX == 0 && LCD_DMA_RX == 0 */
|
||||
|
||||
//=============================================================================
|
||||
/* Fill 24bit bitmap from 16bit color
|
||||
- color : 16 bit (RGB565) color
|
||||
- tg : 24 bit (RGB888) color target bitmap pointer
|
||||
- Size : number of pixel */
|
||||
void FillConvert16to24(uint16_t color, uint8_t * tg, uint32_t Size)
|
||||
{
|
||||
uint32_t c24;
|
||||
c24 = RGB565TO888(color);
|
||||
while(Size--)
|
||||
{
|
||||
*(uint32_t *)tg = c24;
|
||||
tg += 3;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Convert from 16bit bitmnap to 24bit bitmap
|
||||
- src : 16 bit (RGB565) color source bitmap pointer
|
||||
- tg : 24 bit (RGB888) color target bitmap pointer
|
||||
- Size : number of pixel */
|
||||
void BitmapConvert16to24(uint16_t * src, uint8_t * tg, uint32_t Size)
|
||||
{
|
||||
while(Size--)
|
||||
{
|
||||
*(uint32_t *)tg = RGB565TO888(*src);
|
||||
src++;
|
||||
tg += 3;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Convert from 16bit bitmnap to 24bit bitmap
|
||||
- src : 24 bit (RGB888) color source bitmap pointer
|
||||
- tg : 16 bit (RGB565) color target bitmap pointer
|
||||
- Size : number of pixel */
|
||||
void BitmapConvert24to16(uint8_t * src, uint16_t * tg, uint32_t Size)
|
||||
{
|
||||
uint32_t c24;
|
||||
while(Size--)
|
||||
{
|
||||
c24 = *(uint32_t *)src;
|
||||
*tg = RGB888TO565(c24);
|
||||
src += 3;
|
||||
tg++;
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/* TX DMA */
|
||||
#if LCD_DMA_TX == 1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* DMA operation end callback function prototype */
|
||||
__weak void LCD_IO_DmaTxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
UNUSED(hspi);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* SPI DMA operation interrupt */
|
||||
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
if(hspi == &LCD_SPI_HANDLE)
|
||||
{
|
||||
if(dmastatus.size > dmastatus.trsize)
|
||||
{ /* dma operation is still required */
|
||||
|
||||
if(dmastatus.status == (DMA_STATUS_MULTIDATA | DMA_STATUS_8BIT))
|
||||
dmastatus.ptr += dmastatus.trsize; /* 8bit multidata */
|
||||
else if(dmastatus.status == (DMA_STATUS_MULTIDATA | DMA_STATUS_16BIT))
|
||||
dmastatus.ptr += dmastatus.trsize << 1; /* 16bit multidata */
|
||||
else if(dmastatus.status == (DMA_STATUS_MULTIDATA | DMA_STATUS_24BIT))
|
||||
dmastatus.ptr += dmastatus.trsize << 1; /* 24bit multidata */
|
||||
|
||||
dmastatus.size -= dmastatus.trsize;
|
||||
if(dmastatus.size <= dmastatus.maxtrsize)
|
||||
dmastatus.trsize = dmastatus.size;
|
||||
|
||||
#if LCD_RGB24_BUFFSIZE == 0
|
||||
HAL_SPI_Transmit_DMA(&LCD_SPI_HANDLE, (uint8_t *)dmastatus.ptr, dmastatus.trsize);
|
||||
#else
|
||||
if(dmastatus.status == (DMA_STATUS_MULTIDATA | DMA_STATUS_24BIT))
|
||||
{
|
||||
BitmapConvert16to24((uint16_t *)dmastatus.ptr, lcd_rgb24_buffer, dmastatus.trsize);
|
||||
HAL_SPI_Transmit_DMA(&LCD_SPI_HANDLE, (uint8_t *)lcd_rgb24_buffer, dmastatus.trsize * 3);
|
||||
}
|
||||
else if(dmastatus.status == (DMA_STATUS_FILL | DMA_STATUS_24BIT))
|
||||
HAL_SPI_Transmit_DMA(&LCD_SPI_HANDLE, (uint8_t *)lcd_rgb24_buffer, dmastatus.trsize * 3);
|
||||
else
|
||||
HAL_SPI_Transmit_DMA(&LCD_SPI_HANDLE, (uint8_t *)dmastatus.ptr, dmastatus.trsize);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ /* dma operations have ended */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdDmaTransEnd();
|
||||
LCD_IO_DmaTxCpltCallback(hspi);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* #if LCD_DMA_TX == 1 */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Wrtite fill and multi data to Lcd (8 and 16 bit mode)
|
||||
- pData: 8 or 16 bits data pointer
|
||||
- Size: data number
|
||||
- Mode: 8 or 16 or 24 bit mode, write or read, fill or multidata (see the LCD_IO_... defines in lcd_io.h file) */
|
||||
void LCDWriteFillMultiData8and16(uint8_t * pData, uint32_t Size, uint32_t Mode)
|
||||
{
|
||||
if(Mode & LCD_IO_DATA8)
|
||||
LcdSpiMode8();
|
||||
else
|
||||
LcdSpiMode16();
|
||||
|
||||
#if LCD_DMA_TX == 1
|
||||
if((Size > DMA_MINSIZE) && (!LCD_DMA_UNABLE((uint32_t)pData)))
|
||||
{ /* DMA mode */
|
||||
if(Mode & LCD_IO_DATA8)
|
||||
{ /* 8bit DMA */
|
||||
LCD_SPI_HANDLE.hdmatx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
LCD_SPI_HANDLE.hdmatx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
dmastatus.status = DMA_STATUS_8BIT;
|
||||
}
|
||||
else
|
||||
{ /* 16bit DMA */
|
||||
LCD_SPI_HANDLE.hdmatx->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
LCD_SPI_HANDLE.hdmatx->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
dmastatus.status = DMA_STATUS_16BIT;
|
||||
}
|
||||
|
||||
if(Mode & LCD_IO_FILL)
|
||||
{ /* fill */
|
||||
LCD_SPI_HANDLE.hdmatx->Init.MemInc = DMA_MINC_DISABLE;
|
||||
dmastatus.status |= DMA_STATUS_FILL;
|
||||
dmastatus.data = *(uint16_t *)pData;
|
||||
dmastatus.ptr = (uint32_t)&dmastatus.data;
|
||||
}
|
||||
else
|
||||
{ /* multidata */
|
||||
LCD_SPI_HANDLE.hdmatx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
dmastatus.status |= DMA_STATUS_MULTIDATA;
|
||||
dmastatus.ptr = (uint32_t)pData;
|
||||
}
|
||||
|
||||
dmastatus.size = Size;
|
||||
dmastatus.maxtrsize = DMA_MAXSIZE;
|
||||
|
||||
if(Size > DMA_MAXSIZE)
|
||||
dmastatus.trsize = DMA_MAXSIZE;
|
||||
else /* the transaction can be performed with one DMA operation */
|
||||
dmastatus.trsize = Size;
|
||||
|
||||
__HAL_DMA_DISABLE(LCD_SPI_HANDLE.hdmatx);
|
||||
HAL_DMA_Init(LCD_SPI_HANDLE.hdmatx);
|
||||
HAL_SPI_Transmit_DMA(&LCD_SPI_HANDLE, (uint8_t *)dmastatus.ptr, dmastatus.trsize);
|
||||
LcdDmaWaitEnd(Mode & LCD_IO_MULTIDATA);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{ /* not DMA mode */
|
||||
if(Mode & LCD_IO_FILL)
|
||||
{ /* fill */
|
||||
while(Size--) /* fill 8 and 16bit */
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, (uint8_t *)pData, 1, LCD_SPI_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{ /* multidata */
|
||||
uint32_t trsize;
|
||||
while(Size)
|
||||
{
|
||||
if(Size > DMA_MAXSIZE)
|
||||
{
|
||||
trsize = DMA_MAXSIZE;
|
||||
Size -= DMA_MAXSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
trsize = Size;
|
||||
Size = 0;
|
||||
}
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, pData, trsize, LCD_SPI_TIMEOUT);
|
||||
if(Mode & LCD_IO_DATA8)
|
||||
pData += trsize;
|
||||
else
|
||||
pData += (trsize << 1);
|
||||
}
|
||||
}
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdTransEnd();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Wrtite fill and multi data to Lcd (convert RGB16 bit (5-6-5) to RGB24 bit (8-8-8) mode, no dma capability)
|
||||
- pData: RGB 16 bits data pointer
|
||||
- Size: data number
|
||||
- Mode: 8 or 16 or 24 bit mode, write or read, fill or multidata (see the LCD_IO_... defines in lcd_io.h file) */
|
||||
void LCDWriteFillMultiData16to24(uint8_t * pData, uint32_t Size, uint32_t Mode)
|
||||
{
|
||||
LcdSpiMode8();
|
||||
|
||||
#if LCD_DMA_TX == 1 && LCD_RGB24_BUFFSIZE > 0
|
||||
if(Size > DMA_MINSIZE)
|
||||
{ /* DMA mode */
|
||||
LCD_SPI_HANDLE.hdmatx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
LCD_SPI_HANDLE.hdmatx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
LCD_SPI_HANDLE.hdmatx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
__HAL_DMA_DISABLE(LCD_SPI_HANDLE.hdmatx);
|
||||
HAL_DMA_Init(LCD_SPI_HANDLE.hdmatx);
|
||||
|
||||
dmastatus.maxtrsize = LCD_RGB24_BUFFSIZE;
|
||||
dmastatus.size = Size;
|
||||
|
||||
if(Size > LCD_RGB24_BUFFSIZE)
|
||||
dmastatus.trsize = LCD_RGB24_BUFFSIZE;
|
||||
else
|
||||
dmastatus.trsize = Size;
|
||||
|
||||
if(Mode & LCD_IO_FILL)
|
||||
{ /* fill 16bit to 24bit */
|
||||
dmastatus.status = DMA_STATUS_FILL | DMA_STATUS_24BIT;
|
||||
FillConvert16to24(*(uint16_t *)pData, lcd_rgb24_buffer, dmastatus.trsize);
|
||||
}
|
||||
else
|
||||
{ /* multidata 16bit to 24bit */
|
||||
dmastatus.status = DMA_STATUS_MULTIDATA | DMA_STATUS_24BIT;
|
||||
dmastatus.ptr = (uint32_t)pData;
|
||||
BitmapConvert16to24((uint16_t *)pData, lcd_rgb24_buffer, dmastatus.trsize);
|
||||
}
|
||||
|
||||
HAL_SPI_Transmit_DMA(&LCD_SPI_HANDLE, lcd_rgb24_buffer, dmastatus.trsize * 3);
|
||||
LcdDmaWaitEnd(Mode & LCD_IO_MULTIDATA);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{ /* not DMA mode */
|
||||
#if LCD_RGB24_BUFFSIZE == 0
|
||||
uint32_t rgb888;
|
||||
if(Mode & LCD_IO_FILL)
|
||||
{ /* fill 16bit to 24bit */
|
||||
rgb888 = RGB565TO888(*(uint16_t *)pData);
|
||||
while(Size--)
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, (uint8_t *)&rgb888, 3, LCD_SPI_TIMEOUT);
|
||||
}
|
||||
else
|
||||
{ /* multidata 16bit to 24bit */
|
||||
while(Size--)
|
||||
{
|
||||
rgb888 = RGB565TO888(*(uint16_t *)pData);
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, (uint8_t *)&rgb888, 3, LCD_SPI_TIMEOUT);
|
||||
pData+=2;
|
||||
}
|
||||
}
|
||||
#elif LCD_RGB24_BUFFSIZE > 0
|
||||
uint32_t trsize;
|
||||
if(Mode & LCD_IO_FILL)
|
||||
{ /* fill */
|
||||
if(Size > LCD_RGB24_BUFFSIZE)
|
||||
trsize = LCD_RGB24_BUFFSIZE;
|
||||
else
|
||||
trsize = Size;
|
||||
FillConvert16to24(*(uint16_t *)pData, lcd_rgb24_buffer, trsize);
|
||||
while(Size)
|
||||
{
|
||||
if(Size > LCD_RGB24_BUFFSIZE)
|
||||
{
|
||||
trsize = LCD_RGB24_BUFFSIZE;
|
||||
Size -= LCD_RGB24_BUFFSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
trsize = Size;
|
||||
Size = 0;
|
||||
}
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, lcd_rgb24_buffer, trsize * 3, LCD_SPI_TIMEOUT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* bitmap */
|
||||
while(Size)
|
||||
{
|
||||
if(Size > LCD_RGB24_BUFFSIZE)
|
||||
{
|
||||
trsize = LCD_RGB24_BUFFSIZE;
|
||||
Size -= LCD_RGB24_BUFFSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
trsize = Size;
|
||||
Size = 0;
|
||||
}
|
||||
BitmapConvert16to24((uint16_t *)pData, lcd_rgb24_buffer, trsize);
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, lcd_rgb24_buffer, trsize * 3, LCD_SPI_TIMEOUT);
|
||||
pData += trsize << 1;
|
||||
}
|
||||
}
|
||||
#endif /* #elif LCD_RGB24_BUFFSIZE > 0 */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdTransEnd();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/* Read */
|
||||
|
||||
#if LCD_SPI_MODE != 0
|
||||
|
||||
/* RX DMA */
|
||||
#if LCD_DMA_RX == 1
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* DMA operation end callback function prototype */
|
||||
__weak void LCD_IO_DmaRxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
UNUSED(hspi);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* SPI DMA operation interrupt */
|
||||
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
uint32_t dma_status = dmastatus.status;
|
||||
if(hspi == &LCD_SPI_HANDLE)
|
||||
{
|
||||
#if LCD_RGB24_BUFFSIZE > 0
|
||||
if(dma_status == (DMA_STATUS_MULTIDATA | DMA_STATUS_24BIT))
|
||||
{
|
||||
BitmapConvert24to16(lcd_rgb24_buffer, (uint16_t *)dmastatus.ptr, dmastatus.trsize);
|
||||
dmastatus.ptr += dmastatus.trsize << 1; /* 24bit multidata */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(dma_status == (DMA_STATUS_MULTIDATA | DMA_STATUS_8BIT))
|
||||
dmastatus.ptr += dmastatus.trsize; /* 8bit multidata */
|
||||
else if(dma_status == (DMA_STATUS_MULTIDATA | DMA_STATUS_16BIT))
|
||||
dmastatus.ptr += dmastatus.trsize << 1; /* 16bit multidata */
|
||||
}
|
||||
|
||||
if(dmastatus.size > dmastatus.trsize)
|
||||
{ /* dma operation is still required */
|
||||
dmastatus.size -= dmastatus.trsize;
|
||||
if(dmastatus.size <= dmastatus.maxtrsize)
|
||||
dmastatus.trsize = dmastatus.size;
|
||||
|
||||
#if LCD_RGB24_BUFFSIZE > 0
|
||||
if(dma_status == (DMA_STATUS_MULTIDATA | DMA_STATUS_24BIT))
|
||||
HAL_SPI_Receive_DMA(&LCD_SPI_HANDLE, lcd_rgb24_buffer, dmastatus.trsize * 3);
|
||||
else
|
||||
#endif
|
||||
HAL_SPI_Receive_DMA(&LCD_SPI_HANDLE, (uint8_t *)dmastatus.ptr, dmastatus.trsize);
|
||||
}
|
||||
else
|
||||
{ /* dma operations have ended */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdDirWrite();
|
||||
LcdDmaTransEnd();
|
||||
LCD_IO_DmaRxCpltCallback(hspi);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* #if LCD_DMA_RX == 1 */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Read data from Lcd
|
||||
- pData: 8 or 16 bits data pointer
|
||||
- Size: data number
|
||||
- Mode: 8 or 16 or 24 bit mode, write or read, fill or multidata (see the LCD_IO_... defines in lcd_io.h file) */
|
||||
void LCDReadMultiData8and16(uint8_t * pData, uint32_t Size, uint32_t Mode)
|
||||
{
|
||||
if(Mode & LCD_IO_DATA8)
|
||||
LcdSpiMode8();
|
||||
else
|
||||
LcdSpiMode16();
|
||||
|
||||
#if LCD_DMA_RX == 1
|
||||
if((Size > DMA_MINSIZE) && (!LCD_DMA_UNABLE((uint32_t)pData)))
|
||||
{ /* DMA mode */
|
||||
/* SPI RX DMA setting (8bit, multidata) */
|
||||
if(Mode & LCD_IO_DATA8)
|
||||
{
|
||||
LCD_SPI_HANDLE.hdmarx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
LCD_SPI_HANDLE.hdmarx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
dmastatus.status = DMA_STATUS_MULTIDATA | DMA_STATUS_8BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_SPI_HANDLE.hdmarx->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
LCD_SPI_HANDLE.hdmarx->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
dmastatus.status = DMA_STATUS_MULTIDATA | DMA_STATUS_16BIT;
|
||||
}
|
||||
LCD_SPI_HANDLE.hdmarx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
|
||||
__HAL_DMA_DISABLE(LCD_SPI_HANDLE.hdmarx);
|
||||
HAL_DMA_Init(LCD_SPI_HANDLE.hdmarx);
|
||||
|
||||
dmastatus.maxtrsize = DMA_MAXSIZE;
|
||||
dmastatus.size = Size;
|
||||
|
||||
if(Size > DMA_MAXSIZE)
|
||||
dmastatus.trsize = DMA_MAXSIZE;
|
||||
else
|
||||
dmastatus.trsize = Size;
|
||||
|
||||
dmastatus.ptr = (uint32_t)pData;
|
||||
|
||||
HAL_SPI_Receive_DMA(&LCD_SPI_HANDLE, pData, dmastatus.trsize);
|
||||
LcdDmaWaitEnd(1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{ /* not DMA mode */
|
||||
uint32_t trsize;
|
||||
while(Size)
|
||||
{
|
||||
if(Size > DMA_MAXSIZE)
|
||||
{
|
||||
trsize = DMA_MAXSIZE;
|
||||
Size -= DMA_MAXSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
trsize = Size;
|
||||
Size = 0;
|
||||
}
|
||||
HAL_SPI_Receive(&LCD_SPI_HANDLE, pData, trsize, LCD_SPI_TIMEOUT);
|
||||
if(Mode & LCD_IO_DATA8)
|
||||
pData += trsize;
|
||||
else
|
||||
pData += (trsize << 1);
|
||||
}
|
||||
LcdDirWrite();
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdTransEnd();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Read 24bit (8-8-8) RGB data from LCD, and convert to 16bit (5-6-5) RGB data
|
||||
- pData: 16 bits RGB data pointer
|
||||
- Size: pixel number
|
||||
- Mode: 8 or 16 or 24 bit mode, write or read, fill or multidata (see the LCD_IO_... defines in lcd_io.h file) */
|
||||
void LCDReadMultiData24to16(uint8_t * pData, uint32_t Size, uint32_t Mode)
|
||||
{
|
||||
LcdSpiMode8();
|
||||
#if LCD_DMA_RX == 1 && LCD_RGB24_BUFFSIZE > 0
|
||||
if(Size > DMA_MINSIZE)
|
||||
{ /* DMA mode */
|
||||
/* SPI RX DMA setting (8bit, multidata) */
|
||||
LCD_SPI_HANDLE.hdmarx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
LCD_SPI_HANDLE.hdmarx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
LCD_SPI_HANDLE.hdmarx->Init.MemInc = DMA_MINC_ENABLE;
|
||||
__HAL_DMA_DISABLE(LCD_SPI_HANDLE.hdmarx);
|
||||
HAL_DMA_Init(LCD_SPI_HANDLE.hdmarx);
|
||||
|
||||
dmastatus.maxtrsize = LCD_RGB24_BUFFSIZE;
|
||||
dmastatus.size = Size;
|
||||
|
||||
if(Size > LCD_RGB24_BUFFSIZE)
|
||||
dmastatus.trsize = LCD_RGB24_BUFFSIZE;
|
||||
else
|
||||
dmastatus.trsize = Size;
|
||||
|
||||
dmastatus.status = DMA_STATUS_MULTIDATA | DMA_STATUS_24BIT;
|
||||
dmastatus.ptr = (uint32_t)pData;
|
||||
|
||||
HAL_SPI_Receive_DMA(&LCD_SPI_HANDLE, lcd_rgb24_buffer, dmastatus.trsize * 3);
|
||||
LcdDmaWaitEnd(1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{ /* not DMA mode */
|
||||
#if LCD_RGB24_BUFFSIZE == 0
|
||||
uint32_t rgb888;
|
||||
while(Size--)
|
||||
{
|
||||
HAL_SPI_Receive(&LCD_SPI_HANDLE, (uint8_t *)&rgb888, 3, LCD_SPI_TIMEOUT);
|
||||
*(uint16_t *)pData = RGB888TO565(rgb888);
|
||||
pData += 2;
|
||||
}
|
||||
#elif LCD_RGB24_BUFFSIZE > 0
|
||||
uint32_t trsize;
|
||||
while(Size)
|
||||
{
|
||||
if(Size > LCD_RGB24_BUFFSIZE)
|
||||
{
|
||||
trsize = LCD_RGB24_BUFFSIZE;
|
||||
Size -= LCD_RGB24_BUFFSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
trsize = Size;
|
||||
Size = 0;
|
||||
}
|
||||
HAL_SPI_Receive(&LCD_SPI_HANDLE, lcd_rgb24_buffer, trsize * 3, LCD_SPI_TIMEOUT);
|
||||
BitmapConvert24to16(lcd_rgb24_buffer, (uint16_t *)pData, trsize);
|
||||
pData += (trsize << 1);
|
||||
}
|
||||
#endif
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdDirWrite();
|
||||
LcdTransEnd();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if LCD_SPI_MODE != 0 */
|
||||
|
||||
//=============================================================================
|
||||
/* Public functions */
|
||||
|
||||
/* n millisec delay */
|
||||
void LCD_Delay(uint32_t Delay)
|
||||
{
|
||||
#ifndef osCMSIS
|
||||
HAL_Delay(Delay);
|
||||
#else
|
||||
osDelay(Delay);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Backlight on-off (Bl=0 -> off, Bl=1 -> on) */
|
||||
//-----------------------------------------------------------------------------
|
||||
void LCD_IO_Bl_OnOff(uint8_t Bl)
|
||||
{
|
||||
#if defined(LCD_BL_GPIO_Port) && defined (LCD_BL_Pin)
|
||||
if(Bl)
|
||||
#if LCD_BLON == 0
|
||||
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET);
|
||||
#elif LCD_BLON == 1
|
||||
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET);
|
||||
#endif
|
||||
else
|
||||
#if LCD_BLON == 0
|
||||
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET);
|
||||
#elif LCD_BLON == 1
|
||||
HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Lcd IO init, reset, spi speed init, get the freertos task id */
|
||||
void LCD_IO_Init(void)
|
||||
{
|
||||
#if defined(LCD_RST_GPIO_Port) && defined (LCD_RST_Pin)
|
||||
LCD_Delay(50);
|
||||
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_RESET);
|
||||
LCD_Delay(50);
|
||||
HAL_GPIO_WritePin(LCD_RST_GPIO_Port, LCD_RST_Pin, GPIO_PIN_SET);
|
||||
#endif
|
||||
LCD_Delay(10);
|
||||
#if defined(LCD_SPI_SPD_WRITE)
|
||||
LCD_SPI_SETBAUDRATE(LCD_SPI_HANDLE, LCD_SPI_SPD_WRITE);
|
||||
#endif
|
||||
LcdTransInit();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Lcd IO transaction
|
||||
- Cmd: 8 or 16 bits command
|
||||
- pData: 8 or 16 bits data pointer
|
||||
- Size: data number
|
||||
- DummySize: dummy byte number at read
|
||||
- Mode: 8 or 16 or 24 bit mode, write or read, fill or multidata (see the LCD_IO_... defines in lcd_io.h file) */
|
||||
void LCD_IO_Transaction(uint16_t Cmd, uint8_t *pData, uint32_t Size, uint32_t DummySize, uint32_t Mode)
|
||||
{
|
||||
#if LCD_SPI_MODE == 0 /* only TX mode */
|
||||
if(Mode & LCD_IO_READ)
|
||||
return;
|
||||
#endif
|
||||
|
||||
LcdTransStart();
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/* Command write */
|
||||
if(Mode & LCD_IO_CMD8)
|
||||
LcdSpiMode8();
|
||||
else if(Mode & LCD_IO_CMD16)
|
||||
LcdSpiMode16();
|
||||
HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_RESET);
|
||||
HAL_SPI_Transmit(&LCD_SPI_HANDLE, (uint8_t *)&Cmd, 1, LCD_SPI_TIMEOUT); /* CMD write */
|
||||
HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_SET);
|
||||
|
||||
if(Size == 0)
|
||||
{ /* only command byte or word */
|
||||
HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_SET);
|
||||
LcdTransEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Datas write or read */
|
||||
if(Mode & LCD_IO_WRITE)
|
||||
{ /* Write Lcd */
|
||||
if(Mode & LCD_IO_DATA16TO24)
|
||||
LCDWriteFillMultiData16to24(pData, Size, Mode);
|
||||
else
|
||||
LCDWriteFillMultiData8and16(pData, Size, Mode);
|
||||
}
|
||||
#if LCD_SPI_MODE != 0
|
||||
else if(Mode & LCD_IO_READ)
|
||||
{ /* Read LCD */
|
||||
LcdDirRead((DummySize << 3) + LCD_SCK_EXTRACLK);
|
||||
if(Mode & LCD_IO_DATA24TO16)
|
||||
LCDReadMultiData24to16(pData, Size, Mode);
|
||||
else
|
||||
LCDReadMultiData8and16(pData, Size, Mode);
|
||||
}
|
||||
#endif /* #if LCD_SPI_MODE != 0 */
|
||||
}
|
||||
158
Core/Src/Lcd/lcd_io_spi_hal.h
Normal file
158
Core/Src/Lcd/lcd_io_spi_hal.h
Normal file
@@ -0,0 +1,158 @@
|
||||
//=============================================================================
|
||||
/* Information section */
|
||||
|
||||
/*
|
||||
* SPI HAL LCD driver for all stm32 family
|
||||
* author: Roberto Benjami
|
||||
* v.2022.11
|
||||
*/
|
||||
|
||||
/* Features:
|
||||
- only hardware SPI
|
||||
- write function 8 and 16bit without DMA or with DMA (in both fill and bitmap mode)
|
||||
- write function with bitdepth convert (16bit RGB565 to 24bit RGB888) without DMA or with DMA
|
||||
- all writing functions are possible in both fill and bitmap mode
|
||||
- read function 8 and 16bit only without DMA or with DMA
|
||||
- read function with bitdepth convert (24bit RGB888 to 16bit RGB565) without DMA or with DMA */
|
||||
|
||||
/* Settings in CUBEIDE or CUBEMX
|
||||
SPI Parameter Settings
|
||||
- Mode: "Full duplex master" or "Half duplex master" os "Transmit only master"
|
||||
- Hardware NSS signal: disabled
|
||||
- Frame format: Motorola
|
||||
- Data Size: 8 bits
|
||||
- First bit: MSB first
|
||||
- Prescaler: it doesn't matter, the speed needs to be specified elsewhere
|
||||
- Clock Polarity: Low
|
||||
- Clock Phase: 1 Edge
|
||||
note: if the selected SPI pin is not good, change it in the pinout view
|
||||
SPI DMA Settings (if necessary)
|
||||
- Add DMA Request SPIn_TX, left at the default value (if necessary)
|
||||
- Add DMA Request SPIn_RX, left at the default value (if necessary)
|
||||
GPIO
|
||||
- Lcd chip select:
|
||||
- output level: High
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: LCD_CS
|
||||
- Lcd RS
|
||||
- output level: Low
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: LCD_RS
|
||||
- Lcd SCK
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: LCD_SCK
|
||||
- Lcd MOSI
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: LCD_MOSI
|
||||
- Lcd MISO
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: LCD_MISO
|
||||
- Lcd reset pin (only when connected)
|
||||
- output level: High
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Low
|
||||
- User Label: LCD_RST
|
||||
- Lcd back light pin (only when connected)
|
||||
- output level: Low or High
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Low
|
||||
- User Label: LCD_BL
|
||||
|
||||
Settings in main.h:
|
||||
- If you use freertos, add this line the main.h file
|
||||
#include "cmsis_os.h"
|
||||
(note: then the driver will also use the rtos signal to wait for the end of the dma transaction)
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
/* Interface section */
|
||||
|
||||
/* Queries whether a DMA operation is in progress
|
||||
- 0: not in progress
|
||||
- 1: in progress */
|
||||
uint32_t LCD_IO_DmaBusy(void);
|
||||
|
||||
/* If we want to know when the LCD DMA operation is finished, let's create a function in our program:
|
||||
This function is called by the driver at the end of DMA operations. */
|
||||
void LCD_IO_DmaTxCpltCallback(SPI_HandleTypeDef *hspi);
|
||||
void LCD_IO_DmaRxCpltCallback(SPI_HandleTypeDef *hspi);
|
||||
|
||||
//=============================================================================
|
||||
/* Setting section (please set the necessary things in this section) */
|
||||
|
||||
#ifndef __LCD_IO_SPI_HAL_H__
|
||||
#define __LCD_IO_SPI_HAL_H__
|
||||
|
||||
/* SPI handle select (see in main.c file, default: hspi1, hspi2 ... hspi6) */
|
||||
#define LCD_SPI_HANDLE hspi1
|
||||
|
||||
/* SPI mode
|
||||
- 0: only TX (write on MOSI pin, no MISO pin)
|
||||
- 1: half duplex (MOSI pin is bidirectional)
|
||||
- 2: full duplex (write on MOSI pin, read on MISO pin) */
|
||||
#define LCD_SPI_MODE 2
|
||||
|
||||
/* SPI write and read speed (if deleted -> setting in CUBE)
|
||||
- hardware SPI clock div fPCLK: 0=/2, 1=/4, 2=/8, 3=/16, 4=/32, 5=/64, 6=/128, 7=/256 */
|
||||
#define LCD_SPI_SPD_WRITE 1
|
||||
#define LCD_SPI_SPD_READ 4
|
||||
|
||||
/* Backlight control (the logical level of the active state) */
|
||||
#define LCD_BLON 0
|
||||
|
||||
/* When data direction change (OUT->IN) there is a display that requires extra clock
|
||||
example ST7735: 1, ILI9341: 0, ILI9488: 0 */
|
||||
#define LCD_SCK_EXTRACLK 0
|
||||
|
||||
/* DMA TX/RX enable/disable
|
||||
- 0: DMA disable
|
||||
- 1: DMA enable */
|
||||
#define LCD_DMA_TX 1
|
||||
#define LCD_DMA_RX 0
|
||||
|
||||
/* In dma mode the bitmap drawing function is completed before the actual drawing.
|
||||
When should we wait for the previous DMA operation to complete? (see the readme.me file)
|
||||
- 0: DMA check and wait at drawing function start
|
||||
- 1: DMA check and wait at drawing function start + bitmap drawing function end wait on (default mode)
|
||||
- 2: DMA wait at drawing function end */
|
||||
#define LCD_DMA_ENDWAIT 1
|
||||
|
||||
/* Because there are DMA capable and DMA unable memory regions
|
||||
here we can set what is the DMA unable region condition
|
||||
note: where the condition is true, it is considered a DMA-unable region
|
||||
Default (all memory used for bitmap drawing is DMA capable):
|
||||
#define LCD_DMA_UNABLE(addr) 0
|
||||
Example stm32f407 and stm32f429 with CCMRAM (the CCMRAM is not DMA capable):
|
||||
#define LCD_DMA_UNABLE(addr) ((addr < 0x20000000) && (addr >= 0x10000000))
|
||||
Example stm32h743 (the DTCMRAM and ITCMRAM are not DMA capable):
|
||||
#define LCD_DMA_UNABLE(addr) (((addr < 0x24000000) && (addr >= 0x20000000)) || (addr < 0x08000000))
|
||||
Note: if we ensure that we do not draw a bitmap from a DMA-capable memory area, it is not necessary to set it (leave it that way) */
|
||||
#define LCD_DMA_UNABLE(addr) 0
|
||||
|
||||
/* RGB565 to RGB888 and RGB888 to RGB565 convert byte order
|
||||
- 0: forward direction
|
||||
- 1: back direction
|
||||
(warning: the SPI DMA order is from low address to hight address step byte)
|
||||
note: If the red and blue colors are reversed and used 24bit mode, change this value */
|
||||
#define LCD_RGB24_ORDER 0
|
||||
|
||||
/* Pixel buffer size for DMA bitdepth conversion (buffer size [byte] = 3 * pixel buffer size)
|
||||
note: if 0 -> does not use DMA for 24-bit drawing and reading */
|
||||
#define LCD_RGB24_BUFFSIZE 0
|
||||
|
||||
#endif
|
||||
1153
Core/Src/Lcd/stm32_adafruit_lcd.c
Normal file
1153
Core/Src/Lcd/stm32_adafruit_lcd.c
Normal file
File diff suppressed because it is too large
Load Diff
203
Core/Src/Lcd/stm32_adafruit_lcd.h
Normal file
203
Core/Src/Lcd/stm32_adafruit_lcd.h
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
- 2019.05 Add BSP_LCD_ReadID fuction
|
||||
- 2019.05 Add BSP_LCD_ReadPixel fuction
|
||||
- 2019.05 Add BSP_LCD_DrawRGB16Image fuction
|
||||
- 2019.05 Add BSP_LCD_ReadRGB16Image fuction
|
||||
- 2019.11 Add BSP_LCD_FillTriangle
|
||||
- 2019.12 Add LCD_DEFAULT_FONT, LCD_DEFAULT_BACKCOLOR, LCD_DEFAULT_TEXTCOLOR, LCD_INIT_CLEAR
|
||||
- 2020.05 Add BSP_LCD_Scroll function
|
||||
- 2022.11 Modify ReadID return type: uint16_t to uint32_t
|
||||
- 2023.03 Add BSP_LCD_DisplayMultilayerChar function (mainly for drawing icons and buttons)
|
||||
- 2023.03 Add BSP_LCD_DisplayStringOnMultilayerChar function (mainly for drawing texticons and textbuttons)
|
||||
*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32_adafruit_lcd.h
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains the common defines and functions prototypes for
|
||||
* the stm32_adafruit_lcd.c driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32_ADAFRUIT_LCD_H
|
||||
#define __STM32_ADAFRUIT_LCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "lcd.h"
|
||||
#include "Fonts/fonts.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Config section (you can change this defines) */
|
||||
|
||||
/* LCD default font (Font8 or Font12 or Font16 or Font20 or Font24) */
|
||||
#define LCD_DEFAULT_FONT Font12
|
||||
|
||||
/* Font bitmap buffer size (even for the largest font size, at least one line should fit in it) */
|
||||
#define FONTBITMAPBUFSIZE 24 * 16
|
||||
|
||||
/* BSP_LCD_DisplayMultilayerChar max layer */
|
||||
#define MAX_CHAR_LAYER 12
|
||||
|
||||
/* LCD default colors */
|
||||
#define LCD_DEFAULT_BACKCOLOR LCD_COLOR_BLACK
|
||||
#define LCD_DEFAULT_TEXTCOLOR LCD_COLOR_WHITE
|
||||
|
||||
/* LCD clear with LCD_DEFAULT_BACKCOLOR in the BSP_LCD_Init (0:diasble, 1:enable) */
|
||||
#define LCD_INIT_CLEAR 0
|
||||
|
||||
/* some colors */
|
||||
#define LCD_COLOR_BLACK LCD_COLOR(0, 0, 0)
|
||||
#define LCD_COLOR_GRAY LCD_COLOR(192, 192, 192)
|
||||
#define LCD_COLOR_BLUE LCD_COLOR(0, 0, 255)
|
||||
#define LCD_COLOR_RED LCD_COLOR(255, 0, 0)
|
||||
#define LCD_COLOR_GREEN LCD_COLOR(0, 255, 0)
|
||||
#define LCD_COLOR_CYAN LCD_COLOR(0, 255, 255)
|
||||
#define LCD_COLOR_MAGENTA LCD_COLOR(255, 0, 255)
|
||||
#define LCD_COLOR_YELLOW LCD_COLOR(255, 255, 0)
|
||||
#define LCD_COLOR_WHITE LCD_COLOR(255, 255, 255)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Interface section (no modify) */
|
||||
|
||||
/**
|
||||
* @brief Draw Properties structures definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t TextColor;
|
||||
uint32_t BackColor;
|
||||
sFONT *pFont;
|
||||
}LCD_DrawPropTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Point structures definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int16_t X;
|
||||
int16_t Y;
|
||||
}Point, * pPoint;
|
||||
|
||||
/**
|
||||
* @brief Line mode structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CENTER_MODE = 0x01, /*!< Center mode */
|
||||
RIGHT_MODE = 0x02, /*!< Right mode */
|
||||
LEFT_MODE = 0x03 /*!< Left mode */
|
||||
}Line_ModeTypdef;
|
||||
|
||||
#define __IO volatile
|
||||
|
||||
/**
|
||||
* @brief LCD status structure definition
|
||||
*/
|
||||
#define LCD_OK 0x00
|
||||
#define LCD_ERROR 0x01
|
||||
#define LCD_TIMEOUT 0x02
|
||||
|
||||
#if LCD_REVERSE16 == 1
|
||||
#define RC(a) ((((a) & 0xFF) << 8) | (((a) & 0xFF00) >> 8))
|
||||
#else
|
||||
#define RC(a) a
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LCD color
|
||||
*/
|
||||
#define LCD_COLOR(r, g, b) (RC((r & 0xF8) << 8 | (g & 0xFC) << 3 | (b & 0xF8) >> 3))
|
||||
#define LCD_COLOR16(rgb16) (RC(rgb16))
|
||||
|
||||
/** @defgroup STM32_ADAFRUIT_LCD_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
uint8_t BSP_LCD_Init(void);
|
||||
uint16_t BSP_LCD_GetXSize(void);
|
||||
uint16_t BSP_LCD_GetYSize(void);
|
||||
|
||||
uint16_t BSP_LCD_GetTextColor(void);
|
||||
uint16_t BSP_LCD_GetBackColor(void);
|
||||
void BSP_LCD_SetTextColor(__IO uint16_t Color);
|
||||
void BSP_LCD_SetBackColor(__IO uint16_t Color);
|
||||
void BSP_LCD_SetFont(sFONT *fonts);
|
||||
sFONT *BSP_LCD_GetFont(void);
|
||||
|
||||
void BSP_LCD_Clear(uint16_t Color);
|
||||
void BSP_LCD_ClearStringLine(uint16_t Line);
|
||||
void BSP_LCD_DisplayStringAtLine(uint16_t Line, uint8_t *ptr);
|
||||
void BSP_LCD_DisplayStringAt(uint16_t Xpos, uint16_t Ypos, uint8_t *Text, Line_ModeTypdef Mode);
|
||||
void BSP_LCD_DisplayChar(uint16_t Xpos, uint16_t Ypos, uint8_t Ascii);
|
||||
void BSP_LCD_DisplayStringOnMultilayerChar(uint16_t Xpos, uint16_t Ypos, uint8_t *Chars, uint16_t *Colors, sFONT *sf,
|
||||
uint16_t onX, uint16_t onY, uint8_t *onChars);
|
||||
|
||||
void BSP_LCD_DrawPixel(uint16_t Xpos, uint16_t Ypos, uint16_t RGB_Code);
|
||||
void BSP_LCD_DrawHLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
|
||||
void BSP_LCD_DrawVLine(uint16_t Xpos, uint16_t Ypos, uint16_t Length);
|
||||
void BSP_LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
|
||||
void BSP_LCD_DrawRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
|
||||
void BSP_LCD_DrawCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
|
||||
void BSP_LCD_DrawPolygon(pPoint Points, uint16_t PointCount);
|
||||
void BSP_LCD_DrawEllipse(uint16_t Xpos, uint16_t Ypos, uint16_t XRadius, uint16_t YRadius);
|
||||
void BSP_LCD_DrawBitmap(uint16_t Xpos, uint16_t Ypos, uint8_t *pBmp);
|
||||
void BSP_LCD_FillRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height);
|
||||
void BSP_LCD_FillCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius);
|
||||
void BSP_LCD_FillPolygon(pPoint Points, uint16_t PointCount);
|
||||
void BSP_LCD_FillEllipse(uint16_t Xpos, uint16_t Ypos, uint16_t XRadius, uint16_t YRadius);
|
||||
void BSP_LCD_FillTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3);
|
||||
|
||||
void BSP_LCD_DisplayOff(void);
|
||||
void BSP_LCD_DisplayOn(void);
|
||||
|
||||
uint32_t BSP_LCD_ReadID(void);
|
||||
uint16_t BSP_LCD_ReadPixel(uint16_t Xpos, uint16_t Ypos);
|
||||
void BSP_LCD_DrawRGB16Image(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t *pData);
|
||||
void BSP_LCD_ReadRGB16Image(uint16_t Xpos, uint16_t Ypos, uint16_t Xsize, uint16_t Ysize, uint16_t *pData);
|
||||
void BSP_LCD_Scroll(int16_t Scroll, uint16_t TopFix, uint16_t BottonFix);
|
||||
|
||||
/* User direct Lcd data write and read */
|
||||
void BSP_LCD_DataWrite8(uint16_t Cmd, uint8_t *ptr, uint32_t Size);
|
||||
void BSP_LCD_DataWrite16(uint16_t Cmd, uint16_t *ptr, uint32_t Size);
|
||||
void BSP_LCD_DataRead8(uint16_t Cmd, uint8_t *ptr, uint32_t Size);
|
||||
void BSP_LCD_DataRead16(uint16_t Cmd, uint16_t *ptr, uint32_t Size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32_ADAFRUIT_LCD_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
181
Core/Src/Lcd/stm32_adafruit_ts.c
Normal file
181
Core/Src/Lcd/stm32_adafruit_ts.c
Normal file
@@ -0,0 +1,181 @@
|
||||
#include "main.h"
|
||||
#include "ts.h"
|
||||
#include "stm32_adafruit_ts.h"
|
||||
|
||||
extern TS_DrvTypeDef *ts_drv;
|
||||
|
||||
uint16_t TsXBoundary, TsYBoundary;
|
||||
|
||||
#define MAXCINT1245 262144
|
||||
#define MAXCINT36 1073741824
|
||||
|
||||
ts_cindex cindex = TS_CINDEX;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void BSP_TS_CalibCalc(ts_three_points * tp, ts_three_points * dp, ts_cindex * ci)
|
||||
{
|
||||
long long int i0, i1, i2, i3, i4, i5, i6, i1t, i2t, i3t, i4t, i5t, i6t;
|
||||
int idv = 1, d;
|
||||
|
||||
if(ci == NULL)
|
||||
ci = &cindex;
|
||||
|
||||
i0 = (tp->x0 - tp->x2) * (tp->y1 - tp->y2) - (tp->x1 - tp->x2) * (tp->y0 - tp->y2);
|
||||
i1 = (dp->x0 - dp->x2) * (tp->y1 - tp->y2) - (dp->x1 - dp->x2) * (tp->y0 - tp->y2);
|
||||
i2 = (tp->x0 - tp->x2) * (dp->x1 - dp->x2) - (dp->x0 - dp->x2) * (tp->x1 - tp->x2);
|
||||
i3 = (long long int)tp->y0 * (tp->x2 * dp->x1 - tp->x1 * dp->x2) +
|
||||
(long long int)tp->y1 * (tp->x0 * dp->x2 - tp->x2 * dp->x0) +
|
||||
(long long int)tp->y2 * (tp->x1 * dp->x0 - tp->x0 * dp->x1);
|
||||
i4 = (dp->y0 - dp->y2) * (tp->y1 - tp->y2) - (dp->y1 - dp->y2) * (tp->y0 - tp->y2);
|
||||
i5 = (tp->x0 - tp->x2) * (dp->y1 - dp->y2) - (dp->y0 - dp->y2) * (tp->x1 - tp->x2);
|
||||
i6 = (long long int)tp->y0 * (tp->x2 * dp->y1 - tp->x1 * dp->y2) +
|
||||
(long long int)tp->y1 * (tp->x0 * dp->y2 - tp->x2 * dp->y0) +
|
||||
(long long int)tp->y2 * (tp->x1 * dp->y0 - tp->x0 * dp->y1);
|
||||
i1t = i1; i2t = i2; i3t = i3; i4t = i4; i5t = i5; i6t = i6;
|
||||
do
|
||||
{
|
||||
d = 0;
|
||||
if((i1t >= MAXCINT1245) || (i1t < -MAXCINT1245))
|
||||
{
|
||||
d = 1;
|
||||
i1t /= 2;
|
||||
}
|
||||
if((i2t >= MAXCINT1245) || (i2t < -MAXCINT1245))
|
||||
{
|
||||
d = 1;
|
||||
i2t /= 2;
|
||||
}
|
||||
if((i4t >= MAXCINT1245) || (i4t < -MAXCINT1245))
|
||||
{
|
||||
d = 1;
|
||||
i4t /= 2;
|
||||
}
|
||||
if((i5t >= MAXCINT1245) || (i5t < -MAXCINT1245))
|
||||
{
|
||||
d = 1;
|
||||
i5t /= 2;
|
||||
}
|
||||
if((i3t >= MAXCINT36) || (i3t < -MAXCINT36))
|
||||
{
|
||||
d = 1;
|
||||
i3t /= 2;
|
||||
}
|
||||
if((i6t >= MAXCINT36) || (i6t < -MAXCINT36))
|
||||
{
|
||||
d = 1;
|
||||
i6t /= 2;
|
||||
}
|
||||
if(d)
|
||||
idv *= 2;
|
||||
}while(d);
|
||||
|
||||
if(idv > 1)
|
||||
{
|
||||
i0 /= idv; i1 /= idv; i2 /= idv; i3 /= idv; i4 /= idv; i5 /= idv; i6 /= idv;
|
||||
}
|
||||
|
||||
(*ci)[0] = (int32_t)i0;
|
||||
(*ci)[1] = (int32_t)i1;
|
||||
(*ci)[2] = (int32_t)i2;
|
||||
(*ci)[3] = (int32_t)i3;
|
||||
(*ci)[4] = (int32_t)i4;
|
||||
(*ci)[5] = (int32_t)i5;
|
||||
(*ci)[6] = (int32_t)i6;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* calculate display coordinate from touchscreen coordinate and cindex
|
||||
param:
|
||||
- tx : touchscreen X coordinate
|
||||
- ty : touchscreen Y coordinate
|
||||
- dx* : pointer to display X coordinate
|
||||
- dy* : pointer to display Y coordinate
|
||||
- mx : max display X coordinate
|
||||
- my : max display Y coordinate
|
||||
return: dx, dy */
|
||||
void BSP_TS_DisplaycoordCalc(uint16_t tx, uint16_t ty, uint16_t * dx, uint16_t * dy, uint16_t mx, uint16_t my)
|
||||
{
|
||||
int32_t x, y;
|
||||
x = (cindex[1] * tx + cindex[2] * ty + cindex[3]) / cindex[0];
|
||||
y = (cindex[4] * tx + cindex[5] * ty + cindex[6]) / cindex[0];
|
||||
|
||||
if(x < 0)
|
||||
x = 0;
|
||||
else if(x > mx)
|
||||
x = mx;
|
||||
|
||||
if(y < 0)
|
||||
y = 0;
|
||||
else if(y > my)
|
||||
y = my;
|
||||
|
||||
*dx = x;
|
||||
*dy = y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Set the cindex values
|
||||
param:
|
||||
- ci: pointer to cindex array */
|
||||
void BSP_TS_SetCindex(ts_cindex * ci)
|
||||
{
|
||||
for(uint32_t i = 0; i < 7; i++)
|
||||
cindex[i] = (*ci)[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* Get the cindex values
|
||||
param:
|
||||
- ci: pointer to cindex array */
|
||||
void BSP_TS_GetCindex(ts_cindex * ci)
|
||||
{
|
||||
for(uint32_t i = 0; i < 7; i++)
|
||||
(*ci)[i] = cindex[i];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Initializes and configures the touch screen functionalities and
|
||||
* configures all necessary hardware resources (GPIOs, clocks..).
|
||||
* @param XSize: The maximum X size of the TS area on LCD
|
||||
* @param YSize: The maximum Y size of the TS area on LCD
|
||||
* @retval TS_OK: if all initializations are OK. Other value if error.
|
||||
*/
|
||||
uint8_t BSP_TS_Init(uint16_t XSize, uint16_t YSize)
|
||||
{
|
||||
uint8_t ret = TS_ERROR;
|
||||
|
||||
/* Initialize x and y positions boundaries */
|
||||
TsXBoundary = XSize;
|
||||
TsYBoundary = YSize;
|
||||
|
||||
if(ts_drv)
|
||||
ret = TS_OK;
|
||||
|
||||
if(ret == TS_OK)
|
||||
{
|
||||
/* Initialize the LL TS Driver */
|
||||
ts_drv->Init(0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief Returns status and positions of the touch screen.
|
||||
* @param TsState: Pointer to touch screen current state structure
|
||||
*/
|
||||
void BSP_TS_GetState(TS_StateTypeDef* TsState)
|
||||
{
|
||||
uint16_t tx, ty, dx, dy;
|
||||
|
||||
TsState->TouchDetected = ts_drv->DetectTouch(0);
|
||||
if(TsState->TouchDetected)
|
||||
{
|
||||
ts_drv->GetXY(0, &tx, &ty);
|
||||
BSP_TS_DisplaycoordCalc(tx, ty, &dx, &dy, TsXBoundary-1, TsYBoundary-1);
|
||||
TsState->X = dx;
|
||||
TsState->Y = dy;
|
||||
}
|
||||
}
|
||||
62
Core/Src/Lcd/stm32_adafruit_ts.h
Normal file
62
Core/Src/Lcd/stm32_adafruit_ts.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32_ADAFRUIT_TS_H
|
||||
#define __STM32_ADAFRUIT_TS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
/* Setting section (please set the necessary things in this section) */
|
||||
|
||||
/* These values can be created using appTouchCalib */
|
||||
#define TS_CINDEX {2023493, -178832, -1974, 692966059, 1107, 259356, -49493813}
|
||||
//{-1350650, -134489, 521, 71073115, 348, -104248, 44767250}
|
||||
|
||||
//=============================================================================
|
||||
/* Interface section */
|
||||
|
||||
typedef int32_t ts_cindex[7];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t x0, y0, x1, y1, x2, y2;
|
||||
}ts_three_points;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t TouchDetected;
|
||||
uint16_t X;
|
||||
uint16_t Y;
|
||||
uint16_t Z;
|
||||
}TS_StateTypeDef;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TS_OK = 0x00,
|
||||
TS_ERROR = 0x01,
|
||||
TS_TIMEOUT = 0x02
|
||||
}TS_StatusTypeDef;
|
||||
|
||||
uint8_t BSP_TS_Init(uint16_t XSize, uint16_t YSize);
|
||||
void BSP_TS_GetState(TS_StateTypeDef *TsState);
|
||||
|
||||
/* Touchscreen calibration (calculates cindex array values from three touchscreen point coordinates)
|
||||
param:
|
||||
- tp : source pointer to three touchscreen coordinates
|
||||
- dp : source pointer to three display coordinates
|
||||
- ci : result pointer to cindex array (if NULL -> puts it in the current cindex)
|
||||
return; cindex values */
|
||||
void BSP_TS_CalibCalc(ts_three_points * tp, ts_three_points * dp, ts_cindex * ci);
|
||||
|
||||
/* Set the current cindex */
|
||||
void BSP_TS_SetCindex(ts_cindex * ci);
|
||||
|
||||
/* Get for current cindex */
|
||||
void BSP_TS_GetCindex(ts_cindex * ci);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32_ADAFRUIT_TS_H */
|
||||
107
Core/Src/Lcd/ts.h
Normal file
107
Core/Src/Lcd/ts.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ts.h
|
||||
* @author MCD Application Team
|
||||
* @version V4.0.1
|
||||
* @date 21-July-2015
|
||||
* @brief This file contains all the functions prototypes for the Touch Screen driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __TS_H
|
||||
#define __TS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
|
||||
/** @addtogroup BSP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup Components
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TS_Exported_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TS_Driver_structure Touch Sensor Driver structure
|
||||
* @{
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void (*Init)(uint16_t);
|
||||
uint16_t (*ReadID)(uint16_t);
|
||||
void (*Reset)(uint16_t);
|
||||
void (*Start)(uint16_t);
|
||||
uint8_t (*DetectTouch)(uint16_t);
|
||||
void (*GetXY)(uint16_t, uint16_t*, uint16_t*);
|
||||
void (*EnableIT)(uint16_t);
|
||||
void (*ClearIT)(uint16_t);
|
||||
uint8_t (*GetITStatus)(uint16_t);
|
||||
void (*DisableIT)(uint16_t);
|
||||
}TS_DrvTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TS_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
229
Core/Src/Lcd/ts_xpt2046.c
Normal file
229
Core/Src/Lcd/ts_xpt2046.c
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* XPT2046 HAL touch driver
|
||||
* author: Roberto Benjami
|
||||
* v.2023.04
|
||||
*
|
||||
* - software and hardware SPI
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "main.h"
|
||||
#include "lcd.h"
|
||||
#include "ts.h"
|
||||
#include "ts_xpt2046.h"
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32WBA)
|
||||
#define TS_SPI_SETBAUDRATE(htsspi, br) MODIFY_REG(htsspi.Instance->CFG1, SPI_CFG1_MBR, br << SPI_CFG1_MBR_Pos)
|
||||
#else
|
||||
#define TS_SPI_SETBAUDRATE(htsspi, br) MODIFY_REG(htsspi.Instance->CR1, SPI_CR1_BR, br << SPI_CR1_BR_Pos)
|
||||
#endif
|
||||
|
||||
#if !defined(TS_SPI_HANDLE) || TS_SPI_HANDLE == -1 || TS_CS_MODE == 0
|
||||
#define TS_CS_ON HAL_GPIO_WritePin(TS_CS_GPIO_Port, TS_CS_Pin, GPIO_PIN_RESET)
|
||||
#define TS_CS_OFF HAL_GPIO_WritePin(TS_CS_GPIO_Port, TS_CS_Pin, GPIO_PIN_SET)
|
||||
#elif TS_CS_MODE == 1
|
||||
#define TS_CS_ON
|
||||
#define TS_CS_OFF
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/* if not used the TS_IRQ pin -> Z1-Z2 touch sensitivy */
|
||||
#define TS_ZSENS 128
|
||||
|
||||
#define TS_SPI_TIMEOUT HAL_MAX_DELAY
|
||||
|
||||
#define XPT2046_MODE 0
|
||||
#define XPT2046_SER 0
|
||||
#define XPT2046_PD 0
|
||||
#define XPT2046_CMD_GETTEMP ((1 << 7) | (0 << 4) | (XPT2046_MODE << 3) | (XPT2046_SER << 2) | XPT2046_PD)
|
||||
#define XPT2046_CMD_GETTVBAT ((1 << 7) | (2 << 4) | (XPT2046_MODE << 3) | (XPT2046_SER << 2) | XPT2046_PD)
|
||||
#define XPT2046_CMD_GETX ((1 << 7) | (5 << 4) | (XPT2046_MODE << 3) | (XPT2046_SER << 2) | XPT2046_PD)
|
||||
#define XPT2046_CMD_GETY ((1 << 7) | (1 << 4) | (XPT2046_MODE << 3) | (XPT2046_SER << 2) | XPT2046_PD)
|
||||
#define XPT2046_CMD_GETZ1 ((1 << 7) | (3 << 4) | (XPT2046_MODE << 3) | (XPT2046_SER << 2) | XPT2046_PD)
|
||||
#define XPT2046_CMD_GETZ2 ((1 << 7) | (4 << 4) | (XPT2046_MODE << 3) | (XPT2046_SER << 2) | XPT2046_PD)
|
||||
|
||||
#define ABS(N) (((N)<0) ? (-(N)) : (N))
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static uint16_t tx, ty;
|
||||
|
||||
//=============================================================================
|
||||
/* TS chip select pin set */
|
||||
void xpt2046_ts_Init(uint16_t DeviceAddr);
|
||||
uint8_t xpt2046_ts_DetectTouch(uint16_t DeviceAddr);
|
||||
void xpt2046_ts_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
|
||||
|
||||
//=============================================================================
|
||||
#if defined(__CC_ARM)
|
||||
#pragma push
|
||||
#pragma O0
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
#endif
|
||||
void TS_IO_Delay(uint32_t c)
|
||||
{
|
||||
while(c--);
|
||||
}
|
||||
#if defined(__CC_ARM)
|
||||
#pragma pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
|
||||
#if !defined(TS_SPI_HANDLE) || TS_SPI_HANDLE == -1
|
||||
|
||||
#if TS_SPI_SPD > 0
|
||||
#define TS_CLK_DELAY TS_IO_Delay(TS_SPI_SPD);
|
||||
#else
|
||||
#define TS_CLK_DELAY
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint16_t TS_IO_Transaction(uint8_t cmd)
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
uint32_t i;
|
||||
TS_CS_ON;
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
HAL_GPIO_WritePin(TS_MOSI_GPIO_Port, TS_MOSI_Pin, cmd & 0x80);
|
||||
TS_CLK_DELAY;
|
||||
HAL_GPIO_WritePin(TS_SCK_GPIO_Port, TS_SCK_Pin, GPIO_PIN_SET);
|
||||
TS_CLK_DELAY;
|
||||
HAL_GPIO_WritePin(TS_SCK_GPIO_Port, TS_SCK_Pin, GPIO_PIN_RESET);
|
||||
cmd <<= 1;
|
||||
}
|
||||
|
||||
#if XPT2046_READDELAY > 0
|
||||
TS_IO_Delay(XPT2046_READDELAY);
|
||||
#endif
|
||||
|
||||
HAL_GPIO_WritePin(TS_MOSI_GPIO_Port, TS_MOSI_Pin, GPIO_PIN_RESET);
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
ret <<= 1;
|
||||
TS_CLK_DELAY;
|
||||
HAL_GPIO_WritePin(TS_SCK_GPIO_Port, TS_SCK_Pin, GPIO_PIN_SET);
|
||||
if(HAL_GPIO_ReadPin(TS_MISO_GPIO_Port, TS_MISO_Pin))
|
||||
ret |= 1;
|
||||
TS_CLK_DELAY;
|
||||
HAL_GPIO_WritePin(TS_SCK_GPIO_Port, TS_SCK_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
TS_CS_OFF;
|
||||
return ((ret & 0x7FFF) >> 3);
|
||||
}
|
||||
#else
|
||||
|
||||
extern SPI_HandleTypeDef TS_SPI_HANDLE;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint16_t TS_IO_Transaction(uint8_t cmd)
|
||||
{
|
||||
const uint16_t d = 0;
|
||||
uint16_t ret;
|
||||
TS_CS_ON;
|
||||
HAL_SPI_Transmit(&TS_SPI_HANDLE, (uint8_t *)&cmd, 1, TS_SPI_TIMEOUT);
|
||||
#if XPT2046_READDELAY > 0
|
||||
TS_IO_Delay(XPT2046_READDELAY);
|
||||
#endif
|
||||
HAL_SPI_TransmitReceive(&TS_SPI_HANDLE, (uint8_t *)&d, (uint8_t *)&ret, 2, TS_SPI_TIMEOUT);
|
||||
TS_CS_OFF;
|
||||
ret = __REVSH(ret);
|
||||
return ((ret & 0x7FFF) >> 3);
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/* return:
|
||||
- 0 : touchscreen is not pressed
|
||||
- 1 : touchscreen is pressed */
|
||||
uint8_t TS_IO_DetectToch(void)
|
||||
{
|
||||
uint8_t ret;
|
||||
#if defined(TS_IRQ_GPIO_Port) && defined (TS_IRQ_Pin)
|
||||
if(HAL_GPIO_ReadPin(TS_IRQ_GPIO_Port, TS_IRQ_Pin))
|
||||
ret = 0;
|
||||
else
|
||||
ret = 1;
|
||||
#else
|
||||
if((TS_IO_Transaction(XPT2046_CMD_GETZ1) > TS_ZSENS) || (TS_IO_Transaction(XPT2046_CMD_GETZ2) < (4095 - TS_ZSENS)))
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
TS_DrvTypeDef xpt2046_ts_drv =
|
||||
{
|
||||
xpt2046_ts_Init,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
xpt2046_ts_DetectTouch,
|
||||
xpt2046_ts_GetXY,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
TS_DrvTypeDef *ts_drv = &xpt2046_ts_drv;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void xpt2046_ts_Init(uint16_t DeviceAddr)
|
||||
{
|
||||
#if TS_SPI_HANDLE != -1 && defined(TS_SPI_SPD) && TS_SPI_SPD >= 0 && TS_SPI_SPD <= 7
|
||||
TS_SPI_SETBAUDRATE(TS_SPI_HANDLE, TS_SPI_SPD);
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
uint8_t xpt2046_ts_DetectTouch(uint16_t DeviceAddr)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
int32_t x1, x2, y1, y2, i;
|
||||
|
||||
if(TS_IO_DetectToch())
|
||||
{
|
||||
x1 = TS_IO_Transaction(XPT2046_CMD_GETX); /* Get X */
|
||||
y1 = TS_IO_Transaction(XPT2046_CMD_GETY); /* Get Y */
|
||||
i = TOUCH_MAXREPEAT;
|
||||
while(i--)
|
||||
{
|
||||
x2 = TS_IO_Transaction(XPT2046_CMD_GETX); /* Get X */
|
||||
y2 = TS_IO_Transaction(XPT2046_CMD_GETY); /* Get Y */
|
||||
if((ABS(x1 - x2) < TOUCH_FILTER) && (ABS(y1 - y2) < TOUCH_FILTER))
|
||||
{
|
||||
x1 = (x1 + x2) >> 1;
|
||||
y1 = (y1 + y2) >> 1;
|
||||
i = 0;
|
||||
if(TS_IO_DetectToch())
|
||||
{
|
||||
tx = x1;
|
||||
ty = y1;
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void xpt2046_ts_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
|
||||
{
|
||||
*X = tx,
|
||||
*Y = ty;
|
||||
}
|
||||
117
Core/Src/Lcd/ts_xpt2046.h
Normal file
117
Core/Src/Lcd/ts_xpt2046.h
Normal file
@@ -0,0 +1,117 @@
|
||||
//=============================================================================
|
||||
/* Information section */
|
||||
|
||||
/*
|
||||
* XPT2046 touch driver
|
||||
* author: Roberto Benjami
|
||||
* v.2023.03
|
||||
*/
|
||||
|
||||
/* Settings in CUBEIDE or CUBEMX
|
||||
|
||||
If software SPI
|
||||
GPIO
|
||||
- Touchscreen SCK
|
||||
- output level: Low
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_SCK
|
||||
- Touchscreen MOSI
|
||||
- output level: Low
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_MOSI
|
||||
- Touchscreen MISO
|
||||
- output level: n/a
|
||||
- mode: Input mode
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: n/a
|
||||
- User Label: TS_MISO
|
||||
- Touchscreen chip select:
|
||||
- output level: High
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_CS
|
||||
|
||||
If hardvare SPI
|
||||
SPI Parameter Settings
|
||||
- Mode: "Full duplex master"
|
||||
- Hardware NSS signal: disabled or enabled (see the Touchscreen chip select GPIO setting)
|
||||
- Frame format: Motorola
|
||||
- Data Size: 8 bits
|
||||
- First bit: MSB first
|
||||
- Prescaler: 64 (you can experiment with higher speeds)
|
||||
- Clock Polarity: Low
|
||||
- Clock Phase: 1 Edge
|
||||
note: if the selected SPI pin is not good, change it in the pinout view
|
||||
GPIO
|
||||
- Touchscreen SCK
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_SCK
|
||||
- Touchscreen MOSI
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_MOSI
|
||||
- Touchscreen MISO
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_MISO
|
||||
- Touchscreen chip select (if hardware NSS signal == disabled)
|
||||
- output level: High
|
||||
- mode: Output Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_CS
|
||||
- Touchscreen chip select (if hardware NSS signal == enabled)
|
||||
- output level: n/a
|
||||
- mode: Alternate Function Push Pull
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: Very High
|
||||
- User Label: TS_CS
|
||||
|
||||
Software and hardware SPI
|
||||
GPIO
|
||||
- Touchscreen IRQ (only when connected)
|
||||
- output level: n/a
|
||||
- mode: Input mode
|
||||
- Pull-up/Pull-down: No pull-up and no pull-down
|
||||
- Max output speed: n/a
|
||||
- User Label: TS_IRQ
|
||||
*/
|
||||
|
||||
//=============================================================================
|
||||
/* Setting section (please set the necessary things in this section) */
|
||||
|
||||
/* SPI handle select
|
||||
- software SPI (set this macro value: -1, set in CUBEMX the TS_CS, TS_SCK, TS_MISO, TS_MOSI, TS_IRQ pin)
|
||||
- hardware SPI handle: see in main.c file (default: hspi1, hspi2 ... hspi6) */
|
||||
#define TS_SPI_HANDLE hspi2
|
||||
|
||||
/* SPI CS mode (only hardware SPI)
|
||||
- 0: software CS operation (hardware NSS signal: disabled)
|
||||
- 1: hardware CS operation (hardware NSS signal: enabled) */
|
||||
#define TS_CS_MODE 1
|
||||
|
||||
/* SPI write and read speed (if deleted and hardware SPI -> setting in CUBEMX)
|
||||
- software SPI: TS_SCK clock delay (see the TS_IO_Delay function)
|
||||
- hardware SPI: clock div fPCLK: 0=/2, 1=/4, 2=/8, 3=/16, 4=/32, 5=/64, 6=/128, 7=/256 */
|
||||
#define TS_SPI_SPD 5
|
||||
|
||||
/* Wait time before reading xpt2046 (see: TS_IO_Transaction and TS_IO_Delay dunctions) */
|
||||
#define XPT2046_READDELAY 0
|
||||
|
||||
/* The touch value that it still accepts as the same value */
|
||||
#define TOUCH_FILTER 40
|
||||
|
||||
/* This is how many times it tries to read the same value */
|
||||
#define TOUCH_MAXREPEAT 8
|
||||
75
Core/Src/freertos.c
Normal file
75
Core/Src/freertos.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : freertos.c
|
||||
* Description : Code for freertos applications
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Variables */
|
||||
|
||||
/* USER CODE END Variables */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN FunctionPrototypes */
|
||||
|
||||
/* USER CODE END FunctionPrototypes */
|
||||
|
||||
/* GetIdleTaskMemory prototype (linked to static allocation support) */
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );
|
||||
|
||||
/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
|
||||
static StaticTask_t xIdleTaskTCBBuffer;
|
||||
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
|
||||
{
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
|
||||
*ppxIdleTaskStackBuffer = &xIdleStack[0];
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
/* place for user code */
|
||||
}
|
||||
/* USER CODE END GET_IDLE_TASK_MEMORY */
|
||||
|
||||
/* Private application code --------------------------------------------------*/
|
||||
/* USER CODE BEGIN Application */
|
||||
|
||||
/* USER CODE END Application */
|
||||
|
||||
527
Core/Src/main.c
Normal file
527
Core/Src/main.c
Normal file
@@ -0,0 +1,527 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
RTC_HandleTypeDef hrtc;
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
SPI_HandleTypeDef hspi2;
|
||||
DMA_HandleTypeDef hdma_spi1_tx;
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
|
||||
osThreadId defaultTaskHandle;
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_DMA_Init(void);
|
||||
static void MX_RTC_Init(void);
|
||||
static void MX_SPI1_Init(void);
|
||||
static void MX_SPI2_Init(void);
|
||||
static void MX_USART1_UART_Init(void);
|
||||
void StartDefaultTask(void const * argument);
|
||||
|
||||
/* USER CODE BEGIN PFP */
|
||||
void mainApp(void);
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_RTC_Init();
|
||||
MX_SPI1_Init();
|
||||
MX_SPI2_Init();
|
||||
MX_USART1_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* USER CODE BEGIN RTOS_MUTEX */
|
||||
/* add mutexes, ... */
|
||||
/* USER CODE END RTOS_MUTEX */
|
||||
|
||||
/* USER CODE BEGIN RTOS_SEMAPHORES */
|
||||
/* add semaphores, ... */
|
||||
/* USER CODE END RTOS_SEMAPHORES */
|
||||
|
||||
/* USER CODE BEGIN RTOS_TIMERS */
|
||||
/* start timers, add new ones, ... */
|
||||
/* USER CODE END RTOS_TIMERS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_QUEUES */
|
||||
/* add queues, ... */
|
||||
/* USER CODE END RTOS_QUEUES */
|
||||
|
||||
/* Create the thread(s) */
|
||||
/* definition and creation of defaultTask */
|
||||
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 512);
|
||||
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
|
||||
|
||||
/* USER CODE BEGIN RTOS_THREADS */
|
||||
/* add threads, ... */
|
||||
/* USER CODE END RTOS_THREADS */
|
||||
|
||||
/* Start scheduler */
|
||||
osKernelStart();
|
||||
|
||||
/* We should never get here as control is now taken by the scheduler */
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
// mainApp();
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;
|
||||
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RTC Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_RTC_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN RTC_Init 0 */
|
||||
|
||||
/* USER CODE END RTC_Init 0 */
|
||||
|
||||
RTC_TimeTypeDef sTime = {0};
|
||||
RTC_DateTypeDef DateToUpdate = {0};
|
||||
|
||||
/* USER CODE BEGIN RTC_Init 1 */
|
||||
|
||||
/* USER CODE END RTC_Init 1 */
|
||||
|
||||
/** Initialize RTC Only
|
||||
*/
|
||||
hrtc.Instance = RTC;
|
||||
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
|
||||
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
|
||||
if (HAL_RTC_Init(&hrtc) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Check_RTC_BKUP */
|
||||
|
||||
/* USER CODE END Check_RTC_BKUP */
|
||||
|
||||
/** Initialize RTC and set the Time and Date
|
||||
*/
|
||||
sTime.Hours = 0x0;
|
||||
sTime.Minutes = 0x0;
|
||||
sTime.Seconds = 0x0;
|
||||
|
||||
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY;
|
||||
DateToUpdate.Month = RTC_MONTH_JANUARY;
|
||||
DateToUpdate.Date = 0x1;
|
||||
DateToUpdate.Year = 0x0;
|
||||
|
||||
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN RTC_Init 2 */
|
||||
|
||||
/* USER CODE END RTC_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 = 10;
|
||||
if (HAL_SPI_Init(&hspi1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI2 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_SPI2_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI2_Init 0 */
|
||||
|
||||
/* USER CODE END SPI2_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI2_Init 1 */
|
||||
|
||||
/* USER CODE END SPI2_Init 1 */
|
||||
/* SPI2 parameter configuration*/
|
||||
hspi2.Instance = SPI2;
|
||||
hspi2.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
|
||||
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
|
||||
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi2.Init.CRCPolynomial = 10;
|
||||
if (HAL_SPI_Init(&hspi2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI2_Init 2 */
|
||||
|
||||
/* USER CODE END SPI2_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 9600;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable DMA controller clock
|
||||
*/
|
||||
static void MX_DMA_Init(void)
|
||||
{
|
||||
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, LCD_CS_Pin|LCD_RST_Pin|LCD_BL_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, LED1_Pin_Pin|LED0_Pin_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, LED0E0_Pin|LED1E1_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : BT_K0_Pin */
|
||||
GPIO_InitStruct.Pin = BT_K0_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(BT_K0_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : LCD_CS_Pin LCD_RST_Pin LCD_RS_Pin */
|
||||
GPIO_InitStruct.Pin = LCD_CS_Pin|LCD_RST_Pin|LCD_RS_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : LCD_BL_Pin */
|
||||
GPIO_InitStruct.Pin = LCD_BL_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(LCD_BL_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PB11 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : LED1_Pin_Pin LED0_Pin_Pin */
|
||||
GPIO_InitStruct.Pin = LED1_Pin_Pin|LED0_Pin_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : LED0E0_Pin LED1E1_Pin */
|
||||
GPIO_InitStruct.Pin = LED0E0_Pin|LED1E1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/* USER CODE BEGIN Header_StartDefaultTask */
|
||||
/**
|
||||
* @brief Function implementing the defaultTask thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_StartDefaultTask */
|
||||
void StartDefaultTask(void const * argument)
|
||||
{
|
||||
/* USER CODE BEGIN 5 */
|
||||
/* Infinite loop */
|
||||
// HAL_UART_Transmit(&huart1, (uint8_t*)"Hello world!", 13, 1000);
|
||||
mainApp();
|
||||
for(;;)
|
||||
{
|
||||
osDelay(1);
|
||||
}
|
||||
/* USER CODE END 5 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Period elapsed callback in non blocking mode
|
||||
* @note This function is called when TIM8 interrupt took place, inside
|
||||
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
|
||||
* a global variable "uwTick" used as application time base.
|
||||
* @param htim : TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* USER CODE BEGIN Callback 0 */
|
||||
|
||||
/* USER CODE END Callback 0 */
|
||||
if (htim->Instance == TIM8) {
|
||||
HAL_IncTick();
|
||||
}
|
||||
/* USER CODE BEGIN Callback 1 */
|
||||
|
||||
/* USER CODE END Callback 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
353
Core/Src/stm32f1xx_hal_msp.c
Normal file
353
Core/Src/stm32f1xx_hal_msp.c
Normal file
@@ -0,0 +1,353 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
extern DMA_HandleTypeDef hdma_spi1_tx;
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
/* PendSV_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
|
||||
|
||||
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
|
||||
*/
|
||||
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RTC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hrtc: RTC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
|
||||
{
|
||||
if(hrtc->Instance==RTC)
|
||||
{
|
||||
/* USER CODE BEGIN RTC_MspInit 0 */
|
||||
|
||||
/* USER CODE END RTC_MspInit 0 */
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
/* Enable BKP CLK enable for backup registers */
|
||||
__HAL_RCC_BKP_CLK_ENABLE();
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_RTC_ENABLE();
|
||||
/* USER CODE BEGIN RTC_MspInit 1 */
|
||||
|
||||
/* USER CODE END RTC_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RTC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hrtc: RTC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
|
||||
{
|
||||
if(hrtc->Instance==RTC)
|
||||
{
|
||||
/* USER CODE BEGIN RTC_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END RTC_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_RTC_DISABLE();
|
||||
/* USER CODE BEGIN RTC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END RTC_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = LCD_SCK_Pin|LCD_MOSI_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = LCD_MISO_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(LCD_MISO_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* SPI1 DMA Init */
|
||||
/* SPI1_TX Init */
|
||||
hdma_spi1_tx.Instance = DMA1_Channel3;
|
||||
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);
|
||||
|
||||
/* SPI1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(SPI1_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(SPI1_IRQn);
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
else if(hspi->Instance==SPI2)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI2_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_SPI2_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**SPI2 GPIO Configuration
|
||||
PB12 ------> SPI2_NSS
|
||||
PB13 ------> SPI2_SCK
|
||||
PB14 ------> SPI2_MISO
|
||||
PB15 ------> SPI2_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = TS_CS_Pin|TS_SCK_Pin|TS_MOSI_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = TS_MISO_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(TS_MISO_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* SPI2 interrupt Init */
|
||||
HAL_NVIC_SetPriority(SPI2_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(SPI2_IRQn);
|
||||
/* USER CODE BEGIN SPI2_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI2_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
|
||||
PA5 ------> SPI1_SCK
|
||||
PA6 ------> SPI1_MISO
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, LCD_SCK_Pin|LCD_MISO_Pin|LCD_MOSI_Pin);
|
||||
|
||||
/* SPI1 DMA DeInit */
|
||||
HAL_DMA_DeInit(hspi->hdmatx);
|
||||
|
||||
/* SPI1 interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(SPI1_IRQn);
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
else if(hspi->Instance==SPI2)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI2_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI2_CLK_DISABLE();
|
||||
|
||||
/**SPI2 GPIO Configuration
|
||||
PB12 ------> SPI2_NSS
|
||||
PB13 ------> SPI2_SCK
|
||||
PB14 ------> SPI2_MISO
|
||||
PB15 ------> SPI2_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, TS_CS_Pin|TS_SCK_Pin|TS_MISO_Pin|TS_MOSI_Pin);
|
||||
|
||||
/* SPI2 interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(SPI2_IRQn);
|
||||
/* USER CODE BEGIN SPI2_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI2_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(huart->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param huart: UART handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
|
||||
{
|
||||
if(huart->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART1_CLK_DISABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
129
Core/Src/stm32f1xx_hal_timebase_tim.c
Normal file
129
Core/Src/stm32f1xx_hal_timebase_tim.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_timebase_tim.c
|
||||
* @brief HAL time base based on the hardware TIM.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "stm32f1xx_hal_tim.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
TIM_HandleTypeDef htim8;
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void TIM8_IRQHandler(void);
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief This function configures the TIM8 as a time base source.
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* @note This function is called automatically at the beginning of program after
|
||||
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
|
||||
* @param TickPriority: Tick interrupt priority.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
RCC_ClkInitTypeDef clkconfig;
|
||||
uint32_t uwTimclock = 0U;
|
||||
|
||||
uint32_t uwPrescalerValue = 0U;
|
||||
uint32_t pFLatency;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Enable TIM8 clock */
|
||||
__HAL_RCC_TIM8_CLK_ENABLE();
|
||||
|
||||
/* Get clock configuration */
|
||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||
|
||||
/* Compute TIM8 clock */
|
||||
uwTimclock = HAL_RCC_GetPCLK2Freq();
|
||||
|
||||
/* Compute the prescaler value to have TIM8 counter clock equal to 1MHz */
|
||||
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
|
||||
|
||||
/* Initialize TIM8 */
|
||||
htim8.Instance = TIM8;
|
||||
|
||||
/* Initialize TIMx peripheral as follow:
|
||||
|
||||
+ Period = [(TIM8CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||
+ ClockDivision = 0
|
||||
+ Counter direction = Up
|
||||
*/
|
||||
htim8.Init.Period = (1000000U / 1000U) - 1U;
|
||||
htim8.Init.Prescaler = uwPrescalerValue;
|
||||
htim8.Init.ClockDivision = 0;
|
||||
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
status = HAL_TIM_Base_Init(&htim8);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Start the TIM time Base generation in interrupt mode */
|
||||
status = HAL_TIM_Base_Start_IT(&htim8);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the TIM8 global Interrupt */
|
||||
HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);
|
||||
/* Configure the SysTick IRQ priority */
|
||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||
{
|
||||
/* Configure the TIM IRQ priority */
|
||||
HAL_NVIC_SetPriority(TIM8_UP_IRQn, TickPriority, 0U);
|
||||
uwTickPrio = TickPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend Tick increment.
|
||||
* @note Disable the tick increment by disabling TIM8 update interrupt.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SuspendTick(void)
|
||||
{
|
||||
/* Disable TIM8 update Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(&htim8, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume Tick increment.
|
||||
* @note Enable the tick increment by Enabling TIM8 update interrupt.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ResumeTick(void)
|
||||
{
|
||||
/* Enable TIM8 Update interrupt */
|
||||
__HAL_TIM_ENABLE_IT(&htim8, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
208
Core/Src/stm32f1xx_it.c
Normal file
208
Core/Src/stm32f1xx_it.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32f1xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
extern SPI_HandleTypeDef hspi2;
|
||||
extern TIM_HandleTypeDef htim8;
|
||||
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||
|
||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Prefetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END BusFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END UsageFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Debug monitor.
|
||||
*/
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F1xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32f1xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles SPI1 global interrupt.
|
||||
*/
|
||||
void SPI1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_IRQn 0 */
|
||||
|
||||
/* USER CODE END SPI1_IRQn 0 */
|
||||
HAL_SPI_IRQHandler(&hspi1);
|
||||
/* USER CODE BEGIN SPI1_IRQn 1 */
|
||||
|
||||
/* USER CODE END SPI1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles SPI2 global interrupt.
|
||||
*/
|
||||
void SPI2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_IRQn 0 */
|
||||
|
||||
/* USER CODE END SPI2_IRQn 0 */
|
||||
HAL_SPI_IRQHandler(&hspi2);
|
||||
/* USER CODE BEGIN SPI2_IRQn 1 */
|
||||
|
||||
/* USER CODE END SPI2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles TIM8 update interrupt.
|
||||
*/
|
||||
void TIM8_UP_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM8_UP_IRQn 0 */
|
||||
|
||||
/* USER CODE END TIM8_UP_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim8);
|
||||
/* USER CODE BEGIN TIM8_UP_IRQn 1 */
|
||||
|
||||
/* USER CODE END TIM8_UP_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
176
Core/Src/syscalls.c
Normal file
176
Core/Src/syscalls.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file syscalls.c
|
||||
* @author Auto-generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE Minimal System calls file
|
||||
*
|
||||
* For more information about which c-functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the Newlib libc-manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2020-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
|
||||
/* Variables */
|
||||
extern int __io_putchar(int ch) __attribute__((weak));
|
||||
extern int __io_getchar(void) __attribute__((weak));
|
||||
|
||||
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
|
||||
/* Functions */
|
||||
void initialise_monitor_handles()
|
||||
{
|
||||
}
|
||||
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit (int status)
|
||||
{
|
||||
_kill(status, -1);
|
||||
while (1) {} /* Make sure we hang here */
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _read(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
*ptr++ = __io_getchar();
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
__attribute__((weak)) int _write(int file, char *ptr, int len)
|
||||
{
|
||||
(void)file;
|
||||
int DataIdx;
|
||||
|
||||
for (DataIdx = 0; DataIdx < len; DataIdx++)
|
||||
{
|
||||
__io_putchar(*ptr++);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int _close(int file)
|
||||
{
|
||||
(void)file;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void)file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void)file;
|
||||
(void)ptr;
|
||||
(void)dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _open(char *path, int flags, ...)
|
||||
{
|
||||
(void)path;
|
||||
(void)flags;
|
||||
/* Pretend like we always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _wait(int *status)
|
||||
{
|
||||
(void)status;
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _unlink(char *name)
|
||||
{
|
||||
(void)name;
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _times(struct tms *buf)
|
||||
{
|
||||
(void)buf;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _stat(char *file, struct stat *st)
|
||||
{
|
||||
(void)file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
(void)old;
|
||||
(void)new;
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
(void)name;
|
||||
(void)argv;
|
||||
(void)env;
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
79
Core/Src/sysmem.c
Normal file
79
Core/Src/sysmem.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file sysmem.c
|
||||
* @author Generated by STM32CubeIDE
|
||||
* @brief STM32CubeIDE System Memory calls file
|
||||
*
|
||||
* For more information about which C functions
|
||||
* need which of these lowlevel functions
|
||||
* please consult the newlib libc manual
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes */
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Pointer to the current high watermark of the heap usage
|
||||
*/
|
||||
static uint8_t *__sbrk_heap_end = NULL;
|
||||
|
||||
/**
|
||||
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
|
||||
* and others from the C library
|
||||
*
|
||||
* @verbatim
|
||||
* ############################################################################
|
||||
* # .data # .bss # newlib heap # MSP stack #
|
||||
* # # # # Reserved by _Min_Stack_Size #
|
||||
* ############################################################################
|
||||
* ^-- RAM start ^-- _end _estack, RAM end --^
|
||||
* @endverbatim
|
||||
*
|
||||
* This implementation starts allocating at the '_end' linker symbol
|
||||
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
|
||||
* The implementation considers '_estack' linker symbol to be RAM end
|
||||
* NOTE: If the MSP stack, at any point during execution, grows larger than the
|
||||
* reserved size, please increase the '_Min_Stack_Size'.
|
||||
*
|
||||
* @param incr Memory size
|
||||
* @return Pointer to allocated memory
|
||||
*/
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
extern uint8_t _end; /* Symbol defined in the linker script */
|
||||
extern uint8_t _estack; /* Symbol defined in the linker script */
|
||||
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
|
||||
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
|
||||
const uint8_t *max_heap = (uint8_t *)stack_limit;
|
||||
uint8_t *prev_heap_end;
|
||||
|
||||
/* Initialize heap end at first call */
|
||||
if (NULL == __sbrk_heap_end)
|
||||
{
|
||||
__sbrk_heap_end = &_end;
|
||||
}
|
||||
|
||||
/* Protect heap from growing into the reserved MSP stack */
|
||||
if (__sbrk_heap_end + incr > max_heap)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
|
||||
prev_heap_end = __sbrk_heap_end;
|
||||
__sbrk_heap_end += incr;
|
||||
|
||||
return (void *)prev_heap_end;
|
||||
}
|
||||
406
Core/Src/system_stm32f1xx.c
Normal file
406
Core/Src/system_stm32f1xx.c
Normal file
@@ -0,0 +1,406 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f1xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* 1. This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
|
||||
* factors, AHB/APBx prescalers and Flash settings).
|
||||
* This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f1xx_xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
|
||||
* the product used), refer to "HSE_VALUE".
|
||||
* When HSE is used as system clock source, directly or through PLL, and you
|
||||
* are using different crystal you have to adapt the HSE value to your own
|
||||
* configuration.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017-2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f1xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/*!< Uncomment the following line if you need to use external SRAM */
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate the vector table
|
||||
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||
remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||
in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 16000000;
|
||||
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
static void SystemInit_ExtMemCtl(void);
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||
* SystemCoreClock variable.
|
||||
* @note This function should be used only after reset.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
SystemInit_ExtMemCtl();
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif
|
||||
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
|
||||
* that HSE_VALUE is same as the real frequency of the crystal used.
|
||||
* Otherwise, this function may have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
uint32_t prediv1factor = 0U;
|
||||
#endif /* STM32F100xB or STM32F100xE */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00U: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04U: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08U: /* PLL used as system clock */
|
||||
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
|
||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||
pllmull = ( pllmull >> 18U) + 2U;
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
#else
|
||||
/* HSE selected as PLL clock entry */
|
||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
||||
{/* HSE oscillator clock divided by 2 */
|
||||
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
pllmull = pllmull >> 18U;
|
||||
|
||||
if (pllmull != 0x0DU)
|
||||
{
|
||||
pllmull += 2U;
|
||||
}
|
||||
else
|
||||
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||
pllmull = 13U / 2U;
|
||||
}
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PREDIV1 selected as PLL clock entry */
|
||||
|
||||
/* Get PREDIV1 clock source and division factor */
|
||||
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
|
||||
if (prediv1source == 0U)
|
||||
{
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PLL2 clock selected as PREDIV1 clock entry */
|
||||
|
||||
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
||||
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
||||
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||
}
|
||||
}
|
||||
#endif /* STM32F105xC */
|
||||
break;
|
||||
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute HCLK clock frequency ----------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/**
|
||||
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||
* before jump to __main
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||
* board (STM32 High density devices). This SRAM will be used as program
|
||||
* data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||
required, then adjust the Register Addresses */
|
||||
|
||||
/* Enable FSMC clock */
|
||||
RCC->AHBENR = 0x00000114U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||
|
||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||
RCC->APB2ENR = 0x000001E0U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||
|
||||
(void)(tmpreg);
|
||||
|
||||
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||
/*---------------- NE3 configuration ----------------------------------------*/
|
||||
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||
|
||||
GPIOD->CRL = 0x44BB44BBU;
|
||||
GPIOD->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOE->CRL = 0xB44444BBU;
|
||||
GPIOE->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOF->CRL = 0x44BBBBBBU;
|
||||
GPIOF->CRH = 0xBBBB4444U;
|
||||
|
||||
GPIOG->CRL = 0x44BBBBBBU;
|
||||
GPIOG->CRH = 0x444B4B44U;
|
||||
|
||||
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||
|
||||
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
||||
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
||||
}
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Reference in New Issue
Block a user