2 Commit-ok bead5b32ae ... 890fc6861b

Szerző SHA1 Üzenet Dátum
  Thomas Chef 890fc6861b First try. Display works 6 napja
  Thomas Chef bead5b32ae Some basic project 1 hete

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 79 - 77
.cproject


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 11 - 11
.mxproject


+ 1 - 1
.project

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>BoatSpeedDisplay</name>
+	<name>BoatLogger</name>
 	<comment></comment>
 	<projects>
 	</projects>

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 86 - 0
BoatLogger Debug.launch


+ 62 - 46
BoatSpeedDisplay.ioc

@@ -1,74 +1,86 @@
 #MicroXplorer Configuration settings - do not modify
+CAD.formats=
+CAD.pinconfig=
+CAD.provider=
 File.Version=6
 GPIO.groupedBy=Group By Peripherals
 KeepUserPlacement=false
+Mcu.CPN=STM32F103C8T6
 Mcu.Family=STM32F1
 Mcu.IP0=NVIC
 Mcu.IP1=RCC
 Mcu.IP2=SPI1
 Mcu.IP3=SYS
-Mcu.IP4=USART2
+Mcu.IP4=USART1
 Mcu.IPNb=5
 Mcu.Name=STM32F103C(8-B)Tx
 Mcu.Package=LQFP48
-Mcu.Pin0=PC15-OSC32_OUT
+Mcu.Pin0=PC13-TAMPER-RTC
 Mcu.Pin1=PD0-OSC_IN
 Mcu.Pin10=PA13
 Mcu.Pin11=PA14
-Mcu.Pin12=VP_SYS_VS_Systick
+Mcu.Pin12=PB4
+Mcu.Pin13=VP_SYS_VS_Systick
 Mcu.Pin2=PD1-OSC_OUT
 Mcu.Pin3=PA1
 Mcu.Pin4=PA2
-Mcu.Pin5=PA3
-Mcu.Pin6=PA4
-Mcu.Pin7=PA5
-Mcu.Pin8=PA6
-Mcu.Pin9=PA7
-Mcu.PinsNb=13
+Mcu.Pin5=PA4
+Mcu.Pin6=PA5
+Mcu.Pin7=PA7
+Mcu.Pin8=PA9
+Mcu.Pin9=PA10
+Mcu.PinsNb=14
 Mcu.ThirdPartyNb=0
 Mcu.UserConstants=
 Mcu.UserName=STM32F103C8Tx
-MxCube.Version=6.4.0
-MxDb.Version=DB.6.0.40
-NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false
-NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:false\:false\:false
+MxCube.Version=6.15.0
+MxDb.Version=DB.6.0.150
+NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
+NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
 NVIC.ForceEnableDMAVector=true
-NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false
-NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:false\:false\:false
-NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:false\:false\:false
-NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false
+NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
+NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
+NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
-NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false
-NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true
-NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false
-PA1.GPIOParameters=GPIO_Label
+NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
+NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
+NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false
+PA1.GPIOParameters=PinState,GPIO_Label
 PA1.GPIO_Label=RST
 PA1.Locked=true
+PA1.PinState=GPIO_PIN_SET
 PA1.Signal=GPIO_Output
+PA10.Mode=Asynchronous
+PA10.Signal=USART1_RX
 PA13.Mode=Serial_Wire
 PA13.Signal=SYS_JTMS-SWDIO
 PA14.Mode=Serial_Wire
 PA14.Signal=SYS_JTCK-SWCLK
+PA2.GPIOParameters=PinState,GPIO_Label
+PA2.GPIO_Label=DC
 PA2.Locked=true
-PA2.Mode=Asynchronous
-PA2.Signal=USART2_TX
-PA3.Locked=true
-PA3.Mode=Asynchronous
-PA3.Signal=USART2_RX
-PA4.GPIOParameters=GPIO_Label
-PA4.GPIO_Label=PWR
+PA2.PinState=GPIO_PIN_SET
+PA2.Signal=GPIO_Output
+PA4.GPIOParameters=PinState,GPIO_Label
+PA4.GPIO_Label=CS
 PA4.Locked=true
+PA4.PinState=GPIO_PIN_SET
 PA4.Signal=GPIO_Output
-PA5.Mode=Full_Duplex_Master
+PA5.Mode=TX_Only_Simplex_Unidirect_Master
 PA5.Signal=SPI1_SCK
-PA6.Mode=Full_Duplex_Master
-PA6.Signal=SPI1_MISO
-PA7.Mode=Full_Duplex_Master
+PA7.Mode=TX_Only_Simplex_Unidirect_Master
 PA7.Signal=SPI1_MOSI
-PC15-OSC32_OUT.GPIOParameters=GPIO_Label
-PC15-OSC32_OUT.GPIO_Label=DC
-PC15-OSC32_OUT.Locked=true
-PC15-OSC32_OUT.Signal=GPIO_Output
+PA9.Mode=Asynchronous
+PA9.Signal=USART1_TX
+PB4.GPIOParameters=GPIO_Label
+PB4.GPIO_Label=BUSY
+PB4.Locked=true
+PB4.Signal=GPIO_Input
+PC13-TAMPER-RTC.GPIOParameters=GPIO_Label
+PC13-TAMPER-RTC.GPIO_Label=LED
+PC13-TAMPER-RTC.Locked=true
+PC13-TAMPER-RTC.Signal=GPIO_Output
 PCC.Checker=false
 PCC.Line=STM32F103
 PCC.MCU=STM32F103C(8-B)Tx
@@ -114,6 +126,7 @@ PD1-OSC_OUT.Signal=RCC_OSC_OUT
 PinOutPanel.RotationAngle=0
 ProjectManager.AskForMigrate=true
 ProjectManager.BackupPrevious=false
+ProjectManager.CompilerLinker=GCC
 ProjectManager.CompilerOptimize=6
 ProjectManager.ComputerToolchain=false
 ProjectManager.CoupleFile=false
@@ -121,25 +134,28 @@ ProjectManager.CustomerFirmwarePackage=
 ProjectManager.DefaultFWLocation=true
 ProjectManager.DeletePrevious=true
 ProjectManager.DeviceId=STM32F103C8Tx
-ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.4
+ProjectManager.FirmwarePackage=STM32Cube FW_F1 V1.8.6
 ProjectManager.FreePins=false
 ProjectManager.HalAssertFull=false
 ProjectManager.HeapSize=0x200
 ProjectManager.KeepUserCode=true
-ProjectManager.LastFirmware=false
+ProjectManager.LastFirmware=true
 ProjectManager.LibraryCopy=1
 ProjectManager.MainLocation=Core/Src
 ProjectManager.NoMain=false
 ProjectManager.PreviousToolchain=STM32CubeIDE
 ProjectManager.ProjectBuild=false
-ProjectManager.ProjectFileName=BoatSpeedDisplay.ioc
-ProjectManager.ProjectName=BoatSpeedDisplay
+ProjectManager.ProjectFileName=BoatLogger.ioc
+ProjectManager.ProjectName=BoatLogger
+ProjectManager.ProjectStructure=
 ProjectManager.RegisterCallBack=
 ProjectManager.StackSize=0x400
 ProjectManager.TargetToolchain=STM32CubeIDE
 ProjectManager.ToolChainLocation=
+ProjectManager.UAScriptAfterPath=
+ProjectManager.UAScriptBeforePath=
 ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART2_UART_Init-USART2-false-HAL-true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_SPI1_Init-SPI1-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true
 RCC.ADCFreqValue=24000000
 RCC.AHBFreq_Value=48000000
 RCC.APB1CLKDivider=RCC_HCLK_DIV2
@@ -161,15 +177,15 @@ RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
 RCC.TimSysFreq_Value=48000000
 RCC.USBFreq_Value=48000000
 RCC.VCOOutput2Freq_Value=8000000
-SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64
-SPI1.CalculateBaudRate=750.0 KBits/s
+SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8
+SPI1.CalculateBaudRate=6.0 MBits/s
 SPI1.Direction=SPI_DIRECTION_2LINES
 SPI1.IPParameters=VirtualType,Mode,Direction,BaudRatePrescaler,CalculateBaudRate
 SPI1.Mode=SPI_MODE_MASTER
 SPI1.VirtualType=VM_MASTER
-USART2.BaudRate=9600
-USART2.IPParameters=VirtualMode,BaudRate
-USART2.VirtualMode=VM_ASYNC
+USART1.BaudRate=9600
+USART1.IPParameters=VirtualMode,BaudRate
+USART1.VirtualMode=VM_ASYNC
 VP_SYS_VS_Systick.Mode=SysTick
 VP_SYS_VS_Systick.Signal=SYS_VS_Systick
 board=custom

+ 24 - 0
Core/Inc/debug.h

@@ -0,0 +1,24 @@
+/*****************************************************************************
+* | File      	:	Debug.h
+* | Author      :   Waveshare team
+* | Function    :	debug with printf
+* | Info        :
+*   Image scanning
+*      Please use progressive scanning to generate images or fonts
+*----------------
+* |	This version:   V1.0
+* | Date        :   2018-01-11
+* | Info        :   Basic version
+*
+******************************************************************************/
+#ifndef __DEBUG_H
+#define __DEBUG_H
+
+#define DEBUG 1
+#if DEBUG
+	#define Debug(__info,...) printf("Debug: " __info,##__VA_ARGS__)
+#else
+	#define Debug(__info,...)
+#endif
+
+#endif

+ 53 - 0
Core/Inc/epd.h

@@ -0,0 +1,53 @@
+/*****************************************************************************
+* | File      	:   EPD_2Iin13_V4.h
+* | Author      :   Waveshare team
+* | Function    :   2.13inch e-paper V4
+* | Info        :
+*----------------
+* |	This version:   V1.1
+* | Date        :   2021-10-30
+* | Info        :
+* -----------------------------------------------------------------------------
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documnetation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to  whom the Software is
+# furished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+******************************************************************************/
+#ifndef __EPD_2in13_V4_H_
+#define __EPD_2in13_V4_H_
+
+#include "epd_config.h"
+
+
+// Display resolution
+#define EPD_2in13_V4_WIDTH       122
+#define EPD_2in13_V4_HEIGHT      250
+
+void EPD_2in13_V4_Init(void);
+void EPD_2in13_V4_Init_Fast(void);
+void EPD_2in13_V4_Init_GUI(void);
+void EPD_2in13_V4_Clear(void);
+void EPD_2in13_V4_Clear_Black(void);
+void EPD_2in13_V4_Display(UBYTE *Image);
+void EPD_2in13_V4_Display_Fast(UBYTE *Image);
+void EPD_2in13_V4_Display_Base(UBYTE *Image);
+void EPD_2in13_V4_Display_Partial(UBYTE *Image);
+void EPD_2in13_V4_Sleep(void);
+
+
+#endif

+ 95 - 0
Core/Inc/epd_config.h

@@ -0,0 +1,95 @@
+/*****************************************************************************
+* | File      	:   DEV_Config.h
+* | Author      :   Waveshare team
+* | Function    :   Hardware underlying interface
+* | Info        :
+*                Used to shield the underlying layers of each master
+*                and enhance portability
+*----------------
+* |	This version:   V2.0
+* | Date        :   2018-10-30
+* | Info        :
+* 1.add:
+*   UBYTE\UWORD\UDOUBLE
+* 2.Change:
+*   EPD_RST -> EPD_RST_PIN
+*   EPD_DC -> EPD_DC_PIN
+*   EPD_CS -> EPD_CS_PIN
+*   EPD_BUSY -> EPD_BUSY_PIN
+* 3.Remote:
+*   EPD_RST_1\EPD_RST_0
+*   EPD_DC_1\EPD_DC_0
+*   EPD_CS_1\EPD_CS_0
+*   EPD_BUSY_1\EPD_BUSY_0
+* 3.add:
+*   #define DEV_Digital_Write(_pin, _value) bcm2835_gpio_write(_pin, _value)
+*   #define DEV_Digital_Read(_pin) bcm2835_gpio_lev(_pin)
+*   #define DEV_SPI_WriteByte(__value) bcm2835_spi_transfer(__value)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documnetation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to  whom the Software is
+# furished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+******************************************************************************/
+#ifndef _DEV_CONFIG_H_
+#define _DEV_CONFIG_H_
+
+#include "main.h"
+#include "stm32f1xx_hal.h"
+#include "stm32f1xx_hal_gpio.h"
+#include <stdint.h>
+#include <stdio.h>
+
+/**
+ * data
+**/
+#define UBYTE   uint8_t
+#define UWORD   uint16_t
+#define UDOUBLE uint32_t
+
+/**
+ * e-Paper GPIO
+**/
+#define EPD_RST_PIN     RST_GPIO_Port, RST_Pin
+#define EPD_DC_PIN      DC_GPIO_Port, DC_Pin
+//#define EPD_PWR_PIN     PWR_GPIO_Port, PWR_Pin
+#define EPD_CS_PIN      CS_GPIO_Port, CS_Pin
+#define EPD_BUSY_PIN    BUSY_GPIO_Port, BUSY_Pin
+#define EPD_MOSI_PIN    DIN_GPIO_Port, DIN_Pin
+#define EPD_SCLK_PIN    SCK_GPIO_Port, SCK_Pin
+
+/**
+ * GPIO read and write
+**/
+#define DEV_Digital_Write(_pin, _value) HAL_GPIO_WritePin(_pin, _value == 0? GPIO_PIN_RESET:GPIO_PIN_SET)
+#define DEV_Digital_Read(_pin) HAL_GPIO_ReadPin(_pin)
+
+/**
+ * delay x ms
+**/
+#define DEV_Delay_ms(__xms) HAL_Delay(__xms);
+
+void DEV_SPI_WriteByte(UBYTE value);
+void DEV_SPI_Write_nByte(UBYTE *value, UDOUBLE len);
+
+int DEV_Module_Init(void);
+void DEV_Module_Exit(void);
+void DEV_GPIO_Init(void);
+void DEV_SPI_Init(void);
+void DEV_SPI_SendData(UBYTE Reg);
+UBYTE DEV_SPI_ReadData(void);
+#endif

