From 4a8fefed01935c3ede1a6bc272c13ea03a05cadb Mon Sep 17 00:00:00 2001 From: Fabien Le Mentec Date: Sun, 16 Oct 2011 11:05:46 -0500 Subject: [PATCH] [update] lcd example uses libstm32l_discovery --- doc/tutorial/tutorial.pdf | Bin 106056 -> 106136 bytes doc/tutorial/tutorial.tex | 9 + example/lcd/Makefile | 33 +- example/lcd/discover_board.h | 61 +++ example/lcd/main.c | 475 +++++++++++----------- example/lcd/stm32l_discovery_lcd.c | 614 +++++++++++++++++++++++++++++ example/lcd/stm32l_discovery_lcd.h | 127 ++++++ 7 files changed, 1076 insertions(+), 243 deletions(-) create mode 100644 example/lcd/discover_board.h create mode 100644 example/lcd/stm32l_discovery_lcd.c create mode 100644 example/lcd/stm32l_discovery_lcd.h diff --git a/doc/tutorial/tutorial.pdf b/doc/tutorial/tutorial.pdf index f62e4f406d73f29bf597fbfad6ba4806f168e721..b84d061f57921ebc02df6a11261675a97c3d31fa 100644 GIT binary patch delta 2121 zcmah{dpuNI8@Ao5sYoSVW*BPF-ZOiU~(#ru`&ds@=gJ=O;Q{qG~toZG*OB`?B>6*On(f+;u^I z^r|qRO2Cb7=}|kd#V{T}Fa>k&%w38OxX9k!;9LbdauhXq_5}LvBgNkQw;>_5XlVXI zc+-vM^wH=$1(!bDz%v8)_6N~S$DSHG&Zxg%SAMu6+~M_+JiSPR+{bZ4o!xQ6IVoEW z(i|EXvR&?#O{GN*7XvAPdb7%EYhpjE$Bu6wTYvfSCxHfk>8uC&=ecmJu&2@ z9x0>YDBv7T4FmqUf!Ll57^tM3-dWx;9IjWNT7Il=dc6vqd}*rAtg+DFRquxdAzJ&6 zY(02MYtW@{K(!(N=GKn2DbaVCtA4~~ZeE@@nBuJT(w#T9!Q5ZJZ}qu4w_XnyA5(|r?V}^Atke_^JYQolTg8Z7ejws>y5J@YY*k#X z!?*%WpYp8sH~mnx>~gDEHSQy7P{$gcYUkI^9$x>AFkuwa6VV2-ZxzgAeKPi>*qtfP zCjvB=b%lH$Z?q%l$%|h+;AYm;*b90N}Z1O!#?h>WXqwkt9ealM|~)OAxac=vlYcj==R(Q971BdcqDksDnDL zUrAPS77M4Qz47(;c8EmWPAH?>w@*zUl0^SP_z*0wlzjgQr7GAZ=k**oU7~9+_C}Y> zSyT8_95kr)cp$AT)})Q4tiN4({0;u0rwu;q(VM$})+aD^6MymjRmNDpWAg-l)6eaY zGcLD#`1~#FLrlGdwR^;ZeU?y{s@-{~UxCB|?<~_vrGu+YTf5aekbJKJ8BWrN&QYI?j5d4(@V~m z7{8l(xh2qU1L|~qP~I-Zl_ev?k%5@Y^R|WFT?KQJ{Nl3}-SY3}mXoA%iSWR&_Qec`{#$^P-=DYg89$>+MqQbld{aUH3A zr_!LWxX;;4hwXd50=Kk8+>DbeqQ#ik>lyfdL4;6SI3O^JIv`x-p}d|QnDL2aQL|5X zc3FDk`4bm3eriA-bp$nO%%lM@d!s!^s3@!um5Mft>W6tFiE?Htc3sJ;Q^(H9x~r=B z6kR@=#O|Nbh>!A(G9wsid9x(KSDuZZTtS7mXC~XvdA{Ve>yXBAOT*6* z(}~T&fpSG+jVsPF4%#E!9-?lGn@DX~XU>?^SozI3-j5GuZ)puqXeo1e`;FK)XPKP* zj6pI}7MFAuMuyo}gtA#gaL7UCt)b1D=xd3pggR9M;KWv-fD{2*fR7A} zP9cKd7cqp0`@T~^2!*IiFd7C)V=xuwHD3fAH^7vod@7ws;sa^26bi4B4>-yq2oK0# zi5FpBhiiyCx9$_EId5DYG6qRm*LMUYk27@#nr4U%>i%HLpAt)jh$>RS3rE{l% zFbqk_E@B8MrS}~}cqN4Z^9RHnWSLvhEDJrvl;KJ?L6E+E_m9h93_+ZXOQAsE0Ntj5j=L!4G$3FgDu`nP zWI~EgO2Kg}0*yu@w+MlR#8hM@m?)rvmSIm%m+gB0GYKKM? zK5{-<6xCFJXmB8sFL*lpFm8O+`7x(}jxVL+`BWk;IohM5OzDVpJXzQ0bggTLk3T26 zgx0xk&i3Vj({+#URz-&UP5X74HnTf_OdCE^kQom?Zxn?+XuPuc|x zJf-Uf<%P4K*{5Lf-g#7$)rStRxbmhoVg}Tip0{eRaU5Eo(G!~2r(A87^K zCF$9ru*(A1soJ&jwlU)a)3{>;^UkbFRyQB@=BxZva`G?;4h0x9z{WF4#A%M;7#L54(Q&R+ypGKjJ2( zrR%K_vrlXqL0R^_tb~c7Uhf_OQ!#V<4UX%#f!sO%-o|HvbFpk^+V`B1FwR7e>}mO> zyxKr#w(}9wtT^KQWMyyD(XY=@l2bEu&CNxDCbkbvHn@(uskY}H^HI+*jxY10%pI8( zC!`e1W`R+mv?dm_7zmr%EW{gwPlZgc$?s1^Vw+h3!o41FdsNKkHon8XQS*>^O2NpJ zM+10LFLYB?kSkbGGI933(9cWVPNet?*W8H6E^=y*{?LNzBvdmjRLQPn)w`Z*vWO_D z&*sIbd|j;-Ow;vtroY}tikpt%wjNb_trG^irSBv5ONxlPiLE2NzXOrF6egT71$w z6KhxhWKpy_gR(;Y%1ye(*4-|=Bv&|YP@qmS;d(Z&-N$*7Hzu^X?J`yFQvS9hoA;nA z*Jr%1+_UT0$;2kS2Bvelxi6UpSp7BPSNuHneYC4SU+_fA6;Osn>YO zLCUX#?yD}(9sJ4O;Je94hnp*Z_`+}d1%AwqiBnv$smV)E`AK8@2luS>FRi0(uRK)u z^&0f|qvhe!TimRCqZ-OSb}i#r%Xbg+dbS1bSS0Qq<2W@^hqy88&59q=bY`(1Tko>c zdE^Ejne={|K7bG~BKfMAWc}Cir()7H11IPd;Ps;Hp%}g1=>UWwpcaPGAx#XXqmpGZ z62}sPwE1*Gk}M;Mbpc31Dj{)nVN4RRuv;P+{$Cvcz+hBTS3;tRKn&5m!|5odg#nuL zEoh*ah7SP1K@`xc1#wslgK*+ChW!)5LNN|#2@)XuC-L7r0!JmsOG(Q`bWLA$06{f- zfhdM*%7Pf6l?e>eK~!T-7=#f`KQICR<$K%T4+y{nN@#|LL6BB42H}8a6CA=IZH&Mr zhs#LId34R$2?WD5BB28yp_w}!fFVRfb^%*(`CpH(F-$U7Msnvuo-C#Zh_W!yi$w=e xfM7wO7XU)64Fm#sF&PvW{QoH76b8d6F)1=3DK&w|H(C&1aBM`SZt(Lm`U4u;2@C)L diff --git a/doc/tutorial/tutorial.tex b/doc/tutorial/tutorial.tex index 370eb70..cef3632 100644 --- a/doc/tutorial/tutorial.tex +++ b/doc/tutorial/tutorial.tex @@ -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} diff --git a/example/lcd/Makefile b/example/lcd/Makefile index eeb4813..0febe49 100644 --- a/example/lcd/Makefile +++ b/example/lcd/Makefile @@ -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 + +OBJS=$(SRCS:.c=.o) -all: $(BIN_IMAGE) +all: $(ELF) -$(BIN_IMAGE): $(EXECUTABLE) - $(OBJCOPY) -O binary $^ $@ +$(ELF): $(OBJS) + $(CC) $(CFLAGS) -o $@ $(OBJS) -L../libstm32l_discovery/build -lstm32l_discovery -$(EXECUTABLE): main.c - $(CC) $(CFLAGS) $^ -o $@ +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $^ clean: - rm -rf $(EXECUTABLE) - rm -rf $(BIN_IMAGE) + -rm -f $(OBJS) + -rm -f $(ELF) .PHONY: all clean diff --git a/example/lcd/discover_board.h b/example/lcd/discover_board.h new file mode 100644 index 0000000..9161768 --- /dev/null +++ b/example/lcd/discover_board.h @@ -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. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ */ + +/* 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****/ diff --git a/example/lcd/main.c b/example/lcd/main.c index b693084..3713971 100644 --- a/example/lcd/main.c +++ b/example/lcd/main.c @@ -1,8 +1,23 @@ -/* this example is only for stm32l discover */ - -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; - +/* this example is only for stm32l discover. + adapted from ST firmwares projects. + */ + +/* 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 + EXTI_InitTypeDef EXTI_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; +#endif #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 -#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 +#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 -static void setup_lcd(void) -{ +#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 */ - 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 */ - - 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]); - } +#endif /* fixme */ } -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; */ -} - - -#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"); } } diff --git a/example/lcd/stm32l_discovery_lcd.c b/example/lcd/stm32l_discovery_lcd.c new file mode 100644 index 0000000..64163de --- /dev/null +++ b/example/lcd/stm32l_discovery_lcd.c @@ -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. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ */ + +/* 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
© COPYRIGHT 2011 STMicroelectronics
+ */ + +/* 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****/ -- 2.30.2