Skip to content

Commit f7a444b

Browse files
committed
implemented FSMC for driving an LCD on 16 bit parallel data bus
1 parent a84b8b2 commit f7a444b

5 files changed

Lines changed: 119 additions & 73 deletions

File tree

STM32F4/cores/maple/libmaple/fsmc.c

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -35,62 +35,53 @@
3535
#ifdef STM32_HIGH_DENSITY
3636

3737
/**
38-
* Configure FSMC GPIOs for use with SRAM.
39-
*/
40-
void fsmc_sram_init_gpios(void) {
41-
/* Data lines... */
42-
gpio_set_mode(PD0, GPIO_AF_OUTPUT_PP);
43-
gpio_set_mode(PD1, GPIO_AF_OUTPUT_PP);
44-
gpio_set_mode(PD8, GPIO_AF_OUTPUT_PP);
45-
gpio_set_mode(PD9, GPIO_AF_OUTPUT_PP);
46-
gpio_set_mode(PD10, GPIO_AF_OUTPUT_PP);
47-
gpio_set_mode(PD14, GPIO_AF_OUTPUT_PP);
48-
gpio_set_mode(PD15, GPIO_AF_OUTPUT_PP);
49-
gpio_set_mode(PE7, GPIO_AF_OUTPUT_PP);
50-
gpio_set_mode(PE8, GPIO_AF_OUTPUT_PP);
51-
gpio_set_mode(PE9, GPIO_AF_OUTPUT_PP);
52-
gpio_set_mode(PE10, GPIO_AF_OUTPUT_PP);
53-
gpio_set_mode(PE11, GPIO_AF_OUTPUT_PP);
54-
gpio_set_mode(PE12, GPIO_AF_OUTPUT_PP);
55-
gpio_set_mode(PE13, GPIO_AF_OUTPUT_PP);
56-
gpio_set_mode(PE14, GPIO_AF_OUTPUT_PP);
57-
gpio_set_mode(PE15, GPIO_AF_OUTPUT_PP);
38+
* Configure FSMC GPIOs for use with LCDs.
39+
*/
5840

59-
/* Address lines... */
60-
gpio_set_mode(PD11, GPIO_AF_OUTPUT_PP);
61-
gpio_set_mode(PD12, GPIO_AF_OUTPUT_PP);
62-
gpio_set_mode(PD13, GPIO_AF_OUTPUT_PP);
63-
#if 0 // not available on LQFP package
64-
gpio_set_mode(GPIOF, 0, GPIO_AF_OUTPUT_PP);
65-
gpio_set_mode(GPIOF, 1, GPIO_AF_OUTPUT_PP);
66-
gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP);
67-
gpio_set_mode(GPIOF, 3, GPIO_AF_OUTPUT_PP);
68-
gpio_set_mode(GPIOF, 4, GPIO_AF_OUTPUT_PP);
69-
gpio_set_mode(GPIOF, 5, GPIO_AF_OUTPUT_PP);
70-
gpio_set_mode(GPIOF, 12, GPIO_AF_OUTPUT_PP);
71-
gpio_set_mode(GPIOF, 13, GPIO_AF_OUTPUT_PP);
72-
gpio_set_mode(GPIOF, 14, GPIO_AF_OUTPUT_PP);
73-
gpio_set_mode(GPIOF, 15, GPIO_AF_OUTPUT_PP);
74-
gpio_set_mode(GPIOG, 0, GPIO_AF_OUTPUT_PP);
75-
gpio_set_mode(GPIOG, 1, GPIO_AF_OUTPUT_PP);
76-
gpio_set_mode(GPIOG, 2, GPIO_AF_OUTPUT_PP);
77-
gpio_set_mode(GPIOG, 3, GPIO_AF_OUTPUT_PP);
78-
gpio_set_mode(GPIOG, 4, GPIO_AF_OUTPUT_PP);
79-
gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP);
80-
#endif // not available on LQFP package
81-
/* And control lines... */
82-
gpio_set_mode(PD4, GPIO_AF_OUTPUT_PP); // NOE
83-
gpio_set_mode(PD5, GPIO_AF_OUTPUT_PP); // NWE
41+
void fsmc_init(void) {
42+
rcc_clk_enable(RCC_FSMC);
43+
rcc_reset_dev(RCC_FSMC);
44+
}
8445