+ 41 - 0
Core/Inc/epd_test.h

@@ -0,0 +1,41 @@
+/*****************************************************************************
+* | File      	:	  EPD_Test.h
+* | Author      :   Waveshare team
+* | Function    :   e-Paper test Demo
+* | Info        :
+*----------------
+* |	This version:   V1.0
+* | Date        :   2019-06-11
+* | Info        :
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documnetation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to  whom the Software is
+# furished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+******************************************************************************/
+#ifndef _EPD_TEST_H_
+#define _EPD_TEST_H_
+
+#include "epd_config.h"
+#include "GUI_Paint.h"
+//#include "imagedata.h"
+#include "Debug.h"
+#include <stdlib.h> // malloc() free()
+
+int EPD_test(void);
+
+#endif

+ 97 - 0
Core/Inc/fonts.h

@@ -0,0 +1,97 @@
+/**
+  ******************************************************************************
+  * @file    fonts.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    18-February-2014
+  * @brief   Header for fonts.c file
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; 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
+
+/*�������΢���ź�24 (32x41) */
+#define MAX_HEIGHT_FONT         41
+#define MAX_WIDTH_FONT          32
+#define OFFSET_BITMAP
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+
+//ASCII
+typedef struct _tFont
+{
+  const uint8_t *table;
+  uint16_t Width;
+  uint16_t Height;
+
+} sFONT;
+
+
+//GB2312
+typedef struct                                          // ������ģ���ݽṹ
+{
+  unsigned char index[2];                               // ������������
+  const char matrix[MAX_HEIGHT_FONT*MAX_WIDTH_FONT/8];  // ����������
+}CH_CN;
+
+
+typedef struct
+{
+  const CH_CN *table;
+  uint16_t size;
+  uint16_t ASCII_Width;
+  uint16_t Width;
+  uint16_t Height;
+
+}cFONT;
+
+extern sFONT Font24;
+extern sFONT Font20;
+extern sFONT Font16;
+extern sFONT Font12;
+extern sFONT Font8;
+
+extern cFONT Font12CN;
+extern cFONT Font24CN;
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FONTS_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 217 - 0
Core/Inc/gui_paint.h

@@ -0,0 +1,217 @@
+/******************************************************************************
+* | File      	:   GUI_Paint.h
+* | Author      :   Waveshare electronics
+* | Function    :	Achieve drawing: draw points, lines, boxes, circles and
+*                   their size, solid dotted line, solid rectangle hollow
+*                   rectangle, solid circle hollow circle.
+* | Info        :
+*   Achieve display characters: Display a single character, string, number
+*   Achieve time display: adaptive size display time minutes and seconds
+*----------------
+* |	This version:   V3.0
+* | Date        :   2019-04-18
+* | Info        :
+* -----------------------------------------------------------------------------
+* V3.0(2019-04-18):
+* 1.Change:
+*    Paint_DrawPoint(..., DOT_STYLE DOT_STYLE)
+* => Paint_DrawPoint(..., DOT_STYLE Dot_Style)
+*    Paint_DrawLine(..., LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel)
+* => Paint_DrawLine(..., DOT_PIXEL Line_width, LINE_STYLE Line_Style)
+*    Paint_DrawRectangle(..., DRAW_FILL Filled, DOT_PIXEL Dot_Pixel)
+* => Paint_DrawRectangle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
+*    Paint_DrawCircle(..., DRAW_FILL Draw_Fill, DOT_PIXEL Dot_Pixel)
+* => Paint_DrawCircle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Filll)
+*
+* -----------------------------------------------------------------------------
+* V2.0(2018-11-15):
+* 1.add: Paint_NewImage()
+*    Create an image's properties
+* 2.add: Paint_SelectImage()
+*    Select the picture to be drawn
+* 3.add: Paint_SetRotate()
+*    Set the direction of the cache
+* 4.add: Paint_RotateImage()
+*    Can flip the picture, Support 0-360 degrees,
+*    but only 90.180.270 rotation is better
+* 4.add: Paint_SetMirroring()
+*    Can Mirroring the picture, horizontal, vertical, origin
+* 5.add: Paint_DrawString_CN()
+*    Can display Chinese(GB1312)
+*
+* -----------------------------------------------------------------------------
+* V1.0(2018-07-17):
+*   Create library
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documnetation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to  whom the Software is
+* furished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+******************************************************************************/
+#ifndef __GUI_PAINT_H
+#define __GUI_PAINT_H
+
+#include "epd_config.h"
+#include "fonts.h"
+
+/**
+ * Image attributes
+**/
+typedef struct {
+    UBYTE *Image;
+    UWORD Width;
+    UWORD Height;
+    UWORD WidthMemory;
+    UWORD HeightMemory;
+    UWORD Color;
+    UWORD Rotate;
+    UWORD Mirror;
+    UWORD WidthByte;
+    UWORD HeightByte;
+    UWORD Scale;
+} PAINT;
+extern PAINT Paint;
+
+/**
+ * Display rotate
+**/
+#define ROTATE_0            0
+#define ROTATE_90           90
+#define ROTATE_180          180
+#define ROTATE_270          270
+
+/**
+ * Display Flip
+**/
+typedef enum {
+    MIRROR_NONE  = 0x00,
+    MIRROR_HORIZONTAL = 0x01,
+    MIRROR_VERTICAL = 0x02,
+    MIRROR_ORIGIN = 0x03,
+} MIRROR_IMAGE;
+#define MIRROR_IMAGE_DFT MIRROR_NONE
+
+/**
+ * image color
+**/
+#define WHITE          0xFF
+#define BLACK          0x00
+#define RED            BLACK
+
+#define IMAGE_BACKGROUND    WHITE
+#define FONT_FOREGROUND     BLACK
+#define FONT_BACKGROUND     WHITE
+
+#define TRUE 1
+#define FALSE 0
+
+//4 Gray level
+#define  GRAY1 0x03 //Blackest
+#define  GRAY2 0x02
+#define  GRAY3 0x01 //gray
+#define  GRAY4 0x00 //white
+
+/**
+ * The size of the point
+**/
+typedef enum {
+    DOT_PIXEL_1X1  = 1,		// 1 x 1
+    DOT_PIXEL_2X2  , 		// 2 X 2
+    DOT_PIXEL_3X3  ,		// 3 X 3
+    DOT_PIXEL_4X4  ,		// 4 X 4
+    DOT_PIXEL_5X5  , 		// 5 X 5
+    DOT_PIXEL_6X6  , 		// 6 X 6
+    DOT_PIXEL_7X7  , 		// 7 X 7
+    DOT_PIXEL_8X8  , 		// 8 X 8
+} DOT_PIXEL;
+#define DOT_PIXEL_DFT  DOT_PIXEL_1X1  //Default dot pilex
+
+/**
+ * Point size fill style
+**/
+typedef enum {
+    DOT_FILL_AROUND  = 1,		// dot pixel 1 x 1
+    DOT_FILL_RIGHTUP  , 		// dot pixel 2 X 2
+} DOT_STYLE;
+#define DOT_STYLE_DFT  DOT_FILL_AROUND  //Default dot pilex
+
+/**
+ * Line style, solid or dashed
+**/
+typedef enum {
+    LINE_STYLE_SOLID = 0,
+    LINE_STYLE_DOTTED,
+} LINE_STYLE;
+
+/**
+ * Whether the graphic is filled
+**/
+typedef enum {
+    DRAW_FILL_EMPTY = 0,
+    DRAW_FILL_FULL,
+} DRAW_FILL;
+
+/**
+ * Custom structure of a time attribute
+**/
+typedef struct {
+    UWORD Year;  //0000
+    UBYTE  Month; //1 - 12
+    UBYTE  Day;   //1 - 30
+    UBYTE  Hour;  //0 - 23
+    UBYTE  Min;   //0 - 59
+    UBYTE  Sec;   //0 - 59
+} PAINT_TIME;
+extern PAINT_TIME sPaint_time;
+
+//init and Clear
+void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color);
+void Paint_SelectImage(UBYTE *image);
+void Paint_SetRotate(UWORD Rotate);
+void Paint_SetMirroring(UBYTE mirror);
+void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color);
+void Paint_SetScale(UBYTE scale);
+
+void Paint_Clear(UWORD Color);
+void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color);
+
+//Drawing
+void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_FillWay);
+void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style);
+void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill);
+void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill);
+
+//Display string
+void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Acsii_Char, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background);
+void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background);
+void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Foreground, UWORD Color_Background);
+void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background);
+void Paint_DrawNumDecimals(UWORD Xpoint, UWORD Ypoint, double Nummber, sFONT* Font, UWORD Digit, UWORD Color_Foreground, UWORD Color_Background); // Able to display decimals
+void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background);
+
+//pic
+void Paint_DrawBitMap(const unsigned char* image_buffer);
+void Paint_DrawBitMap_Paste(const unsigned char* image_buffer, UWORD Xstart, UWORD Ystart, UWORD imageWidth, UWORD imageHeight, UBYTE flipColor);
+//void Paint_DrawBitMap_Half(const unsigned char* image_buffer, UBYTE Region);
+//void Paint_DrawBitMap_OneQuarter(const unsigned char* image_buffer, UBYTE Region);
+//void Paint_DrawBitMap_OneEighth(const unsigned char* image_buffer, UBYTE Region);
+void Paint_DrawBitMap_Block(const unsigned char* image_buffer, UBYTE Region);
+#endif
+
+
+
+

+ 13 - 4
Core/Inc/main.h

@@ -57,13 +57,22 @@ void Error_Handler(void);
 /* USER CODE END EFP */
 
 /* Private defines -----------------------------------------------------------*/
-#define DC_Pin GPIO_PIN_15
-#define DC_GPIO_Port GPIOC
+#define LED_Pin GPIO_PIN_13
+#define LED_GPIO_Port GPIOC
 #define RST_Pin GPIO_PIN_1
 #define RST_GPIO_Port GPIOA
-#define PWR_Pin GPIO_PIN_4
-#define PWR_GPIO_Port GPIOA
+#define DC_Pin GPIO_PIN_2
+#define DC_GPIO_Port GPIOA
+#define CS_Pin GPIO_PIN_4
+#define CS_GPIO_Port GPIOA
+#define BUSY_Pin GPIO_PIN_4
+#define BUSY_GPIO_Port GPIOB
+
 /* USER CODE BEGIN Private defines */
+#define DIN_GPIO_Port GPIOA
+#define DIN_Pin GPIO_PIN_7
+#define SCK_GPIO_Port GPIOA
+#define SCK_Pin GPIO_PIN_5
 
 /* USER CODE END Private defines */
 

+ 2 - 2
Core/Inc/stm32f1xx_it.h

@@ -13,7 +13,7 @@
   * 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 */
 
@@ -22,7 +22,7 @@
 #define __STM32F1xx_IT_H
 
 #ifdef __cplusplus
