kopia lustrzana https://github.com/stlink-org/stlink
[update] lcd example uses libstm32l_discovery
rodzic
25b68d2743
commit
4a8fefed01
Plik binarny nie jest wyświetlany.
|
@ -178,6 +178,15 @@ $> make
|
|||
\end{lstlisting}
|
||||
\end{small}
|
||||
|
||||
\paragraph{}
|
||||
An example using the library can be built using:\\
|
||||
\begin{small}
|
||||
\begin{lstlisting}[frame=tb]
|
||||
$> cd stlink.git/example/lcd
|
||||
$> make
|
||||
\end{lstlisting}
|
||||
\end{small}
|
||||
|
||||
\newpage
|
||||
\section{References}
|
||||
\begin{itemize}
|
||||
|
|
|
@ -1,28 +1,37 @@
|
|||
EXECUTABLE=lcd.elf
|
||||
BIN_IMAGE=lcd.bin
|
||||
ELF=lcd.elf
|
||||
|
||||
CC=arm-none-eabi-gcc
|
||||
OBJCOPY=arm-none-eabi-objcopy
|
||||
|
||||
CFLAGS=-O2 -mlittle-endian -mthumb
|
||||
CFLAGS+=-mcpu=cortex-m3 -ffreestanding -nostdlib -nostdinc
|
||||
|
||||
CFLAGS+=-I.
|
||||
|
||||
# stm32l_discovery lib
|
||||
CFLAGS+=-I../libstm32l_discovery/inc
|
||||
CFLAGS+=-I../libstm32l_discovery/inc/base
|
||||
CFLAGS+=-I../libstm32l_discovery/inc/core_support
|
||||
CFLAGS+=-I../libstm32l_discovery/inc/device_support
|
||||
|
||||
# to run from SRAM
|
||||
CFLAGS+=-Wl,-T,linker_stm32l.lds
|
||||
|
||||
# to write to flash then run
|
||||
# CFLAGS+=-Wl,-Ttext,0x08000000 -Wl,-e,0x08000000
|
||||
SRCS=\
|
||||
main.c\
|
||||
stm32l_discovery_lcd.c
|
||||
|
||||
all: $(BIN_IMAGE)
|
||||
OBJS=$(SRCS:.c=.o)
|
||||
|
||||
$(BIN_IMAGE): $(EXECUTABLE)
|
||||
$(OBJCOPY) -O binary $^ $@
|
||||
all: $(ELF)
|
||||
|
||||
$(EXECUTABLE): main.c
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
$(ELF): $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJS) -L../libstm32l_discovery/build -lstm32l_discovery
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
||||
clean:
|
||||
rm -rf $(EXECUTABLE)
|
||||
rm -rf $(BIN_IMAGE)
|
||||
-rm -f $(OBJS)
|
||||
-rm -f $(ELF)
|
||||
|
||||
.PHONY: all clean
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file discover_board.h
|
||||
* @author Microcontroller Division
|
||||
* @version V1.0.2
|
||||
* @date September-2011
|
||||
* @brief Input/Output defines
|
||||
******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
|
||||
#ifndef __DISCOVER_BOARD_H
|
||||
#define __DISCOVER_BOARD_H
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l1xx.h"
|
||||
|
||||
#define bool _Bool
|
||||
#define FALSE 0
|
||||
#define TRUE !FALSE
|
||||
|
||||
/* MACROs for SET, RESET or TOGGLE Output port */
|
||||
|
||||
#define GPIO_HIGH(a,b) a->BSRRL = b
|
||||
#define GPIO_LOW(a,b) a->BSRRH = b
|
||||
#define GPIO_TOGGLE(a,b) a->ODR ^= b
|
||||
|
||||
#define USERBUTTON_GPIO_PORT GPIOA
|
||||
#define USERBUTTON_GPIO_PIN GPIO_Pin_0
|
||||
#define USERBUTTON_GPIO_CLK RCC_AHBPeriph_GPIOA
|
||||
|
||||
#define LD_GPIO_PORT GPIOB
|
||||
#define LD_GREEN_GPIO_PIN GPIO_Pin_7
|
||||
#define LD_BLUE_GPIO_PIN GPIO_Pin_6
|
||||
#define LD_GPIO_PORT_CLK RCC_AHBPeriph_GPIOB
|
||||
|
||||
#define CTN_GPIO_PORT GPIOC
|
||||
#define CTN_CNTEN_GPIO_PIN GPIO_Pin_13
|
||||
#define CTN_GPIO_CLK RCC_AHBPeriph_GPIOC
|
||||
|
||||
#define WAKEUP_GPIO_PORT GPIOA
|
||||
|
||||
#define IDD_MEASURE_PORT GPIOA
|
||||
#define IDD_MEASURE GPIO_Pin_4
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
|
@ -1,8 +1,23 @@
|
|||
/* this example is only for stm32l discover */
|
||||
/* this example is only for stm32l discover.
|
||||
adapted from ST firmwares projects.
|
||||
*/
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned int uint32_t;
|
||||
/* base headers */
|
||||
#include "stdint.h"
|
||||
|
||||
/* libstm32l_discovery headers */
|
||||
#include "stm32l1xx_gpio.h"
|
||||
#include "stm32l1xx_adc.h"
|
||||
#include "stm32l1xx_lcd.h"
|
||||
#include "stm32l1xx_rcc.h"
|
||||
#include "stm32l1xx_rtc.h"
|
||||
#include "stm32l1xx_exti.h"
|
||||
#include "stm32l1xx_pwr.h"
|
||||
#include "stm32l1xx_syscfg.h"
|
||||
#include "stm32l1xx_dbgmcu.h"
|
||||
|
||||
/* lcd wrapper routines header */
|
||||
#include "stm32l_discovery_lcd.h"
|
||||
|
||||
/* boot mode */
|
||||
|
||||
|
@ -15,17 +30,14 @@ typedef unsigned int uint32_t;
|
|||
refer to CD00240193.pdf, GPIO.
|
||||
*/
|
||||
|
||||
#define GPIOA 0x40020000
|
||||
#define GPIOA_MODER (GPIOA + 0x00)
|
||||
#define GPIOA_ODR (GPIOA + 0x14)
|
||||
#define GPIOA_MODER (GPIOA_BASE + 0x00)
|
||||
#define GPIOA_ODR (GPIOA_BASE + 0x14)
|
||||
|
||||
#define GPIOB 0x40020400
|
||||
#define GPIOB_MODER (GPIOB + 0x00)
|
||||
#define GPIOB_ODR (GPIOB + 0x14)
|
||||
#define GPIOB_MODER (GPIOB_BASE + 0x00)
|
||||
#define GPIOB_ODR (GPIOB_BASE + 0x14)
|
||||
|
||||
#define GPIOC 0x40020800
|
||||
#define GPIOC_MODER (GPIOC + 0x00)
|
||||
#define GPIOC_ODR (GPIOC + 0x14)
|
||||
#define GPIOC_MODER (GPIOC_BASE + 0x00)
|
||||
#define GPIOC_ODR (GPIOC_BASE + 0x14)
|
||||
|
||||
|
||||
/* leds */
|
||||
|
@ -50,43 +62,212 @@ static inline void switch_leds_off(void)
|
|||
}
|
||||
|
||||
|
||||
/* lcd. refer to DM00027954.pdf. */
|
||||
#define delay() \
|
||||
do { \
|
||||
register unsigned int i; \
|
||||
for (i = 0; i < 1000000; ++i) \
|
||||
__asm__ __volatile__ ("nop\n\t":::"memory"); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if CONFIG_BOOT_SRAM
|
||||
|
||||
extern uint32_t _fstack;
|
||||
|
||||
static inline void setup_stack(void)
|
||||
{
|
||||
/* setup the stack to point to _fstack (refer to ld script) */
|
||||
|
||||
static const uint32_t fstack = (uint32_t)&_fstack;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"ldr sp, %0\n\t"
|
||||
:
|
||||
: "m"(fstack)
|
||||
: "sp"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOOT_SRAM */
|
||||
|
||||
|
||||
/* application related setup */
|
||||
|
||||
static void RCC_Configuration(void)
|
||||
{
|
||||
/* Enable HSI Clock */
|
||||
RCC_HSICmd(ENABLE);
|
||||
|
||||
/*!< Wait till HSI is ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
|
||||
|
||||
/* Set HSI as sys clock*/
|
||||
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
|
||||
|
||||
/* Set MSI clock range to ~4.194MHz*/
|
||||
RCC_MSIRangeConfig(RCC_MSIRange_6);
|
||||
|
||||
/* Enable the GPIOs clocks */
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC| RCC_AHBPeriph_GPIOD| RCC_AHBPeriph_GPIOE| RCC_AHBPeriph_GPIOH, ENABLE);
|
||||
|
||||
/* Enable comparator, LCD and PWR mngt clocks */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP | RCC_APB1Periph_LCD | RCC_APB1Periph_PWR,ENABLE);
|
||||
|
||||
/* Enable ADC & SYSCFG clocks */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG , ENABLE);
|
||||
|
||||
/* Allow access to the RTC */
|
||||
PWR_RTCAccessCmd(ENABLE);
|
||||
|
||||
/* Reset RTC Backup Domain */
|
||||
RCC_RTCResetCmd(ENABLE);
|
||||
RCC_RTCResetCmd(DISABLE);
|
||||
|
||||
/* LSE Enable */
|
||||
RCC_LSEConfig(RCC_LSE_ON);
|
||||
|
||||
/* Wait until LSE is ready */
|
||||
while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
|
||||
|
||||
/* RTC Clock Source Selection */
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
|
||||
|
||||
/* Enable the RTC */
|
||||
RCC_RTCCLKCmd(ENABLE);
|
||||
|
||||
/*Disable HSE*/
|
||||
RCC_HSEConfig(RCC_HSE_OFF);
|
||||
if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET )
|
||||
{
|
||||
/* Stay in infinite loop if HSE is not disabled*/
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void Init_GPIOs(void)
|
||||
{
|
||||
#if 0 /* fixme: GPIO_Init raises a bug in some gcc toolchains */
|
||||
|
||||
/* GPIO, EXTI and NVIC Init structure declaration */
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
#if 0
|
||||
|
||||
#define LCD_SEG0 PA1
|
||||
#define LCD_SEG1 PA2
|
||||
#define LCD_SEG2 PA3
|
||||
#define LCD_SEG3 PB3
|
||||
#define LCD_SEG4 PB4
|
||||
#define LCD_SEG5 PB5
|
||||
#define LCD_SEG6 PB10
|
||||
#define LCD_SEG7 PB11
|
||||
#define LCD_SEG8 PB12
|
||||
#define LCD_SEG9 PB13
|
||||
#define LCD_SEG10 PB14
|
||||
#define LCD_SEG11 PB15
|
||||
#define LCD_SEG12 PA15
|
||||
#define LCD_SEG13 PB8
|
||||
#define LCD_SEG14 PC0
|
||||
#define LCD_SEG15 PC1
|
||||
#define LCD_SEG16 PC2
|
||||
#define LCD_SEG17 PC3
|
||||
#define LCD_SEG18 PC6
|
||||
#define LCD_SEG19 PC7
|
||||
#define LCD_SEG20 PC8
|
||||
#define LCD_SEG21 PC9
|
||||
#define LCD_SEG22 PC10
|
||||
#define LCD_SEG23 PC11
|
||||
#define LCD_COM0 PA8
|
||||
#define LCD_COM1 PA9
|
||||
#define LCD_COM2 PA10
|
||||
#define LCD_COM3 PB9
|
||||
|
||||
EXTI_InitTypeDef EXTI_InitStructure;
|
||||
NVIC_InitTypeDef NVIC_InitStructure;
|
||||
#endif
|
||||
|
||||
static void setup_lcd(void)
|
||||
{
|
||||
#if 0
|
||||
/* Configure User Button pin as input */
|
||||
GPIO_InitStructure.GPIO_Pin = USERBUTTON_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
|
||||
GPIO_Init(USERBUTTON_GPIO_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Select User Button pin as input source for EXTI Line */
|
||||
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
|
||||
|
||||
/* Configure EXT1 Line 0 in interrupt mode trigged on Rising edge */
|
||||
EXTI_InitStructure.EXTI_Line = EXTI_Line0 ; // PA0 for User button AND IDD_WakeUP
|
||||
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
|
||||
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
|
||||
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
|
||||
EXTI_Init(&EXTI_InitStructure);
|
||||
|
||||
/* Enable and set EXTI0 Interrupt to the lowest priority */
|
||||
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn ;
|
||||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
|
||||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||||
NVIC_Init(&NVIC_InitStructure);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Configure the LED_pin as output push-pull for LD3 & LD4 usage*/
|
||||
GPIO_InitStructure.GPIO_Pin = LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
||||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
/* Force a low level on LEDs*/
|
||||
GPIO_LOW(LD_GPIO_PORT,LD_GREEN_GPIO_PIN);
|
||||
GPIO_LOW(LD_GPIO_PORT,LD_BLUE_GPIO_PIN);
|
||||
|
||||
/* Counter enable: GPIO set in output for enable the counter */
|
||||
GPIO_InitStructure.GPIO_Pin = CTN_CNTEN_GPIO_PIN;
|
||||
GPIO_Init( CTN_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
/* To prepare to start counter */
|
||||
GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN);
|
||||
|
||||
/* Configure Port A LCD Output pins as alternate function */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_Init( GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* Select LCD alternate function for Port A LCD Output pins */
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_LCD) ;
|
||||
|
||||
/* Configure Port B LCD Output pins as alternate function */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 \
|
||||
| GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_Init( GPIOB, &GPIO_InitStructure);
|
||||
|
||||
/* Select LCD alternate function for Port B LCD Output pins */
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_LCD) ;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Configure Port C LCD Output pins as alternate function */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 \
|
||||
| GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11 ;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_Init( GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/* Select LCD alternate function for Port B LCD Output pins */
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource0,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource2,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,GPIO_AF_LCD) ;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Configure ADC (IDD_MEASURE) pin as Analogue */
|
||||
GPIO_InitStructure.GPIO_Pin = IDD_MEASURE ;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
|
||||
GPIO_Init( IDD_MEASURE_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
#else /* fixme */
|
||||
|
||||
/* set every port in digital output mode */
|
||||
|
||||
/* PA[1:3,8:10,15] */
|
||||
|
@ -125,187 +306,12 @@ static void setup_lcd(void)
|
|||
(1 << (9 * 2)) |
|
||||
(1 << (10 * 2)) |
|
||||
(1 << (11 * 2));
|
||||
}
|
||||
|
||||
static inline void set_lcd_com(unsigned int i, unsigned int val)
|
||||
{
|
||||
/* table for LCD_COM<N> */
|
||||
static const uint32_t regs[4] = { GPIOA_ODR, GPIOA_ODR, GPIOA_ODR, GPIOB_ODR };
|
||||
static const uint8_t bits[4] = { 8, 9, 10, 9 };
|
||||
|
||||
uint32_t tmp = *(volatile uint32_t*)regs[i];
|
||||
tmp &= ~(1 << bits[i]);
|
||||
tmp |= val << bits[i];
|
||||
*(volatile uint32_t*)regs[i] = tmp;
|
||||
}
|
||||
|
||||
static void clear_lcd(void)
|
||||
{
|
||||
/* tables for LCD_SEG<N> */
|
||||
|
||||
static const uint32_t regs[24] =
|
||||
{
|
||||
GPIOA_ODR,
|
||||
GPIOA_ODR,
|
||||
GPIOA_ODR,
|
||||
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
GPIOB_ODR,
|
||||
|
||||
GPIOA_ODR,
|
||||
|
||||
GPIOB_ODR,
|
||||
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR,
|
||||
GPIOC_ODR
|
||||
};
|
||||
|
||||
static const uint8_t bits[24] =
|
||||
{
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
|
||||
15,
|
||||
|
||||
8,
|
||||
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11
|
||||
};
|
||||
|
||||
/* foreach lcd selector, select and zero */
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(regs) / sizeof(regs[0]); ++i)
|
||||
{
|
||||
/* select */
|
||||
*(volatile uint32_t*)regs[i] |= 1 << bits[i];
|
||||
|
||||
/* set segments */
|
||||
set_lcd_com(0, 0);
|
||||
set_lcd_com(1, 0);
|
||||
set_lcd_com(2, 0);
|
||||
set_lcd_com(3, 0);
|
||||
|
||||
/* deselect */
|
||||
*(volatile uint32_t*)regs[i] &= ~(1 << bits[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_lcd(void)
|
||||
{
|
||||
static unsigned int state = 0;
|
||||
|
||||
clear_lcd();
|
||||
|
||||
/* if (state == 0) */
|
||||
if (1)
|
||||
{
|
||||
/* left square (segments: 1A, 1B, 1C, 1D, 1E, 1F) */
|
||||
|
||||
/* 1A, 1B: PC10, COM0, COM1 */
|
||||
*(volatile uint32_t*)GPIOC_ODR |= 1 << 10;
|
||||
set_lcd_com(0, 1);
|
||||
set_lcd_com(1, 1);
|
||||
set_lcd_com(2, 0);
|
||||
set_lcd_com(3, 0);
|
||||
*(volatile uint32_t*)GPIOC_ODR &= ~(1 << 10);
|
||||
|
||||
/* 1C: PA2, COM1 */
|
||||
*(volatile uint32_t*)GPIOA_ODR |= 1 << 2;
|
||||
set_lcd_com(0, 0);
|
||||
set_lcd_com(1, 1);
|
||||
set_lcd_com(2, 0);
|
||||
set_lcd_com(3, 0);
|
||||
*(volatile uint32_t*)GPIOA_ODR &= ~(1 << 2);
|
||||
|
||||
/* 1D, 1E: PA1, COM0, COM1 */
|
||||
*(volatile uint32_t*)GPIOA_ODR |= 1 << 1;
|
||||
set_lcd_com(0, 1);
|
||||
set_lcd_com(1, 1);
|
||||
set_lcd_com(2, 0);
|
||||
set_lcd_com(3, 0);
|
||||
*(volatile uint32_t*)GPIOA_ODR &= ~(1 << 1);
|
||||
|
||||
/* 1F: PC11, COM1 */
|
||||
*(volatile uint32_t*)GPIOC_ODR |= 1 << 11;
|
||||
set_lcd_com(0, 0);
|
||||
set_lcd_com(1, 1);
|
||||
set_lcd_com(2, 0);
|
||||
set_lcd_com(3, 0);
|
||||
*(volatile uint32_t*)GPIOC_ODR &= ~(1 << 11);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* right square (segments: 6A, 6B, 6C, 6D, 6E, 6F) */
|
||||
}
|
||||
|
||||
/* state ^= 1; */
|
||||
#endif /* fixme */
|
||||
}
|
||||
|
||||
|
||||
#define delay() \
|
||||
do { \
|
||||
register unsigned int i; \
|
||||
for (i = 0; i < 1000000; ++i) \
|
||||
__asm__ __volatile__ ("nop\n\t":::"memory"); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if CONFIG_BOOT_SRAM
|
||||
|
||||
extern uint32_t _fstack;
|
||||
|
||||
static inline void setup_stack(void)
|
||||
{
|
||||
/* setup the stack to point to _fstack (refer to ld script) */
|
||||
|
||||
static const uint32_t fstack = (uint32_t)&_fstack;
|
||||
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"ldr sp, %0\n\t"
|
||||
:
|
||||
: "m"(fstack)
|
||||
: "sp"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOOT_SRAM */
|
||||
|
||||
/* main */
|
||||
|
||||
static void __attribute__((naked)) __attribute__((used)) main(void)
|
||||
{
|
||||
|
@ -314,23 +320,30 @@ static void __attribute__((naked)) __attribute__((used)) main(void)
|
|||
setup_stack();
|
||||
#endif /* CONFIG_BOOT_SRAM */
|
||||
|
||||
setup_leds();
|
||||
RCC_Configuration();
|
||||
|
||||
setup_lcd();
|
||||
clear_lcd();
|
||||
/* while (1) ; */
|
||||
Init_GPIOs();
|
||||
|
||||
update_lcd();
|
||||
LCD_GLASS_Init();
|
||||
LCD_BlinkConfig(LCD_BlinkMode_AllSEG_AllCOM,LCD_BlinkFrequency_Div512);
|
||||
LCD_GLASS_DisplayString("FUBAR");
|
||||
while (1) ;
|
||||
|
||||
setup_leds();
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* update_lcd(); */
|
||||
switch_leds_on();
|
||||
/* switch_leds_on(); */
|
||||
GPIO_HIGH(LD_GPIO_PORT, LD_GREEN_GPIO_PIN);
|
||||
GPIO_HIGH(LD_GPIO_PORT, LD_BLUE_GPIO_PIN);
|
||||
delay();
|
||||
|
||||
/* update_lcd(); */
|
||||
switch_leds_off();
|
||||
/* switch_leds_off(); */
|
||||
GPIO_LOW(LD_GPIO_PORT, LD_GREEN_GPIO_PIN);
|
||||
GPIO_LOW(LD_GPIO_PORT, LD_BLUE_GPIO_PIN);
|
||||
delay();
|
||||
|
||||
LCD_GLASS_Clear();
|
||||
LCD_GLASS_DisplayString("FUBAR");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,614 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l_discovery_lcd.c
|
||||
* @author Microcontroller Division
|
||||
* @version V1.0.0
|
||||
* @date Apri-2011
|
||||
* @brief This file includes driver for the glass LCD Module mounted on
|
||||
* STM32l discovery board MB963
|
||||
******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l_discovery_lcd.h"
|
||||
#include "discover_board.h"
|
||||
#include "stm32l1xx_lcd.h"
|
||||
#include "stm32l1xx_gpio.h"
|
||||
#include "stm32l1xx_rcc.h"
|
||||
/* #include "main.h" */
|
||||
|
||||
/* this variable can be used for accelerate the scrolling exit when push user button */
|
||||
volatile bool KeyPressed = FALSE;
|
||||
|
||||
/* LCD BAR status: We don't write directly in LCD RAM for save the bar setting */
|
||||
uint8_t t_bar[2]={0x0,0X0};
|
||||
|
||||
/* =========================================================================
|
||||
LCD MAPPING
|
||||
=========================================================================
|
||||
A
|
||||
_ ----------
|
||||
COL |_| |\ |J /|
|
||||
F| H | K |B
|
||||
_ | \ | / |
|
||||
COL |_| --G-- --M--
|
||||
| /| \ |
|
||||
E| Q | N |C
|
||||
_ | / |P \|
|
||||
DP |_| -----------
|
||||
D
|
||||
|
||||
An LCD character coding is based on the following matrix:
|
||||
{ E , D , P , N }
|
||||
{ M , C , COL , DP}
|
||||
{ B , A , K , J }
|
||||
{ G , F , Q , H }
|
||||
|
||||
The character 'A' for example is:
|
||||
-------------------------------
|
||||
LSB { 1 , 0 , 0 , 0 }
|
||||
{ 1 , 1 , 0 , 0 }
|
||||
{ 1 , 1 , 0 , 0 }
|
||||
MSB { 1 , 1 , 0 , 0 }
|
||||
-------------------
|
||||
'A' = F E 0 0 hexa
|
||||
|
||||
*/
|
||||
|
||||
/* Constant table for cap characters 'A' --> 'Z' */
|
||||
const uint16_t CapLetterMap[26]=
|
||||
{
|
||||
/* A B C D E F G H I */
|
||||
0xFE00,0x6714,0x1d00,0x4714,0x9d00,0x9c00,0x3f00,0xfa00,0x0014,
|
||||
/* J K L M N O P Q R */
|
||||
0x5300,0x9841,0x1900,0x5a48,0x5a09,0x5f00,0xFC00,0x5F01,0xFC01,
|
||||
/* S T U V W X Y Z */
|
||||
0xAF00,0x0414,0x5b00,0x18c0,0x5a81,0x00c9,0x0058,0x05c0
|
||||
};
|
||||
|
||||
/* Constant table for number '0' --> '9' */
|
||||
const uint16_t NumberMap[10]=
|
||||
{
|
||||
/* 0 1 2 3 4 5 6 7 8 9 */
|
||||
0x5F00,0x4200,0xF500,0x6700,0xEa00,0xAF00,0xBF00,0x04600,0xFF00,0xEF00
|
||||
};
|
||||
|
||||
static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column,uint8_t* digit);
|
||||
|
||||
/**
|
||||
* @brief Configures the LCD GLASS relative GPIO port IOs and LCD peripheral.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void LCD_GLASS_Init(void)
|
||||
{
|
||||
LCD_InitTypeDef LCD_InitStruct;
|
||||
|
||||
|
||||
LCD_InitStruct.LCD_Prescaler = LCD_Prescaler_1;
|
||||
LCD_InitStruct.LCD_Divider = LCD_Divider_31;
|
||||
LCD_InitStruct.LCD_Duty = LCD_Duty_1_4;
|
||||
LCD_InitStruct.LCD_Bias = LCD_Bias_1_3;
|
||||
LCD_InitStruct.LCD_VoltageSource = LCD_VoltageSource_Internal;
|
||||
|
||||
|
||||
/* Initialize the LCD */
|
||||
LCD_Init(&LCD_InitStruct);
|
||||
|
||||
LCD_MuxSegmentCmd(ENABLE);
|
||||
|
||||
/* To set contrast to mean value */
|
||||
LCD_ContrastConfig(LCD_Contrast_Level_4);
|
||||
|
||||
LCD_DeadTimeConfig(LCD_DeadTime_0);
|
||||
LCD_PulseOnDurationConfig(LCD_PulseOnDuration_4);
|
||||
|
||||
/* Wait Until the LCD FCR register is synchronized */
|
||||
LCD_WaitForSynchro();
|
||||
|
||||
/* Enable LCD peripheral */
|
||||
LCD_Cmd(ENABLE);
|
||||
|
||||
/* Wait Until the LCD is enabled */
|
||||
while(LCD_GetFlagStatus(LCD_FLAG_ENS) == RESET)
|
||||
{
|
||||
}
|
||||
/*!< Wait Until the LCD Booster is ready */
|
||||
while(LCD_GetFlagStatus(LCD_FLAG_RDY) == RESET)
|
||||
{
|
||||
}
|
||||
|
||||
LCD_BlinkConfig(LCD_BlinkMode_Off,LCD_BlinkFrequency_Div32);
|
||||
LCD_GLASS_Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief To initialize the LCD pins
|
||||
* @caller main
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void LCD_GLASS_Configure_GPIO(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* Enable GPIOs clock */
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |
|
||||
RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH, ENABLE);
|
||||
|
||||
|
||||
/* Configure Output for LCD */
|
||||
/* Port A */
|
||||
GPIO_StructInit(&GPIO_InitStructure);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_Init( GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_LCD) ;
|
||||
|
||||
/* Configure Output for LCD */
|
||||
/* Port B */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 \
|
||||
| GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_Init( GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_LCD) ;
|
||||
|
||||
/* Configure Output for LCD */
|
||||
/* Port C*/
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 \
|
||||
| GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11 ;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
||||
GPIO_Init( GPIOC, &GPIO_InitStructure);
|
||||
|
||||
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource0,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource2,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource8,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource9,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_LCD) ;
|
||||
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,GPIO_AF_LCD) ;
|
||||
|
||||
/* Disable GPIOs clock */
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |
|
||||
RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE | RCC_AHBPeriph_GPIOH, DISABLE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LCD contrast setting min-->max-->min by pressing user button
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
static void Delay(uint32_t nTime)
|
||||
{
|
||||
while((nTime--) != 0);
|
||||
}
|
||||
|
||||
void LCD_contrast()
|
||||
{
|
||||
uint32_t contrast ;
|
||||
|
||||
/* To get the actual contrast value in register */
|
||||
contrast = LCD->FCR & LCD_Contrast_Level_7;
|
||||
|
||||
while ((GPIOC->IDR & USERBUTTON_GPIO_PIN) == 0x0)
|
||||
{
|
||||
contrast += LCD_Contrast_Level_1;
|
||||
|
||||
if (contrast > LCD_Contrast_Level_7)
|
||||
contrast=LCD_Contrast_Level_0;
|
||||
|
||||
LCD_ContrastConfig(contrast);
|
||||
Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setting bar on LCD, writes bar value in LCD frame buffer
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void LCD_bar()
|
||||
{
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xffff5fff;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xffff5fff;
|
||||
/* bar1 bar3 */
|
||||
LCD->RAM[LCD_RAMRegister_4] |= (uint32_t)(t_bar[0]<<12);
|
||||
|
||||
/*bar0 bar2 */
|
||||
LCD->RAM[LCD_RAMRegister_6] |= (uint32_t)(t_bar[1]<<12);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts an ascii char to the a LCD digit.
|
||||
* @param c: a char to display.
|
||||
* @param point: a point to add in front of char
|
||||
* This parameter can be: POINT_OFF or POINT_ON
|
||||
* @param column : flag indicating if a column has to be add in front
|
||||
* of displayed character.
|
||||
* This parameter can be: COLUMN_OFF or COLUMN_ON.
|
||||
* @param digit array with segment
|
||||
* @retval None
|
||||
*/
|
||||
static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column, uint8_t* digit)
|
||||
{
|
||||
uint16_t ch = 0 ;
|
||||
uint8_t i,j;
|
||||
|
||||
switch (*c)
|
||||
{
|
||||
case ' ' :
|
||||
ch = 0x00;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
ch = star;
|
||||
break;
|
||||
|
||||
case 'µ' :
|
||||
ch = C_UMAP;
|
||||
break;
|
||||
|
||||
case 'm' :
|
||||
ch = C_mMap;
|
||||
break;
|
||||
|
||||
case 'n' :
|
||||
ch = C_nMap;
|
||||
break;
|
||||
|
||||
case '-' :
|
||||
ch = C_minus;
|
||||
break;
|
||||
|
||||
case '/' :
|
||||
ch = C_slatch;
|
||||
break;
|
||||
|
||||
case '°' :
|
||||
ch = C_percent_1;
|
||||
break;
|
||||
case '%' :
|
||||
ch = C_percent_2;
|
||||
break;
|
||||
case 255 :
|
||||
ch = C_full;
|
||||
break ;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
ch = NumberMap[*c-0x30];
|
||||
break;
|
||||
|
||||
default:
|
||||
/* The character c is one letter in upper case*/
|
||||
if ( (*c < 0x5b) && (*c > 0x40) )
|
||||
{
|
||||
ch = CapLetterMap[*c-'A'];
|
||||
}
|
||||
/* The character c is one letter in lower case*/
|
||||
if ( (*c <0x7b) && ( *c> 0x60) )
|
||||
{
|
||||
ch = CapLetterMap[*c-'a'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the digital point can be displayed if the point is on */
|
||||
if (point)
|
||||
{
|
||||
ch |= 0x0002;
|
||||
}
|
||||
|
||||
/* Set the "COL" segment in the character that can be displayed if the column is on */
|
||||
if (column)
|
||||
{
|
||||
ch |= 0x0020;
|
||||
}
|
||||
|
||||
for (i = 12,j=0 ;j<4; i-=4,j++)
|
||||
{
|
||||
digit[j] = (ch >> i) & 0x0f; //To isolate the less signifiant dibit
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes a char in the LCD frame buffer.
|
||||
* @param ch: the character to display.
|
||||
* @param point: a point to add in front of char
|
||||
* This parameter can be: POINT_OFF or POINT_ON
|
||||
* @param column: flag indicating if a column has to be add in front
|
||||
* of displayed character.
|
||||
* This parameter can be: COLUMN_OFF or COLUMN_ON.
|
||||
* @param position: position in the LCD of the caracter to write [0:7]
|
||||
* @retval None
|
||||
* @par Required preconditions: The LCD should be cleared before to start the
|
||||
* write operation.
|
||||
*/
|
||||
void LCD_GLASS_WriteChar(uint8_t* ch, bool point, bool column, uint8_t position)
|
||||
{
|
||||
uint8_t digit[4]; /* Digit frame buffer */
|
||||
|
||||
/* To convert displayed character in segment in array digit */
|
||||
LCD_Conv_Char_Seg(ch,point,column,digit);
|
||||
|
||||
/* TO wait LCD Ready */
|
||||
while( LCD_GetFlagStatus (LCD_FLAG_UDR) != RESET) ;
|
||||
|
||||
switch (position)
|
||||
{
|
||||
/* Position 1 on LCD (Digit1)*/
|
||||
case 1:
|
||||
LCD->RAM[LCD_RAMRegister_0] &= 0xcffffffc;
|
||||
LCD->RAM[LCD_RAMRegister_2] &= 0xcffffffc;
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xcffffffc;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xcffffffc;
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 26 ) | (digit[0]& 0x03) ; // 1G 1B 1M 1E
|
||||
LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 26 ) | (digit[1]& 0x03) ; // 1F 1A 1C 1D
|
||||
LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 26 ) | (digit[2]& 0x03) ; // 1Q 1K 1Col 1P
|
||||
LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 26 ) | (digit[3]& 0x03) ; // 1H 1J 1DP 1N
|
||||
|
||||
break;
|
||||
|
||||
/* Position 2 on LCD (Digit2)*/
|
||||
case 2:
|
||||
LCD->RAM[LCD_RAMRegister_0] &= 0xf3ffff03;
|
||||
LCD->RAM[LCD_RAMRegister_2] &= 0xf3ffff03;
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xf3ffff03;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xf3ffff03;
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 24 )|((digit[0]& 0x02) << 6 )|((digit[0]& 0x01) << 2 ) ; // 2G 2B 2M 2E
|
||||
LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 24 )|((digit[1]& 0x02) << 6 )|((digit[1]& 0x01) << 2 ) ; // 2F 2A 2C 2D
|
||||
LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 24 )|((digit[2]& 0x02) << 6 )|((digit[2]& 0x01) << 2 ) ; // 2Q 2K 2Col 2P
|
||||
LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 24 )|((digit[3]& 0x02) << 6 )|((digit[3]& 0x01) << 2 ) ; // 2H 2J 2DP 2N
|
||||
|
||||
break;
|
||||
|
||||
/* Position 3 on LCD (Digit3)*/
|
||||
case 3:
|
||||
LCD->RAM[LCD_RAMRegister_0] &= 0xfcfffcff;
|
||||
LCD->RAM[LCD_RAMRegister_2] &= 0xfcfffcff;
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xfcfffcff;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xfcfffcff;
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 22 ) | ((digit[0]& 0x03) << 8 ) ; // 3G 3B 3M 3E
|
||||
LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 22 ) | ((digit[1]& 0x03) << 8 ) ; // 3F 3A 3C 3D
|
||||
LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 22 ) | ((digit[2]& 0x03) << 8 ) ; // 3Q 3K 3Col 3P
|
||||
LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 22 ) | ((digit[3]& 0x03) << 8 ) ; // 3H 3J 3DP 3N
|
||||
|
||||
break;
|
||||
|
||||
/* Position 4 on LCD (Digit4)*/
|
||||
case 4:
|
||||
LCD->RAM[LCD_RAMRegister_0] &= 0xffcff3ff;
|
||||
LCD->RAM[LCD_RAMRegister_2] &= 0xffcff3ff;
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xffcff3ff;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xffcff3ff;
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 18 ) | ((digit[0]& 0x03) << 10 ) ; // 4G 4B 4M 4E
|
||||
LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 18 ) | ((digit[1]& 0x03) << 10 ) ; // 4F 4A 4C 4D
|
||||
LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 18 ) | ((digit[2]& 0x03) << 10 ) ; // 4Q 4K 4Col 4P
|
||||
LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 18 ) | ((digit[3]& 0x03) << 10 ) ; // 4H 4J 4DP 4N
|
||||
|
||||
break;
|
||||
|
||||
/* Position 5 on LCD (Digit5)*/
|
||||
case 5:
|
||||
LCD->RAM[LCD_RAMRegister_0] &= 0xfff3cfff;
|
||||
LCD->RAM[LCD_RAMRegister_2] &= 0xfff3cfff;
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xfff3efff;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xfff3efff;
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x0c) << 16 ) | ((digit[0]& 0x03) << 12 ) ; // 5G 5B 5M 5E
|
||||
LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x0c) << 16 ) | ((digit[1]& 0x03) << 12 ) ; // 5F 5A 5C 5D
|
||||
LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x0c) << 16 ) | ((digit[2]& 0x01) << 12 ) ; // 5Q 5K 5P
|
||||
LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x0c) << 16 ) | ((digit[3]& 0x01) << 12 ) ; // 5H 5J 5N
|
||||
|
||||
break;
|
||||
|
||||
/* Position 6 on LCD (Digit6)*/
|
||||
case 6:
|
||||
LCD->RAM[LCD_RAMRegister_0] &= 0xfffc3fff;
|
||||
LCD->RAM[LCD_RAMRegister_2] &= 0xfffc3fff;
|
||||
LCD->RAM[LCD_RAMRegister_4] &= 0xfffc3fff;
|
||||
LCD->RAM[LCD_RAMRegister_6] &= 0xfffc3fff;
|
||||
|
||||
LCD->RAM[LCD_RAMRegister_0] |= ((digit[0]& 0x04) << 15 ) | ((digit[0]& 0x08) << 13 ) | ((digit[0]& 0x03) << 14 ) ; // 6B 6G 6M 6E
|
||||
LCD->RAM[LCD_RAMRegister_2] |= ((digit[1]& 0x04) << 15 ) | ((digit[1]& 0x08) << 13 ) | ((digit[1]& 0x03) << 14 ) ; // 6A 6F 6C 6D
|
||||
LCD->RAM[LCD_RAMRegister_4] |= ((digit[2]& 0x04) << 15 ) | ((digit[2]& 0x08) << 13 ) | ((digit[2]& 0x01) << 14 ) ; // 6K 6Q 6P
|
||||
LCD->RAM[LCD_RAMRegister_6] |= ((digit[3]& 0x04) << 15 ) | ((digit[3]& 0x08) << 13 ) | ((digit[3]& 0x01) << 14 ) ; // 6J 6H 6N
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Refresh LCD bar */
|
||||
LCD_bar();
|
||||
|
||||
/* Update the LCD display */
|
||||
LCD_UpdateDisplayRequest();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes a char in the LCD RAM.
|
||||
* @param ptr: Pointer to string to display on the LCD Glass.
|
||||
* @retval None
|
||||
*/
|
||||
void LCD_GLASS_DisplayString(uint8_t* ptr)
|
||||
{
|
||||
uint8_t i = 0x01;
|
||||
|
||||
/* Send the string character by character on lCD */
|
||||
while ((*ptr != 0) & (i < 8))
|
||||
{
|
||||
/* Display one character on LCD */
|
||||
LCD_GLASS_WriteChar(ptr, FALSE, FALSE, i);
|
||||
|
||||
/* Point on the next character */
|
||||
ptr++;
|
||||
|
||||
/* Increment the character counter */
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes a char in the LCD RAM.
|
||||
* @param ptr: Pointer to string to display on the LCD Glass.
|
||||
* @retval None
|
||||
* @par Required preconditions: Char is ASCCI value "Ored" with decimal point or Column flag
|
||||
*/
|
||||
void LCD_GLASS_DisplayStrDeci(uint16_t* ptr)
|
||||
{
|
||||
uint8_t i = 0x01;
|
||||
uint8_t char_tmp;
|
||||
|
||||
// LCD_GLASS_Clear();
|
||||
/* Send the string character by character on lCD */
|
||||
while ((*ptr != 0) & (i < 8))
|
||||
{
|
||||
char_tmp = (*ptr) & 0x00ff;
|
||||
|
||||
switch ((*ptr) & 0xf000)
|
||||
{
|
||||
case DOT:
|
||||
/* Display one character on LCD with decimal point */
|
||||
LCD_GLASS_WriteChar(&char_tmp, POINT_ON, COLUMN_OFF, i);
|
||||
break;
|
||||
case DOUBLE_DOT:
|
||||
/* Display one character on LCD with decimal point */
|
||||
LCD_GLASS_WriteChar(&char_tmp, POINT_OFF, COLUMN_ON, i);
|
||||
break;
|
||||
default:
|
||||
LCD_GLASS_WriteChar(&char_tmp, POINT_OFF, COLUMN_OFF, i);
|
||||
break;
|
||||
}/* Point on the next character */
|
||||
ptr++;
|
||||
|
||||
/* Increment the character counter */
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function Clear the whole LCD RAM.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void LCD_GLASS_Clear(void)
|
||||
{
|
||||
uint8_t counter = 0;
|
||||
|
||||
/* TO wait LCD Ready */
|
||||
while( LCD_GetFlagStatus (LCD_FLAG_UDR) != RESET) ;
|
||||
|
||||
for (counter = LCD_RAMRegister_0; counter <= LCD_RAMRegister_15; counter++)
|
||||
{
|
||||
LCD->RAM[counter] = 0;
|
||||
}
|
||||
|
||||
/* Update the LCD display */
|
||||
LCD_UpdateDisplayRequest();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display a string in scrolling mode
|
||||
* @param ptr: Pointer to string to display on the LCD Glass.
|
||||
* @param nScroll: Specifies how many time the message will be scrolled
|
||||
* @param ScrollSpeed : Speciifes the speed of the scroll, low value gives
|
||||
* higher speed
|
||||
* @retval None
|
||||
* @par Required preconditions: The LCD should be cleared before to start the
|
||||
* write operation.
|
||||
*/
|
||||
void LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed)
|
||||
{
|
||||
uint8_t Repetition;
|
||||
uint8_t Char_Nb;
|
||||
uint8_t* ptr1;
|
||||
uint8_t str[7]="";
|
||||
uint8_t Str_size;
|
||||
|
||||
if (ptr == 0) return;
|
||||
|
||||
/* To calculate end of string */
|
||||
for (ptr1=ptr,Str_size = 0 ; *ptr1 != 0; Str_size++,ptr1++) ;
|
||||
|
||||
ptr1 = ptr;
|
||||
|
||||
LCD_GLASS_DisplayString(ptr);
|
||||
Delay(ScrollSpeed);
|
||||
|
||||
/* To shift the string for scrolling display*/
|
||||
for (Repetition=0; Repetition<nScroll; Repetition++)
|
||||
{
|
||||
for (Char_Nb=0; Char_Nb<Str_size; Char_Nb++)
|
||||
{
|
||||
*(str) =* (ptr1+((Char_Nb+1)%Str_size));
|
||||
*(str+1) =* (ptr1+((Char_Nb+2)%Str_size));
|
||||
*(str+2) =* (ptr1+((Char_Nb+3)%Str_size));
|
||||
*(str+3) =* (ptr1+((Char_Nb+4)%Str_size));
|
||||
*(str+4) =* (ptr1+((Char_Nb+5)%Str_size));
|
||||
*(str+5) =* (ptr1+((Char_Nb+6)%Str_size));
|
||||
LCD_GLASS_Clear();
|
||||
LCD_GLASS_DisplayString(str);
|
||||
|
||||
/* user button pressed stop the scrolling sentence */
|
||||
if (KeyPressed)
|
||||
return;
|
||||
Delay(ScrollSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32l_discovery_lcd.h
|
||||
* @author Microcontroller Division
|
||||
* @version V1.0.0
|
||||
* @date Apri-2011
|
||||
* @brief This file contains all the functions prototypes for the glass LCD
|
||||
* firmware driver.
|
||||
******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __stm32l_discovery_lcd
|
||||
#define __stm32l_discovery_lcd
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32l1xx.h"
|
||||
#include "discover_board.h"
|
||||
|
||||
/* Define for scrolling sentences*/
|
||||
#define SCROLL_SPEED 300
|
||||
#define SCROLL_SPEED_L 600
|
||||
#define SCROLL_NUM 1
|
||||
|
||||
/* Define for character '.' */
|
||||
#define POINT_OFF FALSE
|
||||
#define POINT_ON TRUE
|
||||
|
||||
/* Define for caracter ":" */
|
||||
#define COLUMN_OFF FALSE
|
||||
#define COLUMN_ON TRUE
|
||||
|
||||
#define DOT 0x8000 /* for add decimal point in string */
|
||||
#define DOUBLE_DOT 0x4000 /* for add decimal point in string */
|
||||
|
||||
|
||||
/* =========================================================================
|
||||
LCD MAPPING
|
||||
=========================================================================
|
||||
A
|
||||
_ ----------
|
||||
COL |_| |\ |J /|
|
||||
F| H | K |B
|
||||
_ | \ | / |
|
||||
COL |_| --G-- --M--
|
||||
| /| \ |
|
||||
E| Q | N |C
|
||||
_ | / |P \|
|
||||
DP |_| -----------
|
||||
D
|
||||
|
||||
An LCD character coding is based on the following matrix:
|
||||
{ E , D , P , N }
|
||||
{ M , C , COL , DP}
|
||||
{ B , A , K , J }
|
||||
{ G , F , Q , H }
|
||||
|
||||
The character 'A' for example is:
|
||||
-------------------------------
|
||||
LSB { 1 , 0 , 0 , 0 }
|
||||
{ 1 , 1 , 0 , 0 }
|
||||
{ 1 , 1 , 0 , 0 }
|
||||
MSB { 1 , 1 , 0 , 0 }
|
||||
-------------------
|
||||
'A' = F E 0 0 hexa
|
||||
|
||||
*/
|
||||
/* Macros used for set/reset bar LCD bar */
|
||||
#define BAR0_ON t_bar[1] |= 8
|
||||
#define BAR0_OFF t_bar[1] &= ~8
|
||||
#define BAR1_ON t_bar[0] |= 8
|
||||
#define BAR1_OFF t_bar[0] &= ~8
|
||||
#define BAR2_ON t_bar[1] |= 2
|
||||
#define BAR2_OFF t_bar[1] &= ~2
|
||||
#define BAR3_ON t_bar[0] |= 2
|
||||
#define BAR3_OFF t_bar[0] &= ~2
|
||||
|
||||
/* code for 'µ' character */
|
||||
#define C_UMAP 0x6084
|
||||
|
||||
/* code for 'm' character */
|
||||
#define C_mMap 0xb210
|
||||
|
||||
/* code for 'n' character */
|
||||
#define C_nMap 0x2210
|
||||
|
||||
/* constant code for '*' character */
|
||||
#define star 0xA0DD
|
||||
|
||||
/* constant code for '-' character */
|
||||
#define C_minus 0xA000
|
||||
|
||||
/* constant code for '/' */
|
||||
#define C_slatch 0x00c0
|
||||
|
||||
/* constant code for ° */
|
||||
#define C_percent_1 0xec00
|
||||
|
||||
/* constant code for small o */
|
||||
#define C_percent_2 0xb300
|
||||
|
||||
#define C_full 0xffdd
|
||||
|
||||
void LCD_bar(void);
|
||||
void LCD_GLASS_Init(void);
|
||||
void LCD_GLASS_WriteChar(uint8_t* ch, bool point, bool column,uint8_t position);
|
||||
void LCD_GLASS_DisplayString(uint8_t* ptr);
|
||||
void LCD_GLASS_DisplayStrDeci(uint16_t* ptr);
|
||||
void LCD_GLASS_ClearChar(uint8_t position);
|
||||
void LCD_GLASS_Clear(void);
|
||||
void LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed);
|
||||
void LCD_GLASS_WriteTime(char a, uint8_t posi, bool column);
|
||||
void LCD_GLASS_Configure_GPIO(void);
|
||||
|
||||
#endif /* stm32l_discovery_lcd*/
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
Ładowanie…
Reference in New Issue