85-
gpio_set_mode(PD7, GPIO_AF_OUTPUT_PP); // NE1
86-
#if 0 // not available on LQFP package
87-
gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2
88-
gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3
89-
gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4
90-
#endif // not available on LQFP package
46+
// used control, address and data lines
47+
// NOE -> RD, NWE -> WR, A18 -> RS, NE1 -> CS
48+
const uint8_t fsmc_pins[]= {FSMC_NOE, FSMC_NWE, FSMC_NE1, FSMC_A18,
49+
FSMC_D0, FSMC_D1, FSMC_D2, FSMC_D3,
50+
FSMC_D4, FSMC_D5, FSMC_D6, FSMC_D7,
51+
FSMC_D8, FSMC_D9, FSMC_D10, FSMC_D11,
52+
FSMC_D12, FSMC_D13, FSMC_D14, FSMC_D15};
9153

92-
gpio_set_mode(PE0, GPIO_AF_OUTPUT_PP); // NBL0
93-
gpio_set_mode(PE1, GPIO_AF_OUTPUT_PP); // NBL1
54+
void fsmc_lcd_init_gpios(void) {
55+
uint8_t i;
56+
for (i=0; i<sizeof(fsmc_pins); i++) {
57+
uint8_t pin = fsmc_pins[i];
58+
gpio_set_mode(pin, GPIO_AF_OUTPUT_PP);
59+
gpio_set_af_mode(pin, 12);
60+
}
9461
}
9562

63+
volatile uint16_t * fsmcCommand;
64+
volatile uint16_t * fsmcData;
65+
66+
void fsmc_lcd_init(void)
67+
{
68+
fsmcCommand = FSMC_BANK1; // clears A18
69+
fsmcData = (fsmcCommand+(1<<18)); // sets A18
70+
71+
fsmc_init();
72+
fsmc_lcd_init_gpios();
73+
// set access for asynchronous SRAM type, 16 bit wide data bus
74+
// see RM0090, 36.5.4, pages 1552-1554
75+
uint32_t val = (FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_WREN);
76+
//Serial.print("BCR: "); Serial.println(val, HEX);
77+
fsmc_nor_psram_set_BCR(FSMC_NOR_PSRAM1_BASE, val);
78+
// set timing data Mode 1. Adjust DATAST according to the WR low period timing from the LCD specification
79+
val = (FSMC_BTR_ACCMOD_A | FSMC_BTR_DATLAT_(0) | FSMC_BTR_CLKDIV_(0) | FSMC_BTR_BUSTURN_(0) | FSMC_BTR_DATAST_(6) | FSMC_BTR_ADDHLD_(0) | FSMC_BTR_ADDSET_(2));
80+
//Serial.print("BTR: "); Serial.println(val, HEX);
81+
fsmc_nor_psram_set_BTR(FSMC_NOR_PSRAM1_BASE, val);
82+
// enable FSCM
83+
fsmc_nor_psram_bank_enable(FSMC_NOR_PSRAM1_BASE);
84+
}
85+
86+
9687
#endif /* STM32_HIGH_DENSITY */

STM32F4/cores/maple/libmaple/fsmc.h

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@
3333
* See ../notes/fsmc.txt for more info
3434
*/
3535

36-
#include "libmaple_types.h"
37-
3836
/**
3937
* @file fsmc.h
4038
*/
4139

4240
#ifndef _FSMC_H_
4341
#define _FSMC_H_
4442