- extern "C" {
+extern "C" {
 #endif
 
 /* Private includes ----------------------------------------------------------*/

+ 370 - 0
Core/Src/epd.c

@@ -0,0 +1,370 @@
+/*****************************************************************************
+* | File      	:  	EPD_2in13_V4.c
+* | Author      :   Waveshare team
+* | Function    :   2.13inch e-paper V4
+* | Info        :
+*----------------
+* |	This version:   V1.1
+* | Date        :   2021-10-30
+* | Info        :
+* -----------------------------------------------------------------------------
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documnetation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to  whom the Software is
+# furished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+******************************************************************************/
+#include "epd.h"
+#include "debug.h"
+
+/******************************************************************************
+function :	Software reset
+parameter:
+******************************************************************************/
+static void EPD_2in13_V4_Reset(void)
+{
+    DEV_Digital_Write(EPD_RST_PIN, 1);
+    DEV_Delay_ms(20);
+    DEV_Digital_Write(EPD_RST_PIN, 0);
+    DEV_Delay_ms(2);
+    DEV_Digital_Write(EPD_RST_PIN, 1);
+    DEV_Delay_ms(20);
+}
+
+/******************************************************************************
+function :	send command
+parameter:
+     Reg : Command register
+******************************************************************************/
+static void EPD_2in13_V4_SendCommand(UBYTE Reg)
+{
+    DEV_Digital_Write(EPD_DC_PIN, 0);
+    DEV_Digital_Write(EPD_CS_PIN, 0);
+    DEV_SPI_WriteByte(Reg);
+    DEV_Digital_Write(EPD_CS_PIN, 1);
+}
+
+/******************************************************************************
+function :	send data
+parameter:
+    Data : Write data
+******************************************************************************/
+static void EPD_2in13_V4_SendData(UBYTE Data)
+{
+    DEV_Digital_Write(EPD_DC_PIN, 1);
+    DEV_Digital_Write(EPD_CS_PIN, 0);
+    DEV_SPI_WriteByte(Data);
+    DEV_Digital_Write(EPD_CS_PIN, 1);
+}
+
+/******************************************************************************
+function :	Wait until the busy_pin goes LOW
+parameter:
+******************************************************************************/
+void EPD_2in13_V4_ReadBusy(void)
+{
+    Debug("e-Paper busy\r\n");
+	while(1)
+	{	 //=1 BUSY
+		if(DEV_Digital_Read(EPD_BUSY_PIN)==0)
+			break;
+		DEV_Delay_ms(10);
+	}
+	DEV_Delay_ms(10);
+    Debug("e-Paper busy release\r\n");
+}
+
+/******************************************************************************
+function :	Setting the display window
+parameter:
+	Xstart : X-axis starting position
+	Ystart : Y-axis starting position
+	Xend : End position of X-axis
+	Yend : End position of Y-axis
+******************************************************************************/
+static void EPD_2in13_V4_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
+{
+    EPD_2in13_V4_SendCommand(0x44); // SET_RAM_X_ADDRESS_START_END_POSITION
+    EPD_2in13_V4_SendData((Xstart>>3) & 0xFF);
+    EPD_2in13_V4_SendData((Xend>>3) & 0xFF);
+
+    EPD_2in13_V4_SendCommand(0x45); // SET_RAM_Y_ADDRESS_START_END_POSITION
+    EPD_2in13_V4_SendData(Ystart & 0xFF);
+    EPD_2in13_V4_SendData((Ystart >> 8) & 0xFF);
+    EPD_2in13_V4_SendData(Yend & 0xFF);
+    EPD_2in13_V4_SendData((Yend >> 8) & 0xFF);
+}
+
+/******************************************************************************
+function :	Set Cursor
+parameter:
+	Xstart : X-axis starting position
+	Ystart : Y-axis starting position
+******************************************************************************/
+static void EPD_2in13_V4_SetCursor(UWORD Xstart, UWORD Ystart)
+{
+    EPD_2in13_V4_SendCommand(0x4E); // SET_RAM_X_ADDRESS_COUNTER
+    EPD_2in13_V4_SendData(Xstart & 0xFF);
+
+    EPD_2in13_V4_SendCommand(0x4F); // SET_RAM_Y_ADDRESS_COUNTER
+    EPD_2in13_V4_SendData(Ystart & 0xFF);
+    EPD_2in13_V4_SendData((Ystart >> 8) & 0xFF);
+}
+
+/******************************************************************************
+function :	Turn On Display
+parameter:
+******************************************************************************/
+static void EPD_2in13_V4_TurnOnDisplay(void)
+{
+	EPD_2in13_V4_SendCommand(0x22); // Display Update Control
+	EPD_2in13_V4_SendData(0xf7);
+	EPD_2in13_V4_SendCommand(0x20); // Activate Display Update Sequence
+	EPD_2in13_V4_ReadBusy();
+}
+
+static void EPD_2in13_V4_TurnOnDisplay_Fast(void)
+{
+	EPD_2in13_V4_SendCommand(0x22); // Display Update Control
+	EPD_2in13_V4_SendData(0xc7);	// fast:0x0c, quality:0x0f, 0xcf
+	EPD_2in13_V4_SendCommand(0x20); // Activate Display Update Sequence
+	EPD_2in13_V4_ReadBusy();
+}
+
+static void EPD_2in13_V4_TurnOnDisplay_Partial(void)
+{
+	EPD_2in13_V4_SendCommand(0x22); // Display Update Control
+	EPD_2in13_V4_SendData(0xff);	// fast:0x0c, quality:0x0f, 0xcf
+	EPD_2in13_V4_SendCommand(0x20); // Activate Display Update Sequence
+	EPD_2in13_V4_ReadBusy();
+}
+
+/******************************************************************************
+function :	Initialize the e-Paper register
+parameter:
+******************************************************************************/
+void EPD_2in13_V4_Init(void)
+{
+	EPD_2in13_V4_Reset();
+
+	EPD_2in13_V4_ReadBusy();
+	EPD_2in13_V4_SendCommand(0x12);  //SWRESET
+	EPD_2in13_V4_ReadBusy();
+
+	EPD_2in13_V4_SendCommand(0x01); //Driver output control
+	EPD_2in13_V4_SendData(0xF9);
+	EPD_2in13_V4_SendData(0x00);
+	EPD_2in13_V4_SendData(0x00);
+
+	EPD_2in13_V4_SendCommand(0x11); //data entry mode
+	EPD_2in13_V4_SendData(0x03);
+
+	EPD_2in13_V4_SetWindows(0, 0, EPD_2in13_V4_WIDTH-1, EPD_2in13_V4_HEIGHT-1);
+	EPD_2in13_V4_SetCursor(0, 0);
+
+	EPD_2in13_V4_SendCommand(0x3C); //BorderWavefrom
+	EPD_2in13_V4_SendData(0x05);
+
+	EPD_2in13_V4_SendCommand(0x21); //  Display update control
+	EPD_2in13_V4_SendData(0x00);
+	EPD_2in13_V4_SendData(0x80);
+
+	EPD_2in13_V4_SendCommand(0x18); //Read built-in temperature sensor
+	EPD_2in13_V4_SendData(0x80);
+	EPD_2in13_V4_ReadBusy();
+}
+
+void EPD_2in13_V4_Init_Fast(void)
+{
+	EPD_2in13_V4_Reset();
+
+	EPD_2in13_V4_SendCommand(0x12);  //SWRESET
+	EPD_2in13_V4_ReadBusy();
+
+	EPD_2in13_V4_SendCommand(0x18); //Read built-in temperature sensor
+	EPD_2in13_V4_SendData(0x80);
+
+	EPD_2in13_V4_SendCommand(0x11); //data entry mode
+	EPD_2in13_V4_SendData(0x03);
+
+	EPD_2in13_V4_SetWindows(0, 0, EPD_2in13_V4_WIDTH-1, EPD_2in13_V4_HEIGHT-1);
+	EPD_2in13_V4_SetCursor(0, 0);
+
+	EPD_2in13_V4_SendCommand(0x22); // Load temperature value
+	EPD_2in13_V4_SendData(0xB1);
+	EPD_2in13_V4_SendCommand(0x20);
+	EPD_2in13_V4_ReadBusy();
+
+	EPD_2in13_V4_SendCommand(0x1A); // Write to temperature register
+	EPD_2in13_V4_SendData(0x64);
+	EPD_2in13_V4_SendData(0x00);
+
+	EPD_2in13_V4_SendCommand(0x22); // Load temperature value
+	EPD_2in13_V4_SendData(0x91);
+	EPD_2in13_V4_SendCommand(0x20);
+	EPD_2in13_V4_ReadBusy();
+}
+
+/******************************************************************************
+function :	Clear screen
+parameter:
+******************************************************************************/
+void EPD_2in13_V4_Clear(void)
+{
+	UWORD Width, Height;
+    Width = (EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1);
+    Height = EPD_2in13_V4_HEIGHT;
+
+    EPD_2in13_V4_SendCommand(0x24);
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+            EPD_2in13_V4_SendData(0XFF);
+        }
+    }
+
+	EPD_2in13_V4_TurnOnDisplay();
+}
+
+void EPD_2in13_V4_Clear_Black(void)
+{
+	UWORD Width, Height;
+    Width = (EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1);
+    Height = EPD_2in13_V4_HEIGHT;
+
+    EPD_2in13_V4_SendCommand(0x24);
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+            EPD_2in13_V4_SendData(0X00);
+        }
+    }
+
+	EPD_2in13_V4_TurnOnDisplay();
+}
+
+/******************************************************************************
+function :	Sends the image buffer in RAM to e-Paper and displays
+parameter:
+	Image : Image data
+******************************************************************************/
+void EPD_2in13_V4_Display(UBYTE *Image)
+{
+	UWORD Width, Height;
+    Width = (EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1);
+    Height = EPD_2in13_V4_HEIGHT;
+
+    EPD_2in13_V4_SendCommand(0x24);
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+            EPD_2in13_V4_SendData(Image[i + j * Width]);
+        }
+    }
+
+	EPD_2in13_V4_TurnOnDisplay();
+}
+
+void EPD_2in13_V4_Display_Fast(UBYTE *Image)
+{
+	UWORD Width, Height;
+    Width = (EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1);
+    Height = EPD_2in13_V4_HEIGHT;
+
+    EPD_2in13_V4_SendCommand(0x24);
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+            EPD_2in13_V4_SendData(Image[i + j * Width]);
+        }
+    }
+
+	EPD_2in13_V4_TurnOnDisplay_Fast();
+}
+
+
+/******************************************************************************
+function :	Refresh a base image
+parameter:
+	Image : Image data
+******************************************************************************/
+void EPD_2in13_V4_Display_Base(UBYTE *Image)
+{
+	UWORD Width, Height;
+    Width = (EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1);
+    Height = EPD_2in13_V4_HEIGHT;
+
+	EPD_2in13_V4_SendCommand(0x24);   //Write Black and White image to RAM
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+			EPD_2in13_V4_SendData(Image[i + j * Width]);
+		}
+	}
+	EPD_2in13_V4_SendCommand(0x26);   //Write Black and White image to RAM
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+			EPD_2in13_V4_SendData(Image[i + j * Width]);
+		}
+	}
+	EPD_2in13_V4_TurnOnDisplay();
+}
+
+/******************************************************************************
+function :	Sends the image buffer in RAM to e-Paper and partial refresh
+parameter:
+	Image : Image data
+******************************************************************************/
+void EPD_2in13_V4_Display_Partial(UBYTE *Image)
+{
+	UWORD Width, Height;
+    Width = (EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1);
+    Height = EPD_2in13_V4_HEIGHT;
+
+	//Reset
+    DEV_Digital_Write(EPD_RST_PIN, 0);
+    DEV_Delay_ms(1);
+    DEV_Digital_Write(EPD_RST_PIN, 1);
+
+	EPD_2in13_V4_SendCommand(0x3C); //BorderWavefrom
+	EPD_2in13_V4_SendData(0x80);
+
+	EPD_2in13_V4_SendCommand(0x01); //Driver output control
+	EPD_2in13_V4_SendData(0xF9);
+	EPD_2in13_V4_SendData(0x00);
+	EPD_2in13_V4_SendData(0x00);
+
+	EPD_2in13_V4_SendCommand(0x11); //data entry mode
+	EPD_2in13_V4_SendData(0x03);
+
+	EPD_2in13_V4_SetWindows(0, 0, EPD_2in13_V4_WIDTH-1, EPD_2in13_V4_HEIGHT-1);
+	EPD_2in13_V4_SetCursor(0, 0);
+
+	EPD_2in13_V4_SendCommand(0x24);   //Write Black and White image to RAM
+    for (UWORD j = 0; j < Height; j++) {
+        for (UWORD i = 0; i < Width; i++) {
+			EPD_2in13_V4_SendData(Image[i + j * Width]);
+		}
+	}
+	EPD_2in13_V4_TurnOnDisplay_Partial();
+}
+
+/******************************************************************************
+function :	Enter sleep mode
+parameter:
+******************************************************************************/
+void EPD_2in13_V4_Sleep(void)
+{
+	EPD_2in13_V4_SendCommand(0x10); //enter deep sleep
+	EPD_2in13_V4_SendData(0x01);
+	DEV_Delay_ms(100);
+}

+ 149 - 0
Core/Src/epd_config.c

