上传初始版本
This commit is contained in:
		
							
								
								
									
										330
									
								
								gd32v_lcd/src/fatfs/00history.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										330
									
								
								gd32v_lcd/src/fatfs/00history.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,330 @@
 | 
			
		||||
----------------------------------------------------------------------------
 | 
			
		||||
  Revision history of FatFs module
 | 
			
		||||
----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
R0.00 (February 26, 2006)
 | 
			
		||||
 | 
			
		||||
  Prototype.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.01 (April 29, 2006)
 | 
			
		||||
 | 
			
		||||
  The first release.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.02 (June 01, 2006)
 | 
			
		||||
 | 
			
		||||
  Added FAT12 support.
 | 
			
		||||
  Removed unbuffered mode.
 | 
			
		||||
  Fixed a problem on small (<32M) partition.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.02a (June 10, 2006)
 | 
			
		||||
 | 
			
		||||
  Added a configuration option (_FS_MINIMUM).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.03 (September 22, 2006)
 | 
			
		||||
 | 
			
		||||
  Added f_rename().
 | 
			
		||||
  Changed option _FS_MINIMUM to _FS_MINIMIZE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.03a (December 11, 2006)
 | 
			
		||||
 | 
			
		||||
  Improved cluster scan algorithm to write files fast.
 | 
			
		||||
  Fixed f_mkdir() creates incorrect directory on FAT32.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.04 (February 04, 2007)
 | 
			
		||||
 | 
			
		||||
  Added f_mkfs().
 | 
			
		||||
  Supported multiple drive system.
 | 
			
		||||
  Changed some interfaces for multiple drive system.
 | 
			
		||||
  Changed f_mountdrv() to f_mount().
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.04a (April 01, 2007)
 | 
			
		||||
 | 
			
		||||
  Supported multiple partitions on a physical drive.
 | 
			
		||||
  Added a capability of extending file size to f_lseek().
 | 
			
		||||
  Added minimization level 3.
 | 
			
		||||
  Fixed an endian sensitive code in f_mkfs().
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.04b (May 05, 2007)
 | 
			
		||||
 | 
			
		||||
  Added a configuration option _USE_NTFLAG.
 | 
			
		||||
  Added FSINFO support.
 | 
			
		||||
  Fixed DBCS name can result FR_INVALID_NAME.
 | 
			
		||||
  Fixed short seek (<= csize) collapses the file object.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.05 (August 25, 2007)
 | 
			
		||||
 | 
			
		||||
  Changed arguments of f_read(), f_write() and f_mkfs().
 | 
			
		||||
  Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
 | 
			
		||||
  Fixed f_mkdir() on FAT32 creates incorrect directory.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.05a (February 03, 2008)
 | 
			
		||||
 | 
			
		||||
  Added f_truncate() and f_utime().
 | 
			
		||||
  Fixed off by one error at FAT sub-type determination.
 | 
			
		||||
  Fixed btr in f_read() can be mistruncated.
 | 
			
		||||
  Fixed cached sector is not flushed when create and close without write.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.06 (April 01, 2008)
 | 
			
		||||
 | 
			
		||||
  Added fputc(), fputs(), fprintf() and fgets().
 | 
			
		||||
  Improved performance of f_lseek() on moving to the same or following cluster.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.07 (April 01, 2009)
 | 
			
		||||
 | 
			
		||||
  Merged Tiny-FatFs as a configuration option. (_FS_TINY)
 | 
			
		||||
  Added long file name feature. (_USE_LFN)
 | 
			
		||||
  Added multiple code page feature. (_CODE_PAGE)
 | 
			
		||||
  Added re-entrancy for multitask operation. (_FS_REENTRANT)
 | 
			
		||||
  Added auto cluster size selection to f_mkfs().
 | 
			
		||||
  Added rewind option to f_readdir().
 | 
			
		||||
  Changed result code of critical errors.
 | 
			
		||||
  Renamed string functions to avoid name collision.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.07a (April 14, 2009)
 | 
			
		||||
 | 
			
		||||
  Septemberarated out OS dependent code on reentrant cfg.
 | 
			
		||||
  Added multiple sector size feature.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.07c (June 21, 2009)
 | 
			
		||||
 | 
			
		||||
  Fixed f_unlink() can return FR_OK on error.
 | 
			
		||||
  Fixed wrong cache control in f_lseek().
 | 
			
		||||
  Added relative path feature.
 | 
			
		||||
  Added f_chdir() and f_chdrive().
 | 
			
		||||
  Added proper case conversion to extended character.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.07e (November 03, 2009)
 | 
			
		||||
 | 
			
		||||
  Septemberarated out configuration options from ff.h to ffconf.h.
 | 
			
		||||
  Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
 | 
			
		||||
  Fixed name matching error on the 13 character boundary.
 | 
			
		||||
  Added a configuration option, _LFN_UNICODE.
 | 
			
		||||
  Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.08 (May 15, 2010)
 | 
			
		||||
 | 
			
		||||
  Added a memory configuration option. (_USE_LFN = 3)
 | 
			
		||||
  Added file lock feature. (_FS_SHARE)
 | 
			
		||||
  Added fast seek feature. (_USE_FASTSEEK)
 | 
			
		||||
  Changed some types on the API, XCHAR->TCHAR.
 | 
			
		||||
  Changed .fname in the FILINFO structure on Unicode cfg.
 | 
			
		||||
  String functions support UTF-8 encoding files on Unicode cfg.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.08a (August 16, 2010)
 | 
			
		||||
 | 
			
		||||
  Added f_getcwd(). (_FS_RPATH = 2)
 | 
			
		||||
  Added sector erase feature. (_USE_ERASE)
 | 
			
		||||
  Moved file lock semaphore table from fs object to the bss.
 | 
			
		||||
  Fixed f_mkfs() creates wrong FAT32 volume.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.08b (January 15, 2011)
 | 
			
		||||
 | 
			
		||||
  Fast seek feature is also applied to f_read() and f_write().
 | 
			
		||||
  f_lseek() reports required table size on creating CLMP.
 | 
			
		||||
  Extended format syntax of f_printf().
 | 
			
		||||
  Ignores duplicated directory separators in given path name.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.09 (September 06, 2011)
 | 
			
		||||
 | 
			
		||||
  f_mkfs() supports multiple partition to complete the multiple partition feature.
 | 
			
		||||
  Added f_fdisk().
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.09a (August 27, 2012)
 | 
			
		||||
 | 
			
		||||
  Changed f_open() and f_opendir() reject null object pointer to avoid crash.
 | 
			
		||||
  Changed option name _FS_SHARE to _FS_LOCK.
 | 
			
		||||
  Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.09b (January 24, 2013)
 | 
			
		||||
 | 
			
		||||
  Added f_setlabel() and f_getlabel().
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.10 (October 02, 2013)
 | 
			
		||||
 | 
			
		||||
  Added selection of character encoding on the file. (_STRF_ENCODE)
 | 
			
		||||
  Added f_closedir().
 | 
			
		||||
  Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
 | 
			
		||||
  Added forced mount feature with changes of f_mount().
 | 
			
		||||
  Improved behavior of volume auto detection.
 | 
			
		||||
  Improved write throughput of f_puts() and f_printf().
 | 
			
		||||
  Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
 | 
			
		||||
  Fixed f_write() can be truncated when the file size is close to 4GB.
 | 
			
		||||
  Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.10a (January 15, 2014)
 | 
			
		||||
 | 
			
		||||
  Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
 | 
			
		||||
  Added a configuration option of minimum sector size. (_MIN_SS)
 | 
			
		||||
  2nd argument of f_rename() can have a drive number and it will be ignored.
 | 
			
		||||
  Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
 | 
			
		||||
  Fixed f_close() invalidates the file object without volume lock.
 | 
			
		||||
  Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
 | 
			
		||||
  Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.10b (May 19, 2014)
 | 
			
		||||
 | 
			
		||||
  Fixed a hard error in the disk I/O layer can collapse the directory entry.
 | 
			
		||||
  Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.10c (November 09, 2014)
 | 
			
		||||
 | 
			
		||||
  Added a configuration option for the platforms without RTC. (_FS_NORTC)
 | 
			
		||||
  Changed option name _USE_ERASE to _USE_TRIM.
 | 
			
		||||
  Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
 | 
			
		||||
  Fixed a potential problem of FAT access that can appear on disk error.
 | 
			
		||||
  Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.11 (February 09, 2015)
 | 
			
		||||
 | 
			
		||||
  Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
 | 
			
		||||
  Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
 | 
			
		||||
  Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.11a (September 05, 2015)
 | 
			
		||||
 | 
			
		||||
  Fixed wrong media change can lead a deadlock at thread-safe configuration.
 | 
			
		||||
  Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
 | 
			
		||||
  Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
 | 
			
		||||
  Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
 | 
			
		||||
  Fixed errors in the case conversion teble of Unicode (cc*.c).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.12 (April 12, 2016)
 | 
			
		||||
 | 
			
		||||
  Added support for exFAT file system. (_FS_EXFAT)
 | 
			
		||||
  Added f_expand(). (_USE_EXPAND)
 | 
			
		||||
  Changed some members in FINFO structure and behavior of f_readdir().
 | 
			
		||||
  Added an option _USE_CHMOD.
 | 
			
		||||
  Removed an option _WORD_ACCESS.
 | 
			
		||||
  Fixed errors in the case conversion table of Unicode (cc*.c).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.12a (July 10, 2016)
 | 
			
		||||
 | 
			
		||||
  Added support for creating exFAT volume with some changes of f_mkfs().
 | 
			
		||||
  Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
 | 
			
		||||
  f_forward() is available regardless of _FS_TINY.
 | 
			
		||||
  Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
 | 
			
		||||
  Fixed wrong memory read in create_name(). (appeared at R0.12)
 | 
			
		||||
  Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.12b (September 04, 2016)
 | 
			
		||||
 | 
			
		||||
  Made f_rename() be able to rename objects with the same name but case.
 | 
			
		||||
  Fixed an error in the case conversion teble of code page 866. (ff.c)
 | 
			
		||||
  Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
 | 
			
		||||
  Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
 | 
			
		||||
  Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
 | 
			
		||||
  Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
 | 
			
		||||
  Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
 | 
			
		||||
  Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.12c (March 04, 2017)
 | 
			
		||||
 | 
			
		||||
  Improved write throughput at the fragmented file on the exFAT volume.
 | 
			
		||||
  Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
 | 
			
		||||
  Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
 | 
			
		||||
  Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.13 (May 21, 2017)
 | 
			
		||||
 | 
			
		||||
  Changed heading character of configuration keywords "_" to "FF_".
 | 
			
		||||
  Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
 | 
			
		||||
  Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
 | 
			
		||||
  Improved cluster allocation time on stretch a deep buried cluster chain.
 | 
			
		||||
  Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
 | 
			
		||||
  Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
 | 
			
		||||
  Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
 | 
			
		||||
  Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
 | 
			
		||||
  Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.13a (October 14, 2017)
 | 
			
		||||
 | 
			
		||||
  Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
 | 
			
		||||
  Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
 | 
			
		||||
  Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
 | 
			
		||||
  Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
 | 
			
		||||
  Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
 | 
			
		||||
  Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.13b (April 07, 2018)
 | 
			
		||||
 | 
			
		||||
  Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
 | 
			
		||||
  Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
 | 
			
		||||
  Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
 | 
			
		||||
  Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