43+
#include <libmaple\util.h>
44+
#include "libmaple_types.h"
45+
4546
#ifdef __cplusplus
4647
extern "C"{
4748
#endif
@@ -62,27 +63,27 @@ typedef struct fsmc_reg_map {
6263
__io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */
6364
__io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */
6465
__io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */
65-
const uint8 RESERVED1[64]; /**< Reserved */
66+
const uint32 RESERVED1[16]; /**< Reserved */
6667
__io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */
6768
__io uint32 SR2; /**< FIFO status and interrupt register 2 */
6869
__io uint32 PMEM2; /**< Common memory space timing register 2 */
6970
__io uint32 PATT2; /**< Attribute memory space timing register 2 */
70-
const uint8 RESERVED2[4]; /**< Reserved */
71+
const uint32 RESERVED2; /**< Reserved */
7172
__io uint32 ECCR2; /**< ECC result register 2 */
72-
const uint8 RESERVED3[2];
73+
const uint32 RESERVED3[2]; /**< Reserved */
7374
__io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */
7475
__io uint32 SR3; /**< FIFO status and interrupt register 3 */
7576
__io uint32 PMEM3; /**< Common memory space timing register 3 */
7677
__io uint32 PATT3; /**< Attribute memory space timing register 3 */
7778
const uint32 RESERVED4; /**< Reserved */
7879
__io uint32 ECCR3; /**< ECC result register 3 */
79-
const uint8 RESERVED5[8]; /**< Reserved */
80+
const uint32 RESERVED5[2]; /**< Reserved */
8081
__io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */
8182
__io uint32 SR4; /**< FIFO status and interrupt register 4 */
8283
__io uint32 PMEM4; /**< Common memory space timing register 4 */
8384
__io uint32 PATT4; /**< Attribute memory space timing register 4 */
8485
__io uint32 PIO4; /**< I/O space timing register 4 */
85-
const uint8 RESERVED6[80]; /**< Reserved */
86+
const uint32 RESERVED6[20]; /**< Reserved */
8687
__io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */
8788
const uint32 RESERVED7; /**< Reserved */
8889
__io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */
@@ -101,7 +102,7 @@ typedef struct fsmc_reg_map {
101102
typedef struct fsmc_nor_psram_reg_map {
102103
__io uint32 BCR; /**< Chip-select control register */
103104
__io uint32 BTR; /**< Chip-select timing register */
104-
const uint8 RESERVED[252]; /**< Reserved */
105+
const uint32 RESERVED[64]; /**< Reserved */
105106
__io uint32 BWTR; /**< Write timing register */
106107
} fsmc_nor_psram_reg_map;
107108

@@ -170,6 +171,13 @@ typedef struct fsmc_nor_psram_reg_map {
170171
#define FSMC_BTR_ADDHLD (0xF << 4)
171172
#define FSMC_BTR_ADDSET 0xF
172173

174+
#define FSMC_BTR_DATLAT_(x) ((x<<24)&FSMC_BTR_DATLAT)
175+
#define FSMC_BTR_CLKDIV_(x) ((x<<20)&FSMC_BTR_CLKDIV)
176+
#define FSMC_BTR_BUSTURN_(x) ((x<<16)&FSMC_BTR_BUSTURN)
177+
#define FSMC_BTR_DATAST_(x) ((x<<8)&FSMC_BTR_DATAST)
178+
#define FSMC_BTR_ADDHLD_(x) ((x<<4)&FSMC_BTR_ADDHLD)
179+
#define FSMC_BTR_ADDSET_(x) ((x<<0)&FSMC_BTR_ADDSET)
180+
173181
/* SRAM/NOR-Flash write timing registers */
174182

175183
#define FSMC_BWTR_ACCMOD (0x3 << 28)
@@ -280,8 +288,26 @@ typedef struct fsmc_nor_psram_reg_map {
280288
/*
281289
* SRAM/NOR Flash routines
282290
*/
291+
extern volatile uint16_t * fsmcData;
292+
extern volatile uint16_t * fsmcCommand;
293+
294+
void fsmc_lcd_init(void);
283295

284-
void fsmc_sram_init_gpios(void);
296+
static inline void fsmc_nor_psram_set_BCR(fsmc_nor_psram_reg_map *regs, uint32_t bcr) {
297+
regs->BCR = bcr;
298+
}
299+
300+
static inline void fsmc_nor_psram_set_BTR(fsmc_nor_psram_reg_map *regs, uint32_t btr) {
301+
regs->BTR = btr;
302+
}
303+
304+
static inline void fsmc_nor_psram_bank_enable(fsmc_nor_psram_reg_map *regs) {
305+
regs->BCR |= FSMC_BCR_MBKEN;
306+
}
307+
308+
static inline void fsmc_nor_psram_bank_disable(fsmc_nor_psram_reg_map *regs) {
309+
regs->BCR ^= FSMC_BCR_MBKEN;
310+
}
285311

286312
/**
287313
* Set the DATAST bits in the given NOR/PSRAM register map's

STM32F4/cores/maple/libmaple/gpio.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,22 @@ static inline void gpio_write_pin(uint8_t pin, uint16 val) {
6969
}
7070
}
7171

72-
static inline void gpio_set_pin(uint8_t pin) {
73-
(PIN_MAP[pin].gpio_device)->regs->BSRRL = BIT(pin&0x0F);
74-
}
75-
7672
static inline void gpio_set_dev_bit(const gpio_dev * dev, uint8_t bit) {
7773
dev->regs->BSRRL = BIT(bit);
7874
}
7975

80-
static inline void gpio_clear_pin(uint8_t pin) {
81-
(PIN_MAP[pin].gpio_device)->regs->BSRRH = BIT(pin&0x0F);
82-
}
83-
8476
static inline void gpio_clear_dev_bit(const gpio_dev * dev, uint8_t bit) {
8577
dev->regs->BSRRH = BIT(bit);
8678
}
8779

80+
static inline void gpio_set_pin(uint8_t pin) {
81+
gpio_set_dev_bit(PIN_MAP[pin].gpio_device, (pin&0x0F));
82+
}
83+
84+
static inline void gpio_clear_pin(uint8_t pin) {
85+
gpio_clear_dev_bit(PIN_MAP[pin].gpio_device, (pin&0x0F));
86+
}
87+
8888
/**
8989
* Determine whether or not a GPIO pin is set.
9090
*

STM32F4/cores/maple/wirish_digital.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
void pinMode(uint8 pin, WiringPinMode mode) {
3535
gpio_pin_mode outputMode;
36-
boolean pwm = false;
36+
// boolean pwm = false;
3737

3838
if (pin >= BOARD_NR_GPIO_PINS) {
3939
return;
@@ -61,11 +61,11 @@ void pinMode(uint8 pin, WiringPinMode mode) {
6161
break;
6262
case PWM:
6363
outputMode = GPIO_AF_OUTPUT_PP;
64-
pwm = true;
64+
// pwm = true;
6565
break;
6666
case PWM_OPEN_DRAIN:
6767
outputMode = GPIO_AF_OUTPUT_OD;
68-
pwm = true;
68+
// pwm = true;
6969
break;
7070
default:
7171
ASSERT(0);

STM32F4/variants/generic_f407v/generic_f407v.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,35 @@
106106
#define BOARD_SDIO_CK PC12 //Port2Pin('C',12)
107107
#define BOARD_SDIO_CMD PD2 //Port2Pin('D', 2)
108108

109+
#define FSMC_NOE PD4
110+
#define FSMC_NWE PD5
111+
#define FSMC_NE1 PD7
112+
#define FSMC_A18 PD13
113+
#define FSMC_A17 PD12
114+
#define FSMC_A16 PD11
115+
#define FSMC_D0 PD14
116+
#define FSMC_D1 PD15
117+
#define FSMC_D2 PD0
118+
#define FSMC_D3 PD1
119+
#define FSMC_D4 PE7
120+
#define FSMC_D5 PE8
121+
#define FSMC_D6 PE9
122+
#define FSMC_D7 PE10
123+
#define FSMC_D8 PE11
124+
#define FSMC_D9 PE12
125+
#define FSMC_D10 PE13
126+
#define FSMC_D11 PE14
127+
#define FSMC_D12 PE15
128+
#define FSMC_D13 PD8
129+
#define FSMC_D14 PD9
130+
#define FSMC_D15 PD10
131+
132+
#define BOARD_T_CS BOARD_SPI2_NSS_PIN
133+
#define BOARD_T_SCK BOARD_SPI2_SCK_PIN
134+
#define BOARD_T_MISO BOARD_SPI2_MISO_PIN
135+
#define BOARD_T_MOSI BOARD_SPI2_MOSI_PIN
136+
#define BOARD_T_PEN PC5
137+
109138
#define BOARD_NR_GPIO_PINS 80
110139
#define BOARD_NR_PWM_PINS 22
111140
#define BOARD_NR_ADC_PINS 16

0 commit comments

Comments
 (0)