@@ -0,0 +1,149 @@
+/*****************************************************************************
+* | File      	:   DEV_Config.c
+* | Author      :   Waveshare team
+* | Function    :   Hardware underlying interface
+* | Info        :
+*                Used to shield the underlying layers of each master
+*                and enhance portability
+*----------------
+* |	This version:   V2.0
+* | Date        :   2018-10-30
+* | Info        :
+# ******************************************************************************
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documnetation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to  whom the Software is
+# furished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+******************************************************************************/
+#include "epd_config.h"
+#include "stm32f1xx_hal_spi.h"
+
+extern SPI_HandleTypeDef hspi1;
+void DEV_SPI_WriteByte(UBYTE value)
+{
+    HAL_SPI_Transmit(&hspi1, &value, 1, 1000);
+}
+
+void DEV_SPI_Write_nByte(UBYTE *value, UDOUBLE len)
+{
+    HAL_SPI_Transmit(&hspi1, value, len, 1000);
+}
+
+void DEV_GPIO_Mode(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, UWORD Mode)
+{
+
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
+    if(Mode == 0) {
+        GPIO_InitStruct.Pin = GPIO_Pin;
+        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+        GPIO_InitStruct.Pull = GPIO_PULLUP;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+	} else {
+		GPIO_InitStruct.Pin = GPIO_Pin;
+        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+		// Debug (" %d OUT \r\n",Pin);
+	}
+}
+
+void DEV_GPIO_Init()
+{
+    HAL_SPI_MspDeInit(&hspi1);
+
+    //HAL_SPI_DeInit(&hspi1);
+//    __HAL_RCC_SPI1_CLK_DISABLE();
+//    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_7);
+}
+
+void DEV_SPI_Init()
+{
+    HAL_SPI_MspInit(&hspi1);
+    //HAL_SPI_DeInit(&hspi1);
+//    __HAL_RCC_SPI1_CLK_DISABLE();
+//    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_7);
+}
+
+
+void DEV_SPI_SendData(UBYTE Reg)
+{
+	UBYTE i,j=Reg;
+	DEV_GPIO_Mode(EPD_MOSI_PIN, 1);
+    DEV_GPIO_Mode(EPD_SCLK_PIN, 1);
+	DEV_Digital_Write(EPD_CS_PIN, 0);
+	for(i = 0; i<8; i++)
+    {
+        DEV_Digital_Write(EPD_SCLK_PIN, 0);
+        if (j & 0x80)
+        {
+            DEV_Digital_Write(EPD_MOSI_PIN, 1);
+        }
+        else
+        {
+            DEV_Digital_Write(EPD_MOSI_PIN, 0);
+        }
+
+        DEV_Digital_Write(EPD_SCLK_PIN, 1);
+        j = j << 1;
+    }
+	DEV_Digital_Write(EPD_SCLK_PIN, 0);
+	DEV_Digital_Write(EPD_CS_PIN, 1);
+}
+
+UBYTE DEV_SPI_ReadData()
+{
+	UBYTE i,j=0xff;
+	DEV_GPIO_Mode(EPD_MOSI_PIN, 0);
+    DEV_GPIO_Mode(EPD_SCLK_PIN, 1);
+	DEV_Digital_Write(EPD_CS_PIN, 0);
+	for(i = 0; i<8; i++)
+	{
+		DEV_Digital_Write(EPD_SCLK_PIN, 0);
+		j = j << 1;
+		if (DEV_Digital_Read(EPD_MOSI_PIN))
+		{
+            j = j | 0x01;
+		}
+		else
+		{
+            j= j & 0xfe;
+		}
+		DEV_Digital_Write(EPD_SCLK_PIN, 1);
+	}
+	DEV_Digital_Write(EPD_SCLK_PIN, 0);
+	DEV_Digital_Write(EPD_CS_PIN, 1);
+	return j;
+}
+
+int DEV_Module_Init(void)
+{
+    DEV_Digital_Write(EPD_DC_PIN, 0);
+    DEV_Digital_Write(EPD_CS_PIN, 0);
+	//DEV_Digital_Write(EPD_PWR_PIN, 1);
+    DEV_Digital_Write(EPD_RST_PIN, 1);
+    return 0;
+}
+
+void DEV_Module_Exit(void)
+{
+    DEV_Digital_Write(EPD_DC_PIN, 0);
+    DEV_Digital_Write(EPD_CS_PIN, 0);
+
+    //close 5V
+	//DEV_Digital_Write(EPD_PWR_PIN, 0);
+    DEV_Digital_Write(EPD_RST_PIN, 0);
+}

+ 151 - 0
Core/Src/epd_test.c

