diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ OPTLVL:=3 # Optimization level, can be [ TOP:=$(shell readlink -f "../..") DISCOVERY:=Utilities/STM32L100C-Discovery STMLIB:=libraries +OLEDDRV:=oleddrv STD_PERIPH:=$(STMLIB)/STM32L1xx_StdPeriph_Driver STARTUP:=$(STMLIB)/CMSIS/Device/ST/STM32L1xx/Source/Templates/gcc_ride7 LINKER_SCRIPT:=$(CURDIR)/stm32-flash.ld @@ -18,6 +19,7 @@ INCLUDE+=-I$(STMLIB)/CMSIS/Include INCLUDE+=-I$(STMLIB)/CMSIS/Device/ST/STM32L1xx/Include INCLUDE+=-I$(STD_PERIPH)/inc INCLUDE+=-I$(DISCOVERY) +INCLUDE+=-I$(STMLIB)/$(OLEDDRV) #INCLUDE+=-I$(STMLIB)/STM32_USB_OTG_Driver/inc #INCLUDE+=-I$(STMLIB)/STM32_USB_Device_Library/Class/hid/inc #INCLUDE+=-I$(STMLIB)/STM32_USB_Device_Library/Core/inc @@ -37,6 +39,7 @@ SRC=main.c SRC+=stm32l1xx_it.c SRC+=system_stm32l1xx.c SRC+=stm32l100c_discovery.c +SRC+=ssd1306.c # Discovery Source Files #SRC+=stm32f4_discovery_lis302dl.c diff --git a/libraries/oleddrv/DrawText.c b/libraries/oleddrv/DrawText.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/DrawText.c @@ -0,0 +1,197 @@ +/******************************************************************************* +* File Name : DrawText.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-01-21 +* Description : Text output implemention file +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "DrawText.h" +#include "font.h" +#include "SSD1303.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +Pos_t DrawChar(Device* pDev, Pos_t x, Pos_t y, char ch); + +/******************************************************************************* +* Function Name : TextOut +* Description : Output a text at specify position +* Input : Device* device +* Pos_t x location +* Pos_t y location +* char* text +* Size_t text length +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +Pos_t TextOut(Device* pDev, Pos_t x, Pos_t y, const char* text, Size_t len) +{ + while(*text && len){ + x += DrawChar(pDev,x,y,*text); + text++; + len--; + } + return x; +} + +/******************************************************************************* +* Function Name : HightLightArea +* Description : Hight Light the specify Area +* Input : Device* device +* Pos_t x location +* Pos_t y location + Pos_t width +* Pos_t length +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +unsigned long HightLightArea( + Pos_t x, + Pos_t y, + Pos_t cx, + Pos_t cy) +{ + return SSD1303_DrawBlock(x,y,cx,cy,0); +} + +/******************************************************************************* +* Function Name : TextOut_HighLight +* Description : Output a text at specify position, then hight them +* Input : Device* device +* Pos_t x location +* Pos_t y location +* char* text +* Size_t text length +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +unsigned long TextOut_HighLight( + Device* pDev, + Pos_t x, + Pos_t y, + const char* text, + Size_t len) +{ + Pos_t res = TextOut(pDev, x, y, text, len); + SSD1303_DrawBlock(x,y,res-x,GetFontTextHeight(pDev->pfnFont,*text),0); + return res; +} + +/******************************************************************************* +* Function Name : SpecTextOut_HighLight +* Description : Output a specify text at specify position then high light them +* Input : Device* device +* Pos_t x location +* Pos_t y location +* const FontData* text dotmatrix data +* Size_t text length +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +unsigned long SpecTextOut_HighLight( + Device* pDev, + Pos_t x, + Pos_t y, + const pfnFontDrawChar pfnFont, + Size_t len) +{ + Pos_t res = SpecTextOut(pDev, x, y, pfnFont, len); + SSD1303_DrawBlock(x,y,res-x,GetFontTextHeight(pfnFont,0),0); + return res; +} + +/******************************************************************************* +* Function Name : SpecTextOut +* Description : Output a specify text at specify position +* Input : Device* device +* Pos_t x location +* Pos_t y location +* const FontData* text dotmatrix data +* Size_t text length +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +Pos_t SpecTextOut(Device* pDev, Pos_t x, Pos_t y,const pfnFontDrawChar pfnFont, Size_t len) +{ + pfnFontDrawChar old = pDev->pfnFont; + pDev->pfnFont = pfnFont; + for(unsigned long i=0;ipfnFont = old; + return x; +} + +/******************************************************************************* +* Function Name : DrawChar +* Description : Output a character at specify position +* Input : Device* device +* Pos_t x location +* Pos_t y location +* char character +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +Pos_t DrawChar(Device* pDev, Pos_t x, Pos_t y, char ch) +{ + return pDev->pfnFont(pDev->pDevProp->pfnDrawBlok,x,y,(unsigned char)ch); + //FontData ft = &pDev->font[ch]; + //pDev->pDevProp->pfnDrawBlok(x,y,ft->width,ft->height,ft->data); + //return ft->width; +} + +/******************************************************************************* +* Function Name : InitialDevice +* Description : Initialize the device strcture +* Input : const DeviceProp* device properties +* const FontData* font +* Output : Device* device pointer +* Return : End x position for the last character +*******************************************************************************/ +void InitialDevice(Device* pDev, const DeviceProp* pDevProp, pfnFontDrawChar pfnFont) +{ + pDev->pDevProp = pDevProp; + pDev->pfnFont = pfnFont; + pDev->curX = 0; + pDev->curY = 0; +} + +/******************************************************************************* +* Function Name : SetPoint +* Description : Draw a point at specify position +* Input : Device* device +* Pos_t x location +* Pos_t y location +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +unsigned long SetPoint( + Device* pDev, + Pos_t x, + Pos_t y) +{ + return pDev->pDevProp->pfnDrawPoint(x,y,1); +} + +/******************************************************************************* +* Function Name : ClearPoint +* Description : Clear a point at specify position +* Input : Device* device +* Pos_t x location +* Pos_t y location +* Output : None +* Return : End x position for the last character +*******************************************************************************/ +unsigned long ClearPoint( + Device* pDev, + Pos_t x, + Pos_t y) +{ + return pDev->pDevProp->pfnDrawPoint(x,y,0); +} diff --git a/libraries/oleddrv/DrawText.h b/libraries/oleddrv/DrawText.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/DrawText.h @@ -0,0 +1,83 @@ +#ifndef DRAWTEXT_H +#define DRAWTEXT_H + +typedef unsigned long Pos_t; +typedef unsigned long Size_t; +typedef unsigned long Color_t; + + +typedef unsigned long (*pfnDrawBlock_t)( + Pos_t x, + Pos_t y, + Pos_t cx, + Pos_t cy, + const unsigned char* data); +typedef unsigned long (*pfnDrawPoint_t)(Pos_t x, Pos_t y, Color_t color); + +#include "font.h" +typedef struct _DeviceProp +{ + pfnDrawBlock_t pfnDrawBlok; + pfnDrawPoint_t pfnDrawPoint; + Size_t xPixel; + Size_t yPixel; +}DeviceProp; + +typedef struct _Device +{ + const DeviceProp* pDevProp; + pfnFontDrawChar pfnFont; + Pos_t curX; + Pos_t curY; +}Device; + + + + +void InitialDevice(Device* pDev, const DeviceProp* pDevProp, pfnFontDrawChar pfnFont); + +unsigned long TextOut_HighLight( + Device* pDev, + Pos_t x, + Pos_t y, + const char* text, + Size_t len); + +unsigned long SpecTextOut_HighLight( + Device* pDev, + Pos_t x, + Pos_t y, + pfnFontDrawChar pfnFont, + Size_t len); + +unsigned long HightLightArea( + Pos_t x, + Pos_t y, + Pos_t cx, + Pos_t cy); + +unsigned long TextOut( + Device* pDev, + Pos_t x, + Pos_t y, + const char* text, + Size_t len); + +unsigned long SpecTextOut( + Device* pDev, + Pos_t x, + Pos_t y, + pfnFontDrawChar pfnFont, + Size_t len); + +unsigned long SetPoint( + Device* pDev, + Pos_t x, + Pos_t y); + +unsigned long ClearPoint( + Device* pDev, + Pos_t x, + Pos_t y); + +#endif diff --git a/libraries/oleddrv/Encoder.c b/libraries/oleddrv/Encoder.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/Encoder.c @@ -0,0 +1,173 @@ +/******************************************************************************* +* File Name : Encoder.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-01-29 +* Description : Main program body +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" +#include "Encoder.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#ifdef DEBUG_BOARD +#define ENCODER_TIM TIM3 +#else +#define ENCODER_TIM TIM4 +#endif +/* + 0000: No filter, sampling is done at + 0001: fSAMPLING=fCK_INT, N=2. + 0010: fSAMPLING=fCK_INT, N=4. + 0011: fSAMPLING=fCK_INT, N=8. + 0100: fSAMPLING=fDTS/2, N=6. + 0101: fSAMPLING=fDTS/2, N=8. + 0110: fSAMPLING=fDTS/4, N=6. + 0111: fSAMPLING=fDTS/4, N=8. + 1000: fSAMPLING=fDTS/8, N=6. + 1001: fSAMPLING=fDTS/8, N=8. + 1010: fSAMPLING=fDTS/16, N=5. + 1011: fSAMPLING=fDTS/16, N=6. + 1100: fSAMPLING=fDTS/16, N=8. + 1101: fSAMPLING=fDTS/32, N=5. + 1110: fSAMPLING=fDTS/32, N=6. + 1111: fSAMPLING=fDTS/32, N=8. +*/ +// Tim clock division is 1, so the FDTS = 72MHz +// Fsample = FDTS/4 = 18MHz, and sample 6 times +#define ENC_FILTER 6 +#define MAX_COUNT 1200 +#define ENCODER_TIM_PERIOD (MAX_COUNT*3) + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static u8 keyStatus = 0; + +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : Enc_Init +* Description : Initialize the encoder +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void Enc_Init(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_ICInitTypeDef TIM_ICInitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable SPI1 and GPIO clocks */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); +#ifdef DEBUG_BOARD + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); + // PA.6,PA.7 for encoder, PA.0 for the encoder button + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA,&GPIO_InitStructure); +#else + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); + // PB.6,PB.7 for encoder, PA.0 for the encoder button + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA,&GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOB,&GPIO_InitStructure); +#endif + + /* Timer configuration in Encoder mode */ + TIM_DeInit(ENCODER_TIM); + + TIM_TimeBaseStructure.TIM_Prescaler = 0; // No prescaling + TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD-1; + TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + + TIM_TimeBaseInit(ENCODER_TIM, &TIM_TimeBaseStructure); + + TIM_EncoderInterfaceConfig(ENCODER_TIM, TIM_EncoderMode_TI12, + TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); + TIM_ICStructInit(&TIM_ICInitStructure); + + TIM_ICInitStructure.TIM_ICFilter = ENC_FILTER;//ICx_FILTER; + TIM_ICInit(ENCODER_TIM, &TIM_ICInitStructure); + + // Initial interuppt structures +// NVIC_InitStructure.NVIC_IRQChannel = TIM3_UP_IRQChannel; +// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; +// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; +// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; +// NVIC_Init(&NVIC_InitStructure); +// NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQChannel; +// NVIC_Init(&NVIC_InitStructure); +// +// // Clear all pending interrupts +// TIM_ClearFlag(ENCODER_TIM, TIM_FLAG_Update); +// TIM_ITConfig(ENCODER_TIM, TIM_IT_Update, ENABLE); + + ENCODER_TIM->CNT = 0; + TIM_Cmd(ENCODER_TIM, ENABLE); +} + +/******************************************************************************* +* Function Name : Enc_GetCount +* Description : Get current encoder count +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +s16 Enc_GetCount(void) +{ + static u16 lastCount = 0; + u16 curCount = ENCODER_TIM->CNT; + s32 dAngle = curCount - lastCount; + if(dAngle >= MAX_COUNT){ + dAngle -= ENCODER_TIM_PERIOD; + }else if(dAngle < -MAX_COUNT){ + dAngle += ENCODER_TIM_PERIOD; + } + lastCount = curCount; + if(0){ + static u8 lastDown = 0; + if(GPIOA->IDR & GPIO_Pin_0){ + if(lastDown>=2){ + lastDown = 0; + keyStatus = 1; + }else{ + lastDown = 0; + } + }else{ + if(lastDown&0x40){ + }else{ + lastDown++; + } + } + } + return (s16)dAngle; +} + +/******************************************************************************* +* Function Name : Enc_IsKeyDown +* Description : Is the encoder button down +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +u8 Enc_IsKeyDown(void) +{ + if(keyStatus){ + keyStatus = 0; + return 1; + } + return 0; +} diff --git a/libraries/oleddrv/Encoder.h b/libraries/oleddrv/Encoder.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/Encoder.h @@ -0,0 +1,10 @@ +#ifndef ENCODER_H +#define ENCODER_H + +void Enc_Init(void); + +s16 Enc_GetCount(void); + +u8 Enc_IsKeyDown(void); + +#endif diff --git a/libraries/oleddrv/GraphicsConfig.h b/libraries/oleddrv/GraphicsConfig.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/GraphicsConfig.h @@ -0,0 +1,164 @@ +/********************************************************************* + * Module for Microchip Graphics Library + * This file contains compile time options for the Graphics Library. + ********************************************************************* + * FileName: none + * Dependencies: See INCLUDES section below + * Processor: PIC24F, PIC24H, dsPIC, PIC32 + * Compiler: C30 V3.00/C32 + * Company: Microchip Technology, Inc. + * + * Software License Agreement + * + * Copyright ?2008 Microchip Technology Inc. All rights reserved. + * Microchip licenses to you the right to use, modify, copy and distribute + * Software only when embedded on a Microchip microcontroller or digital + * signal controller, which is integrated into your product or third party + * product (pursuant to the sublicense terms in the accompanying license + * agreement). + * + * You should refer to the license agreement accompanying this Software + * for additional information regarding your rights and obligations. + * + * SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY + * OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR + * PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR + * OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, + * BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT + * DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, + * INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, + * COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY + * CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), + * OR OTHER SIMILAR COSTS. + * + * Author Date Comment + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Anton Alkhimenok 10/28/2007 + ********************************************************************/ + +#ifndef _GRAPHICSCONFIG_H +#define _GRAPHICSCONFIG_H + +//////////////////// COMPILE OPTIONS AND DEFAULTS //////////////////// + +/********************************************************************* +* Overview: +* Graphics PICtail Plus Board Version setting. The value assigned +* to this macro determines the version of the PICtail Plus Board. +* - 1 - Uses Graphics PICtail Plus Board Version 1 +* - 2 - Uses Graphics PICtail Plus Board Version 2 +* +********************************************************************/ +#define GRAPHICS_PICTAIL_VERSION 1 + +#if (GRAPHICS_PICTAIL_VERSION == 1) + +/********************************************************************* +* Overview: Display controller selection. +* +********************************************************************/ +#define DISPLAY_CONTROLLER CUSTOM_CONTROLLER +/********************************************************************* +* Overview: Horizontal and vertical display resolution +* (from the glass datasheet). +*********************************************************************/ +#define DISP_HOR_RESOLUTION 128 +#define DISP_VER_RESOLUTION 64 +/********************************************************************* +* Overview: Defines color depth. The 1,2,4,8,16 bit per pixel +* color depths are valid. +* +********************************************************************/ +#define COLOR_DEPTH 1 +/********************************************************************* +* Overview: Image orientation (can be 0, 90, 180, 270 degrees). +*********************************************************************/ +#define DISP_ORIENTATION 0 + +#else +#error Graphics controller is not defined +#endif + +/********************************************************************* +* Overview: Blocking and Non-Blocking configuration selection. To +* enable non-blocking configuration USE_NONBLOCKING_CONFIG +* must be defined. If this is not defined, blocking +* configuration is assumed. +* +********************************************************************/ +#define USE_NONBLOCKING_CONFIG // Comment this line to use blocking configuration + +/********************************************************************* +* Overview: Keyboard control on some objects can be used by enabling +* the GOL Focus (USE_FOCUS)support. +* +*********************************************************************/ +//#define USE_FOCUS + +/********************************************************************* +* Overview: Input devices used defines the messages that Objects will +* process. The following definitions indicate the usage of +* the different input device: +* - USE_TOUCHSCREEN - enables the touch screen support. +* - USE_KEYBOARD - enables the key board support. +* +*********************************************************************/ +//#define USE_TOUCHSCREEN // Enable touch screen support. +//#define USE_KEYBOARD // Enable key board support. + +/********************************************************************* +* Overview: To save program memory, unused Widgets or Objects can be +* removed at compile time. +* +*********************************************************************/ +//#define USE_GOL // Enable Graphics Object Layer. +//#define USE_BUTTON // Enable Button Object. +// USE_WINDOW // Enable Window Object. +//#define USE_CHECKBOX // Enable Checkbox Object. +//#define USE_RADIOBUTTON // Enable Radio Button Object. +//#define USE_EDITBOX // Enable Edit Box Object. +//#define USE_LISTBOX // Enable List Box Object. +//#define USE_SLIDER // Enable Slider or Scroll Bar Object. +//#define USE_PROGRESSBAR // Enable Progress Bar Object. +//#define USE_STATICTEXT // Enable Static Text Object. +//#define USE_PICTURE // Enable Picture Object. +//#define USE_GROUPBOX // Enable Group Box Object. +//#define USE_ROUNDDIAL // Enable Dial Object. +//#define USE_METER // Enable Meter Object. +//#define USE_CUSTOM // Enable Custom Control Object (an example to create customized Object). + +/********************************************************************* +* Overview: To enable support for unicode fonts, USE_MULTIBYTECHAR +* must be defined. This changes XCHAR definition. See XCHAR +* for details. +* +*********************************************************************/ +//#define USE_MULTIBYTECHAR + +/********************************************************************* +* Overview: Font data can be placed in two locations. One is in +* FLASH memory and the other is from external memory. +* Definining one or both enables the support for fonts located +* in internal flash and external memory. +* - USE_FONT_FLASH - Font in internal flash memory support. +* - USE_FONT_EXTERNAL - Font in external memory support. +* +*********************************************************************/ +#define USE_FONT_FLASH // Support for fonts located in internal flash +//#define USE_FONT_EXTERNAL // Support for fonts located in external memory + +/********************************************************************* +* Overview: Similar to Font data bitmaps can also be placed in +* two locations. One is in FLASH memory and the other is +* from external memory. +* Definining one or both enables the support for bitmaps located +* in internal flash and external memory. +* - USE_BITMAP_FLASH - Font in internal flash memory support. +* - USE_BITMAP_EXTERNAL - Font in external memory support. +* +*********************************************************************/ +#define USE_BITMAP_FLASH // Support for bitmaps located in internal flash +//#define USE_BITMAP_EXTERNAL // Support for bitmaps located in external memory + +#endif // _GRAPHICSCONFIG_H diff --git a/libraries/oleddrv/HardwareProfile.h b/libraries/oleddrv/HardwareProfile.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/HardwareProfile.h @@ -0,0 +1,461 @@ +/********************************************************************* + * + * Hardware specific definitions + * + ********************************************************************* + * FileName: HardwareProfile.h + * Dependencies: None + * Processor: PIC24F, PIC24H, dsPIC, PIC32 + * Compiler: Microchip C32 v1.00 or higher + * Microchip C30 v3.01 or higher + * Company: Microchip Technology, Inc. + * + * Software License Agreement + * + * Copyright ?2002-2008 Microchip Technology Inc. All rights + * reserved. + * + * Microchip licenses to you the right to use, modify, copy, and + * distribute: + * (i) the Software when embedded on a Microchip microcontroller or + * digital signal controller product (揇evice? which is + * integrated into Licensee抯 product; or + * (ii) ONLY the Software driver source files ENC28J60.c and + * ENC28J60.h ported to a non-Microchip device used in + * conjunction with a Microchip ethernet controller for the + * sole purpose of interfacing with the ethernet controller. + * + * You should refer to the license agreement accompanying this + * Software for additional information regarding your rights and + * obligations. + * + * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS?WITHOUT + * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF + * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS + * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE + * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER + * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT + * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. + * + * + * Author Date Comment + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Howard Schlunder 10/03/06 Original, copied from Compiler.h + ********************************************************************/ +#ifndef __HARDWARE_PROFILE_H +#define __HARDWARE_PROFILE_H + +/********************************************************************* +* GetSystemClock() returns system clock frequency. +* +* GetPeripheralClock() returns peripheral clock frequency. +* +* GetInstructionClock() returns instruction clock frequency. +* +********************************************************************/ + +/********************************************************************* +* Macro: #define GetSystemClock() +* +* Overview: This macro returns the system clock frequency in Hertz. +* * value is 8 MHz x 4 PLL for PIC24 +* * value is 8 MHz/2 x 18 PLL for PIC32 +* +********************************************************************/ +#if defined(__PIC24F__) + #define GetSystemClock() (32000000ul) +#elif defined(__PIC32MX__) + #define GetSystemClock() (72000000ul) +#elif defined(__dsPIC33F__) || defined(__PIC24H__) + #define GetSystemClock() (80000000ul) +#elif defined(_STM32_) + #define GetSystemClock() (72000000ul) +#endif + +/********************************************************************* +* Macro: #define GetPeripheralClock() +* +* Overview: This macro returns the peripheral clock frequency +* used in Hertz. +* * value for PIC24 is
(GetSystemClock()/2) 
+* * value for PIC32 is
(GetSystemClock()/(1<
+*
+********************************************************************/
+#if defined(__PIC24F__)	|| defined(__PIC24H__) || defined(__dsPIC33F__)
+	#define	GetPeripheralClock()		(GetSystemClock()/2)
+#elif defined(__PIC32MX__)
+	#define	GetPeripheralClock()		(GetSystemClock()/(1<(GetSystemClock()/2) 
+* * value for PIC32 is (GetSystemClock()/PFMWSbits.CHECON) +* +********************************************************************/ +#if defined(__PIC24F__) || defined(__PIC24H__) || defined(__dsPIC33F__) + #define GetInstructionClock() (GetSystemClock()/2) +#elif defined(__PIC32MX__) + #define GetInstructionClock() (GetSystemClock()/PFMWSbits.CHECON) +#elif defined(_STM32_) + #define GetInstructionClock() (GetSystemClock()) +#endif + + +/********************************************************************* +* IOS FOR THE DISPLAY CONTROLLER +*********************************************************************/ +#if (GRAPHICS_PICTAIL_VERSION == 1) + +// Definitions for reset pin +#define RST_TRIS_BIT TRISCbits.TRISC1 +#define RST_LAT_BIT LATCbits.LATC1 + +// Definitions for RS pin +#define RS_TRIS_BIT TRISBbits.TRISB15 +#define RS_LAT_BIT LATBbits.LATB15 + +// Definitions for CS pin +#define CS_TRIS_BIT TRISDbits.TRISD8 +#define CS_LAT_BIT LATDbits.LATD8 + +// Definitions for FLASH CS pin +#define CS_FLASH_LAT_BIT LATDbits.LATD9 +#define CS_FLASH_TRIS_BIT TRISDbits.TRISD9 + + +#elif (GRAPHICS_PICTAIL_VERSION == 2) + +#if (DISPLAY_CONTROLLER == LGDP4531) + +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + +// Definitions for reset pin +#define RST_TRIS_BIT TRISAbits.TRISA4 +#define RST_LAT_BIT LATAbits.LATA4 + +// Definitions for RS pin +#define RS_TRIS_BIT TRISAbits.TRISA1 +#define RS_LAT_BIT LATAbits.LATA1 + +// Definitions for CS pin +#define CS_TRIS_BIT TRISBbits.TRISB15 +#define CS_LAT_BIT LATBbits.LATB15 + +// Definitions for FLASH CS pin +#define CS_FLASH_LAT_BIT LATAbits.LATA8 +#define CS_FLASH_TRIS_BIT TRISAbits.TRISA8 + +// Definitions for POWER ON pin +#define POWERON_LAT_BIT LATAbits.LATA10 +#define POWERON_TRIS_BIT TRISAbits.TRISA10 + +#else + +// Definitions for reset pin +#define RST_TRIS_BIT TRISCbits.TRISC1 +#define RST_LAT_BIT LATCbits.LATC1 + +// Definitions for RS pin +#define RS_TRIS_BIT TRISCbits.TRISC2 +#define RS_LAT_BIT LATCbits.LATC2 + +// Definitions for CS pin +#define CS_TRIS_BIT TRISDbits.TRISD10 +#define CS_LAT_BIT LATDbits.LATD10 + +// Definitions for FLASH CS pin +#define CS_FLASH_LAT_BIT LATDbits.LATD1 +#define CS_FLASH_TRIS_BIT TRISDbits.TRISD1 + +// Definitions for POWER ON pin +#define POWERON_LAT_BIT LATCbits.LATC3 +#define POWERON_TRIS_BIT TRISCbits.TRISC3 + +#endif + +#elif (DISPLAY_CONTROLLER == SSD1906) + +// Definitions for reset line +#define RST_TRIS_BIT TRISCbits.TRISC1 +#define RST_LAT_BIT LATCbits.LATC1 + +// Definitions for RS line +#define RS_TRIS_BIT TRISCbits.TRISC2 +#define RS_LAT_BIT LATCbits.LATC2 + +// Definitions for CS line +#define CS_TRIS_BIT TRISDbits.TRISD10 +#define CS_LAT_BIT LATDbits.LATD10 + +// Definitions for A0 line +#define A0_LAT_BIT LATDbits.LATD3 +#define A0_TRIS_BIT TRISDbits.TRISD3 + +// Definitions for A17 line +#define A17_LAT_BIT LATGbits.LATG14 +#define A17_TRIS_BIT TRISGbits.TRISG14 + +#else + +#error GRAPHICS CONTROLLER IS NOT SUPPORTED + +#endif // (DISPLAY_CONTROLLER == ... + +#elif (GRAPHICS_PICTAIL_VERSION == 3) + +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + +// Definitions for reset pin +#define RST_TRIS_BIT TRISAbits.TRISA4 +#define RST_LAT_BIT LATAbits.LATA4 + +// Definitions for RS pin +#define RS_TRIS_BIT TRISAbits.TRISA1 +#define RS_LAT_BIT LATAbits.LATA1 + +// Definitions for CS pin +#define CS_TRIS_BIT TRISBbits.TRISB15 +#define CS_LAT_BIT LATBbits.LATB15 + +#else + +// Definitions for reset line +#define RST_TRIS_BIT TRISCbits.TRISC1 +#define RST_LAT_BIT LATCbits.LATC1 + +// Definitions for RS line +#define RS_TRIS_BIT TRISCbits.TRISC2 +#define RS_LAT_BIT LATCbits.LATC2 + +// Definitions for CS line +#define CS_TRIS_BIT TRISDbits.TRISD10 +#define CS_LAT_BIT LATDbits.LATD10 + +#endif + +#endif // (GRAPHICS_PICTAIL_VERSION == ... + +/********************************************************************* +* IO FOR THE BEEPER +*********************************************************************/ +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) +#define BEEP_TRIS_BIT TRISBbits.TRISB4 +#define BEEP_LAT_BIT LATBbits.LATB4 +#else +#define BEEP_TRIS_BIT TRISDbits.TRISD0 +#define BEEP_LAT_BIT LATDbits.LATD0 +#endif + +/********************************************************************* +* IOS FOR THE FLASH/EEPROM SPI +*********************************************************************/ +#if (GRAPHICS_PICTAIL_VERSION < 3) + +#if defined (__C30__) + #if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + #define EEPROM_CS_TRIS TRISAbits.TRISA0 + #define EEPROM_CS_LAT LATAbits.LATA0 + #elif defined( __PIC24FJ256GB110__ ) + // This PIM has RD12 rerouted to RG0 + #define EEPROM_CS_TRIS TRISGbits.TRISG0 + #define EEPROM_CS_LAT LATGbits.LATG0 + #else + #define EEPROM_CS_TRIS TRISDbits.TRISD12 + #define EEPROM_CS_LAT LATDbits.LATD12 + #endif +#elif defined( __PIC32MX__ ) + #define EEPROM_CS_TRIS TRISDbits.TRISD12 + #define EEPROM_CS_LAT LATDbits.LATD12 +#endif + +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) +#define EEPROM_SCK_TRIS TRISCbits.TRISC2 +#define EEPROM_SDO_TRIS TRISCbits.TRISC0 +#define EEPROM_SDI_TRIS TRISCbits.TRISC1 +#else +#define EEPROM_SCK_TRIS TRISGbits.TRISG6 +#define EEPROM_SDO_TRIS TRISGbits.TRISG8 +#define EEPROM_SDI_TRIS TRISGbits.TRISG7 +#endif + +#else + +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) +#define SST25_CS_TRIS TRISAbits.TRISA8 +#define SST25_CS_LAT LATAbits.LATA8 +#define SST25_SCK_TRIS TRISCbits.TRISC2 +#define SST25_SDO_TRIS TRISCbits.TRISC0 +#define SST25_SDI_TRIS TRISCbits.TRISC1 +#else +#define SST25_CS_TRIS TRISDbits.TRISD1 +#define SST25_CS_LAT LATDbits.LATD1 +#define SST25_SCK_TRIS TRISGbits.TRISG6 +#define SST25_SDO_TRIS TRISGbits.TRISG8 +#define SST25_SDI_TRIS TRISGbits.TRISG7 +#endif + +#endif + +/********************************************************************* +* IOS FOR THE TOUCH SCREEN +*********************************************************************/ +// ADC channel constants +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + #define ADC_TEMP 4 + #define ADC_POT 0 + #define ADC_POT_TRIS TRISAbits.TRISA0 + #define ADC_POT_PCFG AD1PCFGLbits.PCFG0 +#elif defined(__PIC32MX__) + #define ADC_TEMP ADC_CH0_POS_SAMPLEA_AN4 + #define ADC_POT ADC_CH0_POS_SAMPLEA_AN5 +#else + #define ADC_TEMP 4 + #define ADC_POT 5 +#endif + +#if (GRAPHICS_PICTAIL_VERSION == 1) + + #ifdef __PIC32MX__ + #define ADC_XPOS ADC_CH0_POS_SAMPLEA_AN13 + #define ADC_YPOS ADC_CH0_POS_SAMPLEA_AN12 + #else + #define ADC_XPOS 13 + #define ADC_YPOS 12 + #endif + + // Y port definitions + #define ADPCFG_XPOS AD1PCFGbits.PCFG13 + #define LAT_XPOS LATBbits.LATB13 + #define LAT_XNEG LATBbits.LATB11 + #define TRIS_XPOS TRISBbits.TRISB13 + #define TRIS_XNEG TRISBbits.TRISB11 + + // X port definitions + #define ADPCFG_YPOS AD1PCFGbits.PCFG12 + #define LAT_YPOS LATBbits.LATB12 + #define LAT_YNEG LATBbits.LATB10 + #define TRIS_YPOS TRISBbits.TRISB12 + #define TRIS_YNEG TRISBbits.TRISB10 + +#elif (GRAPHICS_PICTAIL_VERSION == 2) + + #if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + #define ADC_XPOS 5 + #define ADC_YPOS 4 + #elif defined(__PIC32MX__) + #define ADC_XPOS ADC_CH0_POS_SAMPLEA_AN11 + #define ADC_YPOS ADC_CH0_POS_SAMPLEA_AN10 + #else + #define ADC_XPOS 11 + #define ADC_YPOS 10 + #endif + + #if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + + // Y port definitions + #define ADPCFG_XPOS AD1PCFGLbits.PCFG5 + #define LAT_XPOS LATBbits.LATB3 + #define LAT_XNEG LATCbits.LATC9 + #define TRIS_XPOS TRISBbits.TRISB3 + #define TRIS_XNEG TRISCbits.TRISC9 + + // X port definitions + #define ADPCFG_YPOS AD1PCFGLbits.PCFG4 + #define LAT_YPOS LATBbits.LATB2 + #define LAT_YNEG LATCbits.LATC8 + #define TRIS_YPOS TRISBbits.TRISB2 + #define TRIS_YNEG TRISCbits.TRISC8 + + #else + + // Y port definitions + #define ADPCFG_XPOS AD1PCFGbits.PCFG11 + #define LAT_XPOS LATBbits.LATB11 + #define LAT_XNEG LATGbits.LATG13 + #define TRIS_XPOS TRISBbits.TRISB11 + #define TRIS_XNEG TRISGbits.TRISG13 + + // X port definitions + #define ADPCFG_YPOS AD1PCFGbits.PCFG10 + #define LAT_YPOS LATBbits.LATB10 + #define LAT_YNEG LATGbits.LATG12 + #define TRIS_YPOS TRISBbits.TRISB10 + #define TRIS_YNEG TRISGbits.TRISG12 + + #endif + +#elif (GRAPHICS_PICTAIL_VERSION == 3) + + #if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + #define ADC_XPOS 5 + #define ADC_YPOS 4 + #elif defined(__PIC32MX__) + #define ADC_XPOS ADC_CH0_POS_SAMPLEA_AN11 + #define ADC_YPOS ADC_CH0_POS_SAMPLEA_AN10 + #else + #define ADC_XPOS 11 + #define ADC_YPOS 10 + #endif + + #if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) + + // Y port definitions + #define ADPCFG_XPOS AD1PCFGLbits.PCFG5 + #define LAT_XPOS LATBbits.LATB3 + #define LAT_XNEG LATCbits.LATC9 + #define TRIS_XPOS TRISBbits.TRISB3 + #define TRIS_XNEG TRISCbits.TRISC9 + + // X port definitions + #define ADPCFG_YPOS AD1PCFGLbits.PCFG4 + #define LAT_YPOS LATBbits.LATB2 + #define LAT_YNEG LATCbits.LATC8 + #define TRIS_YPOS TRISBbits.TRISB2 + #define TRIS_YNEG TRISCbits.TRISC8 + + #else + + // Y port definitions + #define ADPCFG_XPOS AD1PCFGbits.PCFG11 + #define LAT_XPOS LATBbits.LATB11 + #define LAT_XNEG LATDbits.LATD9 + #define TRIS_XPOS TRISBbits.TRISB11 + #define TRIS_XNEG TRISDbits.TRISD9 + + // X port definitions + #define ADPCFG_YPOS AD1PCFGbits.PCFG10 + #define LAT_YPOS LATBbits.LATB10 + #define LAT_YNEG LATDbits.LATD8 + #define TRIS_YPOS TRISBbits.TRISB10 + #define TRIS_YNEG TRISDbits.TRISD8 + + #endif + +#endif + +/********************************************************************* +* IOS FOR THE SIDE BUTTONS +*********************************************************************/ +#if defined(__dsPIC33FJ128GP804__) || defined(__PIC24HJ128GP504__) +#define BTN_S3 PORTAbits.RA9 +#define BTN_S4 0 +#define BTN_S5 0 +#define BTN_S6 0 +#else +#define BTN_S3 PORTDbits.RD6 +#define BTN_S4 PORTDbits.RD13 +#define BTN_S5 PORTAbits.RA7 +#define BTN_S6 PORTDbits.RD7 +#endif + +#endif // __HARDWARE_PROFILE_H diff --git a/libraries/oleddrv/StringResource.c b/libraries/oleddrv/StringResource.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/StringResource.c @@ -0,0 +1,190 @@ +/******************************************************************************* +* File Name : StringResource.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-01-21 +* Description : String resouce file +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "menu.h" +#include "StringResource.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +const LPCSTR StringTable_ENG[STR_LAST] = +{ + [STR_DEFAULT] = "Press to quit...", + [STR_ROOT] = "Quit", + [STR_STATUS] = "Status", + [STR_TEST] = "Test", + [STR_SETTING] = "Setting", + [STR_ABOUT] = "About", + [STR_SETTING_CONTRAST] = "Contrast", + [STR_SETTING_TIME] = "Time", + [STR_STATUS_BAT] = "Battary", + [STR_STATUS_GRAVITY] = "Gravity", + [STR_SETTING_LANGUAGE] = "Language", + [STR_LANG_ENG] = "English", + [STR_LANG_CHS] = "ChineseS", + [STR_CHANGE_CONTRAST] = "Change contrast:", + [STR_SET_TIME] = "Set time:", + [STR_VIEW_BATTARY] = "Battary status:", + [STR_BAT_CHARGE] = "Charging ...", + [STR_BAT_FULL] = "Charge finish", + [STR_BAT_NORMAL] = "Disconnected", + [STR_BAT_CAPACITY] = "Capacity:", + [STR_BAT_VOLTAGE] = "Voltage: ", + [STR_ABOUT_0] = "Oled Project 1.0", + [STR_ABOUT_1] = "lxyppc@163.com", + [STR_ABOUT_2] = "All rights reserved", + [STR_OK] = "OK", + [STR_CANCEL] = "Cancel", + [STR_JAN] = "Jan", + [STR_FEB] = "Feb", + [STR_MAR] = "Mar", + [STR_APR] = "Apr", + [STR_MAY] = "May", + [STR_JUN] = "Jun", + [STR_JUL] = "Jul", + [STR_AUG] = "Aug", + [STR_SEP] = "Sep", + [STR_OCT] = "Oct", + [STR_NOV] = "Nov", + [STR_DEC] = "Dec", + [STR_SUNDAY] = "Sun", + [STR_MONDAY] = "Mon", + [STR_TUESDAY] = "Tue", + [STR_WEDNESDAY] = "Wed", + [STR_THURSDAY] = "Thu", + [STR_FRIDAY] = "Fri", + [STR_SATURDAY] = "Sat", + [STR_AM] = "am", + [STR_PM] = "pm", + [STR_YEAR] = " Year:", + [STR_MONTH] = " Month:", + [STR_DATE] = " Date:", + [STR_HOUR] = " Hour:", + [STR_MINUTE] = "Minute:", +}; + +const LPCSTR StringTable_CHS[STR_LAST] = +{ + /* + [STR_DEFAULT] = "按中键退出", + [STR_ROOT] = "退出", + [STR_STATUS] = "设备状态", + [STR_TEST] = "测试", + [STR_SETTING] = "设置", + [STR_ABOUT] = "关于", + [STR_SETTING_CONTRAST] = "对比度", + [STR_SETTING_TIME] = "时间", + [STR_STATUS_BAT] = "电池", + [STR_STATUS_GRAVITY] = "重力加速度", + [STR_SETTING_LANGUAGE] = "语言", + [STR_LANG_ENG] = "英语", + [STR_LANG_CHS] = "简体中文", + [STR_CHANGE_CONTRAST] = "更改对比度:", + [STR_SET_TIME] = "设置时间:", + [STR_VIEW_BATTARY] = "电池状态:", + [STR_BAT_CHARGE] = "充电中 ...", + [STR_BAT_FULL] = "充电完成", + [STR_BAT_NORMAL] = "断开连接", + [STR_BAT_CAPACITY] = "当前容量:", + [STR_BAT_VOLTAGE] = "当前电压: ", + [STR_ABOUT_0] = "Oled 项目 1.0", + [STR_ABOUT_1] = "lxyppc@163.com", + [STR_ABOUT_2] = "版权所有", + [STR_OK] = "确定", + [STR_CANCEL] = "取消", + [STR_JAN] = " 1月", + [STR_FEB] = " 2月", + [STR_MAR] = " 3月", + [STR_APR] = " 4月", + [STR_MAY] = " 5月", + [STR_JUN] = " 6月", + [STR_JUL] = " 7月", + [STR_AUG] = " 8月", + [STR_SEP] = " 9月", + [STR_OCT] = "10月", + [STR_NOV] = "11月", + [STR_DEC] = "12月", + [STR_SUNDAY] = "周日", + [STR_MONDAY] = "周一", + [STR_TUESDAY] = "周二", + [STR_WEDNESDAY] = "周三", + [STR_THURSDAY] = "周四", + [STR_FRIDAY] = "周五", + [STR_SATURDAY] = "周六", + [STR_AM] = "上午", + [STR_PM] = "下午", + [STR_YEAR] = " 年度:", + [STR_MONTH] = " 月份:", + [STR_DATE] = " 日期:", + [STR_HOUR] = " 小时:", + [STR_MINUTE] = " 分钟:", + */ + [STR_DEFAULT] = /*"按中键退出"*/"\xA4\x84\xC6\xC1\x8D", + [STR_ROOT] = /*"退出"*/"\xC1\x8D", + [STR_STATUS] = /*"设备状态"*/"\xBD\x97\xB5\xA1", + [STR_TEST] = /*"测试"*/"\xB2\xBE", + [STR_SETTING] = /*"设置"*/"\xBD\xBA", + [STR_ABOUT] = /*"关于"*/"\x8C\x86", + [STR_SETTING_CONTRAST] = /*"对比度"*/"\x9B\xB0\x9E", + [STR_SETTING_TIME] = /*"时间"*/"\xAA\xC7", + [STR_STATUS_BAT] = /*"电池"*/"\xB6\xB1", + [STR_STATUS_GRAVITY] = /*"重力加速度"*/"\xC3\x90\x91\xC2\x9E", + [STR_SETTING_LANGUAGE] = /*"语言"*/"\xBF\xBC", + [STR_LANG_ENG] = /*"英语"*/"\xBB\xBF", + [STR_LANG_CHS] = /*"简体中文"*/"\xB9\x89\x84\xA7", + [STR_CHANGE_CONTRAST] = /*"更改对比度:"*/"\xAB\xA6\x9B\xB0\x9E:", + [STR_SET_TIME] = /*"设置时间:"*/"\xBD\xBA\xAA\xC7:", + [STR_VIEW_BATTARY] = /*"电池状态:"*/"\xB6\xB1\xB5\xA1:", + [STR_BAT_CHARGE] = /*"充电中 ..."*/"\x8A\xB6\x84 ...", + [STR_BAT_FULL] = /*"充电完成"*/"\x8A\xB6\x98\xA2", + [STR_BAT_NORMAL] = /*"断开连接"*/"\xA8\x9F\xC0\xA5", + [STR_BAT_CAPACITY] = /*"当前容量:"*/"\xA0\x8F\x9A\xC4:", + [STR_BAT_VOLTAGE] = /*"当前电压: "*/"\xA0\x8F\xB6\x93: ", + [STR_ABOUT_0] = /*"Oled 项目 1.0"*/"Oled \xC8\xB7 1.0", + [STR_ABOUT_1] = /*"lxyppc@163.com"*/"lxyppc@163.com", + [STR_ABOUT_2] = /*"版权所有"*/"\xB4\xAF\xA3\xAD", + [STR_OK] = /*"确定"*/"\xB8\x99", + [STR_CANCEL] = /*"取消"*/"\x94\xB3", + [STR_JAN] = /*" 1月"*/" 1\xAC", + [STR_FEB] = /*" 2月"*/" 2\xAC", + [STR_MAR] = /*" 3月"*/" 3\xAC", + [STR_APR] = /*" 4月"*/" 4\xAC", + [STR_MAY] = /*" 5月"*/" 5\xAC", + [STR_JUN] = /*" 6月"*/" 6\xAC", + [STR_JUL] = /*" 7月"*/" 7\xAC", + [STR_AUG] = /*" 8月"*/" 8\xAC", + [STR_SEP] = /*" 9月"*/" 9\xAC", + [STR_OCT] = /*"10月"*/"10\xAC", + [STR_NOV] = /*"11月"*/"11\xAC", + [STR_DEC] = /*"12月"*/"12\xAC", + [STR_SUNDAY] = /*"周日"*/"\x95\xA9", + [STR_MONDAY] = /*"周一"*/"\x95\x80", + [STR_TUESDAY] = /*"周二"*/"\x95\x85", + [STR_WEDNESDAY] = /*"周三"*/"\x95\x81", + [STR_THURSDAY] = /*"周四"*/"\x95\x96", + [STR_FRIDAY] = /*"周五"*/"\x95\x87", + [STR_SATURDAY] = /*"周六"*/"\x95\x8B", + [STR_AM] = /*"上午"*/"\x82\x92", + [STR_PM] = /*"下午"*/"\x83\x92", + [STR_YEAR] = /*" 年度:"*/" \x9D\x9E:", + [STR_MONTH] = /*" 月份:"*/" \xAC\x88:", + [STR_DATE] = /*" 日期:"*/" \xA9\xAE:", + [STR_HOUR] = /*" 小时:"*/" \x9C\xAA:", + [STR_MINUTE] = /*" 分钟:"*/" \x8E\xC5:", + +/* Replaced strings: + 一三上下中二于五份体充六关出分前力加午压取周四备完定容对小年度开当态成所按接改文断日时更月有期权比池测消版状电目确简置英言设试语连退速重量钟键间项 + 808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8 +*/ + +}; diff --git a/libraries/oleddrv/StringResource.h b/libraries/oleddrv/StringResource.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/StringResource.h @@ -0,0 +1,63 @@ +#ifndef STRING_RESOURCE_H +#define STRING_RESOURCE_H + +#define STR_DEFAULT 0 +#define STR_ROOT 1 +#define STR_STATUS 2 +#define STR_TEST 3 +#define STR_SETTING 4 +#define STR_ABOUT 5 +#define STR_SETTING_CONTRAST 6 +#define STR_SETTING_TIME 7 +#define STR_STATUS_BAT 8 +#define STR_STATUS_GRAVITY 9 +#define STR_SETTING_LANGUAGE 10 +#define STR_LANG_ENG 11 +#define STR_LANG_CHS 12 +#define STR_CHANGE_CONTRAST 13 +#define STR_SET_TIME 14 +#define STR_VIEW_BATTARY 15 +#define STR_BAT_CHARGE 16 +#define STR_BAT_FULL 17 +#define STR_BAT_NORMAL 18 +#define STR_BAT_CAPACITY 19 +#define STR_BAT_VOLTAGE 20 +#define STR_ABOUT_0 21 +#define STR_ABOUT_1 22 +#define STR_ABOUT_2 23 +#define STR_OK 24 +#define STR_CANCEL 25 +#define STR_JAN 26 +#define STR_FEB (STR_JAN+1)//27 +#define STR_MAR (STR_JAN+2)//28 +#define STR_APR (STR_JAN+3)//29 +#define STR_MAY (STR_JAN+4)//30 +#define STR_JUN (STR_JAN+5)//31 +#define STR_JUL (STR_JAN+6)//32 +#define STR_AUG (STR_JAN+7)//33 +#define STR_SEP (STR_JAN+8)//34 +#define STR_OCT (STR_JAN+9)//35 +#define STR_NOV (STR_JAN+10)//36 +#define STR_DEC (STR_JAN+11)//37 +#define STR_SUNDAY 38 +#define STR_MONDAY (STR_SUNDAY+1)//39 +#define STR_TUESDAY (STR_SUNDAY+2)//40 +#define STR_WEDNESDAY (STR_SUNDAY+3)//41 +#define STR_THURSDAY (STR_SUNDAY+4)//42 +#define STR_FRIDAY (STR_SUNDAY+5)//43 +#define STR_SATURDAY (STR_SUNDAY+6)//44 +#define STR_AM 45 +#define STR_PM (STR_AM+1)//46 +#define STR_YEAR 47 +#define STR_MONTH (STR_YEAR+1)//48 +#define STR_DATE (STR_YEAR+2)//49 +#define STR_HOUR (STR_YEAR+3)//50 +#define STR_MINUTE (STR_YEAR+4)//51 + +#define STR_LAST 52 + + +extern const LPCSTR StringTable_ENG[STR_LAST]; +extern const LPCSTR StringTable_CHS[STR_LAST]; + +#endif diff --git a/libraries/oleddrv/UserMenu.c b/libraries/oleddrv/UserMenu.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/UserMenu.c @@ -0,0 +1,698 @@ +/******************************************************************************* +* File Name : UserMenu.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-03-05 +* Description : User menu implemention +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" +#include "menu.h" +#include "SSD1303.h" +#include "Graphics\Graphics.h" +#include "time.h" +#include "icon.h" +#include "bsp.h" +#include "ClockUI.h" +#include "string.h" +#include "StringResource.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +//#define OnMeasureBat DefaultMenuFunc +//#define OnMeasureGravity DefaultMenuFunc +//#define OnSetContrast DefaultMenuFunc +//#define OnSetTime DefaultMenuFunc +//#define OnLanguageSet DefaultMenuFunc +/* Private variables ---------------------------------------------------------*/ +extern const MenuItem MainMenu[]; +extern const MenuItem SettingMenu[]; +extern const MenuItem StatusMenu[]; +extern const MenuItem LanguageMenu[]; +const LPCSTR* curLang = StringTable_CHS; +Device appDevice; +extern ADResult_t ADCResult; + +#define LoadString(STR_ID) curLang[(STR_ID)] +// January is 0 +#define LoadStrMonth(Month) LoadString(STR_JAN + (Month)) +// Sunday is 0 +#define LoadStrWeek(WeekDay) LoadString(STR_SUNDAY + (WeekDay)) +// Year is 0, then month,date,hour and minute +#define LoadStrTimeDesc(index) LoadString(STR_YEAR + (index)) + +//LPCSTR* MonthText = MonthText_En; +//LPCSTR* WeekText = WeekText_En; +//LPCSTR * SetTimeDesc = SetTimeDesc_En; +//LPCSTR* UserText = UserText_En; +//#define UserText (curLang) +//#define MonthText (curLang + STR_JAN) +//#define WeekText (curLang + STR_SUNDAY) +//#define SetTimeDesc (curLang + STR_YEAR) + +/* Private function prototypes -----------------------------------------------*/ +MenuResult OnMenuAbout(void* p, Msg* msg); +MenuResult OnMenuTest(void* p, Msg* msg); +MenuResult DefaultMenuFunc(void* p, Msg* msg); +MenuResult OnMenuRoot(void* param, Msg* msg); +MenuResult OnSetContrast(void* param, Msg* msg); +MenuResult OnSetTime(void* param, Msg* msg); +MenuResult OnMeasureGravity(void* param, Msg* msg); +MenuResult OnMeasureBat(void* param, Msg* msg); +MenuResult OnLanguageSet(void* param, Msg* msg); + +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************/ +/************************** Menu definitions begin ****************************/ +/* Root main */ +const MenuItem RootMenu = { + /*Parent child/pfn index cnt resource type*/ + 0, (void*)OnMenuRoot, 0, 1, STR_ROOT, MT_NULL +}; +/* Main menu */ +const MenuItem MainMenu[] = { + /*Parent child/pfn index cnt resource type*/ + { 0, StatusMenu, 0, 4, STR_STATUS, MT_SUB}, + { 0, (void*)OnMenuTest, 1, 4, STR_TEST, MT_NULL}, + { 0, SettingMenu, 2, 4, STR_SETTING, MT_SUB}, + { 0, (void*)OnMenuAbout, 3, 4, STR_ABOUT, MT_NULL}, +}; + +/* Setting menu */ +const MenuItem SettingMenu[] = { + /*Parent child/pfn index cnt resource type*/ + { MainMenu+2, (void*)OnSetContrast, 0, 3, STR_SETTING_CONTRAST, MT_NULL}, + { MainMenu+2, (void*)OnSetTime, 1, 3, STR_SETTING_TIME, MT_NULL}, + { MainMenu+2, LanguageMenu, 2, 3, STR_SETTING_LANGUAGE, MT_SUB}, +}; +/* Language menu*/ +const MenuItem LanguageMenu[] = { + /*Parent child/pfn index cnt resource type*/ + {SettingMenu+2, (void*)OnLanguageSet, 0, 2, STR_LANG_ENG, MT_NULL}, + {SettingMenu+2, (void*)OnLanguageSet, 1, 2, STR_LANG_CHS, MT_NULL}, +}; + +/**/ +const MenuItem StatusMenu[] = { + /*Parent child/pfn index cnt resource type*/ + { MainMenu+0, (void*)OnMeasureBat, 0, 2, STR_STATUS_BAT, MT_NULL}, + { MainMenu+0, (void*)OnMeasureGravity, 1, 2, STR_STATUS_GRAVITY, MT_NULL}, +}; +/************************** Menu definitions end ****************************/ +/******************************************************************************/ + +/******************************************************************************* +* Function Name : OnMenuAbout +* Description : Callback function for about menu +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnMenuAbout(void* p, Msg* msg) +{ + if(msg->message == MSG_INIT){ + SetColor(BLACK); + ClearDevice(); + TextOut(&appDevice, 0, 5,LoadString(STR_ABOUT_0), 0xFF); + TextOut(&appDevice, 0, 25,LoadString(STR_ABOUT_1), 0xFF); + TextOut(&appDevice, 0, 45,LoadString(STR_ABOUT_2), 0xFF); + return MR_Continue; + }else if(msg->message == MSG_KEY_UP){ + return MR_Finish; + } + return MR_Continue; +} + +/******************************************************************************* +* Function Name : OnMenuTest +* Description : Callback function for test menu +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnMenuTest(void* p, Msg* msg) +{ + if(msg->message == MSG_INIT){ + SetColor(BLACK); + ClearDevice(); + TextOut(&appDevice, 0, 0, "Scroll Test", 0xFF); + return MR_Continue; + }else if(msg->message == MSG_KEY_UP){ + return MR_Finish; + }else if(msg->message == MSG_SCROLL){ + s32 res = (s32)msg->param; + char buf[3] = "+"; + if(res<0){ + res = -res; + buf[0] = '-'; + } + static Pos_t x = 0; + static Pos_t y = 13; + buf[1] = res%10+'0'; + buf[2] = ','; + x = TextOut(&appDevice, x, y, buf, 3); + if(x > 110){ + x = 0; + y+=13; + } + if( y > 64-12){ + y = 13; + } + + } + return MR_Continue; +} + +/******************************************************************************* +* Function Name : DefaultMenuFunc +* Description : Default menu callback function +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult DefaultMenuFunc(void* p, Msg* msg) +{ + if(msg->message == MSG_INIT){ + SetColor(BLACK); + ClearDevice(); + TextOut(&appDevice, 0, 25,curLang[STR_DEFAULT], 0xFF); + return MR_Continue; + }else if(msg->message == MSG_KEY_UP){ + return MR_Finish; + } + return MR_Continue; +} + +/******************************************************************************* +* Function Name : GetBatCap +* Description : Get battery capacity +* Input : None +* Output : Battary capacity percentage +* Return : None +* Details : Battary fully charge is 4.2V, and lower power is 3.3V + Vref = 3.28V, resistive partial-pressure is 10K/13.6K + In 12 bit ADC, 4.2*10/13.6/3.28*4096 = 3875 + 3.3*10/13.6/3.28*4096 = 3030 +*******************************************************************************/ +unsigned long GetBatCap() +{ + u32 res = ADCResult.ADBat; + if(res > 3835){ + res = 800; + }else if(res < 3030){ + res = 0; + }else{ + res -= 3030; + } + return 100*res/800; +} + +/******************************************************************************* +* Function Name : UpdateBatIcon +* Description : Update the battery icon +* Input : Pos_t x position of the icon +* Pos_t y position of the icon +* u32 battery capacity, in percentage +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +void UpdateBatIcon(Pos_t x, Pos_t y,u32 cap) +{ + if(IsCHG()){ + DrawIcon(x,y,ICON_ID_CHARGE); + }else if(IsPGOOD()){ + DrawIcon(x,y,ICON_ID_POWER); + }else{ + DrawIcon(x,y,ICON_ID_BATTARY); + SetColor(BLACK); + SetLineThickness(NORMAL_LINE); + u32 res = cap*16/100; + res += 106; + Bar(res,2,121,7); + } +} + +/******************************************************************************* +* Function Name : OnMenuRoot +* Description : Root menu callback function +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnMenuRoot(void* param, Msg* msg) +{ + static u8 deviceClose = 0; + switch(msg->message){ + case MSG_INIT: + SetColor(BLACK); + ClearDevice(); + Clock_DrawFace(GetMaxY()>>1,GetMaxY()>>1,GetMaxY()>>1); + deviceClose = 0; + case MSG_SECOND: + { + Pos_t x = 70; + Pos_t y = 35; + time_t now = (time_t)RTC_GetCounter(); + struct tm* curTm = localtime(&now); + Clock_UpdateTime(curTm->tm_hour,curTm->tm_min,curTm->tm_sec); + u32 year = curTm->tm_year + 1900; + char tBuf[8] = {year/1000+'0',year/100%10+'0',year/10%10+'0',year%10+'0'}; + x = TextOut(&appDevice,x,y,tBuf,4); + x = TextOut(&appDevice,x,y," ",1); + x = TextOut(&appDevice,x,y,LoadStrWeek(curTm->tm_wday),3); + x = 70; + y += 13; + x = TextOut(&appDevice,x,y,LoadStrMonth(curTm->tm_mon),0xFF); + x = TextOut(&appDevice,x,y," ",1); + tBuf[0] = curTm->tm_mday/10+'0'; + tBuf[1] = curTm->tm_mday%10+'0'; + x = TextOut(&appDevice,x,y,tBuf,2); + x = TextOut(&appDevice,x,y," ",1); + x = TextOut(&appDevice,70,y-26,LoadString(curTm->tm_hour>12 ? STR_PM : STR_AM),2); + +#ifdef DEBUG_BOARD + { + DrawIcon(104,0,ICON_ID_BATTARY); + static u32 res1 = 16; + if(res1)res1--; + else res1=16; + u32 res = res1 + 106; + SetColor(BLACK); + SetLineThickness(NORMAL_LINE); + Bar(res,2,121,7); + } +#else + UpdateBatIcon(104,0,GetBatCap()); +#endif + } + break; + case MSG_KEY_UP: + if((u32)msg->param > SSD1303_FPS*2){ + deviceClose = 1; + SSD1303_TurnOff(); + MMA_SLEEP(); + }else if(deviceClose){ + deviceClose = 0; + SSD1303_TurnOn(); + MMA_WAKEUP(); + }else{ + PopupMenu(MainMenu); + return MR_Finish; + } + } + return MR_Continue; +} + +/******************************************************************************* +* Function Name : OnSetContrast +* Description : Set contrast menu callback function +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnSetContrast(void* param, Msg* msg) +{ + if(msg->message == MSG_INIT){ + SetColor(BLACK); + ClearDevice(); + TextOut(&appDevice,0,0,LoadString(STR_CHANGE_CONTRAST),0xFF); + u32 con = SSD1303_GetContrast(); + char buf[] = {con/100+'0',(con/10)%10+'0',con%10+'0'}; + TextOut(&appDevice,45,18,buf,3); + SetLineThickness(NORMAL_LINE); + SetColor(WHITE); + Rectangle(0,30,127,45); + con = 123*con/256 + 2; + Bar(2,32,con,43); + }else if(msg->message == MSG_SCROLL){ + s16 enc = (s16)((s32)msg->param); + u32 con = SSD1303_GetContrast(); + if(enc>0){ + if(con<255)con++; + }else if(con){ + con--; + } + char buf[] = {con/100+'0',(con/10)%10+'0',con%10+'0'}; + TextOut(&appDevice,45,18,buf,3); + SSD1303_SetContrast(con); + SetColor(BLACK); + Bar(2,32,125,43); + SetColor(WHITE); + con = 123*con/256 + 2; + Bar(2,32,con,43); + }else if(msg->message == MSG_KEY_UP){ + return MR_Finish; + } + return MR_Continue; +} + +typedef unsigned long(*pfnTextOut)(Device*,Pos_t,Pos_t,const char*,Size_t); +#define DrawOK() UpdateTimeText(TextOut,0, TI_OK) +#define DrawCancel() UpdateTimeText(TextOut,0, TI_Cancel) +#define HighLightOK() UpdateTimeText(TextOut_HighLight,0, TI_OK) +#define HighLightCancel() UpdateTimeText(TextOut_HighLight,0, TI_Cancel) +typedef enum{ + TI_All = 0, + TI_Year = 1, + TI_First = 1, + TI_Month = 2, + TI_Date = 3, + TI_Hour = 4, + TI_Minute = 5, + TI_OK = 6, + TI_Cancel = 7, + TI_Last = 8, + TI_Unknown = 0xFF, +}TimeIndex; +/******************************************************************************* +* Function Name : UpdateTimeText +* Description : Update texts when set time +* Input : pfnTextOut pointer of textOut Function +* struct tm* time structure to display +* TimeIndex time item index +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +void UpdateTimeText(pfnTextOut textOut,struct tm* pTM, TimeIndex timeIndex) +{ + u8 wid = GetFontTextWidth(appDevice.pfnFont,' '); + Pos_t yPos = 13; + switch(timeIndex){ + case TI_All:// Inital + textOut(&appDevice,2+16*wid,yPos,":",1); + case TI_Year:// year + { + u32 year = pTM->tm_year + 1900; + char buf[] = {year/1000+'0',year/100%10+'0',year/10%10+'0',year%10+'0'}; + textOut(&appDevice,2,yPos,buf,4); + } + if(timeIndex!=TI_All)break; + case TI_Month:// Month + textOut(&appDevice,2+5*wid,yPos,LoadStrMonth(pTM->tm_mon),3); + if(timeIndex!=TI_All)break; + case TI_Date:// Date + { + char buf[] = {pTM->tm_mday/10+'0',pTM->tm_mday%10+'0'}; + textOut(&appDevice,2+10*wid,yPos,buf,2); + } + if(timeIndex!=TI_All)break; + case TI_Hour:// Hour + { + char buf[] = {pTM->tm_hour/10+'0',pTM->tm_hour%10+'0'}; + textOut(&appDevice,2+14*wid,yPos,buf,2); + } + if(timeIndex!=TI_All)break; + case TI_Minute:// Minute + { + char buf[] = {pTM->tm_min/10+'0',pTM->tm_min%10+'0'}; + textOut(&appDevice,2+17*wid,yPos,buf,2); + } + if(timeIndex!=TI_All)break; + case TI_OK:// OK + textOut(&appDevice,2+1*wid,52,LoadString(STR_OK),2); + if(timeIndex!=TI_All)break; + case TI_Cancel:// cancel + textOut(&appDevice,126-7*wid,52,LoadString(STR_CANCEL),6); + if(timeIndex!=TI_All)break; + default: + break; + } +} + +#define Round(param,low,high) \ + if((param)<(low)){(param)=(high);}else if((param)>(high)){(param)=(low);} +/******************************************************************************* +* Function Name : ModifyTime +* Description : Set contrast menu callback function +* Input : int Current encoder roll dirction +* struct tm* time structure to be modified +* TimeIndex time item index +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +void ModifyTime(int enc, struct tm* pTM, TimeIndex timeIndex) +{ + switch(timeIndex){ + case TI_Year: + pTM->tm_year += enc; + Round(pTM->tm_year,-130,130); + { + u32 year = pTM->tm_year + 1900; + char buf[] = {year/1000+'0',year/100%10+'0',year/10%10+'0',year%10+'0'}; + TextOut_HighLight(&appDevice,64,30,buf,4); + } + break; + case TI_Month: + pTM->tm_mon += enc; + Round(pTM->tm_mon,0,11); + TextOut_HighLight(&appDevice,64,30,LoadStrMonth(pTM->tm_mon),3); + break; + case TI_Date: + pTM->tm_mday += enc; + Round(pTM->tm_mday,1,31); + { + char buf[] = {pTM->tm_mday/10+'0',pTM->tm_mday%10+'0'}; + TextOut_HighLight(&appDevice,64,30,buf,2); + } + break; + case TI_Hour: + pTM->tm_hour += enc; + Round(pTM->tm_hour,0,23); + { + char buf[] = {pTM->tm_hour/10+'0',pTM->tm_hour%10+'0'}; + TextOut_HighLight(&appDevice,64,30,buf,2); + } + break; + case TI_Minute: + pTM->tm_min += enc; + Round(pTM->tm_min,0,59); + { + char buf[] = {pTM->tm_min/10+'0',pTM->tm_min%10+'0'}; + TextOut_HighLight(&appDevice,64,30,buf,2); + } + break; + default: + break; + } +} + +/******************************************************************************* +* Function Name : OnSetTime +* Description : Set time menu callback function +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnSetTime(void* param, Msg* msg) +{ + static struct tm oldTm; + static TimeIndex position; + static TimeIndex lastPosition; + static u8 modifyMode; + if(msg->message == MSG_INIT){ + time_t now = (time_t)RTC_GetCounter(); + struct tm* ptm = localtime(&now); + memcpy(&oldTm,ptm,sizeof(oldTm)); + lastPosition = TI_Unknown; + position = TI_All; + SetColor(BLACK); + ClearDevice(); + TextOut(&appDevice,0,0,LoadString(STR_SET_TIME),0xFF); + UpdateTimeText(TextOut,&oldTm,position); + position++; + UpdateTimeText(TextOut_HighLight,&oldTm,position); + lastPosition = position; + modifyMode = 0; + }else if(msg->message == MSG_KEY_UP){ + if(position == TI_Cancel){ + return MR_Finish; + }else if(position == TI_OK){ + oldTm.tm_sec = 0; + RTC_SetCounter(mktime(&oldTm)); + RTC_WaitForLastTask(); + return MR_Finish; + }else if(position<7 && position>0){ + if(modifyMode){ + modifyMode = 0; + SetColor(BLACK); + Bar(10,30,100,50); + UpdateTimeText(TextOut_HighLight,&oldTm,position); + }else{ + modifyMode = 1; + TextOut(&appDevice,20,30,LoadStrTimeDesc(position-1),0xFF); + ModifyTime(0,&oldTm,position); + } + } + }else if(msg->message == MSG_SCROLL){ + int enc = (int)msg->param; + if(enc>0)enc=1; + else enc = -1; + if(modifyMode){ + ModifyTime(enc,&oldTm,position); + }else{ + position+=enc; + if(position>=TI_Last){ + position = TI_Year; + }else if(positionmessage == MSG_INIT){ + SetColor(BLACK); + ClearDevice(); + SetColor(WHITE); + SetLineThickness(NORMAL_LINE); + Rectangle(64,0,127,63); + Line(0,63,63,63); + Line(63,63,48,40); + Line(16,40,48,40); + Line(16,40,0,63); + MMA_WAKEUP(); + }else if(msg->message == MSG_KEY_UP){ + MMA_SLEEP(); + return MR_Finish; + }else if(msg->message == MSG_GRAV_XY){ + static u16 lastX = 64+64*2; + static u16 lastY = 64/2; + u16 gX = 4096-GetGravX(msg); + u16 gY = 4096-GetGravY(msg); + gX = gX*64 / 4096+64; + gY = gY*64 / 4096; + SetColor(BLACK); + FillCircle(lastX,lastY,2); + SetColor(WHITE); + FillCircle(gX,gY,2); + lastX = gX; + lastY = gY; + }else if(msg->message == MSG_GRAV_Z){ + static u16 lastZ = 50/2; + u16 gZ = GetGravZ(msg); + gZ = gZ*50 / 4096; + SetColor(BLACK); + Circle(32,lastZ,2); + SetColor(WHITE); + Circle(32,gZ,2); + lastZ = gZ; + } + return MR_Continue; +} + +/******************************************************************************* +* Function Name : OnMeasureBat +* Description : Measure battery menu callback function +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnMeasureBat(void* param, Msg* msg) +{ + switch(msg->message){ + case MSG_INIT: + SetColor(BLACK); + ClearDevice(); + TextOut(&appDevice,0,0,LoadString(STR_VIEW_BATTARY),0xFF); + case MSG_SECOND: + if(IsCHG()){ + TextOut(&appDevice,10,16,LoadString(STR_BAT_CHARGE),0xFF); + }else if(IsPGOOD()){ + TextOut(&appDevice,10,16,LoadString(STR_BAT_FULL),0xFF); + }else{ + TextOut(&appDevice,10,16,LoadString(STR_BAT_NORMAL),0xFF); + //DrawIcon(104,0,ICON_ID_BATTARY); + } + { + u32 res = GetBatCap(); + UpdateBatIcon(104,0,res); + char buf[4] = {res/100 + '0',res/10%10+'0',res%10+'0','%'}; + Pos_t x = TextOut(&appDevice,10,32,LoadString(STR_BAT_CAPACITY),0xFF); + x = TextOut(&appDevice,x,32,buf,4); + res = ADCResult.ADBat; + res = ((res*136*120) / ADCResult.ADRef) / 100; + + //res = res * 328 * 136 / (4096*100); + char ADBuf[] = {(res/100)%10+'0', '.', + (res/10)%10+'0', res%10+'0','V', 0}; + x = TextOut(&appDevice,10,48,LoadString(STR_BAT_VOLTAGE),0xFF); + TextOut(&appDevice,x,48,ADBuf,5); + } + break; + case MSG_KEY_UP: + return MR_Finish; + default: + break; + } + return MR_Continue; +} + +/******************************************************************************* +* Function Name : OnLanguageSet +* Description : Set language menu callback function +* Input : void* pointer of the menu item when message is MSG_INIT +* Output : Msg* pointer of the msg structure +* Return : None +*******************************************************************************/ +MenuResult OnLanguageSet(void* param, Msg* msg) +{ + static const LPCSTR* preLang = NULL; + static u8 curSel = 0; + switch(msg->message){ + case MSG_INIT: + { + SetColor(BLACK); + ClearDevice(); + switch(((const MenuItem*)param)->res){ + case STR_LANG_ENG: + preLang = StringTable_ENG; + TextOut(&appDevice,30,20,preLang[STR_LANG_ENG],0xFF); + break; + case STR_LANG_CHS: + default: + preLang = StringTable_CHS; + TextOut(&appDevice,30,20,preLang[STR_LANG_CHS],0xFF); + break; + } + curSel = 1; + } + case MSG_SCROLL: + { + curSel = !curSel; + const LPCSTR* tmp = curLang; + curLang = preLang; + if(curSel){ + HighLightOK(); + DrawCancel(); + }else{ + DrawOK(); + HighLightCancel(); + } + curLang = tmp; + } + break; + case MSG_KEY_UP: + if(curSel){ + curLang = preLang; + } + return MR_Finish; + } + + return MR_Continue; +} diff --git a/libraries/oleddrv/bsp.h b/libraries/oleddrv/bsp.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/bsp.h @@ -0,0 +1,93 @@ +#ifndef BSP_H +#define BSP_H + +/** + IO Connection map + + SSD1303 + Vcc 1 2 Gnd +D1/Data 3 4 D0/Clk + D3 5 6 D2 + D5 7 8 D4 + D7 9 10 D6 + WR 11 12 RD + RES 13 14 A0 (1-data,0-command) + CS 15 16 C86 (1-8080, 0-SPI) + + STM32 + D0/Clk PB13/SPI2 Clk + D1/Data PB15/SPI2 MOSI + RES PB12 + A0 PB14 + CS Gnd + D2~D7 (Float) + WR (Float) + RD (Float) + */ + +#define SSD_Clk GPIOB,GPIO_Pin_13 +#define SSD_Data GPIOB,GPIO_Pin_15 +#define SSD_Reset GPIOD,GPIO_Pin_12 +#define SSD_A0 GPIOD,GPIO_Pin_14 +#define SSD_CS //GPIOG,GPIO_Pin_2 + +#define SSD_Clk_Low() GPIOB->BRR = GPIO_Pin_13 +#define SSD_Clk_High() GPIOB->BSRR = GPIO_Pin_13 +#define SSD_Data_Low() GPIOB->BRR = GPIO_Pin_15 +#define SSD_Data_High() GPIOB->BSRR = GPIO_Pin_15 +#define SSD_Reset_Low() GPIOB->BRR = GPIO_Pin_12 +#define SSD_Reset_High() GPIOB->BSRR = GPIO_Pin_12 +#define SSD_A0_Low() GPIOB->BRR = GPIO_Pin_14 +#define SSD_A0_High() GPIOB->BSRR = GPIO_Pin_14 +#define SSD_CS_Low() //GPIOG->BRR = GPIO_Pin_2 +#define SSD_CS_High() //GPIOG->BSRR = GPIO_Pin_2 + +#define SPI_SendByte(data) SPI2->DR = (data) +#define SPI_Wait() while(!(SPI2->SR&SPI_I2S_FLAG_TXE));while(SPI2->SR&SPI_I2S_FLAG_BSY); + +#define SSD1303_FPS 50 + + + +#define IsLedOn() (!(GPIOA->ODR & GPIO_Pin_8)) +#define LED_ON() GPIOA->BRR = GPIO_Pin_8 +#define LED_OFF() GPIOA->BSRR = GPIO_Pin_8 +#define ToggleLED() if(GPIOA->ODR & GPIO_Pin_8){GPIOA->BRR = GPIO_Pin_8;}\ + else{GPIOA->BSRR = GPIO_Pin_8;} + +#define IsCHG() (!(GPIOB->IDR & GPIO_Pin_5)) +#define IsPGOOD() (!(GPIOB->IDR & GPIO_Pin_4)) + +#define GSel1_High() GPIOB->BSRR = GPIO_Pin_9 +#define GSel1_Low() GPIOB->BRR = GPIO_Pin_9 +#define GSel2_High() GPIOB->BSRR = GPIO_Pin_8 +#define GSel2_Low() GPIOB->BRR = GPIO_Pin_8 + +#define MMA_SLEEP() GPIOB->BRR = GPIO_Pin_11 +#define MMA_WAKEUP() GPIOB->BSRR = GPIO_Pin_11 +#define Is_MMA_WAKEUP() (GPIOB->ODR & GPIO_Pin_11) + +#define AD_CH_BAT ADC_Channel_4 +#define AD_CH_X ADC_Channel_1 +#define AD_CH_Y ADC_Channel_2 +#define AD_CH_Z ADC_Channel_3 +#define AD_CH_CHG ADC_Channel_9 +#define AD_CH_REF ADC_Channel_17 + +#define DMA_SSD_1303 DMA1_Channel5 +#define DMA_Handler_SSD_1303 DMA1_Channel5_IRQHandler +#define DMA_ADC DMA1_Channel1 + +#define Is_Enc_Key_Down() (!(GPIOA->IDR & GPIO_Pin_0)) + +typedef struct _ADResult_t +{ + uint16_t ADRef; // ADC1 + uint16_t ADBat; // ADC2 + uint16_t ADX; // ADC1 + uint16_t ADY; // ADC2 + uint16_t ADZ; // ADC1 + uint16_t ADChg; // ADC2 +}ADResult_t; + +#endif diff --git a/libraries/oleddrv/cortexm3_macro.s b/libraries/oleddrv/cortexm3_macro.s new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/cortexm3_macro.s @@ -0,0 +1,300 @@ +;******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** +;* File Name : cortexm3_macro.s +;* Author : MCD Application Team +;* Version : V2.0.2 +;* Date : 07/11/2008 +;* Description : Instruction wrappers for special Cortex-M3 instructions. +;* to be used with EWARM4.x toolchain. +;******************************************************************************* +; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS +; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. +; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, +; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE +; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING +; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. +;******************************************************************************* + + RSEG CODE:CODE(2) + + ; Exported functions + EXPORT __WFI + EXPORT __WFE + EXPORT __SEV + EXPORT __ISB + EXPORT __DSB + EXPORT __DMB + EXPORT __SVC + EXPORT __MRS_CONTROL + EXPORT __MSR_CONTROL + EXPORT __MRS_PSP + EXPORT __MSR_PSP + EXPORT __MRS_MSP + EXPORT __MSR_MSP + EXPORT __RESETPRIMASK + EXPORT __SETPRIMASK + EXPORT __READ_PRIMASK + EXPORT __RESETFAULTMASK + EXPORT __SETFAULTMASK + EXPORT __READ_FAULTMASK + EXPORT __BASEPRICONFIG + EXPORT __GetBASEPRI + EXPORT __REV_HalfWord + EXPORT __REV_Word + +;******************************************************************************* +; Function Name : __WFI +; Description : Assembler function for the WFI instruction. +; Input : None +; Return : None +;******************************************************************************* +__WFI + + WFI + BX r14 + +;******************************************************************************* +; Function Name : __WFE +; Description : Assembler function for the WFE instruction. +; Input : None +; Return : None +;******************************************************************************* +__WFE + + WFE + BX r14 + +;******************************************************************************* +; Function Name : __SEV +; Description : Assembler function for the SEV instruction. +; Input : None +; Return : None +;******************************************************************************* +__SEV + + SEV + BX r14 + +;******************************************************************************* +; Function Name : __ISB +; Description : Assembler function for the ISB instruction. +; Input : None +; Return : None +;******************************************************************************* +__ISB + + ISB + BX r14 + +;******************************************************************************* +; Function Name : __DSB +; Description : Assembler function for the DSB instruction. +; Input : None +; Return : None +;******************************************************************************* +__DSB + + DSB + BX r14 + +;******************************************************************************* +; Function Name : __DMB +; Description : Assembler function for the DMB instruction. +; Input : None +; Return : None +;******************************************************************************* +__DMB + + DMB + BX r14 + +;******************************************************************************* +; Function Name : __SVC +; Description : Assembler function for the SVC instruction. +; Input : None +; Return : None +;******************************************************************************* +__SVC + + SVC 0x01 + BX r14 + +;******************************************************************************* +; Function Name : __MRS_CONTROL +; Description : Assembler function for the MRS instruction. +; Input : None +; Return : - r0 : Cortex-M3 CONTROL register value. +;******************************************************************************* +__MRS_CONTROL + + MRS r0, CONTROL + BX r14 + +;******************************************************************************* +; Function Name : __MSR_CONTROL +; Description : Assembler function for the MSR instruction. +; Input : - r0 : Cortex-M3 CONTROL register new value. +; Return : None +;******************************************************************************* +__MSR_CONTROL + + MSR CONTROL, r0 + ISB + BX r14 + +;******************************************************************************* +; Function Name : __MRS_PSP +; Description : Assembler function for the MRS instruction. +; Input : None +; Return : - r0 : Process Stack value. +;******************************************************************************* +__MRS_PSP + + MRS r0, PSP + BX r14 + +;******************************************************************************* +; Function Name : __MSR_PSP +; Description : Assembler function for the MSR instruction. +; Input : - r0 : Process Stack new value. +; Return : None +;******************************************************************************* +__MSR_PSP + + MSR PSP, r0 ; set Process Stack value + BX r14 + +;******************************************************************************* +; Function Name : __MRS_MSP +; Description : Assembler function for the MRS instruction. +; Input : None +; Return : - r0 : Main Stack value. +;******************************************************************************* +__MRS_MSP + + MRS r0, MSP + BX r14 + +;******************************************************************************* +; Function Name : __MSR_MSP +; Description : Assembler function for the MSR instruction. +; Input : - r0 : Main Stack new value. +; Return : None +;******************************************************************************* +__MSR_MSP + + MSR MSP, r0 ; set Main Stack value + BX r14 + +;******************************************************************************* +; Function Name : __RESETPRIMASK +; Description : Assembler function to reset the PRIMASK. +; Input : None +; Return : None +;******************************************************************************* +__RESETPRIMASK + + CPSIE i + BX r14 + +;******************************************************************************* +; Function Name : __SETPRIMASK +; Description : Assembler function to set the PRIMASK. +; Input : None +; Return : None +;******************************************************************************* +__SETPRIMASK + + CPSID i + BX r14 + +;******************************************************************************* +; Function Name : __READ_PRIMASK +; Description : Assembler function to get the PRIMASK value. +; Input : None +; Return : - r0 : PRIMASK register value +;******************************************************************************* +__READ_PRIMASK + + MRS r0, PRIMASK + BX r14 + +;******************************************************************************* +; Function Name : __RESETFAULTMASK +; Description : Assembler function to reset the FAULTMASK. +; Input : None +; Return : None +;******************************************************************************* +__RESETFAULTMASK + + CPSIE f + BX r14 + +;******************************************************************************* +; Function Name : __SETFAULTMASK +; Description : Assembler function to set the FAULTMASK. +; Input : None +; Return : None +;******************************************************************************* +__SETFAULTMASK + + CPSID f + BX r14 + +;******************************************************************************* +; Function Name : __READ_FAULTMASK +; Description : Assembler function to get the FAULTMASK value. +; Input : None +; Return : - r0 : FAULTMASK register value +;******************************************************************************* +__READ_FAULTMASK + + MRS r0, FAULTMASK + BX r14 + +;******************************************************************************* +; Function Name : __BASEPRICONFIG +; Description : Assembler function to set the Base Priority. +; Input : - r0 : Base Priority new value +; Return : None +;******************************************************************************* +__BASEPRICONFIG + + MSR BASEPRI, r0 + BX r14 + +;******************************************************************************* +; Function Name : __GetBASEPRI +; Description : Assembler function to get the Base Priority value. +; Input : None +; Return : - r0 : Base Priority value +;******************************************************************************* +__GetBASEPRI + + MRS r0, BASEPRI_MAX + BX r14 + +;******************************************************************************* +; Function Name : __REV_HalfWord +; Description : Reverses the byte order in HalfWord(16-bit) input variable. +; Input : - r0 : specifies the input variable +; Return : - r0 : holds tve variable value after byte reversing. +;******************************************************************************* +__REV_HalfWord + + REV16 r0, r0 + BX r14 + +;******************************************************************************* +; Function Name : __REV_Word +; Description : Reverses the byte order in Word(32-bit) input variable. +; Input : - r0 : specifies the input variable +; Return : - r0 : holds tve variable value after byte reversing. +;******************************************************************************* +__REV_Word + + REV r0, r0 + BX r14 + + END + +;******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE***** diff --git a/libraries/oleddrv/font.c b/libraries/oleddrv/font.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/font.c @@ -0,0 +1,43 @@ +/******************************************************************************* +* File Name : font.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-01-21 +* Description : Font data file +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "DrawText.h" +#include "font.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/* Install font data for "宋体 小五"*/ +#include ".\Font\SongSmall5.c" + +unsigned long SongSmall5_DrawChar(pfnDrawBlock_t DrawBlock,Pos_t x, Pos_t y,unsigned int ch) +{ + if(DrawBlock == 0){ + if(ch>0x7f){ + if(x) return SongSmall5_Chinese_Width(ch); + else return SongSmall5_Chinese_Height(ch); + }else{ + if(x) return SongSmall5_English_Width(ch); + else return SongSmall5_English_Height(ch); + } + } + if(ch>0x7F){ + DrawBlock(x,y,12,12,SongSmall5_Chinese[ch-0x80].data); + return SongSmall5_Chinese_Width(ch); + }else if(ch>0x1F){ + DrawBlock(x,y,6,12,SongSmall5_English[ch-0x20].data); + }else{ + DrawBlock(x,y,6,12,SongSmall5_English[0x7F-0x20].data); + } + return SongSmall5_English_Width(ch); +} diff --git a/libraries/oleddrv/font.h b/libraries/oleddrv/font.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/font.h @@ -0,0 +1,11 @@ +#ifndef FONT_H +#define FONT_H + +typedef unsigned long(*pfnFontDrawChar)(pfnDrawBlock_t DrawBlock,Pos_t x, Pos_t y, unsigned int ch); + +unsigned long SongSmall5_DrawChar(pfnDrawBlock_t DrawBlock,Pos_t x, Pos_t y,unsigned int ch); + +#define GetFontTextHeight(pfnFont,ch) pfnFont(0,0,0,(unsigned char)(ch)) +#define GetFontTextWidth(pfnFont,ch) pfnFont(0,1,0,(unsigned char)(ch)) + +#endif diff --git a/libraries/oleddrv/font/SongSmall5.c b/libraries/oleddrv/font/SongSmall5.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/font/SongSmall5.c @@ -0,0 +1,305 @@ +/******************************************************************************* +* File Name : SongSmall5.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-03-07 +* Description : Font data for "宋体 小五" +*******************************************************************************/ + +#define SongSmall5_English_Height(ch) (12) +#define SongSmall5_English_Width(ch) (6) +const struct +{ + unsigned char data[12]; +}SongSmall5_English[0x60] = { + /* Char Code {data} */ + {/* 0x0020*/ { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* ! 0x0021*/ { + 0x00,0x00,0xFC,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,}}, + {/* " 0x0022*/ { + 0x00,0x0C,0x02,0x0C,0x02,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* # 0x0023*/ { + 0x90,0xD0,0xBC,0xD0,0xBC,0x90,0x00,0x03, + 0x00,0x03,0x00,0x00,}}, + {/* $ 0x0024*/ { + 0x18,0x24,0xFE,0x44,0x8C,0x00,0x03,0x02, + 0x07,0x02,0x01,0x00,}}, + {/* % 0x0025*/ { + 0x18,0x24,0xD8,0xB0,0x4C,0x80,0x00,0x03, + 0x00,0x01,0x02,0x01,}}, + {/* & 0x0026*/ { + 0xC0,0x38,0xE4,0x38,0xE0,0x00,0x01,0x02, + 0x02,0x01,0x02,0x02,}}, + {/* ' 0x0027*/ { + 0x08,0x06,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* ( 0x0028*/ { + 0x00,0x00,0x00,0xF8,0x04,0x02,0x00,0x00, + 0x00,0x01,0x02,0x04,}}, + {/* ) 0x0029*/ { + 0x00,0x02,0x04,0xF8,0x00,0x00,0x00,0x04, + 0x02,0x01,0x00,0x00,}}, + {/* * 0x002A*/ { + 0x90,0x60,0xF8,0x60,0x90,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,}}, + {/* + 0x002B*/ { + 0x20,0x20,0xFC,0x20,0x20,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,}}, + {/* , 0x002C*/ { + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x06, + 0x00,0x00,0x00,0x00,}}, + {/* - 0x002D*/ { + 0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* . 0x002E*/ { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02, + 0x00,0x00,0x00,0x00,}}, + {/* / 0x002F*/ { + 0x00,0x80,0x60,0x1C,0x02,0x00,0x04,0x03, + 0x00,0x00,0x00,0x00,}}, + {/* 0 0x0030*/ { + 0xF8,0x04,0x04,0x04,0xF8,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* 1 0x0031*/ { + 0x00,0x08,0xFC,0x00,0x00,0x00,0x00,0x02, + 0x03,0x02,0x00,0x00,}}, + {/* 2 0x0032*/ { + 0x18,0x84,0x44,0x24,0x18,0x00,0x03,0x02, + 0x02,0x02,0x02,0x00,}}, + {/* 3 0x0033*/ { + 0x08,0x04,0x24,0x24,0xD8,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* 4 0x0034*/ { + 0x40,0xB0,0x88,0xFC,0x80,0x00,0x00,0x00, + 0x00,0x03,0x02,0x00,}}, + {/* 5 0x0035*/ { + 0x3C,0x24,0x24,0x24,0xC4,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* 6 0x0036*/ { + 0xF8,0x24,0x24,0x2C,0xC0,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* 7 0x0037*/ { + 0x0C,0x04,0xE4,0x1C,0x04,0x00,0x00,0x00, + 0x03,0x00,0x00,0x00,}}, + {/* 8 0x0038*/ { + 0xD8,0x24,0x24,0x24,0xD8,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* 9 0x0039*/ { + 0x38,0x44,0x44,0x44,0xF8,0x00,0x00,0x03, + 0x02,0x02,0x01,0x00,}}, + {/* : 0x003A*/ { + 0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,}}, + {/* ; 0x003B*/ { + 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00, + 0x06,0x00,0x00,0x00,}}, + {/* < 0x003C*/ { + 0x00,0x20,0x50,0x88,0x04,0x02,0x00,0x00, + 0x00,0x00,0x01,0x02,}}, + {/* = 0x003D*/ { + 0x90,0x90,0x90,0x90,0x90,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* > 0x003E*/ { + 0x00,0x02,0x04,0x88,0x50,0x20,0x00,0x02, + 0x01,0x00,0x00,0x00,}}, + {/* ? 0x003F*/ { + 0x18,0x04,0xC4,0x24,0x18,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,}}, + {/* @ 0x0040*/ { + 0xF8,0x04,0xE4,0x94,0xF8,0x00,0x01,0x02, + 0x02,0x02,0x02,0x00,}}, + {/* A 0x0041*/ { + 0x00,0xE0,0x9C,0xF0,0x80,0x00,0x02,0x03, + 0x00,0x00,0x03,0x02,}}, + {/* B 0x0042*/ { + 0x04,0xFC,0x24,0x24,0xD8,0x00,0x02,0x03, + 0x02,0x02,0x01,0x00,}}, + {/* C 0x0043*/ { + 0xF8,0x04,0x04,0x04,0x0C,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* D 0x0044*/ { + 0x04,0xFC,0x04,0x04,0xF8,0x00,0x02,0x03, + 0x02,0x02,0x01,0x00,}}, + {/* E 0x0045*/ { + 0x04,0xFC,0x24,0x74,0x0C,0x00,0x02,0x03, + 0x02,0x02,0x03,0x00,}}, + {/* F 0x0046*/ { + 0x04,0xFC,0x24,0x74,0x0C,0x00,0x02,0x03, + 0x02,0x00,0x00,0x00,}}, + {/* G 0x0047*/ { + 0xF0,0x08,0x04,0x44,0xCC,0x40,0x00,0x01, + 0x02,0x02,0x01,0x00,}}, + {/* H 0x0048*/ { + 0x04,0xFC,0x20,0x20,0xFC,0x04,0x02,0x03, + 0x00,0x00,0x03,0x02,}}, + {/* I 0x0049*/ { + 0x04,0x04,0xFC,0x04,0x04,0x00,0x02,0x02, + 0x03,0x02,0x02,0x00,}}, + {/* J 0x004A*/ { + 0x00,0x04,0x04,0xFC,0x04,0x04,0x06,0x04, + 0x04,0x03,0x00,0x00,}}, + {/* K 0x004B*/ { + 0x04,0xFC,0x24,0xD0,0x0C,0x04,0x02,0x03, + 0x02,0x00,0x03,0x02,}}, + {/* L 0x004C*/ { + 0x04,0xFC,0x04,0x00,0x00,0x00,0x02,0x03, + 0x02,0x02,0x02,0x03,}}, + {/* M 0x004D*/ { + 0xFC,0x3C,0xC0,0x3C,0xFC,0x00,0x03,0x00, + 0x03,0x00,0x03,0x00,}}, + {/* N 0x004E*/ { + 0x04,0xFC,0x30,0xC4,0xFC,0x04,0x02,0x03, + 0x02,0x00,0x03,0x00,}}, + {/* O 0x004F*/ { + 0xF8,0x04,0x04,0x04,0xF8,0x00,0x01,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* P 0x0050*/ { + 0x04,0xFC,0x24,0x24,0x18,0x00,0x02,0x03, + 0x02,0x00,0x00,0x00,}}, + {/* Q 0x0051*/ { + 0xF8,0x84,0x84,0x04,0xF8,0x00,0x01,0x02, + 0x02,0x07,0x05,0x00,}}, + {/* R 0x0052*/ { + 0x04,0xFC,0x24,0x64,0x98,0x00,0x02,0x03, + 0x02,0x00,0x03,0x02,}}, + {/* S 0x0053*/ { + 0x18,0x24,0x24,0x44,0x8C,0x00,0x03,0x02, + 0x02,0x02,0x01,0x00,}}, + {/* T 0x0054*/ { + 0x0C,0x04,0xFC,0x04,0x0C,0x00,0x00,0x02, + 0x03,0x02,0x00,0x00,}}, + {/* U 0x0055*/ { + 0x04,0xFC,0x00,0x00,0xFC,0x04,0x00,0x01, + 0x02,0x02,0x01,0x00,}}, + {/* V 0x0056*/ { + 0x04,0x7C,0x80,0xE0,0x1C,0x04,0x00,0x00, + 0x03,0x00,0x00,0x00,}}, + {/* W 0x0057*/ { + 0x1C,0xE0,0x3C,0xE0,0x1C,0x00,0x00,0x03, + 0x00,0x03,0x00,0x00,}}, + {/* X 0x0058*/ { + 0x04,0x9C,0x60,0x9C,0x04,0x00,0x02,0x03, + 0x00,0x03,0x02,0x00,}}, + {/* Y 0x0059*/ { + 0x04,0x1C,0xE0,0x1C,0x04,0x00,0x00,0x02, + 0x03,0x02,0x00,0x00,}}, + {/* Z 0x005A*/ { + 0x0C,0x84,0x64,0x1C,0x04,0x00,0x02,0x03, + 0x02,0x02,0x03,0x00,}}, + {/* [ 0x005B*/ { + 0x00,0x00,0xFE,0x02,0x02,0x00,0x00,0x00, + 0x07,0x04,0x04,0x00,}}, + {/* \ 0x005C*/ { + 0x00,0x0E,0x30,0xC0,0x00,0x00,0x00,0x00, + 0x00,0x01,0x02,0x00,}}, + {/* ] 0x005D*/ { + 0x00,0x02,0x02,0xFE,0x00,0x00,0x00,0x04, + 0x04,0x07,0x00,0x00,}}, + {/* ^ 0x005E*/ { + 0x00,0x04,0x02,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* _ 0x005F*/ { + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08, + 0x08,0x08,0x08,0x08,}}, + {/* ` 0x0060*/ { + 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/* a 0x0061*/ { + 0x00,0x40,0xA0,0xA0,0xC0,0x00,0x00,0x01, + 0x02,0x02,0x03,0x02,}}, + {/* b 0x0062*/ { + 0x04,0xFC,0x20,0x20,0xC0,0x00,0x00,0x03, + 0x02,0x02,0x01,0x00,}}, + {/* c 0x0063*/ { + 0x00,0xC0,0x20,0x20,0x60,0x00,0x00,0x01, + 0x02,0x02,0x02,0x00,}}, + {/* d 0x0064*/ { + 0x00,0xC0,0x20,0x24,0xFC,0x00,0x00,0x01, + 0x02,0x02,0x03,0x02,}}, + {/* e 0x0065*/ { + 0x00,0xC0,0xA0,0xA0,0xC0,0x00,0x00,0x01, + 0x02,0x02,0x02,0x00,}}, + {/* f 0x0066*/ { + 0x00,0x20,0xF8,0x24,0x24,0x04,0x00,0x02, + 0x03,0x02,0x02,0x00,}}, + {/* g 0x0067*/ { + 0x00,0x40,0xA0,0xA0,0x60,0x20,0x00,0x07, + 0x0A,0x0A,0x0A,0x04,}}, + {/* h 0x0068*/ { + 0x04,0xFC,0x20,0x20,0xC0,0x00,0x02,0x03, + 0x02,0x00,0x03,0x02,}}, + {/* i 0x0069*/ { + 0x00,0x20,0xE4,0x00,0x00,0x00,0x00,0x02, + 0x03,0x02,0x00,0x00,}}, + {/* j 0x006A*/ { + 0x00,0x00,0x20,0xE4,0x00,0x00,0x08,0x08, + 0x08,0x07,0x00,0x00,}}, + {/* k 0x006B*/ { + 0x04,0xFC,0x80,0xE0,0x20,0x20,0x02,0x03, + 0x02,0x00,0x03,0x02,}}, + {/* l 0x006C*/ { + 0x04,0x04,0xFC,0x00,0x00,0x00,0x02,0x02, + 0x03,0x02,0x02,0x00,}}, + {/* m 0x006D*/ { + 0xE0,0x20,0xE0,0x20,0xC0,0x00,0x03,0x00, + 0x03,0x00,0x03,0x00,}}, + {/* n 0x006E*/ { + 0x20,0xE0,0x20,0x20,0xC0,0x00,0x02,0x03, + 0x02,0x00,0x03,0x02,}}, + {/* o 0x006F*/ { + 0x00,0xC0,0x20,0x20,0xC0,0x00,0x00,0x01, + 0x02,0x02,0x01,0x00,}}, + {/* p 0x0070*/ { + 0x20,0xE0,0x20,0x20,0xC0,0x00,0x08,0x0F, + 0x0A,0x02,0x01,0x00,}}, + {/* q 0x0071*/ { + 0x00,0xC0,0x20,0x20,0xE0,0x00,0x00,0x01, + 0x02,0x0A,0x0F,0x08,}}, + {/* r 0x0072*/ { + 0x20,0xE0,0x40,0x20,0x20,0x00,0x02,0x03, + 0x02,0x00,0x00,0x00,}}, + {/* s 0x0073*/ { + 0x00,0x60,0xA0,0xA0,0x20,0x00,0x00,0x02, + 0x02,0x02,0x03,0x00,}}, + {/* t 0x0074*/ { + 0x00,0x20,0xF8,0x20,0x00,0x00,0x00,0x00, + 0x01,0x02,0x02,0x00,}}, + {/* u 0x0075*/ { + 0x20,0xE0,0x00,0x20,0xE0,0x00,0x00,0x01, + 0x02,0x02,0x03,0x02,}}, + {/* v 0x0076*/ { + 0x20,0xE0,0x20,0x80,0x60,0x20,0x00,0x00, + 0x03,0x01,0x00,0x00,}}, + {/* w 0x0077*/ { + 0x60,0x80,0xE0,0x80,0x60,0x00,0x00,0x03, + 0x00,0x03,0x00,0x00,}}, + {/* x 0x0078*/ { + 0x20,0x60,0x80,0x60,0x20,0x00,0x02,0x03, + 0x00,0x03,0x02,0x00,}}, + {/* y 0x0079*/ { + 0x20,0xE0,0x20,0x80,0x60,0x20,0x08,0x08, + 0x07,0x01,0x00,0x00,}}, + {/* z 0x007A*/ { + 0x00,0x20,0xA0,0x60,0x20,0x00,0x00,0x02, + 0x03,0x02,0x02,0x00,}}, + {/* { 0x007B*/ { + 0x00,0x00,0x20,0xDE,0x02,0x00,0x00,0x00, + 0x00,0x07,0x04,0x00,}}, + {/* | 0x007C*/ { + 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, + 0x00,0x0F,0x00,0x00,}}, + {/* } 0x007D*/ { + 0x00,0x02,0xDE,0x20,0x00,0x00,0x00,0x04, + 0x07,0x00,0x00,0x00,}}, + {/* ~ 0x007E*/ { + 0x02,0x01,0x02,0x04,0x04,0x02,0x00,0x00, + 0x00,0x00,0x00,0x00,}}, + {/*  0x007F*/ { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,}}, +}; + diff --git a/libraries/oleddrv/main.c b/libraries/oleddrv/main.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/main.c @@ -0,0 +1,899 @@ +/******************************************************************************* +* File Name : main.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-01-21 +* Description : Main program body +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" +#include "bsp.h" +#include "SSD1303.h" +#include "Graphics\Graphics.h" // Graphic primitives layer +#include "ClockUI.h" +#include "ClockSet.h" +#include "Encoder.h" +#include "..\..\oledLoader\Inc\Export.h" +#include "time.h" +#include "icon.h" +#include "menu.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +//#define RTCClockSource_LSI +#define RTCClockSource_LSE + +/* Private macro -------------------------------------------------------------*/ +#define WAIT_UNTIL_FINISH(x) (x) + +/* Private variables ---------------------------------------------------------*/ +static u32 minute = 0; +static s16 encCount = 0; +static vu32 TimeDisplay = 0; +static const char HexTable[] = "0123456789ABCDEF"; +ADResult_t ADCResult; + +/* Private function prototypes -----------------------------------------------*/ +void RCC_Configuration(void); +void NVIC_Configuration(void); +void SSD1303_IO_Configuration(void); +void SSD1303_Controller_Init(void); +void CCW_Rotate(unsigned char *des, const unsigned char *src); +void RTC_Configuration(void); +void Initial_Tim2(void); +void InitialIO(void); +void InitialADC(void); +void InitialSystem(); +#ifdef DEBUG_UI +u32 InitialUIDebugger(u16 width, u16 height, u16 depth, u8* buffer); +#endif +/* Private functions ---------------------------------------------------------*/ +void GraphTest(void) +{ + SHORT counter; + Device dev; + InitialDevice(&dev,&SSD1303_Prop,SongSmall5_DrawChar); + + while(1){ + SetColor(WHITE); + for(counter=0; counter>1; counter+=10){ + DelayMs(500); + WAIT_UNTIL_FINISH(Circle(GetMaxX()>>1,GetMaxY()>>1,counter)); + } + + DelayMs(2000); + WAIT_UNTIL_FINISH(FillCircle(GetMaxX()>>1,GetMaxY()>>1,10)); + + DelayMs(2000); + WAIT_UNTIL_FINISH(FillCircle(GetMaxX()>>1,GetMaxY()>>1,20)); + + DelayMs(2000); + WAIT_UNTIL_FINISH(FillCircle(GetMaxX()>>1,GetMaxY()>>1,30)); + + DelayMs(2000); + SetColor(BLACK); + ClearDevice(); + + SetColor(WHITE); + WAIT_UNTIL_FINISH(Bevel((GetMaxX()>>1)-30,(GetMaxY()>>1)-30,(GetMaxX()>>1)+30,(GetMaxY()>>1)+30,15)); + + WAIT_UNTIL_FINISH(Bevel((GetMaxX()>>1)-20,(GetMaxY()>>1)-20,(GetMaxX()>>1)+20,(GetMaxY()>>1)+20,15)); + + WAIT_UNTIL_FINISH(Bevel((GetMaxX()>>1)-10,(GetMaxY()>>1)-10,(GetMaxX()>>1)+10,(GetMaxY()>>1)+10,15)); + + DelayMs(2000); + SetColor(BLACK); + ClearDevice(); + SetColor(WHITE); + WAIT_UNTIL_FINISH(Arc((GetMaxX()>>1)-30,(GetMaxY()>>1)-30,(GetMaxX()>>1)+30,(GetMaxY()>>1)+30,10,15,0xFF)); + + WAIT_UNTIL_FINISH(Arc((GetMaxX()>>1)-20,(GetMaxY()>>1)-20,(GetMaxX()>>1)+20,(GetMaxY()>>1)+20,10,15,0xFF)); + + WAIT_UNTIL_FINISH(Arc((GetMaxX()>>1)-10,(GetMaxY()>>1)-10,(GetMaxX()>>1)+10,(GetMaxY()>>1)+10,10,15,0xFF)); + + DelayMs(2000); + SetColor(BLACK); + ClearDevice(); + + SetColor(WHITE); + + for(counter=0; counter>1; counter+=4){ + DelayMs(500); + WAIT_UNTIL_FINISH(Rectangle(GetMaxX()/2-counter, + GetMaxY()/2-counter, + GetMaxX()/2+counter, + GetMaxY()/2+counter)); + } + + DelayMs(2000); + SetColor(BLACK); + ClearDevice(); + + /* Draw a box */ + for(u32 x=0;x<128;x++){ + SetPoint(&dev,x,0); + SetPoint(&dev,x,63); + } + for(u32 y=0;y<63;y++){ + SetPoint(&dev,0,y); + SetPoint(&dev,127,y); + } + static u32 yPos = 1; + yPos = 0; + while(1){ + unsigned long xPos = 10; + yPos++; + if(yPos == 47){ + break; + } + /* Cleare previous display data */ + TextOut(&dev,xPos,yPos>1?yPos-1:46," ",0xff); + /* Output the English characters "Hello" */ + xPos = TextOut(&dev,xPos,yPos,"Hello ",0xFF); + /* Output the Chinese characters "世界" */ + xPos = TextOut(&dev,xPos,yPos,"World",2); + /* Output the '!' sign */ + //xPos = TextOut(&dev,xPos,yPos,"!",0xFF); + + TextOut(&dev,xPos + 8,8, (yPos & 2) ? (yPos&1 ? "\\" : "-" ) : (yPos&1 ? "/" : "|" ),0xFF); + + for(u32 i=2000000;--i;); + } + SetColor(BLACK); + ClearDevice(); + break; + } +} + +/******************************************************************************* +* Function Name : main +* Description : Main program +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +int main(void) +{ +#ifdef DEBUG + debug(); +#endif + { + /* + Todo: the app will crash if remove the follow codes + */ + time_t now = 0; + struct tm* curTm = localtime(&now); + } + + InitialSystem(); + //GraphTest(); + Device dev; + InitialDevice(&dev,&SSD1303_Prop,SongSmall5_DrawChar); + + //SpecTextOut(&dev,1,10,song_6_fontBuffer,7); + //while(1); + InitialMenu(); + while(1){ + static Msg msg; + if(GetMessage(&msg)){ + MenuProcess(&msg); + } + } + + Clock_DrawFace(GetMaxY()>>1,GetMaxY()>>1,GetMaxY()>>1); + //Line(counter,0,GetMaxX()-1-counter,GetMaxY()-1); + while(1){ + static Msg msg; + if(!GetMessage(&msg))continue; +// if(minute != lastM){ +// lastM = minute; +// char buf[] = {minute/10+'0',minute%10+'0',0}; +// TextOut(&dev,80,20,buf,0xff); +// if(encCount<0){ +// encCount = -encCount; +// char buf[] = {'-',encCount/10+'0',encCount%10+'0',0}; +// TextOut(&dev,100,20,buf,0xff); +// }else{ +// char buf[] = {'+',encCount/10+'0',encCount%10+'0',0}; +// TextOut(&dev,100,20,buf,0xff); +// } +// } + if(msg.message == MSG_KEY_UP){ + if(SSD1303_IsOn()){ + SSD1303_TurnOff(); + }else{ + SSD1303_TurnOn(); + } + char buf[] = {minute/10+'0',minute%10+'0',0}; + TextOut(&dev,80,40,buf,0xff); + } + char buf[64]; + if(ReadUsbData(buf,64) == LDR_SUCCESS){ + if(buf[1] == 0xAA){ + RTC_SetCounter(*(u32*)(buf+4)); + RTC_WaitForLastTask(); + } + } + if(msg.message == MSG_SECOND){ + //if(TimeDisplay){ + CheckConnection(); + vu16 ccr1 = TIM3->CCR1; + Pos_t x = 64; + Pos_t y = 16; + TimeDisplay = 0; + u32 TimeVar = RTC_GetCounter(); + u32 THH = 0, TMM = 0, TSS = 0; + /* Compute hours */ + THH = TimeVar / 3600; + /* Compute minutes */ + TMM = (TimeVar % 3600) / 60; + /* Compute seconds */ + TSS = (TimeVar % 3600) % 60; + char tBuf[64] = {1}; + //x = TextOut(&dev,x,y,tBuf+1,0xff); + Clock_UpdateTime(THH,TMM,TSS); + time_t now = (time_t)TimeVar; + char* p = ctime(&now); + for(u32 i=0;i<26;){ + i++; + tBuf[i] = *p++; + } + TextOut_HighLight(&dev,x,y,tBuf+12,8); + TextOut(&dev,x,y+16,tBuf+5,6); + TextOut(&dev,x,y+32,tBuf+21,4); + TextOut(&dev,x+32,y+32,tBuf+20,1); + TextOut_HighLight(&dev,x+40,y+32,tBuf+1,3); + if(0){ + u32 res = ADCResult.ADBat; + res = res * 328 * 136 / (4096*100); +// char ADBuf[] = {'0', 'x', HexTable[(res>>12)&0xF], +// HexTable[(res>>8)&0xF],HexTable[(res>>4)&0xF],HexTable[res&0xF],0}; + + char ADBuf[] = {'B', 'a', 't', HexTable[(res/100)%10], '.', + HexTable[(res/10)%10], HexTable[res%10],'V', 0}; + y+=16; + TextOut(&dev,x,y,ADBuf,8); + } + if(0){ + u16 res = ADCResult.ADX; + char ADBuf[] = {'0', 'x', HexTable[(res>>12)&0xF], + HexTable[(res>>8)&0xF],HexTable[(res>>4)&0xF],HexTable[res&0xF], + ' ', IsPGOOD() ? 'P' : 'X', 0}; + y+=16; + TextOut(&dev,x,y,ADBuf,8); + } + if(0){ + u16 res = ADCResult.ADY; + char ADBuf[] = {'0', 'x', HexTable[(res>>12)&0xF], + HexTable[(res>>8)&0xF],HexTable[(res>>4)&0xF],HexTable[res&0xF], + ' ', IsCHG() ? 'C' : 'X', 0}; + y+=16; + TextOut(&dev,x,y,ADBuf,8); + } + + static unsigned char icoY = 0; + //icoY++; + //if(icoY==64)icoY=0; + if(IsCHG()){ + DrawIcon(104,icoY,ICON_ID_CHARGE); + }else if(IsPGOOD()){ + DrawIcon(104,icoY,ICON_ID_POWER); + }else{ + DrawIcon(104,0,ICON_ID_BATTARY); + // Battary check + // Full charge is 4.2V, lower power is 3.3V + // Vref = 3.28V + // 10K/13.6K + // 4.2*10/13.6/3.28*4096 = 3875 + // 3.3*10/13.6/3.28*4096 = 3030 + u32 res = ADCResult.ADBat; + if(res > 3835){ + res = 800; + }else if(res < 3030){ + res = 0; + }else{ + res -= 3030; + } + res = 16*res/800; + res += 106; + SetColor(BLACK); + SetLineThickness(NORMAL_LINE); + Bar(res,2,121,7); + } + + WaitAndSendUsbData(tBuf,64,1); + //ToggleLED(); + } + } +} + +/******************************************************************************* +* Function Name : InitialSystem +* Description : Initialize the system +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void InitialSystem() +{ + GPIO_AFIODeInit(); + GPIO_DeInit(GPIOB); + /* The bootloader has already initialize the GPIOA*/ + //GPIO_DeInit(GPIOA); + GPIO_DeInit(GPIOD); + + /* NVIC configuration */ + NVIC_Configuration(); + + /* Initialize GPIO */ + InitialIO(); + + /* Initialize ADC */ + InitialADC(); + + /* Initializer system colck */ +#ifdef DEBUG_UI + InitialUIDebugger(128, 64, 1, SSD1303_GetBuffer()); +#else + RCC_DeInit(); + CheckConnection(); + + /* Initialize the SSD1303 related IO */ + SSD1303_IO_Configuration(); + + /* Initialize the SSD1303 */ + SSD1303_Init(); +#endif + + /* Initialize the SSD1303 controller, + which is simulated by STM32 DMA and systick*/ + SSD1303_Controller_Init(); + + /* Initialize the RTC peripheral */ + RTC_Configuration(); + + /* Initial graph lib*/ + InitGraph(); + + /* Initial encoder interface*/ + Enc_Init(); +} + +/******************************************************************************* +* Function Name : InitialADC +* Description : Initial the ADC for voltage measure +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void InitialADC(void) +{ + ADC_InitTypeDef ADC_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + DMA_InitTypeDef DMA_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA + | RCC_APB2Periph_GPIOB + | RCC_APB2Periph_ADC1 + | RCC_APB2Periph_ADC2, ENABLE); + + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); + + /* Configure PC.0(ADC Channel1, Channel2, ) + as analog input -----------------------------------------------------------*/ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + RCC_ADCCLKConfig(RCC_PCLK2_Div6); /// 12MHz for ADC clock + + /* Here we config the ADC1 and ADC2 in regular simultaneous mode + They are trigerred by TIM3 TRGO signal + The result will stored in ADC1's DR, + */ + ADC_DeInit(ADC1); + ADC_DeInit(ADC2); + + ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; + ADC_InitStructure.ADC_ScanConvMode = ENABLE; + ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; + ADC_InitStructure.ADC_ExternalTrigConv = + ADC_ExternalTrigConv_None; + //ADC_ExternalTrigConv_T3_TRGO; + //ADC_ExternalTrigConv_T2_CC2; + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_NbrOfChannel = 3; + ADC_Init(ADC1, &ADC_InitStructure); + ADC_Init(ADC2, &ADC_InitStructure); + + ADC_RegularChannelConfig(ADC1, AD_CH_REF, 1, ADC_SampleTime_13Cycles5); + ADC_RegularChannelConfig(ADC2, AD_CH_BAT, 1, ADC_SampleTime_13Cycles5); + ADC_RegularChannelConfig(ADC1, AD_CH_X, 2, ADC_SampleTime_13Cycles5); + ADC_RegularChannelConfig(ADC2, AD_CH_Y, 2, ADC_SampleTime_13Cycles5); + ADC_RegularChannelConfig(ADC1, AD_CH_Z, 3, ADC_SampleTime_13Cycles5); + ADC_RegularChannelConfig(ADC2, AD_CH_CHG, 3, ADC_SampleTime_13Cycles5); + + /* Initialize the ADC DMA channel */ + ADC_DMACmd(ADC1,ENABLE); + DMA_DeInit(DMA_ADC); + DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&ADC1->DR); + DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCResult; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + DMA_InitStructure.DMA_BufferSize = 3; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//DMA_Priority_Low DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA_ADC, &DMA_InitStructure); + + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQChannel; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + DMA_ITConfig(DMA_ADC, DMA_IT_TC, ENABLE); + + DMA_Cmd(DMA_ADC, ENABLE); + + ADC_TempSensorVrefintCmd(ENABLE); + + //ADC_ExternalTrigConvCmd(ADC1, ENABLE); + ADC_ExternalTrigConvCmd(ADC2, ENABLE); + ADC_Cmd(ADC1, ENABLE); + ADC_Cmd(ADC2, ENABLE); + + ADC_ResetCalibration(ADC1); + /* Check the end of ADC1 reset calibration register */ + while(ADC_GetResetCalibrationStatus(ADC1)); + /* Start ADC1 calibaration */ + ADC_StartCalibration(ADC1); + /* Check the end of ADC1 calibration */ + while(ADC_GetCalibrationStatus(ADC1)); + + + ADC_ResetCalibration(ADC2); + /* Check the end of ADC1 reset calibration register */ + while(ADC_GetResetCalibrationStatus(ADC2)); + /* Start ADC1 calibaration */ + ADC_StartCalibration(ADC2); + /* Check the end of ADC1 calibration */ + while(ADC_GetCalibrationStatus(ADC2)); +} + +/******************************************************************************* +* Function Name : DMA1_Channel1_IRQHandler +* Description : This function handles DMA1 Channel 1 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA1_Channel1_IRQHandler(void) +{ + if(DMA_GetITStatus(DMA1_IT_TC1)){ + DMA_ClearITPendingBit(DMA1_IT_GL1); + Msg msg; + if(Is_MMA_WAKEUP()){ + MakeMsgGrav_XY(&msg,ADCResult.ADX,ADCResult.ADY); + PostMessage(&msg); + MakeMsgGrav_Z(&msg,ADCResult.ADZ); + PostMessage(&msg); + } + } +} + +/******************************************************************************* +* Function Name : InitialIO +* Description : Initial the GPIOs +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void InitialIO(void) +{ +#ifdef DEBUG_BOARD + GPIO_InitTypeDef GPIO_InitStructure; + RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); + + GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); + + // PA8 is the led + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + // PB4 for PGOOD signal, PB5 for CHG signal + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // PB8 for GSel 2, PB9 for GSel2, PB11 for MMA Sleep + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GSel1_Low(); + GSel2_Low(); + LED_OFF(); + MMA_WAKEUP(); + +#else + GPIO_InitTypeDef GPIO_InitStructure; + RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); + + GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); + + // PA8 is the led + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + // PB4 for PGOOD signal, PB5 for CHG signal + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // PB8 for GSel 2, PB9 for GSel2, PB11 for MMA Sleep + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GSel1_Low(); + GSel2_Low(); + LED_OFF(); + MMA_SLEEP(); +#endif +} + +/******************************************************************************* +* Function Name : SysTickHandler +* Description : This function handles SysTick Handler. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +#define SCROLL_THRESHOLD 4 +void SysTickHandler(void) +{ + Msg msg; + static s16 lastEncCnt = 0; + encCount = Enc_GetCount(); + if((lastEncCnt ^ encCount) & 0x8000 ){ + lastEncCnt = encCount; + } + lastEncCnt += encCount; + if(lastEncCnt>SCROLL_THRESHOLD){ + msg.param = (void*)((s32)encCount); + msg.message = MSG_SCROLL; + PostMessage(&msg); + lastEncCnt -= SCROLL_THRESHOLD; + }else if(lastEncCnt<-SCROLL_THRESHOLD){ + msg.param = (void*)((s32)encCount); + msg.message = MSG_SCROLL; + PostMessage(&msg); + lastEncCnt += SCROLL_THRESHOLD; + } + static u32 keyDown = 0; + if(Is_Enc_Key_Down()){ + if(keyDown == 1){ + msg.param = 0; + msg.message = MSG_KEY_DOWN; + PostMessage(&msg); + } + keyDown++; + }else{ + if(keyDown > 2){ + msg.param = (void*)keyDown; + msg.message = MSG_KEY_UP; + PostMessage(&msg); + } + keyDown = 0; + } + +// if(encCount>0){ +// minute++; +// if(minute>=60)minute = 0; +// }else if(encCount<0){ +// if(minute){ +// minute--; +// }else{ +// minute = 59; +// } +// } +#ifndef DEBUG_UI + StartPageTransfer(); +#endif + + if(Is_MMA_WAKEUP()){ + ADC_SoftwareStartConvCmd(ADC1, ENABLE); + } +} + +/******************************************************************************* +* Function Name : NVIC_Configuration +* Description : Configure the nested vectored interrupt controller. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RTC_IRQHandler(void); +void DMA1_Channel5_IRQHandler(void); +void NVIC_Configuration(void) +{ +#if WITH_BOOTLOADER + RegisterIrq(-1,SysTickHandler); + RegisterIrq(RTC_IRQChannel,RTC_IRQHandler); + RegisterIrq(DMA1_Channel5_IRQChannel,DMA1_Channel5_IRQHandler); + RegisterIrq(DMA1_Channel1_IRQChannel,DMA1_Channel1_IRQHandler); +#else +#ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x20000000 */ + NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); +#else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x08000000 */ + NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); +#endif + /* 2 bits for pre-emption priority */ + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); +#endif +} + +/******************************************************************************* +* Function Name : SSD1303_IO_Configuration +* Description : Configure the IO used for SSD1303. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SSD1303_IO_Configuration(void) +{ + SPI_InitTypeDef SPI_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable SPI1 and GPIO clocks */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); + + SPI_I2S_DeInit(SPI2); + + /* Configure SPI2 pins: SCK, MOSI */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_Init(GPIOB, &GPIO_InitStructure); + /* Configure SSD1303 pins: RES,A0*/ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_14; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + /* SPI1 configuration */ + SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + //SPI_Init(SPI1, &SPI_InitStructure); + SPI_Init(SPI2, &SPI_InitStructure); + + SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); + + /* Enable SPI1 */ + SPI_Cmd(SPI2, ENABLE); +} + +/******************************************************************************* +* Function Name : SSD1303_Controller_Init +* Description : Initialize the oled controller, which is simulated by STM32. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SSD1303_Controller_Init(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + DMA_InitTypeDef DMA_InitStructure; + + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); + + DMA_DeInit(DMA1_Channel5); + DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&SPI2->DR); + DMA_InitStructure.DMA_MemoryBaseAddr = 0; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_BufferSize = 1; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA1_Channel5, &DMA_InitStructure); + + NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQChannel; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); + + NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick,2,0); + + SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); + SysTick_SetReload(72000000/SSD1303_FPS); + SysTick_ITConfig(ENABLE); + SysTick_CounterCmd(SysTick_Counter_Enable); +} + +/******************************************************************************* +* Function Name : RTC_Configuration +* Description : Initialize the RTC peripheral. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RTC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + /* Enable PWR and BKP clocks */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); + + /* Allow access to BKP Domain */ + PWR_BackupAccessCmd(ENABLE); + + NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQChannel; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + /* Enable the RTC Second */ + RTC_ITConfig(RTC_IT_SEC, ENABLE); + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + if(BKP_ReadBackupRegister(BKP_DR1) == 0xA5A5){ + + /* Wait for RTC registers synchronization */ + RTC_WaitForSynchro(); + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + return; + } + + /* Reset Backup Domain */ + BKP_DeInit(); + +#ifdef RTCClockSource_LSI + /* Enable LSI */ + RCC_LSICmd(ENABLE); + /* Wait till LSI is ready */ + while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) + { + } + + /* Select LSI as RTC Clock Source */ + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); +#elif defined RTCClockSource_LSE + /* Enable LSE */ + RCC_LSEConfig(RCC_LSE_ON); + /* Wait till LSE is ready */ + while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) + { + } + + /* Select LSE as RTC Clock Source */ + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); +#endif + + /* Enable RTC Clock */ + RCC_RTCCLKCmd(ENABLE); + + /* Wait for RTC registers synchronization */ + RTC_WaitForSynchro(); + + /* Set RTC prescaler: set RTC period to 1sec */ +#ifdef RTCClockSource_LSI + RTC_SetPrescaler(31999); /* RTC period = RTCCLK/RTC_PR = (32.000 KHz)/(31999+1) */ +#elif defined RTCClockSource_LSE + RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */ +#endif + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + RTC_SetCounter(0x4B880000); + + RTC_WaitForLastTask(); + + BKP_WriteBackupRegister(BKP_DR1, 0xA5A5); +} + +/******************************************************************************* +* Function Name : RTC_IRQHandler +* Description : This function handles RTC global interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void RTC_IRQHandler(void) +{ + if (RTC_GetITStatus(RTC_IT_SEC) != RESET) + { + /* Clear the RTC Second interrupt */ + RTC_ClearITPendingBit(RTC_IT_SEC); + + /* Toggle GPIO_LED pin 6 each 1s */ + + Msg msg; + msg.param = (void*)RTC_GetCounter(); + msg.message = MSG_SECOND; + PostMessage(&msg); + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + if(!Is_MMA_WAKEUP()){ + // When MMA is power off, use the seoond interrupt + ADC_SoftwareStartConvCmd(ADC1, ENABLE); + } + } +} + +#ifdef DEBUG +/******************************************************************************* +* Function Name : assert_failed +* Description : Reports the name of the source file and the source line number +* where the assert_param error has occurred. +* Input : - file: pointer to the source file name +* - line: assert_param error line source number +* Output : None +* Return : None +*******************************************************************************/ +void assert_failed(u8* file, u32 line) +{ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + + /* Infinite loop */ + while (1) + { + } +} +#endif +/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ diff --git a/libraries/oleddrv/menu.c b/libraries/oleddrv/menu.c new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/menu.c @@ -0,0 +1,202 @@ +/******************************************************************************* +* File Name : menu.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-03-05 +* Description : Menu implement +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f10x_lib.h" +#include "menu.h" +#include "SSD1303.h" +#include "Graphics\Graphics.h" +#include "time.h" +#include "icon.h" +#include "bsp.h" +#include "ClockUI.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +static const MenuItem* curMenuItem; +static u8 preQuit = 0; +extern const LPCSTR* curLang; +extern const MenuItem MainMenu[]; +extern const MenuItem RootMenu; +static MenuFunc_t menuProc = 0; +extern Device appDevice; +/* Private function prototypes -----------------------------------------------*/ +void UpdateMenu(void); + +/* Private functions ---------------------------------------------------------*/ + +/******************************************************************************* +* Function Name : InitialMenu +* Description : Initialize the menu +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +MenuFunc_t InitialMenu() +{ + InitialDevice(&appDevice,&SSD1303_Prop,SongSmall5_DrawChar); + curMenuItem = MainMenu; + menuProc = RootMenu.pfnMenu; + Msg msg = {.param = 0, .message = MSG_INIT}; + menuProc(0,&msg); + return MR_Finish; +} + +unsigned long MenuProcess(Msg* msg) +{ + if(menuProc){ + if(menuProc((void*)curMenuItem,msg) == MR_Finish){ + menuProc = 0; + UpdateMenu(); + } + return 0; + } + unsigned char menuUpdate = 0; + switch(msg->message){ + case MSG_SCROLL: + if((signed long)msg->param > 0){ + // Scroll down + if(preQuit){ + preQuit = 0; + menuUpdate = 1; + }else{ + unsigned char idx = curMenuItem->index+1; + if(idx >= curMenuItem->cnt){ + //curMenuItem = curMenuItem - curMenuItem->index; + }else{ + curMenuItem++; + menuUpdate = 1; + } + } + }else{ + // Scroll up + if(curMenuItem->index){ + curMenuItem--; + menuUpdate = 1; + }else{ + menuUpdate = !preQuit; + preQuit = 1; + } + } + break; + case MSG_KEY_UP: + if(preQuit){ + preQuit = 0; + curMenuItem = curMenuItem->parent; + menuUpdate = 1; + if(!curMenuItem){ + menuProc = RootMenu.pfnMenu; + } + }else{ + if(curMenuItem->type & MT_SUB){ + curMenuItem = curMenuItem->child; + menuUpdate = 1; + }else{ + menuProc = curMenuItem->pfnMenu; + } + } + break; + default: + return 0; + } + if(menuProc){ + Msg ini = { .param = 0, .message = MSG_INIT}; + menuProc((void*)curMenuItem,&ini); + }else{ + if(menuUpdate){ + UpdateMenu(); + } + } + return 0; +} + +#define MARGIN 1 +#define LEFT_MARGIN 12 +#define MENU_HEIGHT 12 +void UpdateMenu(void) +{ + const char* text; + if(!curMenuItem)return; + SetColor(BLACK); + ClearDevice(); + if(curMenuItem->parent){ + text = curLang[curMenuItem->parent->res]; + }else{ + text = curLang[RootMenu.res]; + } + Pos_t x; + if(preQuit){ + x = TextOut_HighLight(&appDevice, 0, 0, text ,0xFF); + }else{ + x = TextOut(&appDevice, 0, 0, text ,0xFF); + } + TextOut(&appDevice, x, 0, "<<" ,0xFF); + + Pos_t y = MENU_HEIGHT + MARGIN; + const MenuItem* items = curMenuItem; + if(curMenuItem->index){ + items--; + } + for(u32 i=0; i<4; i++){ + text = curLang[items->res]; + if(items == curMenuItem && !preQuit){ + TextOut_HighLight(&appDevice, LEFT_MARGIN, y, text ,0xFF); + }else{ + TextOut(&appDevice, LEFT_MARGIN, y, text ,0xFF); + } + if(items->index + 1 == items->cnt){ + break; + } + items++; + y += MENU_HEIGHT + MARGIN; + } +} + +MenuResult PopupMenu(const MenuItem* menu) +{ + curMenuItem = menu; + return MR_Finish; +} + +/** + Message realted definitions + */ +#define MSG_STACK_SIZE 16 +#define MSG_STACK_MASK 15 +static unsigned char wrMsgIndex = 0; +static unsigned char rdMsgIndex = 0; +static Msg msgStack[MSG_STACK_SIZE]; +/******************************************************************************* +* Function Name : GetMessage +* Description : Get message +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long GetMessage(Msg* msg) +{ + if(wrMsgIndex != rdMsgIndex){ + Msg* p = &msgStack[rdMsgIndex & MSG_STACK_MASK]; + msg->message = p->message; + msg->param = p->param; + rdMsgIndex++; + return 1; + } + return 0; +} + +unsigned long PostMessage(Msg* msg) +{ + Msg* p = &msgStack[wrMsgIndex & MSG_STACK_MASK]; + p->message = msg->message; + p->param = msg->param; + wrMsgIndex++; + return 0; +} diff --git a/libraries/oleddrv/menu.h b/libraries/oleddrv/menu.h new file mode 100644 --- /dev/null +++ b/libraries/oleddrv/menu.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* File Name : menu.h +* Author : lxyppc +* Version : V1.0 +* Date : 10-03-05 +* Description : menu header +*******************************************************************************/ +#ifndef MENU_H +#define MENU_H + +// Menu message definition +#define MSG_SCROLL 0x00000001ul +#define MSG_KEY_UP 0x00000002ul +#define MSG_KEY_DOWN 0x00000003ul +#define MSG_SECOND 0x00000004ul +#define MSG_SENSE 0x00000005ul +#define MSG_INIT 0x00000006ul +#define MSG_POWER 0x00000007ul +#define MSG_GRAV_XY 0x00000008ul +#define MSG_GRAV_Z 0x00000009ul + +#define MakeMsgGrav_XY(pMsg,x,y) \ + {\ + (pMsg)->message = MSG_GRAV_XY;\ + (pMsg)->param = (void*)((x) | (((unsigned long)(y))<<16));\ + } +#define MakeMsgGrav_Z(pMsg,z) \ + {\ + (pMsg)->message = MSG_GRAV_Z;\ + (pMsg)->param = (void*)(z);\ + } + +// Here Gravity X is MMA Y axis output +#define GetGravX(pMsg) (u16)(((u32)(pMsg)->param>>16) & 0x0FFF) +// Here Gravity Y is MMA X axis output +#define GetGravY(pMsg) (u16)((u32)(pMsg)->param & 0x0FFF) +#define GetGravZ(pMsg) (u16)((u32)(pMsg)->param & 0x0FFF) + +// POWER mode definition +#define PWR_CHG 0x0001 +#define PWR_GOOD 0x0002 +#define GetBatValue(pMsg) (u16)(((u32)(pMsg)->param)>>16) + +// Menu type definition +#define MT_NULL 0x00 +#define MT_SUB 0x01 // Has sub menu +#define MT_CHECK 0x02 // Has check box + +typedef const char* LPCSTR; + +typedef struct _Msg +{ + void* param; + unsigned long message; +}Msg; + +typedef enum{ + MR_Finish, + MR_Error, + MR_Continue, +}MenuResult; + +typedef MenuResult(*MenuFunc_t)(void* param, Msg* pVoid); + +typedef struct _MenuItem +{ + const struct _MenuItem* parent; + union{ + const void* justMakeInitialEasy; + const MenuFunc_t pfnMenu; + const struct _MenuItem* child; + }; + unsigned char index; // menu index + unsigned char cnt; // menu count + unsigned char res; // menu resource + unsigned char type; +}MenuItem; + +MenuFunc_t InitialMenu(); + +unsigned long MenuProcess(Msg* msg); +MenuResult PopupMenu(const MenuItem* menu); +unsigned long GetMessage(Msg* msg); +unsigned long PostMessage(Msg* msg); + +#endif diff --git a/main.c b/main.c --- a/main.c +++ b/main.c @@ -14,6 +14,8 @@ int main(void) STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); + SSD1303_Init(); + /* Initialize User_Button on STM32L100C-Discovery */ //STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_GPIO); diff --git a/ssd1306.c b/ssd1306.c new file mode 100644 --- /dev/null +++ b/ssd1306.c @@ -0,0 +1,527 @@ +/******************************************************************************* +* File Name : SSD1303.c +* Author : lxyppc +* Version : V1.0 +* Date : 10-01-21 +* Description : SSD1303 operations +* the SSH1101A is compatible with SSD1303 +*******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l100c_discovery.h" +#include "bsp.h" +#include "ssd1306.h" +#include "DrawText.h" + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +#define SSD1303_PAGE_NUMBER 8 +#define SSD1303_COLUMN_NUMBER 128 +#define SSD1303_COLUMN_MARGIN_START 2 +#define SSD1303_COLUMN_MARGIN_END 2 +#define SSD1303_X_PIXEL 128 +#define SSD1303_Y_PIXEL 64 + +/* Private macro -------------------------------------------------------------*/ +#define SSD1303_Buffer (_SSD1303_Buffer + SSD1303_COLUMN_MARGIN_START) + +/* Private variables ---------------------------------------------------------*/ +static uint8_t _SSD1303_Buffer[SSD1303_COLUMN_NUMBER*SSD1303_PAGE_NUMBER ++ SSD1303_COLUMN_MARGIN_START + SSD1303_COLUMN_MARGIN_END] = {0}; +static uint8_t pageIndex = 0; +static uint8_t iS_SSD_On = 0; +static uint8_t pre_on = 0; +static uint8_t curContrast = 0xCC; +static uint8_t lastContrast = 0xCC; + +/* Private function prototypes -----------------------------------------------*/ +void WriteCommand(unsigned char command); +void WriteData(unsigned char data); +void OnPageTransferDone(void); +unsigned long SSD1303_OFF(void); +unsigned long SSD1303_ON(void); +unsigned char* SSD1303_GetBuffer() +{ + return SSD1303_Buffer; +} +/******************************************************************************* +* Function Name : WriteCommand +* Description : Write command to the SSD1303 +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void WriteCommand(unsigned char command) +{ + SSD_A0_Low(); + SPI_SendByte(command); + SPI_Wait(); +} + +/******************************************************************************* +* Function Name : WriteData +* Description : Write data to the SSD1303 +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void WriteData(unsigned char data) +{ + SSD_A0_High(); + SPI_SendByte(data); + SPI_Wait(); +} + +/******************************************************************************* +* Function Name : SSD1303_Init +* Description : Initialize the SSD1303 +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SSD1303_Init(void) +{ + /* Generate a reset */ + SSD_Reset_Low(); + for(u32 i=5000;--i;);//延时5uS以上 + SSD_Reset_High(); + + /************************************************* + // SSD1303 Initialization Command + *************************************************/ + // Lower Column Address + WriteCommand(0x00); /* Set Lower Column Address */ + // High Column Address + WriteCommand(0x10); /* Set Higher Column Address*/ + // Display Start Line + WriteCommand(0x40); /* Set Display Start Line */ +#ifdef DEBUG_BOARD + curContrast = lastContrast = 0x30; +#else + curContrast = lastContrast = 0xCF; +#endif + // Contrast Control Register + WriteCommand(0x81); /* Set Contrast Control */ + WriteCommand(lastContrast); /* 0 ~ 255 0x1f*/ + + // Re-map + WriteCommand(0xA1); /* [A0]:column address 0 is map + to SEG0 , [A1]: columnaddress 131 is map to SEG0*/ + // Entire Display ON/OFF + WriteCommand(0xA4); /* A4=ON */ + // Normal or Inverse Display + WriteCommand(0XA6); /* Normal Display*/ + // Multiplex Ratio + WriteCommand(0xA8); /* Set Multiplex Ratio */ + WriteCommand(0x3f); /* Set to 36 Mux*/ + // Set DC-DC + WriteCommand(0xAD); /* Set DC-DC */ + WriteCommand(0x8B); /* 8B=ON, 8A=Off */ + + // Display ON/OFF + WriteCommand(0xAE); /* AF=ON , AE=OFF*/ + // Display Offset + WriteCommand(0xD3); /* Set Display Offset */ + WriteCommand(0x00); /* No offset */ + // Display Clock Divide + WriteCommand(0xD5); /* Set Clock Divide */ + WriteCommand(0x20); /* Set to 80Hz */ + // Area Color Mode + WriteCommand(0xD8); /* Set Area Color On or Off*/ + WriteCommand(0x00); /* Mono Mode */ + // COM Pins Hardware Configuration + WriteCommand(0xDA); /* Set Pins HardwareConfiguration */ + WriteCommand(0x12); + // VCOMH + WriteCommand(0xDB); /* Set VCOMH */ + WriteCommand(0x00); + // VP + WriteCommand(0xD9); /* Set VP */ + WriteCommand(0x22); /* P1=2 , P2=2 */ + + // Set Common output scan direction + WriteCommand(0xc8);/* Set COM scan direction */ + + // For SSD1306 Set the address mode + WriteCommand(0x20);/* Set address mode */ + WriteCommand(0x00);/* Set address mode horizontal */ + + // Set the page start address + WriteCommand(0xb0); + WriteCommand(0x00); + WriteCommand(0x10); + + /* Turn on the controller */ + pre_on = SSD1303_ON(); +// // Set Charge pump +// WriteCommand(0x8D); /* Set Charge pump */ +// WriteCommand(0x14); /* 0x14=ON, 0x10=Off */ +// +// // Turn on the display +// WriteCommand(0xaf); +} + +/******************************************************************************* +* Function Name : SSD1303_TurnOff +* Description : Turn off the SSD1303 controller +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long SSD1303_TurnOff(void) +{ + pre_on = 0; + return iS_SSD_On; +} + +/******************************************************************************* +* Function Name : SSD1303_TurnOn +* Description : Turn off the SSD1303 controller +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long SSD1303_TurnOn(void) +{ + pre_on = 1; + return iS_SSD_On; +} + +/******************************************************************************* +* Function Name : SSD1303_SetContrast +* Description : Set the SSD1303 contrast +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned char SSD1303_SetContrast(unsigned char contrast) +{ + curContrast = contrast; + return lastContrast; +} + +/******************************************************************************* +* Function Name : SSD1303_GetContrast +* Description : Get the SSD1303 contrast +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned char SSD1303_GetContrast() +{ + return lastContrast; +} + +/******************************************************************************* +* Function Name : SSD1303_OFF +* Description : Turn off the SSD1303 controller +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long SSD1303_OFF(void) +{ + if(iS_SSD_On){ +#ifdef DEBUG_UI + for(u32 i=0;iCCR &= ((u32)0xFFFFFFFE); + DMA1_Channel5->CNDTR = SSD1303_COLUMN_NUMBER+SSD1303_COLUMN_MARGIN_START + SSD1303_COLUMN_MARGIN_END; + DMA1_Channel5->CMAR = (u32)(SSD1303_Buffer+SSD1303_COLUMN_NUMBER*pageIndex - SSD1303_COLUMN_MARGIN_START); + DMA_SSD_1303->CCR |= ((u32)0x00000001); + pageIndex++; +#else + SSD_A0_High(); + DMA_SSD_1303->CCR &= ((u32)0xFFFFFFFE); + DMA_SSD_1303->CNDTR = SSD1303_COLUMN_NUMBER*SSD1303_PAGE_NUMBER;//+SSD1303_COLUMN_MARGIN_START + SSD1303_COLUMN_MARGIN_END; + DMA_SSD_1303->CMAR = (u32)(SSD1303_Buffer);//+SSD1303_COLUMN_NUMBER*pageIndex); + //DMA_Cmd(DMA_SSD_1303, ENABLE); + DMA_SSD_1303->CCR |= ((u32)0x00000001); +// pageIndex++; + pageIndex = SSD1303_PAGE_NUMBER; +#endif +} + +/******************************************************************************* +* Function Name : DMA1_Channel5_IRQHandler +* Description : This function handles DMA1 Channel 5 interrupt request. +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void DMA_Handler_SSD_1303(void) //DMA1_Channel5_IRQHandler(void) +{ + if(DMA_GetITStatus(DMA1_IT_TC5)){ + DMA_ClearITPendingBit(DMA1_IT_GL5); + OnPageTransferDone(); + } +} + +/******************************************************************************* +* Function Name : StartPageTransfer +* Description : Start a new page transfer +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void StartPageTransfer(void) +{ + pageIndex = 0; + if(pre_on){ + if(iS_SSD_On == 0){ + pre_on = SSD1303_ON(); + } + }else{ + if(iS_SSD_On){ + pre_on = SSD1303_OFF(); + } + } + if( curContrast != lastContrast ){ + lastContrast = curContrast; + WriteCommand(0x81); /* Set Contrast Control */ + WriteCommand(lastContrast); /* 0 ~ 255 0x1f*/ + } + + if(iS_SSD_On){ + OnPageTransferDone(); + } +} + +/******************************************************************************* + Display related functions + ******************************************************************************/ +/******************************************************************************* +* Function Name : SSD1303_DrawBlock +* Description : Draw a block with specify data to SSD1303 +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long SSD1303_DrawBlock( + Pos_t x, + Pos_t y, + Pos_t cx, + Pos_t cy, + const unsigned char* data) +{ + if(x >= SSD1303_X_PIXEL)return 0; + if(y >= SSD1303_Y_PIXEL)return 0; + if(x+cx > SSD1303_X_PIXEL ) cx = SSD1303_X_PIXEL - x ; + if(y+cy > SSD1303_Y_PIXEL ) cy = SSD1303_Y_PIXEL - y ; + unsigned char* pStart = SSD1303_Buffer + (y/8)*SSD1303_COLUMN_NUMBER + x; + unsigned char offset1 = y%8; + unsigned char offset2 = (cy+y)%8; + if(data){ + unsigned char mask1 = (1<>=8; + } + if(offset2){ + tmp |= ((((unsigned short)data[j*cx])<>=8; +// if(j == (cy/8)-1){ +// // Last line +// *(pStart + (j+1)*SSD1303_COLUMN_NUMBER + i + x) &= ~mask; +// *(pStart + (j+1)*SSD1303_COLUMN_NUMBER + i + x) |= tmp; +// } +// } +// } +// } + + return 0; +} + +/******************************************************************************* +* Function Name : SSD1303_DrawPoint +* Description : Draw a point with specify data to SSD1303 +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long SSD1303_DrawPoint( + Pos_t x, + Pos_t y, + Color_t color) +{ + if(x >= SSD1303_X_PIXEL)return 0; + if(y >= SSD1303_Y_PIXEL)return 0; + unsigned char* pStart = SSD1303_Buffer + (y/8)*SSD1303_COLUMN_NUMBER + x; + unsigned char mask = 1<<(y%8); + if(color){ + *pStart |= mask; + }else{ + *pStart &= ~mask; + } + return 0; +} + +/******************************************************************************* +* Function Name : SSD1303_ReadPoint +* Description : Read a point from SSD1303 +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +unsigned long SSD1303_ReadPoint( + Pos_t x, + Pos_t y) +{ + unsigned char* pStart = SSD1303_Buffer + (y/8)*SSD1303_COLUMN_NUMBER + x; + unsigned char mask = 1<<(y%8); + return *pStart&mask ? 1 : 0; +} + +/******************************************************************************* +* Function Name : SSD1303_ClearScreen +* Description : Clear the screen contents +* Input : None +* Output : None +* Return : None +*******************************************************************************/ +void SSD1303_FillScreen(Color_t color) +{ + unsigned char mask = color ? 0xFF : 0; + for(unsigned long i=0;i