R0.13c (October 14, 2018)
 | 
			
		||||
  Supported stdint.h for C99 and later. (integer.h was included in ff.h)
 | 
			
		||||
  Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
 | 
			
		||||
  Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
 | 
			
		||||
  Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								gd32v_lcd/src/fatfs/00readme.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								gd32v_lcd/src/fatfs/00readme.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
FatFs Module Source Files R0.13c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FILES
 | 
			
		||||
 | 
			
		||||
  00readme.txt   This file.
 | 
			
		||||
  00history.txt  Revision history.
 | 
			
		||||
  ff.c           FatFs module.
 | 
			
		||||
  ffconf.h       Configuration file of FatFs module.
 | 
			
		||||
  ff.h           Common include file for FatFs and application module.
 | 
			
		||||
  diskio.h       Common include file for FatFs and disk I/O module.
 | 
			
		||||
  diskio.c       An example of glue function to attach existing disk I/O module to FatFs.
 | 
			
		||||
  ffunicode.c    Optional Unicode utility functions.
 | 
			
		||||
  ffsystem.c     An example of optional O/S related functions.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Low level disk I/O module is not included in this archive because the FatFs
 | 
			
		||||
  module is only a generic file system layer and it does not depend on any specific
 | 
			
		||||
  storage device. You need to provide a low level disk I/O module written to
 | 
			
		||||
  control the storage device that attached to the target system.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6554
									
								
								gd32v_lcd/src/fatfs/ff.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6554
									
								
								gd32v_lcd/src/fatfs/ff.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										170
									
								
								gd32v_lcd/src/fatfs/ffsystem.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								gd32v_lcd/src/fatfs/ffsystem.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Sample Code of OS Dependent Functions for FatFs                        */
 | 
			
		||||