@@ -0,0 +1,151 @@
+/*****************************************************************************
+* | File      	:   EPD_2in13_V4_test.c
+* | Author      :   Waveshare team
+* | Function    :   2.13inch e-paper V4 test demo
+* | Info        :
+*----------------
+* |	This version:   V1.0
+* | Date        :   2023-6-25
+* | Info        :
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documnetation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to  whom the Software is
+# furished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+******************************************************************************/
+#include "EPD_Test.h"
+#include "epd.h"
+#include <time.h>
+
+int EPD_test(void)
+{
+
+    Debug("EPD_2in13_V4_test Demo\r\n");
+    if(DEV_Module_Init()!=0){
+        return -1;
+    }
+
+    Debug("e-Paper Init and Clear...\r\n");
+	EPD_2in13_V4_Init();
+
+    EPD_2in13_V4_Clear();
+
+    //Create a new image cache
+    UBYTE *BlackImage;
+    UWORD Imagesize = ((EPD_2in13_V4_WIDTH % 8 == 0)? (EPD_2in13_V4_WIDTH / 8 ): (EPD_2in13_V4_WIDTH / 8 + 1)) * EPD_2in13_V4_HEIGHT;
+    if((BlackImage = (UBYTE *)malloc(Imagesize)) == NULL) {
+        Debug("Failed to apply for black memory...\r\n");
+        return -1;
+    }
+    Debug("Paint_NewImage\r\n");
+    Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
+	Paint_Clear(WHITE);
+
+
+#if 0   //show image for array
+    Debug("The e-paper quickly refreshes the display image\r\n");
+    EPD_2in13_V4_Init_Fast();
+    Paint_SelectImage(BlackImage);
+    Paint_Clear(WHITE);
+    //Paint_DrawBitMap(gImage_2in13);
+
+    EPD_2in13_V4_Display_Fast(BlackImage);
+    DEV_Delay_ms(2000);
+#endif
+
+#if 1  // Drawing on the image
+	Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
+    Debug("Drawing\r\n");
+    //1.Select Image
+    EPD_2in13_V4_Init();
+    Paint_SelectImage(BlackImage);
+    Paint_Clear(WHITE);
+
+    // 2.Drawing on the image
+    Paint_DrawPoint(5, 10, BLACK, DOT_PIXEL_1X1, DOT_STYLE_DFT);
+    Paint_DrawPoint(5, 25, BLACK, DOT_PIXEL_2X2, DOT_STYLE_DFT);
+    Paint_DrawPoint(5, 40, BLACK, DOT_PIXEL_3X3, DOT_STYLE_DFT);
+    Paint_DrawPoint(5, 55, BLACK, DOT_PIXEL_4X4, DOT_STYLE_DFT);
+
+    Paint_DrawLine(20, 10, 70, 60, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
+    Paint_DrawLine(70, 10, 20, 60, BLACK, DOT_PIXEL_1X1, LINE_STYLE_SOLID);
+    Paint_DrawRectangle(20, 10, 70, 60, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
+    Paint_DrawRectangle(85, 10, 135, 60, BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
+
+    Paint_DrawLine(45, 15, 45, 55, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
+    Paint_DrawLine(25, 35, 70, 35, BLACK, DOT_PIXEL_1X1, LINE_STYLE_DOTTED);
+    Paint_DrawCircle(45, 35, 20, BLACK, DOT_PIXEL_1X1, DRAW_FILL_EMPTY);
+    Paint_DrawCircle(110, 35, 20, WHITE, DOT_PIXEL_1X1, DRAW_FILL_FULL);
+
+    Paint_DrawString_EN(140, 15, "waveshare", &Font16, BLACK, WHITE);
+    Paint_DrawNum(140, 40, 123456789, &Font16, BLACK, WHITE);
+
+    EPD_2in13_V4_Display_Base(BlackImage);
+    DEV_Delay_ms(3000);
+#endif
+
+#if 1   //Partial refresh, example shows time
+	Paint_NewImage(BlackImage, EPD_2in13_V4_WIDTH, EPD_2in13_V4_HEIGHT, 90, WHITE);
+    Debug("Partial refresh\r\n");
+    Paint_SelectImage(BlackImage);
+
+    PAINT_TIME sPaint_time;
+    sPaint_time.Hour = 12;
+    sPaint_time.Min = 34;
+    sPaint_time.Sec = 56;
+    UBYTE num = 10;
+    for (;;) {
+        sPaint_time.Sec = sPaint_time.Sec + 1;
+        if (sPaint_time.Sec == 60) {
+            sPaint_time.Min = sPaint_time.Min + 1;
+            sPaint_time.Sec = 0;
+            if (sPaint_time.Min == 60) {
+                sPaint_time.Hour =  sPaint_time.Hour + 1;
+                sPaint_time.Min = 0;
+                if (sPaint_time.Hour == 24) {
+                    sPaint_time.Hour = 0;
+                    sPaint_time.Min = 0;
+                    sPaint_time.Sec = 0;
+                }
+            }
+        }
+        Paint_ClearWindows(150, 80, 150 + Font16.Width * 7, 80 + Font16.Height, WHITE);
+        Paint_DrawTime(150, 80, &sPaint_time, &Font16, WHITE, BLACK);
+
+        num = num - 1;
+        if(num == 0) {
+            break;
+        }
+		EPD_2in13_V4_Display_Partial(BlackImage);
+        DEV_Delay_ms(500);//Analog clock 1s
+    }
+#endif
+
+	Debug("Clear...\r\n");
+	EPD_2in13_V4_Init();
+    //EPD_2in13_V4_Clear();
+
+    Debug("Goto Sleep...\r\n");
+    EPD_2in13_V4_Sleep();
+    free(BlackImage);
+    BlackImage = NULL;
+    DEV_Delay_ms(2000);//important, at least 2s
+    // close 5V
+    Debug("close 5V, Module enters 0 power consumption ...\r\n");
+    DEV_Module_Exit();
+    return 0;
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1764 - 0
Core/Src/font16.c


+ 965 - 0
Core/Src/gui_paint.c

@@ -0,0 +1,965 @@
+/******************************************************************************
+* | File      	:   GUI_Paint.c
+* | Author      :   Waveshare electronics
+* | Function    :	Achieve drawing: draw points, lines, boxes, circles and
+*                   their size, solid dotted line, solid rectangle hollow
+*                   rectangle, solid circle hollow circle.
+* | Info        :
+*   Achieve display characters: Display a single character, string, number
+*   Achieve time display: adaptive size display time minutes and seconds
+*----------------
+* |	This version:   V3.1
+* | Date        :   2020-07-08
+* | Info        :
+* -----------------------------------------------------------------------------
+* V3.1(2020-07-08):
+* 1.Change: Paint_SetScale(UBYTE scale)
+*		 Add scale 7 for 5.65f e-Parper
+* 2.Change: Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
+*		 Add the branch for scale 7
+* 3.Change: Paint_Clear(UWORD Color)
+*		 Add the branch for scale 7
+*
+* -----------------------------------------------------------------------------
+* V3.0(2019-04-18):
+* 1.Change:
+*    Paint_DrawPoint(..., DOT_STYLE DOT_STYLE)
+* => Paint_DrawPoint(..., DOT_STYLE Dot_Style)
+*    Paint_DrawLine(..., LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel)
+* => Paint_DrawLine(..., DOT_PIXEL Line_width, LINE_STYLE Line_Style)
+*    Paint_DrawRectangle(..., DRAW_FILL Filled, DOT_PIXEL Dot_Pixel)
+* => Paint_DrawRectangle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
+*    Paint_DrawCircle(..., DRAW_FILL Draw_Fill, DOT_PIXEL Dot_Pixel)
+* => Paint_DrawCircle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Filll)
+*
+* -----------------------------------------------------------------------------
+* V2.0(2018-11-15):
+* 1.add: Paint_NewImage()
+*    Create an image's properties
+* 2.add: Paint_SelectImage()
+*    Select the picture to be drawn
+* 3.add: Paint_SetRotate()
+*    Set the direction of the cache
+* 4.add: Paint_RotateImage()
+*    Can flip the picture, Support 0-360 degrees,
+*    but only 90.180.270 rotation is better
+* 4.add: Paint_SetMirroring()
+*    Can Mirroring the picture, horizontal, vertical, origin
+* 5.add: Paint_DrawString_CN()
+*    Can display Chinese(GB1312)
+*
+* -----------------------------------------------------------------------------
+* V1.0(2018-07-17):
+*   Create library
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documnetation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to  whom the Software is
+* furished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+******************************************************************************/
+#include "GUI_Paint.h"
+#include "epd_config.h"
+#include "Debug.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h> //memset()
+#include <math.h>
+
+PAINT Paint;
+
+/******************************************************************************
+function: Create Image
+parameter:
+    image   :   Pointer to the image cache
+    width   :   The width of the picture
+    Height  :   The height of the picture
+    Color   :   Whether the picture is inverted
+******************************************************************************/
+void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color)
+{
+    Paint.Image = NULL;
+    Paint.Image = image;
+
+    Paint.WidthMemory = Width;
+    Paint.HeightMemory = Height;
+    Paint.Color = Color;
+	Paint.Scale = 2;
+
+    Paint.WidthByte = (Width % 8 == 0)? (Width / 8 ): (Width / 8 + 1);
+    Paint.HeightByte = Height;
+//    printf("WidthByte = %d, HeightByte = %d\r\n", Paint.WidthByte, Paint.HeightByte);
+//    printf(" EPD_WIDTH / 8 = %d\r\n",  122 / 8);
+
+    Paint.Rotate = Rotate;
+    Paint.Mirror = MIRROR_NONE;
+
+    if(Rotate == ROTATE_0 || Rotate == ROTATE_180) {
+        Paint.Width = Width;
+        Paint.Height = Height;
+    } else {
+        Paint.Width = Height;
+        Paint.Height = Width;
+    }
+}
+
+/******************************************************************************
+function: Select Image
+parameter:
+    image : Pointer to the image cache
+******************************************************************************/
+void Paint_SelectImage(UBYTE *image)
+{
+    Paint.Image = image;
+}
+
+/******************************************************************************
+function: Select Image Rotate
+parameter:
+    Rotate : 0,90,180,270
+******************************************************************************/
+void Paint_SetRotate(UWORD Rotate)
+{
+    if(Rotate == ROTATE_0 || Rotate == ROTATE_90 || Rotate == ROTATE_180 || Rotate == ROTATE_270) {
+        Debug("Set image Rotate %d\r\n", Rotate);
+        Paint.Rotate = Rotate;
+    } else {
+        Debug("rotate = 0, 90, 180, 270\r\n");
+    }
+}
+
+void Paint_SetScale(UBYTE scale)
+{
+    if(scale == 2){
+        Paint.Scale = scale;
+        Paint.WidthByte = (Paint.WidthMemory % 8 == 0)? (Paint.WidthMemory / 8 ): (Paint.WidthMemory / 8 + 1);
+    }else if(scale == 4){
+        Paint.Scale = scale;
+        Paint.WidthByte = (Paint.WidthMemory % 4 == 0)? (Paint.WidthMemory / 4 ): (Paint.WidthMemory / 4 + 1);
+    }else if(scale == 6 || scale == 7){//Only applicable with 5in65 e-Paper
+				Paint.Scale = scale;
+				Paint.WidthByte = (Paint.WidthMemory % 2 == 0)? (Paint.WidthMemory / 2 ): (Paint.WidthMemory / 2 + 1);;
+		}else{
+        Debug("Set Scale Input parameter error\r\n");
+        Debug("Scale Only support: 2 4 7\r\n");
+    }
+}
+/******************************************************************************
+function:	Select Image mirror
+parameter:
+    mirror   :Not mirror,Horizontal mirror,Vertical mirror,Origin mirror
+******************************************************************************/
+void Paint_SetMirroring(UBYTE mirror)
+{
+    if(mirror == MIRROR_NONE || mirror == MIRROR_HORIZONTAL ||
+        mirror == MIRROR_VERTICAL || mirror == MIRROR_ORIGIN) {
+        Debug("mirror image x:%s, y:%s\r\n",(mirror & 0x01)? "mirror":"none", ((mirror >> 1) & 0x01)? "mirror":"none");
+        Paint.Mirror = mirror;
+    } else {
+        Debug("mirror should be MIRROR_NONE, MIRROR_HORIZONTAL, \
+        MIRROR_VERTICAL or MIRROR_ORIGIN\r\n");
+    }
+}
+
+/******************************************************************************
+function: Draw Pixels
+parameter:
+    Xpoint : At point X
+    Ypoint : At point Y
+    Color  : Painted colors
+******************************************************************************/
+void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
+{
+    if(Xpoint > Paint.Width || Ypoint > Paint.Height){
+        Debug("Exceeding display boundaries\r\n");
+        return;
+    }
+    UWORD X, Y;
+
+    switch(Paint.Rotate) {
+    case 0:
+        X = Xpoint;
+        Y = Ypoint;
+        break;
+    case 90:
+        X = Paint.WidthMemory - Ypoint - 1;
+        Y = Xpoint;
+        break;
+    case 180:
+        X = Paint.WidthMemory - Xpoint - 1;
+        Y = Paint.HeightMemory - Ypoint - 1;
+        break;
+    case 270:
+        X = Ypoint;
+        Y = Paint.HeightMemory - Xpoint - 1;
+        break;
+    default:
+        return;
+    }
+
+    switch(Paint.Mirror) {
+    case MIRROR_NONE:
+        break;
+    case MIRROR_HORIZONTAL:
+        X = Paint.WidthMemory - X - 1;
+        break;
+    case MIRROR_VERTICAL:
+        Y = Paint.HeightMemory - Y - 1;
+        break;
+    case MIRROR_ORIGIN:
+        X = Paint.WidthMemory - X - 1;
+        Y = Paint.HeightMemory - Y - 1;
+        break;
+    default:
+        return;
+    }
+
+    if(X > Paint.WidthMemory || Y > Paint.HeightMemory){
+        Debug("Exceeding display boundaries\r\n");
+        return;
+    }
+
+    if(Paint.Scale == 2){
+        UDOUBLE Addr = X / 8 + Y * Paint.WidthByte;
+        UBYTE Rdata = Paint.Image[Addr];
+        if(Color == BLACK)
+            Paint.Image[Addr] = Rdata & ~(0x80 >> (X % 8));
+        else
+            Paint.Image[Addr] = Rdata | (0x80 >> (X % 8));
+    }else if(Paint.Scale == 4){
+        UDOUBLE Addr = X / 4 + Y * Paint.WidthByte;
+        Color = Color % 4;//Guaranteed color scale is 4  --- 0~3
+        UBYTE Rdata = Paint.Image[Addr];
+
+        Rdata = Rdata & (~(0xC0 >> ((X % 4)*2)));
+        Paint.Image[Addr] = Rdata | ((Color << 6) >> ((X % 4)*2));
+    }else if(Paint.Scale == 6 || Paint.Scale == 7){
+		UDOUBLE Addr = X / 2  + Y * Paint.WidthByte;
+		UBYTE Rdata = Paint.Image[Addr];
+		Rdata = Rdata & (~(0xF0 >> ((X % 2)*4)));//Clear first, then set value
+		Paint.Image[Addr] = Rdata | ((Color << 4) >> ((X % 2)*4));
+		//printf("Add =  %d ,data = %d\r\n",Addr,Rdata);
+		}
+}
+
+/******************************************************************************
+function: Clear the color of the picture
+parameter:
+    Color : Painted colors
+******************************************************************************/
+void Paint_Clear(UWORD Color)
+{
+	if(Paint.Scale == 2) {
+		for (UWORD Y = 0; Y < Paint.HeightByte; Y++) {
+			for (UWORD X = 0; X < Paint.WidthByte; X++ ) {//8 pixel =  1 byte
+				UDOUBLE Addr = X + Y*Paint.WidthByte;
+				Paint.Image[Addr] = Color;
+			}
+		}
+    }else if(Paint.Scale == 4) {
+        for (UWORD Y = 0; Y < Paint.HeightByte; Y++) {
+			for (UWORD X = 0; X < Paint.WidthByte; X++ ) {
+				UDOUBLE Addr = X + Y*Paint.WidthByte;
+				Paint.Image[Addr] = (Color<<6)|(Color<<4)|(Color<<2)|Color;
+			}
+		}
+	}else if(Paint.Scale == 6 || Paint.Scale == 7) {
+		for (UWORD Y = 0; Y < Paint.HeightByte; Y++) {
+			for (UWORD X = 0; X < Paint.WidthByte; X++ ) {
+				UDOUBLE Addr = X + Y*Paint.WidthByte;
+				Paint.Image[Addr] = (Color<<4)|Color;
+			}
+		}
+	}
+}
+
+/******************************************************************************
+function: Clear the color of a window
+parameter:
+    Xstart : x starting point
+    Ystart : Y starting point
+    Xend   : x end point
+    Yend   : y end point
+    Color  : Painted colors
+******************************************************************************/
+void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color)
+{
+    UWORD X, Y;
+    for (Y = Ystart; Y < Yend; Y++) {
+        for (X = Xstart; X < Xend; X++) {//8 pixel =  1 byte
+            Paint_SetPixel(X, Y, Color);
+        }
+    }
+}
+
+/******************************************************************************
+function: Draw Point(Xpoint, Ypoint) Fill the color
+parameter:
+    Xpoint		: The Xpoint coordinate of the point
+    Ypoint		: The Ypoint coordinate of the point
+    Color		: Painted color
+    Dot_Pixel	: point size
+    Dot_Style	: point Style
+******************************************************************************/
+void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color,
+                     DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)
+{
+    if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
+        Debug("Paint_DrawPoint Input exceeds the normal display range\r\n");
+				printf("Xpoint = %d , Paint.Width = %d  \r\n ",Xpoint,Paint.Width);
+				printf("Ypoint = %d , Paint.Height = %d  \r\n ",Ypoint,Paint.Height);
+        return;
+    }
+
+    int16_t XDir_Num , YDir_Num;
+    if (Dot_Style == DOT_FILL_AROUND) {
+        for (XDir_Num = 0; XDir_Num < 2 * Dot_Pixel - 1; XDir_Num++) {
+            for (YDir_Num = 0; YDir_Num < 2 * Dot_Pixel - 1; YDir_Num++) {
+                if(Xpoint + XDir_Num - Dot_Pixel < 0 || Ypoint + YDir_Num - Dot_Pixel < 0)
+                    break;
+                // printf("x = %d, y = %d\r\n", Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel);
+                Paint_SetPixel(Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel, Color);
+            }
+        }
+    } else {
+        for (XDir_Num = 0; XDir_Num <  Dot_Pixel; XDir_Num++) {
+            for (YDir_Num = 0; YDir_Num <  Dot_Pixel; YDir_Num++) {
+                Paint_SetPixel(Xpoint + XDir_Num - 1, Ypoint + YDir_Num - 1, Color);
+            }
+        }
+    }
+}
+
+/******************************************************************************
+function: Draw a line of arbitrary slope
+parameter:
+    Xstart :Starting Xpoint point coordinates
+    Ystart :Starting Xpoint point coordinates
+    Xend   :End point Xpoint coordinate
+    Yend   :End point Ypoint coordinate
+    Color  :The color of the line segment
+    Line_width : Line width
+    Line_Style: Solid and dotted lines
+******************************************************************************/
+void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,
+                    UWORD Color, DOT_PIXEL Line_width, LINE_STYLE Line_Style)
+{
+    if (Xstart > Paint.Width || Ystart > Paint.Height ||
+        Xend > Paint.Width || Yend > Paint.Height) {
+        Debug("Paint_DrawLine Input exceeds the normal display range\r\n");
+        return;
+    }
+
+    UWORD Xpoint = Xstart;
+    UWORD Ypoint = Ystart;
+    int dx = (int)Xend - (int)Xstart >= 0 ? Xend - Xstart : Xstart - Xend;
+    int dy = (int)Yend - (int)Ystart <= 0 ? Yend - Ystart : Ystart - Yend;
+
+    // Increment direction, 1 is positive, -1 is counter;
+    int XAddway = Xstart < Xend ? 1 : -1;
+    int YAddway = Ystart < Yend ? 1 : -1;
+
+    //Cumulative error
+    int Esp = dx + dy;
+    char Dotted_Len = 0;
+
+    for (;;) {
+        Dotted_Len++;
+        //Painted dotted line, 2 point is really virtual
+        if (Line_Style == LINE_STYLE_DOTTED && Dotted_Len % 3 == 0) {
+            //Debug("LINE_DOTTED\r\n");
+            Paint_DrawPoint(Xpoint, Ypoint, IMAGE_BACKGROUND, Line_width, DOT_STYLE_DFT);
+            Dotted_Len = 0;
+        } else {
+            Paint_DrawPoint(Xpoint, Ypoint, Color, Line_width, DOT_STYLE_DFT);
+        }
+        if (2 * Esp >= dy) {
+            if (Xpoint == Xend)
+                break;
+            Esp += dy;
+            Xpoint += XAddway;
+        }
+        if (2 * Esp <= dx) {
+            if (Ypoint == Yend)
+                break;
+            Esp += dx;
+            Ypoint += YAddway;
+        }
+    }
+}
+
+/******************************************************************************
+function: Draw a rectangle
+parameter:
+    Xstart :Rectangular  Starting Xpoint point coordinates
+    Ystart :Rectangular  Starting Xpoint point coordinates
+    Xend   :Rectangular  End point Xpoint coordinate
+    Yend   :Rectangular  End point Ypoint coordinate
+    Color  :The color of the Rectangular segment
+    Line_width: Line width
+    Draw_Fill : Whether to fill the inside of the rectangle
+******************************************************************************/
+void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,
+                         UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
+{
+    if (Xstart > Paint.Width || Ystart > Paint.Height ||
+        Xend > Paint.Width || Yend > Paint.Height) {
+        Debug("Input exceeds the normal display range\r\n");
+        return;
+    }
+
+    if (Draw_Fill) {
+        UWORD Ypoint;
+        for(Ypoint = Ystart; Ypoint < Yend; Ypoint++) {
+            Paint_DrawLine(Xstart, Ypoint, Xend, Ypoint, Color , Line_width, LINE_STYLE_SOLID);
+        }
+    } else {
+        Paint_DrawLine(Xstart, Ystart, Xend, Ystart, Color, Line_width, LINE_STYLE_SOLID);
+        Paint_DrawLine(Xstart, Ystart, Xstart, Yend, Color, Line_width, LINE_STYLE_SOLID);
+        Paint_DrawLine(Xend, Yend, Xend, Ystart, Color, Line_width, LINE_STYLE_SOLID);
+        Paint_DrawLine(Xend, Yend, Xstart, Yend, Color, Line_width, LINE_STYLE_SOLID);
+    }
+}
+
+/******************************************************************************
+function: Use the 8-point method to draw a circle of the
+            specified size at the specified position->
+parameter:
+    X_Center  :Center X coordinate
+    Y_Center  :Center Y coordinate
+    Radius    :circle Radius
+    Color     :The color of the :circle segment
+    Line_width: Line width
+    Draw_Fill : Whether to fill the inside of the Circle
+******************************************************************************/
+void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius,
+                      UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
+{
+    if (X_Center > Paint.Width || Y_Center >= Paint.Height) {
+        Debug("Paint_DrawCircle Input exceeds the normal display range\r\n");
+        return;
+    }
+
+    //Draw a circle from(0, R) as a starting point
+    int16_t XCurrent, YCurrent;
+    XCurrent = 0;
+    YCurrent = Radius;
+
+    //Cumulative error,judge the next point of the logo
+    int16_t Esp = 3 - (Radius << 1 );
+
+    int16_t sCountY;
+    if (Draw_Fill == DRAW_FILL_FULL) {
+        while (XCurrent <= YCurrent ) { //Realistic circles
+            for (sCountY = XCurrent; sCountY <= YCurrent; sCountY ++ ) {
+                Paint_DrawPoint(X_Center + XCurrent, Y_Center + sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//1
+                Paint_DrawPoint(X_Center - XCurrent, Y_Center + sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//2
+                Paint_DrawPoint(X_Center - sCountY, Y_Center + XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//3
+                Paint_DrawPoint(X_Center - sCountY, Y_Center - XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//4
+                Paint_DrawPoint(X_Center - XCurrent, Y_Center - sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//5
+                Paint_DrawPoint(X_Center + XCurrent, Y_Center - sCountY, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//6
+                Paint_DrawPoint(X_Center + sCountY, Y_Center - XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);//7
+                Paint_DrawPoint(X_Center + sCountY, Y_Center + XCurrent, Color, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+            }
+            if (Esp < 0 )
+                Esp += 4 * XCurrent + 6;
+            else {
+                Esp += 10 + 4 * (XCurrent - YCurrent );
+                YCurrent --;
+            }
+            XCurrent ++;
+        }
+    } else { //Draw a hollow circle
+        while (XCurrent <= YCurrent ) {
+            Paint_DrawPoint(X_Center + XCurrent, Y_Center + YCurrent, Color, Line_width, DOT_STYLE_DFT);//1
+            Paint_DrawPoint(X_Center - XCurrent, Y_Center + YCurrent, Color, Line_width, DOT_STYLE_DFT);//2
+            Paint_DrawPoint(X_Center - YCurrent, Y_Center + XCurrent, Color, Line_width, DOT_STYLE_DFT);//3
+            Paint_DrawPoint(X_Center - YCurrent, Y_Center - XCurrent, Color, Line_width, DOT_STYLE_DFT);//4
+            Paint_DrawPoint(X_Center - XCurrent, Y_Center - YCurrent, Color, Line_width, DOT_STYLE_DFT);//5
+            Paint_DrawPoint(X_Center + XCurrent, Y_Center - YCurrent, Color, Line_width, DOT_STYLE_DFT);//6
+            Paint_DrawPoint(X_Center + YCurrent, Y_Center - XCurrent, Color, Line_width, DOT_STYLE_DFT);//7
+            Paint_DrawPoint(X_Center + YCurrent, Y_Center + XCurrent, Color, Line_width, DOT_STYLE_DFT);//0
+
+            if (Esp < 0 )
+                Esp += 4 * XCurrent + 6;
+            else {
+                Esp += 10 + 4 * (XCurrent - YCurrent );
+                YCurrent --;
+            }
+            XCurrent ++;
+        }
+    }
+}
+
+/******************************************************************************
+function: Show English characters
+parameter:
+    Xpoint           :X coordinate
+    Ypoint           :Y coordinate
+    Acsii_Char       :To display the English characters
+    Font             :A structure pointer that displays a character size
+    Color_Foreground : Select the foreground color
+    Color_Background : Select the background color
+******************************************************************************/
+void Paint_DrawChar(UWORD Xpoint, UWORD Ypoint, const char Acsii_Char,
+                    sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
+{
+    UWORD Page, Column;
+
+    if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
+        Debug("Paint_DrawChar Input exceeds the normal display range\r\n");
+        return;
+    }
+
+    uint32_t Char_Offset = (Acsii_Char - ' ') * Font->Height * (Font->Width / 8 + (Font->Width % 8 ? 1 : 0));
+    const unsigned char *ptr = &Font->table[Char_Offset];
+
+    for (Page = 0; Page < Font->Height; Page ++ ) {
+        for (Column = 0; Column < Font->Width; Column ++ ) {
+
+            //To determine whether the font background color and screen background color is consistent
+            if (FONT_BACKGROUND == Color_Background) { //this process is to speed up the scan
+                if (*ptr & (0x80 >> (Column % 8)))
+                    Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground);
+                    // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+            } else {
+                if (*ptr & (0x80 >> (Column % 8))) {
+                    Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground);
+                    // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                } else {
+                    Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background);
+                    // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                }
+            }
+            //One pixel is 8 bits
+            if (Column % 8 == 7)
+                ptr++;
+        }// Write a line
+        if (Font->Width % 8 != 0)
+            ptr++;
+    }// Write all
+}
+
+/******************************************************************************
+function:	Display the string
+parameter:
+    Xstart           :X coordinate
+    Ystart           :Y coordinate
+    pString          :The first address of the English string to be displayed
+    Font             :A structure pointer that displays a character size
+    Color_Foreground : Select the foreground color
+    Color_Background : Select the background color
+******************************************************************************/
+void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString,
+                         sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
+{
+    UWORD Xpoint = Xstart;
+    UWORD Ypoint = Ystart;
+
+    if (Xstart > Paint.Width || Ystart > Paint.Height) {
+        Debug("Paint_DrawString_EN Input exceeds the normal display range\r\n");
+        return;
+    }
+
+    while (* pString != '\0') {
+        //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character
+        if ((Xpoint + Font->Width ) > Paint.Width ) {
+            Xpoint = Xstart;
+            Ypoint += Font->Height;
+        }
+
+        // If the Y direction is full, reposition to(Xstart, Ystart)
+        if ((Ypoint  + Font->Height ) > Paint.Height ) {
+            Xpoint = Xstart;
+            Ypoint = Ystart;
+        }
+        Paint_DrawChar(Xpoint, Ypoint, * pString, Font, Color_Background, Color_Foreground);
+
+        //The next character of the address
+        pString ++;
+
+        //The next word of the abscissa increases the font of the broadband
+        Xpoint += Font->Width;
+    }
+}
+
+
+/******************************************************************************
+function: Display the string
+parameter:
+    Xstart  :X coordinate
+    Ystart  :Y coordinate
+    pString :The first address of the Chinese string and English
+              string to be displayed
+    Font    :A structure pointer that displays a character size
+    Color_Foreground : Select the foreground color
+    Color_Background : Select the background color
+******************************************************************************/
+void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font,
+                        UWORD Color_Foreground, UWORD Color_Background)
+{
+    const char* p_text = pString;
+    int x = Xstart, y = Ystart;
+    int i, j,Num;
+
+    /* Send the string character by character on EPD */
+    while (*p_text != 0) {
+        if(*p_text <= 0x7F) {  //ASCII < 126
+            for(Num = 0; Num < font->size; Num++) {
+                if(*p_text== font->table[Num].index[0]) {
+                    const char* ptr = &font->table[Num].matrix[0];
+
+                    for (j = 0; j < font->Height; j++) {
+                        for (i = 0; i < font->Width; i++) {
+                            if (FONT_BACKGROUND == Color_Background) { //this process is to speed up the scan
+                                if (*ptr & (0x80 >> (i % 8))) {
+                                    Paint_SetPixel(x + i, y + j, Color_Foreground);
+                                    // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                                }
+                            } else {
+                                if (*ptr & (0x80 >> (i % 8))) {
+                                    Paint_SetPixel(x + i, y + j, Color_Foreground);
+                                    // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                                } else {
+                                    Paint_SetPixel(x + i, y + j, Color_Background);
+                                    // Paint_DrawPoint(x + i, y + j, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                                }
+                            }
+                            if (i % 8 == 7) {
+                                ptr++;
+                            }
+                        }
+                        if (font->Width % 8 != 0) {
+                            ptr++;
+                        }
+                    }
+                    break;
+                }
+            }
+            /* Point on the next character */
+            p_text += 1;
+            /* Decrement the column position by 16 */
+            x += font->ASCII_Width;
+        } else {        //Chinese
+            for(Num = 0; Num < font->size; Num++) {
+                if((*p_text== font->table[Num].index[0]) && (*(p_text+1) == font->table[Num].index[1])) {
+                    const char* ptr = &font->table[Num].matrix[0];
+
+                    for (j = 0; j < font->Height; j++) {
+                        for (i = 0; i < font->Width; i++) {
+                            if (FONT_BACKGROUND == Color_Background) { //this process is to speed up the scan
+                                if (*ptr & (0x80 >> (i % 8))) {
+                                    Paint_SetPixel(x + i, y + j, Color_Foreground);
+                                    // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                                }
+                            } else {
+                                if (*ptr & (0x80 >> (i % 8))) {
+                                    Paint_SetPixel(x + i, y + j, Color_Foreground);
+                                    // Paint_DrawPoint(x + i, y + j, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                                } else {
+                                    Paint_SetPixel(x + i, y + j, Color_Background);
+                                    // Paint_DrawPoint(x + i, y + j, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
+                                }
+                            }
+                            if (i % 8 == 7) {
+                                ptr++;
+                            }
+                        }
+                        if (font->Width % 8 != 0) {
+                            ptr++;
+                        }
+                    }
+                    break;
+                }
+            }
+            /* Point on the next character */
+            p_text += 2;
+            /* Decrement the column position by 16 */
+            x += font->Width;
+        }
+    }
+}
+
+/******************************************************************************
+function:	Display nummber
+parameter:
+    Xstart           :X coordinate
+    Ystart           : Y coordinate
+    Nummber          : The number displayed
+    Font             :A structure pointer that displays a character size
+    Color_Foreground : Select the foreground color
+    Color_Background : Select the background color
+******************************************************************************/
+#define  ARRAY_LEN 255
+void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber,
+                   sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
+{
+
+    int16_t Num_Bit = 0, Str_Bit = 0;
+    uint8_t Str_Array[ARRAY_LEN] = {0}, Num_Array[ARRAY_LEN] = {0};
+    uint8_t *pStr = Str_Array;
+
+    if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
+        Debug("Paint_DisNum Input exceeds the normal display range\r\n");
+        return;
+    }
+
+    //Converts a number to a string
+    do {
+        Num_Array[Num_Bit] = Nummber % 10 + '0';
+        Num_Bit++;
+        Nummber /= 10;
+    } while(Nummber);
+
+
+    //The string is inverted
+    while (Num_Bit > 0) {
+        Str_Array[Str_Bit] = Num_Array[Num_Bit - 1];
+        Str_Bit ++;
+        Num_Bit --;
+    }
+
+    //show
+    Paint_DrawString_EN(Xpoint, Ypoint, (const char*)pStr, Font, Color_Background, Color_Foreground);
+}
+
+/******************************************************************************
+function:	Display nummber (Able to display decimals)
+parameter:
+    Xstart           :X coordinate
+    Ystart           : Y coordinate
+    Nummber          : The number displayed
+    Font             :A structure pointer that displays a character size
+    Digit            : Fractional width
+    Color_Foreground : Select the foreground color
+    Color_Background : Select the background color
+******************************************************************************/
+void Paint_DrawNumDecimals(UWORD Xpoint, UWORD Ypoint, double Nummber,
+                    sFONT* Font, UWORD Digit, UWORD Color_Foreground, UWORD Color_Background)
+{
+    int16_t Num_Bit = 0, Str_Bit = 0;
+    uint8_t Str_Array[ARRAY_LEN] = {0}, Num_Array[ARRAY_LEN] = {0};
+    uint8_t *pStr = Str_Array;
+	int temp = Nummber;
+	float decimals;
+	uint8_t i;
+    if (Xpoint > Paint.Width || Ypoint > Paint.Height) {
+        Debug("Paint_DisNum Input exceeds the normal display range\r\n");
+        return;
+    }
+
+	if(Digit > 0) {
+		decimals = Nummber - temp;
+		for(i=Digit; i > 0; i--) {
+			decimals*=10;
+		}
+		temp = decimals;
+		//Converts a number to a string
+		for(i=Digit; i>0; i--) {
+			Num_Array[Num_Bit] = temp % 10 + '0';
+			Num_Bit++;
+			temp /= 10;
+		}
+		Num_Array[Num_Bit] = '.';
+		Num_Bit++;
+	}
+
+	temp = Nummber;
+    //Converts a number to a string
+    do {
+        Num_Array[Num_Bit] = temp % 10 + '0';
+        Num_Bit++;
+        temp /= 10;
+    } while(temp);
+
+    //The string is inverted
+    while (Num_Bit > 0) {
+        Str_Array[Str_Bit] = Num_Array[Num_Bit - 1];
+        Str_Bit ++;
+        Num_Bit --;
+    }
+
+    //show
+    Paint_DrawString_EN(Xpoint, Ypoint, (const char*)pStr, Font, Color_Background, Color_Foreground);
+}
+
+/******************************************************************************
+function:	Display time
+parameter:
+    Xstart           :X coordinate
+    Ystart           : Y coordinate
+    pTime            : Time-related structures
+    Font             :A structure pointer that displays a character size
+    Color_Foreground : Select the foreground color
+    Color_Background : Select the background color
+******************************************************************************/
+void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font,
+                    UWORD Color_Foreground, UWORD Color_Background)
+{
+    uint8_t value[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+    UWORD Dx = Font->Width;
+
+    //Write data into the cache
+    Paint_DrawChar(Xstart                           , Ystart, value[pTime->Hour / 10], Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx                      , Ystart, value[pTime->Hour % 10], Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx  + Dx / 4 + Dx / 2   , Ystart, ':'                    , Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx * 2 + Dx / 2         , Ystart, value[pTime->Min / 10] , Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx * 3 + Dx / 2         , Ystart, value[pTime->Min % 10] , Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx * 4 + Dx / 2 - Dx / 4, Ystart, ':'                    , Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx * 5                  , Ystart, value[pTime->Sec / 10] , Font, Color_Background, Color_Foreground);
+    Paint_DrawChar(Xstart + Dx * 6                  , Ystart, value[pTime->Sec % 10] , Font, Color_Background, Color_Foreground);
+}
+
+/******************************************************************************
+function:	Display monochrome bitmap
+parameter:
+    image_buffer :A picture data converted to a bitmap
+info:
+    Use a computer to convert the image into a corresponding array,
+    and then embed the array directly into Imagedata.cpp as a .c file.
+******************************************************************************/
+void Paint_DrawBitMap(const unsigned char* image_buffer)
+{
+    UWORD x, y;
+    UDOUBLE Addr = 0;
+
+    for (y = 0; y < Paint.HeightByte; y++) {
+        for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+            Addr = x + y * Paint.WidthByte;
+            Paint.Image[Addr] = (unsigned char)image_buffer[Addr];
+        }
+    }
+}
+
+/******************************************************************************
+function:	paste monochrome bitmap to a frame buff
+parameter:
+    image_buffer :A picture data converted to a bitmap
+    xStart: The starting x coordinate
+    yStart: The starting y coordinate
+    imageWidth: Original image width
+    imageHeight: Original image height
+    flipColor: Whether the color is reversed
+info:
+    Use this function to paste image data into a buffer
+******************************************************************************/
+void Paint_DrawBitMap_Paste(const unsigned char* image_buffer, UWORD xStart, UWORD yStart, UWORD imageWidth, UWORD imageHeight, UBYTE flipColor)
+{
+    UBYTE color, srcImage;
+    UWORD x, y;
+    UWORD width = (imageWidth%8==0 ? imageWidth/8 : imageWidth/8+1);
+
+    for (y = 0; y < imageHeight; y++) {
+        for (x = 0; x < imageWidth; x++) {
+            srcImage = image_buffer[y*width + x/8];
+            if(flipColor)
+                color = (((srcImage<<(x%8) & 0x80) == 0) ? 1 : 0);
+            else
+                color = (((srcImage<<(x%8) & 0x80) == 0) ? 0 : 1);
+            Paint_SetPixel(x+xStart, y+yStart, color);
+        }
+    }
+}
+
+///******************************************************************************
+//function:	SDisplay half of monochrome bitmap
+//parameter:
+//	Region : 1 Upper half
+//					 2 Lower half
+//info:
+//******************************************************************************/
+//void Paint_DrawBitMap_Half(const unsigned char* image_buffer, UBYTE Region)
+//{
+//    UWORD x, y;
+//    UDOUBLE Addr = 0;
+//
+//		if(Region == 1){
+//			for (y = 0; y < Paint.HeightByte; y++) {
+//					for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+//							Addr = x + y * Paint.WidthByte;
+//							Paint.Image[Addr] = (unsigned char)image_buffer[Addr];
+//					}
+//			}
+//		}else{
+//			for (y = 0; y < Paint.HeightByte; y++) {
+//					for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+//							Addr = x + y * Paint.WidthByte ;
+//							Paint.Image[Addr] = \
+//							(unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte];
+//					}
+//			}
+//		}
+//}
+
+///******************************************************************************
+//function:	SDisplay half of monochrome bitmap
+//parameter:
+//	Region : 1 Upper half
+//					 2 Lower half
+//info:
+//******************************************************************************/
+//void Paint_DrawBitMap_OneQuarter(const unsigned char* image_buffer, UBYTE Region)
+//{
+//    UWORD x, y;
+//    UDOUBLE Addr = 0;
+//
+//		if(Region == 1){
+//			for (y = 0; y < Paint.HeightByte; y++) {
+//					for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+//							Addr = x + y * Paint.WidthByte;
+//							Paint.Image[Addr] = (unsigned char)image_buffer[Addr];
+//					}
+//			}
+//		}else if(Region == 2){
+//			for (y = 0; y < Paint.HeightByte; y++) {
+//					for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+//							Addr = x + y * Paint.WidthByte ;
+//							Paint.Image[Addr] = \
+//							(unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte];
+//					}
+//			}
+//		}else if(Region == 3){
+//			for (y = 0; y < Paint.HeightByte; y++) {
+//					for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+//							Addr = x + y * Paint.WidthByte ;
+//							Paint.Image[Addr] = \
+//							(unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*2];
+//					}
+//			}
+//		}else if(Region == 4){
+//			for (y = 0; y < Paint.HeightByte; y++) {
+//					for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+//							Addr = x + y * Paint.WidthByte ;
+//							Paint.Image[Addr] = \
+//							(unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*3];
+//					}
+//			}
+//		}
+//}
+
+void Paint_DrawBitMap_Block(const unsigned char* image_buffer, UBYTE Region)
+{
+    UWORD x, y;
+    UDOUBLE Addr = 0;
+		for (y = 0; y < Paint.HeightByte; y++) {
+				for (x = 0; x < Paint.WidthByte; x++) {//8 pixel =  1 byte
+						Addr = x + y * Paint.WidthByte ;
+						Paint.Image[Addr] = \
+						(unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*(Region - 1)];
+				}
+		}
+}

+ 51 - 31
Core/Src/main.c

@@ -21,6 +21,7 @@
 
 /* Private includes ----------------------------------------------------------*/
 /* USER CODE BEGIN Includes */
+#include "epd_test.h"
 
 /* USER CODE END Includes */
 
@@ -31,6 +32,7 @@
 
 /* Private define ------------------------------------------------------------*/
 /* USER CODE BEGIN PD */
+
 /* USER CODE END PD */
 
 /* Private macro -------------------------------------------------------------*/
@@ -41,7 +43,7 @@
 /* Private variables ---------------------------------------------------------*/
 SPI_HandleTypeDef hspi1;
 
-UART_HandleTypeDef huart2;
+UART_HandleTypeDef huart1;
 
 /* USER CODE BEGIN PV */
 
@@ -50,8 +52,8 @@ UART_HandleTypeDef huart2;
 /* Private function prototypes -----------------------------------------------*/
 void SystemClock_Config(void);
 static void MX_GPIO_Init(void);
-static void MX_USART2_UART_Init(void);
 static void MX_SPI1_Init(void);
+static void MX_USART1_UART_Init(void);
 /* USER CODE BEGIN PFP */
 
 /* USER CODE END PFP */
@@ -67,6 +69,7 @@ static void MX_SPI1_Init(void);
   */
 int main(void)
 {
+
   /* USER CODE BEGIN 1 */
 
   /* USER CODE END 1 */
@@ -89,10 +92,12 @@ int main(void)
 
   /* Initialize all configured peripherals */
   MX_GPIO_Init();
-  MX_USART2_UART_Init();
   MX_SPI1_Init();
+  MX_USART1_UART_Init();
   /* USER CODE BEGIN 2 */
 
+  EPD_test();
+
   /* USER CODE END 2 */
 
   /* Infinite loop */
@@ -102,6 +107,9 @@ int main(void)
     /* USER CODE END WHILE */
 
     /* USER CODE BEGIN 3 */
+	  HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
+
+	  HAL_Delay(1000);
   }
   /* USER CODE END 3 */
 }
@@ -129,6 +137,7 @@ void SystemClock_Config(void)
   {
     Error_Handler();
   }
+
   /** Initializes the CPU, AHB and APB buses clocks
   */
   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
@@ -167,7 +176,7 @@ static void MX_SPI1_Init(void)
   hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
   hspi1.Init.NSS = SPI_NSS_SOFT;
-  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
+  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
@@ -183,35 +192,35 @@ static void MX_SPI1_Init(void)
 }
 
 /**
-  * @brief USART2 Initialization Function
+  * @brief USART1 Initialization Function
   * @param None
   * @retval None
   */
-static void MX_USART2_UART_Init(void)
+static void MX_USART1_UART_Init(void)
 {
 
-  /* USER CODE BEGIN USART2_Init 0 */
+  /* USER CODE BEGIN USART1_Init 0 */
 
-  /* USER CODE END USART2_Init 0 */
+  /* USER CODE END USART1_Init 0 */
 
-  /* USER CODE BEGIN USART2_Init 1 */
+  /* USER CODE BEGIN USART1_Init 1 */
 
-  /* USER CODE END USART2_Init 1 */
-  huart2.Instance = USART2;
-  huart2.Init.BaudRate = 9600;
-  huart2.Init.WordLength = UART_WORDLENGTH_8B;
-  huart2.Init.StopBits = UART_STOPBITS_1;
-  huart2.Init.Parity = UART_PARITY_NONE;
-  huart2.Init.Mode = UART_MODE_TX_RX;
-  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
-  if (HAL_UART_Init(&huart2) != HAL_OK)
+  /* 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 USART2_Init 2 */
+  /* USER CODE BEGIN USART1_Init 2 */
 
-  /* USER CODE END USART2_Init 2 */
+  /* USER CODE END USART1_Init 2 */
 
 }
 
@@ -223,32 +232,45 @@ static void MX_USART2_UART_Init(void)
 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_GPIOD_CLK_ENABLE();
   __HAL_RCC_GPIOA_CLK_ENABLE();
+  __HAL_RCC_GPIOB_CLK_ENABLE();
 
   /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_RESET);
+  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
 
   /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(GPIOA, RST_Pin|PWR_Pin, GPIO_PIN_RESET);
+  HAL_GPIO_WritePin(GPIOA, RST_Pin|DC_Pin|CS_Pin, GPIO_PIN_SET);
 
-  /*Configure GPIO pin : DC_Pin */
-  GPIO_InitStruct.Pin = DC_Pin;
+  /*Configure GPIO pin : LED_Pin */
+  GPIO_InitStruct.Pin = LED_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(DC_GPIO_Port, &GPIO_InitStruct);
+  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
 
-  /*Configure GPIO pins : RST_Pin PWR_Pin */
-  GPIO_InitStruct.Pin = RST_Pin|PWR_Pin;
+  /*Configure GPIO pins : RST_Pin DC_Pin CS_Pin */
+  GPIO_InitStruct.Pin = RST_Pin|DC_Pin|CS_Pin;
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
+  /*Configure GPIO pin : BUSY_Pin */
+  GPIO_InitStruct.Pin = BUSY_Pin;
+  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(BUSY_GPIO_Port, &GPIO_InitStruct);
+
+  /* USER CODE BEGIN MX_GPIO_Init_2 */
+
+  /* USER CODE END MX_GPIO_Init_2 */
 }
 
 /* USER CODE BEGIN 4 */
@@ -269,8 +291,7 @@ void Error_Handler(void)
   }
   /* USER CODE END Error_Handler_Debug */
 }
