Skip to content

Commit 1010cbc

Browse files
author
Andy Gock
committed
Merge pull request #5 from miguelmoreto/master
STM32F4 support, Zolen LCD and text.c bug
2 parents 440c4c9 + bf7f401 commit 1010cbc

File tree

7 files changed

+479
-6
lines changed

7 files changed

+479
-6
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ The following Newhaven displays have been physically tested with and confirmed w
4141
- NHD-C12864WC-FSW-FBW-3V3-M
4242
- NHD-C12864A1Z-FSW-FBW-HTT
4343
- NHD-C12832A1Z-FSW-FBW-3V3
44+
- ZOLEN-12864-FFSSWE-NAA
4445

4546
Supported microcontrollers
4647
--------------------------
@@ -51,6 +52,7 @@ MCUs supported:
5152
- NXP LPC111x ARM Cortex-M0
5253
- NXP LPC11Uxx ARM Cortex-M0
5354
- ST STM32 F0 ARM Cortex-M0
55+
- ST STM32 F4 ARM Cortex-M4
5456
- Microchip PIC24H (and probably other 16-bit MCUs)
5557

5658
Development boards tested on (with on-board LCD):
@@ -60,6 +62,7 @@ Development boards tested on (with on-board LCD):
6062
Development boards tested on (without on-board LCD):
6163

6264
- Microstick II with PIC24H and Nokia 3310/5110 LCD, ST7565R and ST7565P
65+
- ST Nucleo F401RE.
6366

6467
### Special note
6568

@@ -76,6 +79,7 @@ Pick microcontroller type (pick one only):
7679
GLCD_DEVICE_LPX11UXX
7780
GLCD_DEVICE_AVR8
7881
GLCD_DEVICE_STM32F0XX
82+
GLCD_DEVICE_STM32F4XX
7983
GLCD_DEVICE_PIC24H
8084

8185
Pick LCD controller type (pick one only):
@@ -104,6 +108,7 @@ sequence, define one of the following:
104108
GLCD_INIT_NHD_C12832A1Z_FSW_FBW_3V3
105109
GLCD_INIT_NHD_C12864A1Z_FSW_FBW_HTT
106110
GLCD_INIT_NHD_C12864WC_FSW_FBW_3V3_M
111+
GLCD_INIT_ZOLEN_12864_FFSSWE_NAA
107112

108113
If you don't specify a NHD model, ST7565 controller selection will default to `GLCD_INIT_NHD_C12864WC_FSW_FBW_3V3_M` sequence.
109114
This however may change in the future.