/* (C)ChaN, 2018                                                          */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "./fatfs/ff.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if FF_USE_LFN == 3	/* Dynamic memory allocation */
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Allocate a memory block                                                */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void* ff_memalloc (	/* Returns pointer to the allocated memory block (null if not enough core) */
 | 
			
		||||
	UINT msize		/* Number of bytes to allocate */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return malloc(msize);	/* Allocate a new memory block with POSIX API */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Free a memory block                                                    */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void ff_memfree (
 | 
			
		||||
	void* mblock	/* Pointer to the memory block to free (nothing to do if null) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	free(mblock);	/* Free the memory block with POSIX API */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if FF_FS_REENTRANT	/* Mutal exclusion */
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Create a Synchronization Object                                        */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* This function is called in f_mount() function to create a new
 | 
			
		||||
/  synchronization object for the volume, such as semaphore and mutex.
 | 
			
		||||
/  When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
//const osMutexDef_t Mutex[FF_VOLUMES];	/* Table of CMSIS-RTOS mutex */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int ff_cre_syncobj (	/* 1:Function succeeded, 0:Could not create the sync object */
 | 
			
		||||
	BYTE vol,			/* Corresponding volume (logical drive number) */
 | 
			
		||||
	FF_SYNC_t* sobj		/* Pointer to return the created sync object */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	/* Win32 */
 | 
			
		||||
	*sobj = CreateMutex(NULL, FALSE, NULL);
 | 
			
		||||
	return (int)(*sobj != INVALID_HANDLE_VALUE);
 | 
			
		||||
 | 
			
		||||
	/* uITRON */
 | 
			
		||||
//	T_CSEM csem = {TA_TPRI,1,1};
 | 
			
		||||
//	*sobj = acre_sem(&csem);
 | 
			
		||||
//	return (int)(*sobj > 0);
 | 
			
		||||
 | 
			
		||||
	/* uC/OS-II */
 | 
			
		||||
//	OS_ERR err;
 | 
			
		||||
//	*sobj = OSMutexCreate(0, &err);
 | 
			
		||||
//	return (int)(err == OS_NO_ERR);
 | 
			
		||||
 | 
			
		||||
	/* FreeRTOS */
 | 
			
		||||
//	*sobj = xSemaphoreCreateMutex();
 | 
			
		||||
//	return (int)(*sobj != NULL);
 | 
			
		||||
 | 
			
		||||
	/* CMSIS-RTOS */
 | 
			
		||||
//	*sobj = osMutexCreate(&Mutex[vol]);
 | 
			
		||||
//	return (int)(*sobj != NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Delete a Synchronization Object                                        */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* This function is called in f_mount() function to delete a synchronization
 | 
			
		||||
/  object that created with ff_cre_syncobj() function. When a 0 is returned,
 | 
			
		||||
/  the f_mount() function fails with FR_INT_ERR.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
int ff_del_syncobj (	/* 1:Function succeeded, 0:Could not delete due to an error */
 | 
			
		||||
	FF_SYNC_t sobj		/* Sync object tied to the logical drive to be deleted */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	/* Win32 */
 | 
			
		||||
	return (int)CloseHandle(sobj);
 | 
			
		||||
 | 
			
		||||
	/* uITRON */
 | 
			
		||||
//	return (int)(del_sem(sobj) == E_OK);
 | 
			
		||||
 | 
			
		||||
	/* uC/OS-II */
 | 
			
		||||
//	OS_ERR err;
 | 
			
		||||
//	OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
 | 
			
		||||
//	return (int)(err == OS_NO_ERR);
 | 
			
		||||
 | 
			
		||||
	/* FreeRTOS */
 | 
			
		||||
//  vSemaphoreDelete(sobj);
 | 
			
		||||
//	return 1;
 | 
			
		||||
 | 
			
		||||
	/* CMSIS-RTOS */
 | 
			
		||||
//	return (int)(osMutexDelete(sobj) == osOK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Request Grant to Access the Volume                                     */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* This function is called on entering file functions to lock the volume.
 | 
			
		||||
/  When a 0 is returned, the file function fails with FR_TIMEOUT.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
int ff_req_grant (	/* 1:Got a grant to access the volume, 0:Could not get a grant */
 | 
			
		||||
	FF_SYNC_t sobj	/* Sync object to wait */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	/* Win32 */
 | 
			
		||||
	return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
 | 
			
		||||
 | 
			
		||||
	/* uITRON */
 | 
			
		||||
//	return (int)(wai_sem(sobj) == E_OK);
 | 
			
		||||
 | 
			
		||||
	/* uC/OS-II */
 | 
			
		||||
//	OS_ERR err;
 | 
			
		||||
//	OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
 | 
			
		||||
//	return (int)(err == OS_NO_ERR);
 | 
			
		||||
 | 
			
		||||
	/* FreeRTOS */
 | 
			
		||||
//	return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
 | 
			
		||||
 | 
			
		||||
	/* CMSIS-RTOS */
 | 
			
		||||
//	return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* Release Grant to Access the Volume                                     */
 | 
			
		||||
/*------------------------------------------------------------------------*/
 | 
			
		||||
/* This function is called on leaving file functions to unlock the volume.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void ff_rel_grant (
 | 
			
		||||
	FF_SYNC_t sobj	/* Sync object to be signaled */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	/* Win32 */
 | 
			
		||||
	ReleaseMutex(sobj);
 | 
			
		||||
 | 
			
		||||
	/* uITRON */
 | 
			
		||||
//	sig_sem(sobj);
 | 
			
		||||
 | 
			
		||||
	/* uC/OS-II */
 | 
			
		||||
//	OSMutexPost(sobj);
 | 
			
		||||
 | 
			
		||||
	/* FreeRTOS */
 | 
			
		||||
//	xSemaphoreGive(sobj);
 | 
			
		||||
 | 
			
		||||
	/* CMSIS-RTOS */
 | 
			
		||||
//	osMutexRelease(sobj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										15597
									
								
								gd32v_lcd/src/fatfs/ffunicode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15597
									
								
								gd32v_lcd/src/fatfs/ffunicode.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										568
									
								
								gd32v_lcd/src/fatfs/tf_card.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										568
									
								
								gd32v_lcd/src/fatfs/tf_card.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,568 @@
 | 
			
		||||
#include "fatfs/tf_card.h"
 | 
			
		||||
 | 
			
		||||
#define FCLK_SLOW() { SPI_CTL0(SPI1) = (SPI_CTL0(SPI1) & ~0x38) | 0x28; }	/* Set SCLK = PCLK2 / 64 */
 | 
			
		||||
#define FCLK_FAST() { SPI_CTL0(SPI1) = (SPI_CTL0(SPI1) & ~0x38) | 0x00; }	/* Set SCLK = PCLK2 / 2 */
 | 
			
		||||
 | 
			
		||||
// #define FCLK_SLOW()
 | 
			
		||||
// #define FCLK_FAST()
 | 
			
		||||
 | 
			
		||||
#define CS_HIGH() PB_OUT(12,1)
 | 
			
		||||
#define CS_LOW() PB_OUT(12,0)
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
   Module Private Functions
 | 
			
		||||
 | 
			
		||||
---------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* MMC/SD command */
 | 
			
		||||
#define CMD0	(0)			/* GO_IDLE_STATE */
 | 
			
		||||
#define CMD1	(1)			/* SEND_OP_COND (MMC) */
 | 
			
		||||
#define	ACMD41	(0x80+41)	/* SEND_OP_COND (SDC) */
 | 
			
		||||
#define CMD8	(8)			/* SEND_IF_COND */
 | 
			
		||||
#define CMD9	(9)			/* SEND_CSD */
 | 
			
		||||
#define CMD10	(10)		/* SEND_CID */
 | 
			
		||||
#define CMD12	(12)		/* STOP_TRANSMISSION */
 | 
			
		||||
#define ACMD13	(0x80+13)	/* SD_STATUS (SDC) */
 | 
			
		||||
#define CMD16	(16)		/* SET_BLOCKLEN */
 | 
			
		||||
#define CMD17	(17)		/* READ_SINGLE_BLOCK */
 | 
			
		||||
#define CMD18	(18)		/* READ_MULTIPLE_BLOCK */
 | 
			
		||||
#define CMD23	(23)		/* SET_BLOCK_COUNT (MMC) */
 | 
			
		||||
#define	ACMD23	(0x80+23)	/* SET_WR_BLK_ERASE_COUNT (SDC) */
 | 
			
		||||
#define CMD24	(24)		/* WRITE_BLOCK */
 | 
			
		||||
#define CMD25	(25)		/* WRITE_MULTIPLE_BLOCK */
 | 
			
		||||
#define CMD32	(32)		/* ERASE_ER_BLK_START */
 | 
			
		||||
#define CMD33	(33)		/* ERASE_ER_BLK_END */
 | 
			
		||||
#define CMD38	(38)		/* ERASE */
 | 
			
		||||
#define CMD55	(55)		/* APP_CMD */
 | 
			
		||||
#define CMD58	(58)		/* READ_OCR */
 | 
			
		||||
 | 
			
		||||
static volatile
 | 
			
		||||
DSTATUS Stat = STA_NOINIT;	/* Physical drive status */
 | 
			
		||||
 | 
			
		||||
// static volatile
 | 
			
		||||
// UINT Timer1, Timer2;	/* 1kHz decrement timer stopped at zero (disk_timerproc()) */
 | 
			
		||||
static volatile
 | 
			
		||||
UINT delay_timer1, delay_timer2;        	/* 1kHz decrement timer stopped at zero (disk_timerproc()) */
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
BYTE CardType;			/* Card type flags */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* SPI controls (Platform dependent)                                     */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Initialize MMC interface */
 | 
			
		||||
static
 | 
			
		||||
void init_spi(void)
 | 
			
		||||
{
 | 
			
		||||
    spi_parameter_struct spi_init_struct;
 | 
			
		||||
 | 
			
		||||
    rcu_periph_clock_enable(RCU_GPIOB);
 | 
			
		||||
    rcu_periph_clock_enable(RCU_SPI1);
 | 
			
		||||
 | 
			
		||||
    /* SPI1_SCK(PB13), SPI1_MISO(PB14) and SPI1_MOSI(PB15) GPIO pin configuration */
 | 
			
		||||
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15);
 | 
			
		||||
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
 | 
			
		||||
    /* SPI1_CS(PB12) GPIO pin configuration */
 | 
			
		||||
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
 | 
			
		||||
 | 
			
		||||
    /* chip _select invalid*/
 | 
			
		||||
    CS_HIGH();
 | 
			
		||||
 | 
			
		||||
    /* SPI1 parameter config */
 | 
			
		||||
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
 | 
			
		||||
    spi_init_struct.device_mode          = SPI_MASTER;
 | 
			
		||||
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
 | 
			
		||||
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
 | 
			
		||||
    spi_init_struct.nss                  = SPI_NSS_SOFT;
 | 
			
		||||
    spi_init_struct.prescale             = SPI_PSC_32;
 | 
			
		||||
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
 | 
			
		||||
    spi_init(SPI1, &spi_init_struct);
 | 
			
		||||
 | 
			
		||||
    /* set crc polynomial */
 | 
			
		||||
    spi_crc_polynomial_set(SPI1,7);
 | 
			
		||||
    /* enable SPI1 */
 | 
			
		||||
    spi_enable(SPI1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Exchange a byte */
 | 
			
		||||
static
 | 
			
		||||
BYTE xchg_spi (
 | 
			
		||||
	BYTE dat	/* Data to send */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_TBE));
 | 
			
		||||
        spi_i2s_data_transmit(SPI1, dat);
 | 
			
		||||
	while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE));
 | 
			
		||||
        return(spi_i2s_data_receive(SPI1));     /* Return received byte */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Receive multiple byte */
 | 
			
		||||
static
 | 
			
		||||
void rcvr_spi_multi (
 | 
			
		||||
	BYTE *buff,		/* Pointer to data buffer */
 | 
			
		||||
	UINT btr		/* Number of bytes to receive (even number) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	// WORD d;
 | 
			
		||||
 | 
			
		||||
    // SPI_CTL0(SPI1) = (SPI_CTL0(SPI1) & ~0x800) | 0x800;  /* Put SPI into 16-bit mode */
 | 
			
		||||
 | 
			
		||||
	// spi_i2s_data_transmit(SPI1, 0xFFFF);		/* Start the first SPI transaction */
 | 
			
		||||
	// btr -= 2;
 | 
			
		||||
	// do {					/* Receive the data block into buffer */
 | 
			
		||||
	// 	while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE));	/* Wait for end of the SPI transaction */
 | 
			
		||||
	// 	d = spi_i2s_data_receive(SPI1);						/* Get received word */
 | 
			
		||||
	// 	spi_i2s_data_transmit(SPI1, 0xFFFF);					/* Start next transaction */
 | 
			
		||||
	// 	buff[1] = d; buff[0] = d >> 8; 		/* Store received data */
 | 
			
		||||
	// 	buff += 2;
 | 
			
		||||
	// } while (btr -= 2);
 | 
			
		||||
	// while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_RBNE));		/* Wait for end of the SPI transaction */
 | 
			
		||||
	// d = spi_i2s_data_receive(SPI1);							/* Get last word received */
 | 
			
		||||
	// buff[1] = d; buff[0] = d >> 8;			/* Store it */
 | 
			
		||||
 | 
			
		||||
	// SPI_CTL0(SPI1) = (SPI_CTL0(SPI1) & ~0x800) | 0x00;	/* Put SPI into 8-bit mode */
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		*buff = xchg_spi(0xff);
 | 
			
		||||
		buff++;
 | 
			
		||||
	} while (btr--);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Wait for card ready                                                   */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
int wait_ready (	/* 1:Ready, 0:Timeout */
 | 
			
		||||
	UINT wt			/* Timeout [ms] */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	BYTE d;
 | 
			
		||||
 | 
			
		||||
	// Timer2 = wt;
 | 
			
		||||
    delay_timer2 = wt;
 | 
			
		||||
	do {
 | 
			
		||||
		d = xchg_spi(0xFF);
 | 
			
		||||
		/* This loop takes a time. Insert rot_rdq() here for multitask envilonment. */
 | 
			
		||||
	} while (d != 0xFF && delay_timer2);	/* Wait for card goes ready or timeout */
 | 
			
		||||
 | 
			
		||||
	return (d == 0xFF) ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Deselect card and release SPI                                         */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void deselect (void)
 | 
			
		||||
{
 | 
			
		||||
	CS_HIGH();		/* Set CS# high */
 | 
			
		||||
	xchg_spi(0xFF);	/* Dummy clock (force DO hi-z for multiple slave SPI) */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Select card and wait for ready                                        */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
int _select (void)	/* 1:OK, 0:Timeout */
 | 
			
		||||
{
 | 
			
		||||
	CS_LOW();		/* Set CS# low */
 | 
			
		||||
	xchg_spi(0xFF);	/* Dummy clock (force DO enabled) */
 | 
			
		||||
	if (wait_ready(500)) return 1;	/* Wait for card ready */
 | 
			
		||||
 | 
			
		||||
	deselect();
 | 
			
		||||
	return 0;	/* Timeout */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Receive a data packet from the MMC                                    */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
int rcvr_datablock (	/* 1:OK, 0:Error */
 | 
			
		||||
	BYTE *buff,			/* Data buffer */
 | 
			
		||||
	UINT btr			/* Data block length (byte) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	BYTE token;
 | 
			
		||||
 | 
			
		||||
	delay_timer1 = 200;
 | 
			
		||||
	do {							/* Wait for DataStart token in timeout of 200ms */
 | 
			
		||||
		token = xchg_spi(0xFF);
 | 
			
		||||
		/* This loop will take a time. Insert rot_rdq() here for multitask envilonment. */
 | 
			
		||||
	} while ((token == 0xFF) && delay_timer1);
 | 
			
		||||
	if(token != 0xFE) return 0;		/* Function fails if invalid DataStart token or timeout */
 | 
			
		||||
 | 
			
		||||
	rcvr_spi_multi(buff, btr);		/* Store trailing data to the buffer */
 | 
			
		||||
	xchg_spi(0xFF); xchg_spi(0xFF);			/* Discard CRC */
 | 
			
		||||
 | 
			
		||||
	return 1;						/* Function succeeded */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Send a command packet to the MMC                                      */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
BYTE send_cmd (		/* Return value: R1 resp (bit7==1:Failed to send) */
 | 
			
		||||
	BYTE cmd,		/* Command index */
 | 
			
		||||
	DWORD arg		/* Argument */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	BYTE n, res;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (cmd & 0x80) {	/* Send a CMD55 prior to ACMD<n> */
 | 
			
		||||
		cmd &= 0x7F;
 | 
			
		||||
		res = send_cmd(CMD55, 0);
 | 
			
		||||
		if (res > 1) return res;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Select the card and wait for ready except to stop multiple block read */
 | 
			
		||||
	if (cmd != CMD12) {
 | 
			
		||||
		deselect();
 | 
			
		||||
		if (!_select()) return 0xFF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Send command packet */
 | 
			
		||||
	xchg_spi(0x40 | cmd);				/* Start + command index */
 | 
			
		||||
	xchg_spi((BYTE)(arg >> 24));		/* Argument[31..24] */
 | 
			
		||||
	xchg_spi((BYTE)(arg >> 16));		/* Argument[23..16] */
 | 
			
		||||
	xchg_spi((BYTE)(arg >> 8));			/* Argument[15..8] */
 | 
			
		||||
	xchg_spi((BYTE)arg);				/* Argument[7..0] */
 | 
			
		||||
	n = 0x01;							/* Dummy CRC + Stop */
 | 
			
		||||
	if (cmd == CMD0) n = 0x95;			/* Valid CRC for CMD0(0) */
 | 
			
		||||
	if (cmd == CMD8) n = 0x87;			/* Valid CRC for CMD8(0x1AA) */
 | 
			
		||||
	xchg_spi(n);
 | 
			
		||||
 | 
			
		||||
	/* Receive command resp */
 | 
			
		||||
	if (cmd == CMD12) xchg_spi(0xFF);	/* Diacard following one byte when CMD12 */
 | 
			
		||||
	n = 10;								/* Wait for response (10 bytes max) */
 | 
			
		||||
	do {
 | 
			
		||||
		res = xchg_spi(0xFF);
 | 
			
		||||
	} while ((res & 0x80) && --n);
 | 
			
		||||
 | 
			
		||||
	return res;							/* Return received response */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void init_timer2(void)
 | 
			
		||||
{
 | 
			
		||||
    timer_parameter_struct timer_initpara;
 | 
			
		||||
 | 
			
		||||
    rcu_periph_clock_enable(RCU_TIMER2);
 | 
			
		||||
    timer_deinit(TIMER2);
 | 
			
		||||
    /* ((1+TIM_Prescaler )/时钟)*(1+TIM_Period ) 
 | 
			
		||||
        (108000/108000000)*(1000)=1ms
 | 
			
		||||
    */
 | 
			
		||||
    timer_initpara.period = (1000 - 1);
 | 
			
		||||
    timer_initpara.prescaler         = (108 - 1);
 | 
			
		||||
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
 | 
			
		||||
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
 | 
			
		||||
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
 | 
			
		||||
    timer_initpara.repetitioncounter = 0;
 | 
			
		||||
    timer_init(TIMER2, &timer_initpara);
 | 
			
		||||
 | 
			
		||||
    timer_update_event_enable(TIMER2);
 | 
			
		||||
    timer_interrupt_enable(TIMER2,TIMER_INT_UP);
 | 
			
		||||
    timer_flag_clear(TIMER2, TIMER_FLAG_UP);
 | 
			
		||||
    timer_update_source_config(TIMER2, TIMER_UPDATE_SRC_GLOBAL);
 | 
			
		||||
 | 
			
		||||
    /* TIMER2 counter enable */
 | 
			
		||||
    timer_enable(TIMER2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
    \brief      time base IRQ
 | 
			
		||||
    \param[in]  none
 | 
			
		||||
    \param[out] none
 | 
			
		||||
    \retval     none
 | 
			
		||||
*/
 | 
			
		||||
static
 | 
			
		||||
void tfcard_timer_irq (void)
 | 
			
		||||
{
 | 
			
		||||
    if (RESET != timer_flag_get(TIMER2, TIMER_FLAG_UP)){
 | 
			
		||||
        timer_flag_clear(TIMER2, TIMER_FLAG_UP);
 | 
			
		||||
 | 
			
		||||
        if (delay_timer1 > 0x00U){
 | 
			
		||||
            delay_timer1--;
 | 
			
		||||
        }
 | 
			
		||||
        if (delay_timer2 > 0x00U){
 | 
			
		||||
            delay_timer2--;
 | 
			
		||||
        }
 | 
			
		||||
        // else {
 | 
			
		||||
        //     timer_disable(TIMER2);
 | 
			
		||||
        // }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
    \brief      this function handles Timer0 updata interrupt request.
 | 
			
		||||
    \param[in]  none
 | 
			
		||||
    \param[out] none
 | 
			
		||||
    \retval     none
 | 
			
		||||
*/
 | 
			
		||||
void TIMER2_IRQHandler(void)
 | 
			
		||||
{
 | 
			
		||||
    // tfcard_timer_irq();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
   Public Functions
 | 
			
		||||
 | 
			
		||||
---------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Initialize disk drive                                                 */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
DSTATUS disk_initialize (
 | 
			
		||||
	BYTE drv		/* Physical drive number (0) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	BYTE n, cmd, ty, ocr[4];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (drv) return STA_NOINIT;			/* Supports only drive 0 */
 | 
			
		||||
	init_spi();							/* Initialize SPI */
 | 
			
		||||
    delay_1ms(10);
 | 
			
		||||
    init_timer2();
 | 
			
		||||
 | 
			
		||||
	if (Stat & STA_NODISK) return Stat;	/* Is card existing in the soket? */
 | 
			
		||||
 | 
			
		||||
	FCLK_SLOW();
 | 
			
		||||
	CS_LOW();
 | 
			
		||||
	for (n = 10; n; n--) xchg_spi(0xFF);	/* Send 80 dummy clocks */
 | 
			
		||||
 | 
			
		||||
	ty = 0;
 | 
			
		||||
	if (send_cmd(CMD0, 0) == 1) {			/* Put the card SPI/Idle state */
 | 
			
		||||
		delay_timer1 = 1000;						/* Initialization timeout = 1 sec */
 | 
			
		||||
		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2? */
 | 
			
		||||
			for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);	/* Get 32 bit return value of R7 resp */
 | 
			
		||||
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				/* Is the card supports vcc of 2.7-3.6V? */
 | 
			
		||||
				while (delay_timer1 && send_cmd(ACMD41, 1UL << 30)) ;	/* Wait for end of initialization with ACMD41(HCS) */
 | 
			
		||||
				if (delay_timer1 && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
 | 
			
		||||
					for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
 | 
			
		||||
					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* Card id SDv2 */
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {	/* Not SDv2 card */
 | 
			
		||||
			if (send_cmd(ACMD41, 0) <= 1) 	{	/* SDv1 or MMC? */
 | 
			
		||||
				ty = CT_SD1; cmd = ACMD41;	/* SDv1 (ACMD41(0)) */
 | 
			
		||||
			} else {
 | 
			
		||||
				ty = CT_MMC; cmd = CMD1;	/* MMCv3 (CMD1(0)) */
 | 
			
		||||
			}
 | 
			
		||||
			while (delay_timer1 && send_cmd(cmd, 0)) ;		/* Wait for end of initialization */
 | 
			
		||||
			if (!delay_timer1 || send_cmd(CMD16, 512) != 0)	/* Set block length: 512 */
 | 
			
		||||
				ty = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	CardType = ty;	/* Card type */
 | 
			
		||||
	deselect();
 | 
			
		||||
 | 
			
		||||
	if (ty) {			/* OK */
 | 
			
		||||
		FCLK_FAST();			/* Set fast clock */
 | 
			
		||||
		Stat &= ~STA_NOINIT;	/* Clear STA_NOINIT flag */
 | 
			
		||||
	} else {			/* Failed */
 | 
			
		||||
		Stat = STA_NOINIT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Stat;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Get disk status                                                       */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
DSTATUS disk_status (
 | 
			
		||||
	BYTE drv		/* Physical drive number (0) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	if (drv) return STA_NOINIT;		/* Supports only drive 0 */
 | 
			
		||||
 | 
			
		||||
	return Stat;	/* Return disk status */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Read sector(s)                                                        */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
DRESULT disk_read (
 | 
			
		||||
	BYTE drv,		/* Physical drive number (0) */
 | 
			
		||||
	BYTE *buff,		/* Pointer to the data buffer to store read data */
 | 
			
		||||
	DWORD sector,	/* Start sector number (LBA) */
 | 
			
		||||
	UINT count		/* Number of sectors to read (1..128) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	if (drv || !count) return RES_PARERR;		/* Check parameter */
 | 
			
		||||
	if (Stat & STA_NOINIT) return RES_NOTRDY;	/* Check if drive is ready */
 | 
			
		||||
 | 
			
		||||
	if (!(CardType & CT_BLOCK)) sector *= 512;	/* LBA ot BA conversion (byte addressing cards) */
 | 
			
		||||
 | 
			
		||||
	if (count == 1) {	/* Single sector read */
 | 
			
		||||
		if ((send_cmd(CMD17, sector) == 0)	/* READ_SINGLE_BLOCK */
 | 
			
		||||
			&& rcvr_datablock(buff, 512)) {
 | 
			
		||||
			count = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {				/* Multiple sector read */
 | 
			
		||||
		if (send_cmd(CMD18, sector) == 0) {	/* READ_MULTIPLE_BLOCK */
 | 
			
		||||
			do {
 | 
			
		||||
				if (!rcvr_datablock(buff, 512)) break;
 | 
			
		||||
				buff += 512;
 | 
			
		||||
			} while (--count);
 | 
			
		||||
			send_cmd(CMD12, 0);				/* STOP_TRANSMISSION */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	deselect();
 | 
			
		||||
 | 
			
		||||
	return count ? RES_ERROR : RES_OK;	/* Return result */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Write sector(s)                                                       */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if FF_FS_READONLY == 0
 | 
			
		||||
DRESULT disk_write (
 | 
			
		||||
	BYTE drv,			/* Physical drive number (0) */
 | 
			
		||||
	const BYTE *buff,	/* Ponter to the data to write */
 | 
			
		||||
	DWORD sector,		/* Start sector number (LBA) */
 | 
			
		||||
	UINT count			/* Number of sectors to write (1..128) */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	if (drv || !count) return RES_PARERR;		/* Check parameter */
 | 
			
		||||
	if (Stat & STA_NOINIT) return RES_NOTRDY;	/* Check drive status */
 | 
			
		||||
	if (Stat & STA_PROTECT) return RES_WRPRT;	/* Check write protect */
 | 
			
		||||
 | 
			
		||||
	if (!(CardType & CT_BLOCK)) sector *= 512;	/* LBA ==> BA conversion (byte addressing cards) */
 | 
			
		||||
 | 
			
		||||
	if (count == 1) {	/* Single sector write */
 | 
			
		||||
		if ((send_cmd(CMD24, sector) == 0)	/* WRITE_BLOCK */
 | 
			
		||||
			&& xmit_datablock(buff, 0xFE)) {
 | 
			
		||||
			count = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {				/* Multiple sector write */
 | 
			
		||||
		if (CardType & CT_SDC) send_cmd(ACMD23, count);	/* Predefine number of sectors */
 | 
			
		||||
		if (send_cmd(CMD25, sector) == 0) {	/* WRITE_MULTIPLE_BLOCK */
 | 
			
		||||
			do {
 | 
			
		||||
				if (!xmit_datablock(buff, 0xFC)) break;
 | 
			
		||||
				buff += 512;
 | 
			
		||||
			} while (--count);
 | 
			
		||||
			if (!xmit_datablock(0, 0xFD)) count = 1;	/* STOP_TRAN token */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	deselect();
 | 
			
		||||
 | 
			
		||||
	return count ? RES_ERROR : RES_OK;	/* Return result */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
/* Miscellaneous drive controls other than data read/write               */
 | 
			
		||||
/*-----------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
DRESULT disk_ioctl (
 | 
			
		||||
	BYTE drv,		/* Physical drive number (0) */
 | 
			
		||||
	BYTE cmd,		/* Control command code */
 | 
			
		||||
	void *buff		/* Pointer to the conrtol data */
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	DRESULT res;
 | 
			
		||||
	BYTE n, csd[16];
 | 
			
		||||
	DWORD *dp, st, ed, csize;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (drv) return RES_PARERR;					/* Check parameter */
 | 
			
		||||
	if (Stat & STA_NOINIT) return RES_NOTRDY;	/* Check if drive is ready */
 | 
			
		||||
 | 
			
		||||
	res = RES_ERROR;
 | 
			
		||||
 | 
			
		||||
	switch (cmd) {
 | 
			
		||||
	case CTRL_SYNC :		/* Wait for end of internal write process of the drive */
 | 
			
		||||
		if (_select()) res = RES_OK;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case GET_SECTOR_COUNT :	/* Get drive capacity in unit of sector (DWORD) */
 | 
			
		||||
		if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
 | 
			
		||||
			if ((csd[0] >> 6) == 1) {	/* SDC ver 2.00 */
 | 
			
		||||
				csize = csd[9] + ((WORD)csd[8] << 8) + ((DWORD)(csd[7] & 63) << 16) + 1;
 | 
			
		||||
				*(DWORD*)buff = csize << 10;
 | 
			
		||||
			} else {					/* SDC ver 1.XX or MMC ver 3 */
 | 
			
		||||
				n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
 | 
			
		||||
				csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
 | 
			
		||||
				*(DWORD*)buff = csize << (n - 9);
 | 
			
		||||
			}
 | 
			
		||||
			res = RES_OK;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case GET_BLOCK_SIZE :	/* Get erase block size in unit of sector (DWORD) */
 | 
			
		||||
		if (CardType & CT_SD2) {	/* SDC ver 2.00 */
 | 
			
		||||
			if (send_cmd(ACMD13, 0) == 0) {	/* Read SD status */
 | 
			
		||||
				xchg_spi(0xFF);
 | 
			
		||||
				if (rcvr_datablock(csd, 16)) {				/* Read partial block */
 | 
			
		||||
					for (n = 64 - 16; n; n--) xchg_spi(0xFF);	/* Purge trailing data */
 | 
			
		||||
					*(DWORD*)buff = 16UL << (csd[10] >> 4);
 | 
			
		||||
					res = RES_OK;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {					/* SDC ver 1.XX or MMC */
 | 
			
		||||
			if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {	/* Read CSD */
 | 
			
		||||
				if (CardType & CT_SD1) {	/* SDC ver 1.XX */
 | 
			
		||||
					*(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
 | 
			
		||||
				} else {					/* MMC */
 | 
			
		||||
					*(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
 | 
			
		||||
				}
 | 
			
		||||
				res = RES_OK;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case CTRL_TRIM :	/* Erase a block of sectors (used when _USE_ERASE == 1) */
 | 
			
		||||
		if (!(CardType & CT_SDC)) break;				/* Check if the card is SDC */
 | 
			
		||||
		if (disk_ioctl(drv, MMC_GET_CSD, csd)) break;	/* Get CSD */
 | 
			
		||||
		if (!(csd[0] >> 6) && !(csd[10] & 0x40)) break;	/* Check if sector erase can be applied to the card */
 | 
			
		||||
		dp = buff; st = dp[0]; ed = dp[1];				/* Load sector block */
 | 
			
		||||
		if (!(CardType & CT_BLOCK)) {
 | 
			
		||||
			st *= 512; ed *= 512;
 | 
			
		||||
		}
 | 
			
		||||
		if (send_cmd(CMD32, st) == 0 && send_cmd(CMD33, ed) == 0 && send_cmd(CMD38, 0) == 0 && wait_ready(30000)) {	/* Erase sector block */
 | 
			
		||||
			res = RES_OK;	/* FatFs does not check result of this command */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		res = RES_PARERR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	deselect();
 | 
			
		||||
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										673
									
								
								gd32v_lcd/src/lcd/lcd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										673
									
								
								gd32v_lcd/src/lcd/lcd.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,673 @@
 | 
			
		||||
#include "lcd/lcd.h"
 | 
			
		||||
#include "lcd/oledfont.h"
 | 
			
		||||
#include "lcd/bmp.h"
 | 
			
		||||
u16 BACK_COLOR;   //背景色
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD串行数据写入函数
 | 
			
		||||
      入口数据:dat  要写入的串行数据
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_Writ_Bus(u8 dat) 
 | 
			
		||||
{
 | 
			
		||||
#if SPI0_CFG == 1
 | 
			
		||||
	OLED_CS_Clr();
 | 
			
		||||
 | 
			
		||||
	while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE));
 | 
			
		||||
        spi_i2s_data_transmit(SPI0, dat);
 | 
			
		||||
	while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE));
 | 
			
		||||
        spi_i2s_data_receive(SPI0);
 | 
			
		||||
 | 
			
		||||
	OLED_CS_Set();
 | 
			
		||||
#elif SPI0_CFG == 2
 | 
			
		||||
	spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
 | 
			
		||||
#else
 | 
			
		||||
	u8 i;
 | 
			
		||||
	OLED_CS_Clr();
 | 
			
		||||
	for(i=0;i<8;i++)
 | 
			
		||||
	{			  
 | 
			
		||||
		OLED_SCLK_Clr();
 | 
			
		||||
		if(dat&0x80)
 | 
			
		||||
		   OLED_SDIN_Set();
 | 
			
		||||
		else
 | 
			
		||||
		   OLED_SDIN_Clr();
 | 
			
		||||
		OLED_SCLK_Set();
 | 
			
		||||
		dat<<=1;
 | 
			
		||||
	}	
 | 
			
		||||
  OLED_CS_Set();	
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD写入数据
 | 
			
		||||
      入口数据:dat 写入的数据
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_WR_DATA8(u8 dat)
 | 
			
		||||
{
 | 
			
		||||
	OLED_DC_Set();//写数据
 | 
			
		||||
	LCD_Writ_Bus(dat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD写入数据
 | 
			
		||||
      入口数据:dat 写入的数据
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_WR_DATA(u16 dat)
 | 
			
		||||
{
 | 
			
		||||
	OLED_DC_Set();//写数据
 | 
			
		||||
	LCD_Writ_Bus(dat>>8);
 | 
			
		||||
	LCD_Writ_Bus(dat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD写入命令
 | 
			
		||||
      入口数据:dat 写入的命令
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_WR_REG(u8 dat)
 | 
			
		||||
{
 | 
			
		||||
	OLED_DC_Clr();//写命令
 | 
			
		||||
	LCD_Writ_Bus(dat);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:设置起始和结束地址
 | 
			
		||||
      入口数据:x1,x2 设置列的起始和结束地址
 | 
			
		||||
                y1,y2 设置行的起始和结束地址
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_Address_Set(u16 x1,u16 y1,u16 x2,u16 y2)
 | 
			
		||||
{
 | 
			
		||||
	if(USE_HORIZONTAL==0)
 | 
			
		||||
	{
 | 
			
		||||
		LCD_WR_REG(0x2a);//列地址设置
 | 
			
		||||
		LCD_WR_DATA(x1+26);
 | 
			
		||||
		LCD_WR_DATA(x2+26);
 | 
			
		||||
		LCD_WR_REG(0x2b);//行地址设置
 | 
			
		||||
		LCD_WR_DATA(y1+1);
 | 
			
		||||
		LCD_WR_DATA(y2+1);
 | 
			
		||||
		LCD_WR_REG(0x2c);//储存器写
 | 
			
		||||
	}
 | 
			
		||||
	else if(USE_HORIZONTAL==1)
 | 
			
		||||
	{
 | 
			
		||||
		LCD_WR_REG(0x2a);//列地址设置
 | 
			
		||||
		LCD_WR_DATA(x1+26);
 | 
			
		||||
		LCD_WR_DATA(x2+26);
 | 
			
		||||
		LCD_WR_REG(0x2b);//行地址设置
 | 
			
		||||
		LCD_WR_DATA(y1+1);
 | 
			
		||||
		LCD_WR_DATA(y2+1);
 | 
			
		||||
		LCD_WR_REG(0x2c);//储存器写
 | 
			
		||||
	}
 | 
			
		||||
	else if(USE_HORIZONTAL==2)
 | 
			
		||||
	{
 | 
			
		||||
		LCD_WR_REG(0x2a);//列地址设置
 | 
			
		||||
		LCD_WR_DATA(x1+1);
 | 
			
		||||
		LCD_WR_DATA(x2+1);
 | 
			
		||||
		LCD_WR_REG(0x2b);//行地址设置
 | 
			
		||||
		LCD_WR_DATA(y1+26);
 | 
			
		||||
		LCD_WR_DATA(y2+26);
 | 
			
		||||
		LCD_WR_REG(0x2c);//储存器写
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		LCD_WR_REG(0x2a);//列地址设置
 | 
			
		||||
		LCD_WR_DATA(x1+1);
 | 
			
		||||
		LCD_WR_DATA(x2+1);
 | 
			
		||||
		LCD_WR_REG(0x2b);//行地址设置
 | 
			
		||||
		LCD_WR_DATA(y1+26);
 | 
			
		||||
		LCD_WR_DATA(y2+26);
 | 
			
		||||
		LCD_WR_REG(0x2c);//储存器写
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if SPI0_CFG == 2
 | 
			
		||||
/*!
 | 
			
		||||
    \brief      configure the DMA peripheral
 | 
			
		||||
    \param[in]  none
 | 
			
		||||
    \param[out] none
 | 
			
		||||
    \retval     none
 | 
			
		||||
*/
 | 
			
		||||
void dma_config(void)
 | 
			
		||||
{
 | 
			
		||||
	dma_parameter_struct dma_init_struct;
 | 
			
		||||
 | 
			
		||||
    /* SPI0 transmit dma config:DMA0,DMA_CH2 */
 | 
			
		||||
    dma_deinit(DMA0, DMA_CH2);
 | 
			
		||||
    dma_struct_para_init(&dma_init_struct);
 | 
			
		||||
 | 
			
		||||
    dma_init_struct.periph_addr  = (uint32_t)&SPI_DATA(SPI0);
 | 
			
		||||
    dma_init_struct.memory_addr  = (uint32_t)image;
 | 
			
		||||
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERAL;
 | 
			
		||||
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
 | 
			
		||||
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
 | 
			
		||||
    dma_init_struct.priority     = DMA_PRIORITY_LOW;
 | 
			
		||||
    dma_init_struct.number       = FRAME_SIZE;
 | 
			
		||||
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
 | 
			
		||||
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
 | 
			
		||||
    dma_init(DMA0, DMA_CH2, &dma_init_struct);
 | 
			
		||||
    /* configure DMA mode */
 | 
			
		||||
    dma_circulation_disable(DMA0, DMA_CH2);
 | 
			
		||||
    dma_memory_to_memory_disable(DMA0, DMA_CH2);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if SPI0_CFG == 1
 | 
			
		||||
/*!
 | 
			
		||||
    \brief      configure the SPI peripheral
 | 
			
		||||
    \param[in]  none
 | 
			
		||||
    \param[out] none
 | 
			
		||||
    \retval     none
 | 
			
		||||
*/
 | 
			
		||||
void spi_config(void)
 | 
			
		||||
{
 | 
			
		||||
    spi_parameter_struct spi_init_struct;
 | 
			
		||||
    /* deinitilize SPI and the parameters */
 | 
			
		||||
    OLED_CS_Set();
 | 
			
		||||
    spi_struct_para_init(&spi_init_struct);
 | 
			
		||||
 | 
			
		||||
    /* SPI0 parameter config */
 | 
			
		||||
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
 | 
			
		||||
    spi_init_struct.device_mode          = SPI_MASTER;
 | 
			
		||||
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
 | 
			
		||||
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
 | 
			
		||||
    spi_init_struct.nss                  = SPI_NSS_SOFT;
 | 
			
		||||
    spi_init_struct.prescale             = SPI_PSC_8;
 | 
			
		||||
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
 | 
			
		||||
    spi_init(SPI0, &spi_init_struct);
 | 
			
		||||
 | 
			
		||||
	spi_crc_polynomial_set(SPI0,7);
 | 
			
		||||
	spi_enable(SPI0);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD初始化函数
 | 
			
		||||
      入口数据:无
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void Lcd_Init(void)
 | 
			
		||||
{
 | 
			
		||||
	rcu_periph_clock_enable(RCU_GPIOA);
 | 
			
		||||
	rcu_periph_clock_enable(RCU_GPIOB);
 | 
			
		||||
 | 
			
		||||
#if SPI0_CFG == 1
 | 
			
		||||
 	rcu_periph_clock_enable(RCU_AF);
 | 
			
		||||
	rcu_periph_clock_enable(RCU_SPI0);
 | 
			
		||||
	/* SPI0 GPIO config: NSS/PA4, SCK/PA5, MOSI/PA7 */
 | 
			
		||||
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 |GPIO_PIN_6| GPIO_PIN_7);
 | 
			
		||||
	gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
 | 
			
		||||
 | 
			
		||||
	spi_config();
 | 
			
		||||
 | 
			
		||||
#elif SPI0_CFG == 2
 | 
			
		||||
    rcu_periph_clock_enable(RCU_DMA0);
 | 
			
		||||
    rcu_periph_clock_enable(RCU_SPI0);
 | 
			
		||||
 | 
			
		||||
	/* SPI0 GPIO config: NSS/PA4, SCK/PA5, MOSI/PA7 */
 | 
			
		||||
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7);
 | 
			
		||||
    /* SPI0 GPIO config: MISO/PA6 */
 | 
			
		||||
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
 | 
			
		||||
 | 
			
		||||
	dma_config();
 | 
			
		||||
 | 
			
		||||
	dma_channel_enable(DMA0,DMA_CH2);
 | 
			
		||||
#elif SPI0_CFG == 3
 | 
			
		||||
	gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);
 | 
			
		||||
	gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
 | 
			
		||||
 | 
			
		||||
	gpio_bit_reset(GPIOA, GPIO_PIN_5 | GPIO_PIN_7);
 | 
			
		||||
	gpio_bit_reset(GPIOB, GPIO_PIN_2);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1);
 | 
			
		||||
	gpio_bit_reset(GPIOB, GPIO_PIN_0 | GPIO_PIN_1);
 | 
			
		||||
 | 
			
		||||
	OLED_RST_Clr();
 | 
			
		||||
	delay_1ms(200);
 | 
			
		||||
	OLED_RST_Set();
 | 
			
		||||
	delay_1ms(20);
 | 
			
		||||
	OLED_BLK_Set();
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0x11); 
 | 
			
		||||
	delay_1ms(100);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0x21); 
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xB1); 
 | 
			
		||||
	LCD_WR_DATA8(0x05);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xB2);
 | 
			
		||||
	LCD_WR_DATA8(0x05);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xB3); 
 | 
			
		||||
	LCD_WR_DATA8(0x05);  
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
	LCD_WR_DATA8(0x05);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
	LCD_WR_DATA8(0x3A);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xB4);
 | 
			
		||||
	LCD_WR_DATA8(0x03);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xC0);
 | 
			
		||||
	LCD_WR_DATA8(0x62);
 | 
			
		||||
	LCD_WR_DATA8(0x02);
 | 
			
		||||
	LCD_WR_DATA8(0x04);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xC1);
 | 
			
		||||
	LCD_WR_DATA8(0xC0);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xC2);
 | 
			
		||||
	LCD_WR_DATA8(0x0D);
 | 
			
		||||
	LCD_WR_DATA8(0x00);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xC3);
 | 
			
		||||
	LCD_WR_DATA8(0x8D);
 | 
			
		||||
	LCD_WR_DATA8(0x6A);   
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xC4);
 | 
			
		||||
	LCD_WR_DATA8(0x8D); 
 | 
			
		||||
	LCD_WR_DATA8(0xEE); 
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xC5);  /*VCOM*/
 | 
			
		||||
	LCD_WR_DATA8(0x0E);    
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xE0);
 | 
			
		||||
	LCD_WR_DATA8(0x10);
 | 
			
		||||
	LCD_WR_DATA8(0x0E);
 | 
			
		||||
	LCD_WR_DATA8(0x02);
 | 
			
		||||
	LCD_WR_DATA8(0x03);
 | 
			
		||||
	LCD_WR_DATA8(0x0E);
 | 
			
		||||
	LCD_WR_DATA8(0x07);
 | 
			
		||||
	LCD_WR_DATA8(0x02);
 | 
			
		||||
	LCD_WR_DATA8(0x07);
 | 
			
		||||
	LCD_WR_DATA8(0x0A);
 | 
			
		||||
	LCD_WR_DATA8(0x12);
 | 
			
		||||
	LCD_WR_DATA8(0x27);
 | 
			
		||||
	LCD_WR_DATA8(0x37);
 | 
			
		||||
	LCD_WR_DATA8(0x00);
 | 
			
		||||
	LCD_WR_DATA8(0x0D);
 | 
			
		||||
	LCD_WR_DATA8(0x0E);
 | 
			
		||||
	LCD_WR_DATA8(0x10);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0xE1);
 | 
			
		||||
	LCD_WR_DATA8(0x10);
 | 
			
		||||
	LCD_WR_DATA8(0x0E);
 | 
			
		||||
	LCD_WR_DATA8(0x03);
 | 
			
		||||
	LCD_WR_DATA8(0x03);
 | 
			
		||||
	LCD_WR_DATA8(0x0F);
 | 
			
		||||
	LCD_WR_DATA8(0x06);
 | 
			
		||||
	LCD_WR_DATA8(0x02);
 | 
			
		||||
	LCD_WR_DATA8(0x08);
 | 
			
		||||
	LCD_WR_DATA8(0x0A);
 | 
			
		||||
	LCD_WR_DATA8(0x13);
 | 
			
		||||
	LCD_WR_DATA8(0x26);
 | 
			
		||||
	LCD_WR_DATA8(0x36);
 | 
			
		||||
	LCD_WR_DATA8(0x00);
 | 
			
		||||
	LCD_WR_DATA8(0x0D);
 | 
			
		||||
	LCD_WR_DATA8(0x0E);
 | 
			
		||||
	LCD_WR_DATA8(0x10);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0x3A); 
 | 
			
		||||
	LCD_WR_DATA8(0x05);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0x36);
 | 
			
		||||
	if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x08);
 | 
			
		||||
	else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC8);
 | 
			
		||||
	else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x78);
 | 
			
		||||
	else LCD_WR_DATA8(0xA8);
 | 
			
		||||
 | 
			
		||||
	LCD_WR_REG(0x29); 
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD清屏函数
 | 
			
		||||
      入口数据:无
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_Clear(u16 Color)
 | 
			
		||||
{
 | 
			
		||||
	u16 i,j;  	
 | 
			
		||||
	LCD_Address_Set(0,0,LCD_W-1,LCD_H-1);
 | 
			
		||||
    for(i=0;i<LCD_W;i++)
 | 
			
		||||
	  {
 | 
			
		||||
			for (j=0;j<LCD_H;j++)
 | 
			
		||||
				{
 | 
			
		||||
					LCD_WR_DATA(Color);
 | 
			
		||||
				}
 | 
			
		||||
	  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD显示汉字
 | 
			
		||||
      入口数据:x,y   起始坐标
 | 
			
		||||
                index 汉字的序号
 | 
			
		||||
                size  字号
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_ShowChinese(u16 x,u16 y,u8 index,u8 size,u16 color)	
 | 
			
		||||
{  
 | 
			
		||||
	u8 i,j;
 | 
			
		||||
	u8 *temp,size1;
 | 
			
		||||
	if(size==16){temp=Hzk16;}//选择字号
 | 
			
		||||
	if(size==32){temp=Hzk32;}
 | 
			
		||||
  LCD_Address_Set(x,y,x+size-1,y+size-1); //设置一个汉字的区域
 | 
			
		||||
  size1=size*size/8;//一个汉字所占的字节
 | 
			
		||||
	temp+=index*size1;//写入的起始位置
 | 
			
		||||
	for(j=0;j<size1;j++)
 | 
			
		||||
	{
 | 
			
		||||
		for(i=0;i<8;i++)
 | 
			
		||||
		{
 | 
			
		||||
		 	if((*temp&(1<<i))!=0)//从数据的低位开始读
 | 
			
		||||
			{
 | 
			
		||||
				LCD_WR_DATA(color);//点亮
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				LCD_WR_DATA(BACK_COLOR);//不点亮
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		temp++;
 | 
			
		||||
	 }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD显示汉字
 | 
			
		||||
      入口数据:x,y   起始坐标
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_DrawPoint(u16 x,u16 y,u16 color)
 | 
			
		||||
{
 | 
			
		||||
	LCD_Address_Set(x,y,x,y);//设置光标位置 
 | 
			
		||||
	LCD_WR_DATA(color);
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:LCD画一个大的点
 | 
			
		||||
      入口数据:x,y   起始坐标
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_DrawPoint_big(u16 x,u16 y,u16 color)
 | 
			
		||||
{
 | 
			
		||||
	LCD_Fill(x-1,y-1,x+1,y+1,color);
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:在指定区域填充颜色
 | 
			
		||||
      入口数据:xsta,ysta   起始坐标
 | 
			
		||||
                xend,yend   终止坐标
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)
 | 
			
		||||
{          
 | 
			
		||||
	u16 i,j; 
 | 
			
		||||
	LCD_Address_Set(xsta,ysta,xend,yend);      //设置光标位置 
 | 
			
		||||
	for(i=ysta;i<=yend;i++)
 | 
			
		||||
	{													   	 	
 | 
			
		||||
		for(j=xsta;j<=xend;j++)LCD_WR_DATA(color);//设置光标位置 	    
 | 
			
		||||
	} 					  	    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:画线
 | 
			
		||||
      入口数据:x1,y1   起始坐标
 | 
			
		||||
                x2,y2   终止坐标
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
 | 
			
		||||
{
 | 
			
		||||
	u16 t; 
 | 
			
		||||
	int xerr=0,yerr=0,delta_x,delta_y,distance;
 | 
			
		||||
	int incx,incy,uRow,uCol;
 | 
			
		||||
	delta_x=x2-x1; //计算坐标增量 
 | 
			
		||||
	delta_y=y2-y1;
 | 
			
		||||
	uRow=x1;//画线起点坐标
 | 
			
		||||
	uCol=y1;
 | 
			
		||||
	if(delta_x>0)incx=1; //设置单步方向 
 | 
			
		||||
	else if (delta_x==0)incx=0;//垂直线 
 | 
			
		||||
	else {incx=-1;delta_x=-delta_x;}
 | 
			
		||||
	if(delta_y>0)incy=1;
 | 
			
		||||
	else if (delta_y==0)incy=0;//水平线 
 | 
			
		||||
	else {incy=-1;delta_y=-delta_x;}
 | 
			
		||||
	if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴 
 | 
			
		||||
	else distance=delta_y;
 | 
			
		||||
	for(t=0;t<distance+1;t++)
 | 
			
		||||
	{
 | 
			
		||||
		LCD_DrawPoint(uRow,uCol,color);//画点
 | 
			
		||||
		xerr+=delta_x;
 | 
			
		||||
		yerr+=delta_y;
 | 
			
		||||
		if(xerr>distance)
 | 
			
		||||
		{
 | 
			
		||||
			xerr-=distance;
 | 
			
		||||
			uRow+=incx;
 | 
			
		||||
		}
 | 
			
		||||
		if(yerr>distance)
 | 
			
		||||
		{
 | 
			
		||||
			yerr-=distance;
 | 
			
		||||
			uCol+=incy;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:画矩形
 | 
			
		||||
      入口数据:x1,y1   起始坐标
 | 
			
		||||
                x2,y2   终止坐标
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2,u16 color)
 | 
			
		||||
{
 | 
			
		||||
	LCD_DrawLine(x1,y1,x2,y1,color);
 | 
			
		||||
	LCD_DrawLine(x1,y1,x1,y2,color);
 | 
			
		||||
	LCD_DrawLine(x1,y2,x2,y2,color);
 | 
			
		||||
	LCD_DrawLine(x2,y1,x2,y2,color);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:画圆
 | 
			
		||||
      入口数据:x0,y0   圆心坐标
 | 
			
		||||
                r       半径
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void Draw_Circle(u16 x0,u16 y0,u8 r,u16 color)
 | 
			
		||||
{
 | 
			
		||||
	int a,b;
 | 
			
		||||
	// int di;
 | 
			
		||||
	a=0;b=r;	  
 | 
			
		||||
	while(a<=b)
 | 
			
		||||
	{
 | 
			
		||||
		LCD_DrawPoint(x0-b,y0-a,color);             //3           
 | 
			
		||||
		LCD_DrawPoint(x0+b,y0-a,color);             //0           
 | 
			
		||||
		LCD_DrawPoint(x0-a,y0+b,color);             //1                
 | 
			
		||||
		LCD_DrawPoint(x0-a,y0-b,color);             //2             
 | 
			
		||||
		LCD_DrawPoint(x0+b,y0+a,color);             //4               
 | 
			
		||||
		LCD_DrawPoint(x0+a,y0-b,color);             //5
 | 
			
		||||
		LCD_DrawPoint(x0+a,y0+b,color);             //6 
 | 
			
		||||
		LCD_DrawPoint(x0-b,y0+a,color);             //7
 | 
			
		||||
		a++;
 | 
			
		||||
		if((a*a+b*b)>(r*r))//判断要画的点是否过远
 | 
			
		||||
		{
 | 
			
		||||
			b--;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:显示字符
 | 
			
		||||
      入口数据:x,y    起点坐标
 | 
			
		||||
                num    要显示的字符
 | 
			
		||||
                mode   1叠加方式  0非叠加方式
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_ShowChar(u16 x,u16 y,u8 num,u8 mode,u16 color)
 | 
			
		||||
{
 | 
			
		||||
    u8 temp;
 | 
			
		||||
    u8 pos,t;
 | 
			
		||||
	  u16 x0=x;    
 | 
			
		||||
    if(x>LCD_W-16||y>LCD_H-16)return;	    //设置窗口		   
 | 
			
		||||
	num=num-' ';//得到偏移后的值
 | 
			
		||||
	LCD_Address_Set(x,y,x+8-1,y+16-1);      //设置光标位置 
 | 
			
		||||
	if(!mode) //非叠加方式
 | 
			
		||||
	{
 | 
			
		||||
		for(pos=0;pos<16;pos++)
 | 
			
		||||
		{ 
 | 
			
		||||
			temp=asc2_1608[(u16)num*16+pos];		 //调用1608字体
 | 
			
		||||
			for(t=0;t<8;t++)
 | 
			
		||||
		    {                 
 | 
			
		||||
		        if(temp&0x01)LCD_WR_DATA(color);
 | 
			
		||||
				else LCD_WR_DATA(BACK_COLOR);
 | 
			
		||||
				temp>>=1;
 | 
			
		||||
				x++;
 | 
			
		||||
		    }
 | 
			
		||||
			x=x0;
 | 
			
		||||
			y++;
 | 
			
		||||
		}	
 | 
			
		||||
	}else//叠加方式
 | 
			
		||||
	{
 | 
			
		||||
		for(pos=0;pos<16;pos++)
 | 
			
		||||
		{
 | 
			
		||||
		    temp=asc2_1608[(u16)num*16+pos];		 //调用1608字体
 | 
			
		||||
			for(t=0;t<8;t++)
 | 
			
		||||
		    {                 
 | 
			
		||||
		        if(temp&0x01)LCD_DrawPoint(x+t,y+pos,color);//画一个点     
 | 
			
		||||
		        temp>>=1; 
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
	}   	   	 	  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:显示字符串
 | 
			
		||||
      入口数据:x,y    起点坐标
 | 
			
		||||
                *p     字符串起始地址
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 color)
 | 
			
		||||
{         
 | 
			
		||||
    while(*p!='\0')
 | 
			
		||||
    {       
 | 
			
		||||
        if(x>LCD_W-16){x=0;y+=16;}
 | 
			
		||||
        if(y>LCD_H-16){y=x=0;LCD_Clear(RED);}
 | 
			
		||||
        LCD_ShowChar(x,y,*p,0,color);
 | 
			
		||||
        x+=8;
 | 
			
		||||
        p++;
 | 
			
		||||
    }  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:显示数字
 | 
			
		||||
      入口数据:m底数,n指数
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
u32 mypow(u8 m,u8 n)
 | 
			
		||||
{
 | 
			
		||||
	u32 result=1;	 
 | 
			
		||||
	while(n--)result*=m;    
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:显示数字
 | 
			
		||||
      入口数据:x,y    起点坐标
 | 
			
		||||
                num    要显示的数字
 | 
			
		||||
                len    要显示的数字个数
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_ShowNum(u16 x,u16 y,u16 num,u8 len,u16 color)
 | 
			
		||||
{         	
 | 
			
		||||
	u8 t,temp;
 | 
			
		||||
	u8 enshow=0;
 | 
			
		||||
	for(t=0;t<len;t++)
 | 
			
		||||
	{
 | 
			
		||||
		temp=(num/mypow(10,len-t-1))%10;
 | 
			
		||||
		if(enshow==0&&t<(len-1))
 | 
			
		||||
		{
 | 
			
		||||
			if(temp==0)
 | 
			
		||||
			{
 | 
			
		||||
				LCD_ShowChar(x+8*t,y,' ',0,color);
 | 
			
		||||
				continue;
 | 
			
		||||
			}else enshow=1; 
 | 
			
		||||
		 	 
 | 
			
		||||
		}
 | 
			
		||||
	 	LCD_ShowChar(x+8*t,y,temp+48,0,color); 
 | 
			
		||||
	}
 | 
			
		||||
} 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:显示小数
 | 
			
		||||
      入口数据:x,y    起点坐标
 | 
			
		||||
                num    要显示的小数
 | 
			
		||||
                len    要显示的数字个数
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_ShowNum1(u16 x,u16 y,float num,u8 len,u16 color)
 | 
			
		||||
{         	
 | 
			
		||||
	u8 t,temp;
 | 
			
		||||
	// u8 enshow=0;
 | 
			
		||||
	u16 num1;
 | 
			
		||||
	num1=num*100;
 | 
			
		||||
	for(t=0;t<len;t++)
 | 
			
		||||
	{
 | 
			
		||||
		temp=(num1/mypow(10,len-t-1))%10;
 | 
			
		||||
		if(t==(len-2))
 | 
			
		||||
		{
 | 
			
		||||
			LCD_ShowChar(x+8*(len-2),y,'.',0,color);
 | 
			
		||||
			t++;
 | 
			
		||||
			len+=1;
 | 
			
		||||
		}
 | 
			
		||||
	 	LCD_ShowChar(x+8*t,y,temp+48,0,color);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
      函数说明:显示40x40图片
 | 
			
		||||
      入口数据:x,y    起点坐标
 | 
			
		||||
      返回值:  无
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
void LCD_ShowPicture(u16 x1,u16 y1,u16 x2,u16 y2)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	LCD_Address_Set(x1,y1,x2,y2);
 | 
			
		||||
	for(i=0;i<12800;i++)
 | 
			
		||||
	{ 	
 | 
			
		||||
		// LCD_WR_DATA8(image[i*2+1]);
 | 
			
		||||
		LCD_WR_DATA8(image[i]);
 | 
			
		||||
	}			
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LCD_ShowLogo(void)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	LCD_Address_Set(0,0,159,75);
 | 
			
		||||
	for(i=0;i<25600;i++)
 | 
			
		||||
	{
 | 
			
		||||
		LCD_WR_DATA8(logo_bmp[i]);
 | 
			
		||||
	}			
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										109
									
								
								gd32v_lcd/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								gd32v_lcd/src/main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
#include "lcd/lcd.h"
 | 
			
		||||
#include "fatfs/tf_card.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
unsigned char image[12800];
 | 
			
		||||
FATFS fs;
 | 
			
		||||
 | 
			
		||||
void init_uart0(void)
 | 
			
		||||
{	
 | 
			
		||||
	/* enable GPIO clock */
 | 
			
		||||
    rcu_periph_clock_enable(RCU_GPIOA);
 | 
			
		||||
    /* enable USART clock */
 | 
			
		||||
    rcu_periph_clock_enable(RCU_USART0);
 | 
			
		||||
 | 
			
		||||
    /* connect port to USARTx_Tx */
 | 
			
		||||
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
 | 
			
		||||
    /* connect port to USARTx_Rx */
 | 
			
		||||
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
 | 
			
		||||
 | 
			
		||||
	/* USART configure */
 | 
			
		||||
    usart_deinit(USART0);
 | 
			
		||||
    usart_baudrate_set(USART0, 115200U);
 | 
			
		||||
    usart_word_length_set(USART0, USART_WL_8BIT);
 | 
			
		||||
    usart_stop_bit_set(USART0, USART_STB_1BIT);
 | 
			
		||||
    usart_parity_config(USART0, USART_PM_NONE);
 | 
			
		||||
    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
 | 
			
		||||
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
 | 
			
		||||
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
 | 
			
		||||
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
 | 
			
		||||
    usart_enable(USART0);
 | 
			
		||||
 | 
			
		||||
    usart_interrupt_enable(USART0, USART_INT_RBNE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(void)
 | 
			
		||||
{	
 | 
			
		||||
    u8 i,m;
 | 
			
		||||
    float t=0;
 | 
			
		||||
    int offset = 0;
 | 
			
		||||
    uint64_t start_mtime, delta_mtime;
 | 
			
		||||
    FIL fil;
 | 
			
		||||
 | 
			
		||||
    FRESULT fr;     /* FatFs return code */
 | 
			
		||||
    UINT br, bw;
 | 
			
		||||
 | 
			
		||||
    rcu_periph_clock_enable(RCU_GPIOA);
 | 
			
		||||
    rcu_periph_clock_enable(RCU_GPIOC);
 | 
			
		||||
    gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
 | 
			
		||||
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1|GPIO_PIN_2);
 | 
			
		||||
 | 
			
		||||
    init_uart0();
 | 
			
		||||
 | 
			
		||||
    Lcd_Init();			// init OLED
 | 
			
		||||
    LCD_Clear(WHITE);
 | 
			
		||||
    BACK_COLOR=WHITE;
 | 
			
		||||
 | 
			
		||||
    LEDR(1);
 | 
			
		||||
    LEDG(1);
 | 
			
		||||
    LEDB(1);
 | 
			
		||||
    fr = f_mount(&fs, "", 1);
 | 
			
		||||
 | 
			
		||||
    while(1)
 | 
			
		||||
    {
 | 
			
		||||
        offset = 0;
 | 
			
		||||
        fr = f_open(&fil, "logo.bin", FA_READ);
 | 
			
		||||
        if (fr) printf("open error: %d!\n\r", (int)fr);
 | 
			
		||||
        f_lseek(&fil, offset);
 | 
			
		||||
        fr = f_read(&fil, image, sizeof(image), &br);
 | 
			
		||||
        LCD_ShowPicture(0,0,159,39);
 | 
			
		||||
        offset += 12800;
 | 
			
		||||
        LEDB_TOG;
 | 
			
		||||
        f_lseek(&fil, offset);
 | 
			
		||||
        fr = f_read(&fil, image, sizeof(image), &br);
 | 
			
		||||
        LCD_ShowPicture(0,40,159,79);
 | 
			
		||||
        LEDB_TOG;
 | 
			
		||||
        delay_1ms(1500);
 | 
			
		||||
        f_close(&fil);
 | 
			
		||||
 | 
			
		||||
        fr = f_open(&fil, "bmp.bin", FA_READ);
 | 
			
		||||
        if (fr) printf("open error: %d!\n\r", (int)fr);
 | 
			
		||||
        offset = 0;
 | 
			
		||||
 | 
			
		||||
        for (int i=0; i<2189;i++)
 | 
			
		||||
        {
 | 
			
		||||
            fr = f_read(&fil, image, sizeof(image), &br);
 | 
			
		||||
            LCD_ShowPicture(0,0,159,39);
 | 
			
		||||
            offset += 12800;
 | 
			
		||||
            f_lseek(&fil, offset);
 | 
			
		||||
            LEDB_TOG;
 | 
			
		||||
            fr = f_read(&fil, image, sizeof(image), &br);
 | 
			
		||||
            LCD_ShowPicture(0,40,159,79);
 | 
			
		||||
            offset += 12800;
 | 
			
		||||
            f_lseek(&fil, offset);
 | 
			
		||||
            LEDB_TOG;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Close the file */
 | 
			
		||||
        f_close(&fil);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int _put_char(int ch)
 | 
			
		||||
{
 | 
			
		||||
    usart_data_transmit(USART0, (uint8_t) ch );
 | 
			
		||||
    while ( usart_flag_get(USART0, USART_FLAG_TBE)== RESET){
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ch;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								gd32v_lcd/src/systick.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								gd32v_lcd/src/systick.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
/*!
 | 
			
		||||
    \file  systick.c
 | 
			
		||||
    \brief the systick configuration file
 | 
			
		||||
 | 
			
		||||
    \version 2019-6-5, V1.0.0, firmware for GD32VF103
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    Copyright (c) 2019, GigaDevice Semiconductor Inc.
 | 
			
		||||
 | 
			
		||||
    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 the copyright holder 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.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "gd32vf103.h"
 | 
			
		||||
#include "systick.h"
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
    \brief      delay a time in milliseconds
 | 
			
		||||
    \param[in]  count: count in milliseconds
 | 
			
		||||
    \param[out] none
 | 
			
		||||
    \retval     none
 | 
			
		||||
*/
 | 
			
		||||
void delay_1ms(uint32_t count)
 | 
			
		||||
{
 | 
			
		||||
	uint64_t start_mtime, delta_mtime;
 | 
			
		||||
 | 
			
		||||
	// Don't start measuruing until we see an mtime tick
 | 
			
		||||
	uint64_t tmp = get_timer_value();
 | 
			
		||||
	do {
 | 
			
		||||
	start_mtime = get_timer_value();
 | 
			
		||||
	} while (start_mtime == tmp);
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
	delta_mtime = get_timer_value() - start_mtime;
 | 
			
		||||
	}while(delta_mtime <(SystemCoreClock/4000.0 *count ));
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user