-
-#ifdef  USE_FULL_ASSERT
+#ifdef USE_FULL_ASSERT
 /**
   * @brief  Reports the name of the source file and the source line number
   *         where the assert_param error has occurred.
@@ -286,4 +307,3 @@ void assert_failed(uint8_t *file, uint32_t line)
   /* USER CODE END 6 */
 }
 #endif /* USE_FULL_ASSERT */
-

+ 52 - 57
Core/Src/stm32f1xx_hal_msp.c

@@ -62,6 +62,7 @@
   */
 void HAL_MspInit(void)
 {
+
   /* USER CODE BEGIN MspInit 0 */
 
   /* USER CODE END MspInit 0 */
@@ -81,26 +82,25 @@ void HAL_MspInit(void)
 }
 
 /**
-* @brief SPI MSP Initialization
-* This function configures the hardware resources used in this example
-* @param hspi: SPI handle pointer
-* @retval None
-*/
+  * @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 BEGIN SPI1_MspInit 0 */
 
-  /* USER CODE END 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 = GPIO_PIN_5|GPIO_PIN_7;
@@ -108,112 +108,108 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
-    GPIO_InitStruct.Pin = GPIO_PIN_6;
-    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
-    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    /* USER CODE BEGIN SPI1_MspInit 1 */
 