controllers/ST7565R.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,23 @@ void glcd_set_contrast(uint8_t val) {
3737

3838
void glcd_power_down(void)
3939
{
40-
/* Not applicable */
41-
return;
42-
//asm("break");
40+
/* Command sequence as in ST7565 datasheet */
41+
glcd_command(0xac); // Static indicator off
42+
glcd_command(0x00); // Static indicator register, not blinking
43+
glcd_command(0xae); // Display OFF
44+
glcd_command(0xa5); // Display all points ON
45+
46+
/* Display is now in sleep mode */
4347
}
4448

4549
void glcd_power_up(void)
4650
{
47-
/* Not applicable */
51+
glcd_command(0xa4); // Display all points OFF
52+
glcd_command(0xad); // Static indicator ON
53+
glcd_command(0x00); // Static indicator register, not Blinking
54+
glcd_command(0xaf);
55+
4856
return;
49-
//asm("break");
5057
}
5158

5259
void glcd_set_y_address(uint8_t y)
@@ -188,6 +195,18 @@ void glcd_ST7565R_init(void) {
188195
glcd_set_contrast(45); /* Set contrast value, experimentally determined, value 0 to 63 */
189196
glcd_command(0x2f); /* Power controller set */
190197
glcd_command(0xaf); /* Display on */
198+
#elif defined(GLCD_INIT_ZOLEN_12864_FFSSWE_NAA)
199+
/* Init sequence for Zolen 128x64 module with
200+
* size 40x35mm. Chip ST7567 */
201+
202+
glcd_command(0xa0); /* ADC select in normal mode */
203+
glcd_command(0xae); /* Display OFF */
204+
glcd_command(0xc8); /* Common output mode select: reverse direction (last 3 bits are ignored) */
205+
glcd_command(0xa3); /* LCD bias set at 1/9 */
206+
glcd_command(0x2f); /* Power control set to operating mode: 7 */
207+
glcd_command(0x24); /* Internal resistor ratio, set to: 6 */
208+
glcd_set_contrast(20); /* Set contrast, value experimentally determined, value 0 to 63 */
209+
glcd_command(0xaf); /* Display on */
191210

192211
#else
193212

devices/STM32F4.c

Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
/**
2+
\file STM32F4.h
3+
\author Andy Gock (modified for STM32F4xx by Moreto)
4+
\brief Functions specific to STM32 F4 ARM Cortex-M4 devices.
5+
*/
6+
7+
/*
8+
Copyright (c) 2012, Andy Gock
9+
10+
All rights reserved.
11+
12+
Redistribution and use in source and binary forms, with or without
13+
modification, are permitted provided that the following conditions are met:
14+
* Redistributions of source code must retain the above copyright
15+
notice, this list of conditions and the following disclaimer.
16+
* Redistributions in binary form must reproduce the above copyright
17+
notice, this list of conditions and the following disclaimer in the
18+
documentation and/or other materials provided with the distribution.
19+
* Neither the name of Andy Gock nor the
20+
names of its contributors may be used to endorse or promote products
21+
derived from this software without specific prior written permission.
22+
23+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26+
DISCLAIMED. IN NO EVENT SHALL ANDY GOCK BE LIABLE FOR ANY
27+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33+
*/
34+
35+
#if defined(GLCD_DEVICE_STM32F4XX)
36+
37+
/* Includes from CMSIS and Peripheral Library */
38+
#include "devices\STM32F4.h"
39+
#include "stm32f4xx_spi.h"
40+
41+
/* Includes from GLCD */
42+
#include "glcd.h"
43+
44+
/* Includes for RTOS */
45+
#ifdef GLCD_USE_RTOS
46+
#include "BRTOS.h"
47+
#endif
48+
49+
void delay_ms(uint32_t ms);
50+
51+
//#define BACKLIGHT_INVERT // Uncomment if LED backlight turn on with low value
52+
53+
void glcd_init(void)
54+
{
55+
56+
/* Initialisation for PCD8544 controller */
57+
58+
/* Declare GPIO and SPI init structures */
59+
GPIO_InitTypeDef GPIO_InitStructure;
60+
SPI_InitTypeDef SPI_InitStructure;
61+
62+
/* Configuring CS, DC (A0) and RST pin */
63+
/* Peripheral clock init. */
64+
RCC_AHB1PeriphClockCmd(CONTROLLER_SPI_DC_RCC | CONTROLLER_SPI_SS_RCC | \
65+
CONTROLLER_SPI_RST_RCC, ENABLE);
66+
/* CS pin */
67+
GPIO_InitStructure.GPIO_Pin = CONTROLLER_SPI_SS_PIN;
68+
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
69+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
70+
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
71+
GPIO_Init(CONTROLLER_SPI_SS_PORT, &GPIO_InitStructure);
72+
73+
/* DC (A0) pin */
74+
GPIO_InitStructure.GPIO_Pin = CONTROLLER_SPI_DC_PIN;
75+
GPIO_Init(CONTROLLER_SPI_DC_PORT, &GPIO_InitStructure);
76+
77+
/* RST pin */
78+
GPIO_InitStructure.GPIO_Pin = CONTROLLER_SPI_RST_PIN;
79+
GPIO_Init(CONTROLLER_SPI_RST_PORT, &GPIO_InitStructure);
80+
81+
/* Make sure chip is de-selected by default */
82+
GLCD_DESELECT();
83+
84+
/*
85+
* Configuring SPI:
86+
*/
87+
/* Enable the SPI clock */
88+
SPIx_CLK_INIT(SPIx_CLK, ENABLE);
89+
/* Enable SPI GPIO clocks */
90+
RCC_AHB1PeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MOSI_GPIO_CLK, ENABLE);
91+
/* Connect SPI pins to the corresponding alternate function */
92+
GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF);
93+
GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF);
94+
// GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF);
95+
96+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
97+
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
98+
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
99+
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
100+
101+
/* SPI SCK pin configuration */
102+
GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
103+
GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure);
104+
/* SPI MOSI pin configuration */
105+
GPIO_InitStructure.GPIO_Pin = SPIx_MOSI_PIN;
106+
GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure);
107+
#if 0
108+
GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN;
109+
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
110+
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
111+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
112+
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
113+
GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure);
114+
#endif
115+
/* SPI configuration */
116+
SPI_I2S_DeInit(SPIx);
117+
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
118+
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
119+
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
120+
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
121+
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
122+
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
123+
/* Clock set to 8MHz */
124+
SPI_InitStructure.SPI_BaudRatePrescaler = SPIx_PRESCALLER;
125+
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
126+
SPI_Init(SPIx, &SPI_InitStructure);
127+
/* Enable the SPI peripheral */
128+
SPI_Cmd(SPIx, ENABLE);
129+
130+
glcd_select_screen((uint8_t *)&glcd_buffer,&glcd_bbox);
131+
132+
RCC_AHB1PeriphClockCmd(LCD_LED_GPIO_RCC, ENABLE);
133+
GPIO_InitStructure.GPIO_Pin = LCD_LED_PIN;
134+
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
135+
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
136+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
137+
GPIO_Init(LCD_LED_PORT, &GPIO_InitStructure);
138+
139+
140+
#if defined(GLCD_CONTROLLER_PCD8544)
141+
/* Initialisation sequence of controller */
142+
143+
glcd_PCD8544_init();
144+
glcd_clear();
145+
146+
#elif defined(GLCD_CONTROLLER_ST7565R)
147+
glcd_reset();
148+
glcd_enable_backlight(ENABLE);
149+
glcd_ST7565R_init();
150+
151+
#else
152+
#error "Controller not supported by STM32F0xx"
153+
#endif
154+
155+
}
156+
157+
/* Change backlight led state ENABLE or DISABLE*/
158+
void glcd_enable_backlight(FunctionalState state)
159+
{
160+
161+
#ifdef USE_TIMER_PWM
162+
GPIO_InitTypeDef GPIO_InitStructure;
163+
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
164+
TIM_OCInitTypeDef TIM_OCInitStructure;
165+
166+
uint16_t PrescalerValue = 0;
167+
/* Init LED backlight pin*/
168+
GPIO_InitStructure.GPIO_Pin = LCD_LED_PIN;
169+
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
170+
171+
if (state == ENABLE){
172+
173+
/* Compute the prescaler value
174+
* This formula yelds the prescaller for a frequency of 100Hz with
175+
* 255 steps (period) */
176+
PrescalerValue = (uint16_t) (((SystemCoreClock /LCD_TIM_Sys_Prescaller) / 255)/100) - 1;
177+
178+
/* Init LED pin as Alternated Function: */
179+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
180+
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
181+
GPIO_Init(LCD_LED_PORT, &GPIO_InitStructure);
182+
183+
/* Connect TIM2 pins to AF */
184+
GPIO_PinAFConfig(LCD_LED_PORT, LCD_LED_PinSource, LCD_AF);
185+
186+
/* TIM clock enable */
187+
LCD_TIM_PeriphClockCmd(LCD_TIM_RCC, ENABLE);
188+
189+
/* Time base configuration: 100Hz period with 255 steps */
190+
TIM_TimeBaseStructure.TIM_Period = 254;
191+
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
192+
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
193+
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
194+
TIM_TimeBaseInit(LCD_TIM, &TIM_TimeBaseStructure);
195+
196+
/* PWM1 Mode configuration: Channel3 */
197+
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
198+
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
199+
TIM_OCInitStructure.TIM_Pulse = 128; // Initial value (half)
200+
#ifdef BACKLIGHT_INVERT_OUT
201+
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
202+
#else
203+
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
204+
#endif
205+
LCD_TIM_OCInit(LCD_TIM, &TIM_OCInitStructure);
206+
LCD_TIM_OCPreload(LCD_TIM, TIM_OCPreload_Enable);
207+
208+
TIM_ARRPreloadConfig(LCD_TIM, ENABLE);
209+
210+
/* TIM3 enable counter */
211+
TIM_Cmd(LCD_TIM, ENABLE);
212+
213+
}
214+
/* If DISABLE: Disable timer and turn off led */
215+
else{
216+
// DeInit LED pin as Alternated Function:
217+
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
218+
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
219+
GPIO_Init(LCD_LED_PORT, &GPIO_InitStructure);
220+
/* TIM clock disable */
221+
TIM_Cmd(LCD_TIM, DISABLE);
222+
LCD_TIM_PeriphClockCmd(LCD_TIM_RCC, DISABLE);
223+
#ifdef BACKLIGHT_INVERT_OUT
224+
GPIO_SetBits(LCD_LED_PORT,LCD_LED_PIN);
225+
#else
226+
// Turn off LED backlight
227+
GPIO_ResetBits(LCD_LED_PORT,LCD_LED_PIN);
228+
}
229+
#endif
230+
#else // if not defined USE_TIMER_PWM
231+
if (state == ENABLE){
232+
#ifdef BACKLIGHT_INVERT_OUT
233+
GPIO_ResetBits(LCD_LED_PORT,LCD_LED_PIN);
234+
#else
235+
GPIO_SetBits(LCD_LED_PORT,LCD_LED_PIN);
236+
#endif
237+
}else{
238+
#ifdef BACKLIGHT_INVERT_OUT
239+
GPIO_SetBits(LCD_LED_PORT,LCD_LED_PIN);
240+
#else
241+
GPIO_ResetBits(LCD_LED_PORT,LCD_LED_PIN);
242+
#endif
243+
}
244+
#endif
245+
}
246+
247+
#ifdef USE_TIMER_PWM
248+
/* Change PWM duty cycle (brightness).
249+
* values between 0 and 255 */
250+
void glcd_change_backlight(uint8_t value){
251+
252+
LCD_TIM_SetCompare(LCD_TIM,value);
253+
}
254+
#endif
255+
256+
void glcd_spi_write(uint8_t c)
257+
{
258+
//uint8_t temp;
259+
260+
GLCD_SELECT();
261+
/*!< Loop while DR register in not emplty */
262+
while (SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
263+
264+
SPI_I2S_SendData(SPIx, (uint16_t) c);
265+
266+
/* Wait until entire byte has been read (which we discard anyway) */
267+
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) != RESET);
268+
269+
//temp = SPI_I2S_ReceiveData(SPIx);
270+
271+
GLCD_DESELECT();
272+
}
273+
274+
void glcd_reset(void)
275+
{
276+
/* Toggle RST low to reset. Minimum pulse 100ns on datasheet. */
277+
GLCD_SELECT();
278+
GLCD_RESET_LOW();
279+
280+
281+
delay_ms(GLCD_RESET_TIME);
282+
//DelayTask(GLCD_RESET_TIME);
283+
GLCD_RESET_HIGH();
284+
GLCD_DESELECT();
285+
}
286+
287+
void delay_ms(uint32_t ms){
288+
289+
#ifndef GLCD_USE_RTOS
290+
uint32_t count = 0;
291+
uint32_t ms_counter = 0;
292+
do{
293+
count = 0;
294+
const uint32_t utime = 100000;
295+
do{
296+
count++;
297+
}
298+
while (count < utime);
299+
ms_counter++;
300+
}while(ms_counter < ms);
301+
#else
302+
GLCD_RTOS_DELAY_FCN // Call the delay function defined in the header file.
303+
#endif
304+
}
305+
306+
307+
#endif

0 commit comments

Comments
 (0)