-  /* USER CODE BEGIN SPI1_MspInit 1 */
+    /* USER CODE END SPI1_MspInit 1 */
 
-  /* USER CODE END SPI1_MspInit 1 */
   }
 
 }
 
 /**
-* @brief SPI MSP De-Initialization
-* This function freeze the hardware resources used in this example
-* @param hspi: SPI handle pointer
-* @retval None
-*/
+  * @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 BEGIN SPI1_MspDeInit 0 */
 
-  /* USER CODE END 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, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_7);
 
-  /* USER CODE BEGIN SPI1_MspDeInit 1 */
+    /* USER CODE BEGIN SPI1_MspDeInit 1 */
 
-  /* USER CODE END SPI1_MspDeInit 1 */
+    /* USER CODE END SPI1_MspDeInit 1 */
   }
 
 }
 
 /**
-* @brief UART MSP Initialization
-* This function configures the hardware resources used in this example
-* @param huart: UART handle pointer
-* @retval None
-*/
+  * @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==USART2)
+  if(huart->Instance==USART1)
   {
-  /* USER CODE BEGIN USART2_MspInit 0 */
+    /* USER CODE BEGIN USART1_MspInit 0 */
 
-  /* USER CODE END USART2_MspInit 0 */
+    /* USER CODE END USART1_MspInit 0 */
     /* Peripheral clock enable */
-    __HAL_RCC_USART2_CLK_ENABLE();
+    __HAL_RCC_USART1_CLK_ENABLE();
 
     __HAL_RCC_GPIOA_CLK_ENABLE();
-    /**USART2 GPIO Configuration
-    PA2     ------> USART2_TX
-    PA3     ------> USART2_RX
+    /**USART1 GPIO Configuration
+    PA9     ------> USART1_TX
+    PA10     ------> USART1_RX
     */
-    GPIO_InitStruct.Pin = GPIO_PIN_2;
+    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_3;
+    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 USART2_MspInit 1 */
+    /* USER CODE BEGIN USART1_MspInit 1 */
+
+    /* USER CODE END USART1_MspInit 1 */
 
-  /* USER CODE END USART2_MspInit 1 */
   }
 
 }
 
 /**
-* @brief UART MSP De-Initialization
-* This function freeze the hardware resources used in this example
-* @param huart: UART handle pointer
-* @retval None
-*/
+  * @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==USART2)
+  if(huart->Instance==USART1)
   {
-  /* USER CODE BEGIN USART2_MspDeInit 0 */
+    /* USER CODE BEGIN USART1_MspDeInit 0 */
 
-  /* USER CODE END USART2_MspDeInit 0 */
+    /* USER CODE END USART1_MspDeInit 0 */
     /* Peripheral clock disable */
-    __HAL_RCC_USART2_CLK_DISABLE();
+    __HAL_RCC_USART1_CLK_DISABLE();
 
-    /**USART2 GPIO Configuration
-    PA2     ------> USART2_TX
-    PA3     ------> USART2_RX
+    /**USART1 GPIO Configuration
+    PA9     ------> USART1_TX
+    PA10     ------> USART1_RX
     */
-    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
 
-  /* USER CODE BEGIN USART2_MspDeInit 1 */
+    /* USER CODE BEGIN USART1_MspDeInit 1 */
 
-  /* USER CODE END USART2_MspDeInit 1 */
+    /* USER CODE END USART1_MspDeInit 1 */
   }
 
 }
@@ -221,4 +217,3 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
-

+ 0 - 1
Core/Src/stm32f1xx_it.c

@@ -87,4 +87,3 @@ void SysTick_Handler(void)
 /* USER CODE BEGIN 1 */
 
 /* USER CODE END 1 */
-

+ 59 - 38
Core/Src/syscalls.c

@@ -10,7 +10,7 @@
  ******************************************************************************
  * @attention
  *
- * Copyright (c) 2021 STMicroelectronics.
+ * Copyright (c) 2020-2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
@@ -47,109 +47,130 @@ void initialise_monitor_handles()
 
 int _getpid(void)
 {
-	return 1;
+  return 1;
 }
 
 int _kill(int pid, int sig)
 {
-	errno = EINVAL;
-	return -1;
+  (void)pid;
+  (void)sig;
+  errno = EINVAL;
+  return -1;
 }
 
 void _exit (int status)
 {
-	_kill(status, -1);
-	while (1) {}		/* Make sure we hang here */
+  _kill(status, -1);
+  while (1) {}    /* Make sure we hang here */
 }
 
 __attribute__((weak)) int _read(int file, char *ptr, int len)
 {
-	int DataIdx;
+  (void)file;
+  int DataIdx;
 
-	for (DataIdx = 0; DataIdx < len; DataIdx++)
-	{
-		*ptr++ = __io_getchar();
-	}
+  for (DataIdx = 0; DataIdx < len; DataIdx++)
+  {
+    *ptr++ = __io_getchar();
+  }
 
-return len;
+  return len;
 }
 
 __attribute__((weak)) int _write(int file, char *ptr, int len)
 {
-	int DataIdx;
+  (void)file;
+  int DataIdx;
 
-	for (DataIdx = 0; DataIdx < len; DataIdx++)
-	{
-		__io_putchar(*ptr++);
-	}
-	return len;
+  for (DataIdx = 0; DataIdx < len; DataIdx++)
+  {
+    __io_putchar(*ptr++);
+  }
+  return len;
 }
 
 int _close(int file)
 {
-	return -1;
+  (void)file;
+  return -1;
 }
 
 
 int _fstat(int file, struct stat *st)
 {
-	st->st_mode = S_IFCHR;
-	return 0;
+  (void)file;
+  st->st_mode = S_IFCHR;
+  return 0;
 }
 
 int _isatty(int file)
 {
-	return 1;
+  (void)file;
+  return 1;
 }
 
 int _lseek(int file, int ptr, int dir)
 {
-	return 0;
+  (void)file;
+  (void)ptr;
+  (void)dir;
+  return 0;
 }
 
 int _open(char *path, int flags, ...)
 {
-	/* Pretend like we always fail */
-	return -1;
+  (void)path;
+  (void)flags;
+  /* Pretend like we always fail */
+  return -1;
 }
 
 int _wait(int *status)
 {
-	errno = ECHILD;
-	return -1;
+  (void)status;
+  errno = ECHILD;
+  return -1;
 }
 
 int _unlink(char *name)
 {
-	errno = ENOENT;
-	return -1;
+  (void)name;
+  errno = ENOENT;
+  return -1;
 }
 
 int _times(struct tms *buf)
 {
-	return -1;
+  (void)buf;
+  return -1;
 }
 
 int _stat(char *file, struct stat *st)
 {
-	st->st_mode = S_IFCHR;
-	return 0;
+  (void)file;
+  st->st_mode = S_IFCHR;
+  return 0;
 }
 
 int _link(char *old, char *new)
 {
-	errno = EMLINK;
-	return -1;
+  (void)old;
+  (void)new;
+  errno = EMLINK;
+  return -1;
 }
 
 int _fork(void)
 {
-	errno = EAGAIN;
-	return -1;
+  errno = EAGAIN;
+  return -1;
 }
 
 int _execve(char *name, char **argv, char **env)
 {
-	errno = ENOMEM;
-	return -1;
+  (void)name;
+  (void)argv;
+  (void)env;
+  errno = ENOMEM;
+  return -1;
 }

+ 1 - 1
Core/Src/sysmem.c

@@ -10,7 +10,7 @@
  ******************************************************************************
  * @attention
  *
- * Copyright (c) 2021 STMicroelectronics.
+ * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file

+ 7 - 9
Core/Src/system_stm32f1xx.c

@@ -33,13 +33,12 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
-  * All rights reserved.</center></h2>
+  * Copyright (c) 2017-2021 STMicroelectronics.
+  * All rights reserved.
   *
-  * This software component is licensed by ST under BSD 3-Clause license,
-  * the "License"; You may not use this file except in compliance with the
-  * License. You may obtain a copy of the License at:
-  *                        opensource.org/licenses/BSD-3-Clause
+  * 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.
   *
   ******************************************************************************
   */
@@ -139,7 +138,7 @@
                is no need to call the 2 first functions listed above, since SystemCoreClock
                variable is updated automatically.
   */
-uint32_t SystemCoreClock = 16000000;
+uint32_t SystemCoreClock = 8000000;
 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};
 
@@ -404,5 +403,4 @@ void SystemInit_ExtMemCtl(void)
   
 /**
   * @}
-  */    
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+  */

+ 8 - 9
Core/Startup/startup_stm32f103c8tx.s

@@ -15,13 +15,12 @@
   ******************************************************************************
   * @attention
   *
-  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
-  * All rights reserved.</center></h2>
+  * Copyright (c) 2017-2021 STMicroelectronics.
+  * All rights reserved.
   *
-  * This software component is licensed by ST under BSD 3-Clause license,
-  * the "License"; You may not use this file except in compliance with the
-  * License. You may obtain a copy of the License at:
-  *                        opensource.org/licenses/BSD-3-Clause
+  * 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.
   *
   ******************************************************************************
   */
@@ -61,6 +60,9 @@ defined in linker script */
   .type Reset_Handler, %function
 Reset_Handler:
 
+/* Call the clock system initialization function.*/
+    bl  SystemInit
+
 /* Copy the data segment initializers from flash to SRAM */
   ldr r0, =_sdata
   ldr r1, =_edata
@@ -92,8 +94,6 @@ LoopFillZerobss:
   cmp r2, r4
   bcc FillZerobss
 
-/* Call the clock system intitialization function.*/
-    bl  SystemInit
 /* Call static constructors */
     bl __libc_init_array
 /* Call the application's entry point.*/
@@ -361,5 +361,4 @@ g_pfnVectors:
   .weak USBWakeUp_IRQHandler
   .thumb_set USBWakeUp_IRQHandler,Default_Handler
 
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 

+ 12 - 9
STM32F103C8TX_FLASH.ld

@@ -6,8 +6,8 @@
 ** @author      : Auto-generated by STM32CubeIDE
 **
 ** @brief       : Linker script for STM32F103C8Tx Device from STM32F1 series
-**                      64Kbytes FLASH
-**                      20Kbytes RAM
+**                      64KBytes FLASH
+**                      20KBytes RAM
 **
 **                Set heap size, stack size and stack location according
 **                to application requirements.
@@ -38,8 +38,8 @@ ENTRY(Reset_Handler)
 /* Highest address of the user mode stack */
 _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
 
-_Min_Heap_Size = 0x200 ; /* required amount of heap */
-_Min_Stack_Size = 0x400 ; /* required amount of stack */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
 
 /* Memories definition */
 MEMORY
@@ -51,6 +51,7 @@ MEMORY
 /* Sections */
 SECTIONS
 {
+
   /* The startup code into "FLASH" Rom type memory */
   .isr_vector :
   {
@@ -85,13 +86,15 @@ SECTIONS
     . = ALIGN(4);
   } >FLASH
 
-  .ARM.extab   : {
+  .ARM.extab (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+  {
     . = ALIGN(4);
     *(.ARM.extab* .gnu.linkonce.armextab.*)
     . = ALIGN(4);
   } >FLASH
 
-  .ARM : {
+  .ARM (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
+  {
     . = ALIGN(4);
     __exidx_start = .;
     *(.ARM.exidx*)
@@ -99,7 +102,7 @@ SECTIONS
     . = ALIGN(4);
   } >FLASH
 
-  .preinit_array     :
+  .preinit_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
   {
     . = ALIGN(4);
     PROVIDE_HIDDEN (__preinit_array_start = .);
@@ -108,7 +111,7 @@ SECTIONS
     . = ALIGN(4);
   } >FLASH
 
-  .init_array :
+  .init_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
   {
     . = ALIGN(4);
     PROVIDE_HIDDEN (__init_array_start = .);
@@ -118,7 +121,7 @@ SECTIONS
     . = ALIGN(4);
   } >FLASH
 
-  .fini_array :
+  .fini_array (READONLY) : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */
   {
     . = ALIGN(4);
     PROVIDE_HIDDEN (__fini_array_start = .);