added FSMC + SPI brought in line with F1

This commit is contained in:
stevstrong 2017-05-22 17:36:50 +02:00
parent 220247c115
commit 8574d238e8
4 changed files with 114 additions and 72 deletions

View File

@ -35,62 +35,53 @@
#ifdef STM32_HIGH_DENSITY
/**
* Configure FSMC GPIOs for use with SRAM.
*/
void fsmc_sram_init_gpios(void) {
/* Data lines... */
gpio_set_mode(PD0, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD1, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD8, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD9, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD10, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD14, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD15, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE7, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE8, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE9, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE10, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE11, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE12, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE13, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE14, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PE15, GPIO_AF_OUTPUT_PP);
* Configure FSMC GPIOs for use with LCDs.
*/
/* Address lines... */
gpio_set_mode(PD11, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD12, GPIO_AF_OUTPUT_PP);
gpio_set_mode(PD13, GPIO_AF_OUTPUT_PP);
#if 0 // not available on LQFP package
gpio_set_mode(GPIOF, 0, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 1, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 2, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 3, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 4, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 5, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 12, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 13, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 14, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOF, 15, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOG, 0, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOG, 1, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOG, 2, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOG, 3, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOG, 4, GPIO_AF_OUTPUT_PP);
gpio_set_mode(GPIOG, 5, GPIO_AF_OUTPUT_PP);
#endif // not available on LQFP package
/* And control lines... */
gpio_set_mode(PD4, GPIO_AF_OUTPUT_PP); // NOE
gpio_set_mode(PD5, GPIO_AF_OUTPUT_PP); // NWE
gpio_set_mode(PD7, GPIO_AF_OUTPUT_PP); // NE1
#if 0 // not available on LQFP package
gpio_set_mode(GPIOG, 9, GPIO_AF_OUTPUT_PP); // NE2
gpio_set_mode(GPIOG, 10, GPIO_AF_OUTPUT_PP); // NE3
gpio_set_mode(GPIOG, 12, GPIO_AF_OUTPUT_PP); // NE4
#endif // not available on LQFP package
gpio_set_mode(PE0, GPIO_AF_OUTPUT_PP); // NBL0
gpio_set_mode(PE1, GPIO_AF_OUTPUT_PP); // NBL1
void fsmc_init(void) {
rcc_clk_enable(RCC_FSMC);
rcc_reset_dev(RCC_FSMC);
}
// used control, address and data lines
// NOE -> RD, NWE -> WR, A18 -> RS, NE1 -> CS
const uint8_t fsmc_pins[]= {FSMC_NOE, FSMC_NWE, FSMC_NE1, FSMC_A18,
FSMC_D0, FSMC_D1, FSMC_D2, FSMC_D3,
FSMC_D4, FSMC_D5, FSMC_D6, FSMC_D7,
FSMC_D8, FSMC_D9, FSMC_D10, FSMC_D11,
FSMC_D12, FSMC_D13, FSMC_D14, FSMC_D15};
void fsmc_lcd_init_gpios(void) {
uint8_t i;
for (i=0; i<sizeof(fsmc_pins); i++) {
uint8_t pin = fsmc_pins[i];
gpio_set_mode(pin, GPIO_AF_OUTPUT_PP);
gpio_set_af_mode(pin, 12);
}
}
volatile uint16_t * fsmcCommand;
volatile uint16_t * fsmcData;
void fsmc_lcd_init(void)
{
fsmcCommand = FSMC_BANK1; // clears A18
fsmcData = (fsmcCommand+(1<<18)); // sets A18
fsmc_init();
fsmc_lcd_init_gpios();
// set access for asynchronous SRAM type, 16 bit wide data bus
// see RM0090, 36.5.4, pages 1552-1554
uint32_t val = (FSMC_BCR_MTYP_SRAM | FSMC_BCR_MWID_16BITS | FSMC_BCR_WREN);
//Serial.print("BCR: "); Serial.println(val, HEX);
fsmc_nor_psram_set_BCR(FSMC_NOR_PSRAM1_BASE, val);
// set timing data Mode 1. Adjust DATAST according to the WR low period timing from the LCD specification
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));
//Serial.print("BTR: "); Serial.println(val, HEX);
fsmc_nor_psram_set_BTR(FSMC_NOR_PSRAM1_BASE, val);
// enable FSCM
fsmc_nor_psram_bank_enable(FSMC_NOR_PSRAM1_BASE);
}
#endif /* STM32_HIGH_DENSITY */

View File

@ -33,8 +33,6 @@
* See ../notes/fsmc.txt for more info
*/
#include "libmaple_types.h"
/**
* @file fsmc.h
*/
@ -42,6 +40,9 @@
#ifndef _FSMC_H_
#define _FSMC_H_
#include <libmaple\util.h>
#include "libmaple_types.h"
#ifdef __cplusplus
extern "C"{
#endif
@ -62,27 +63,27 @@ typedef struct fsmc_reg_map {
__io uint32 BTR3; /**< SRAM/NOR-Flash chip-select timing register 3 */
__io uint32 BCR4; /**< SRAM/NOR-Flash chip-select control register 4 */
__io uint32 BTR4; /**< SRAM/NOR-Flash chip-select timing register 4 */
const uint8 RESERVED1[64]; /**< Reserved */
const uint32 RESERVED1[16]; /**< Reserved */
__io uint32 PCR2; /**< PC Card/NAND Flash control register 2 */
__io uint32 SR2; /**< FIFO status and interrupt register 2 */
__io uint32 PMEM2; /**< Common memory space timing register 2 */
__io uint32 PATT2; /**< Attribute memory space timing register 2 */
const uint8 RESERVED2[4]; /**< Reserved */
const uint32 RESERVED2; /**< Reserved */
__io uint32 ECCR2; /**< ECC result register 2 */
const uint8 RESERVED3[2];
const uint32 RESERVED3[2]; /**< Reserved */
__io uint32 PCR3; /**< PC Card/NAND Flash control register 3 */
__io uint32 SR3; /**< FIFO status and interrupt register 3 */
__io uint32 PMEM3; /**< Common memory space timing register 3 */
__io uint32 PATT3; /**< Attribute memory space timing register 3 */
const uint32 RESERVED4; /**< Reserved */
__io uint32 ECCR3; /**< ECC result register 3 */
const uint8 RESERVED5[8]; /**< Reserved */
const uint32 RESERVED5[2]; /**< Reserved */
__io uint32 PCR4; /**< PC Card/NAND Flash control register 4 */
__io uint32 SR4; /**< FIFO status and interrupt register 4 */
__io uint32 PMEM4; /**< Common memory space timing register 4 */
__io uint32 PATT4; /**< Attribute memory space timing register 4 */
__io uint32 PIO4; /**< I/O space timing register 4 */
const uint8 RESERVED6[80]; /**< Reserved */
const uint32 RESERVED6[20]; /**< Reserved */
__io uint32 BWTR1; /**< SRAM/NOR-Flash write timing register 1 */
const uint32 RESERVED7; /**< Reserved */
__io uint32 BWTR2; /**< SRAM/NOR-Flash write timing register 2 */
@ -101,7 +102,7 @@ typedef struct fsmc_reg_map {
typedef struct fsmc_nor_psram_reg_map {
__io uint32 BCR; /**< Chip-select control register */
__io uint32 BTR; /**< Chip-select timing register */
const uint8 RESERVED[252]; /**< Reserved */
const uint32 RESERVED[63]; /**< Reserved */
__io uint32 BWTR; /**< Write timing register */
} fsmc_nor_psram_reg_map;
@ -170,6 +171,13 @@ typedef struct fsmc_nor_psram_reg_map {
#define FSMC_BTR_ADDHLD (0xF << 4)
#define FSMC_BTR_ADDSET 0xF
#define FSMC_BTR_DATLAT_(x) ((x<<24)&FSMC_BTR_DATLAT)
#define FSMC_BTR_CLKDIV_(x) ((x<<20)&FSMC_BTR_CLKDIV)
#define FSMC_BTR_BUSTURN_(x) ((x<<16)&FSMC_BTR_BUSTURN)
#define FSMC_BTR_DATAST_(x) ((x<<8)&FSMC_BTR_DATAST)
#define FSMC_BTR_ADDHLD_(x) ((x<<4)&FSMC_BTR_ADDHLD)
#define FSMC_BTR_ADDSET_(x) ((x<<0)&FSMC_BTR_ADDSET)
/* SRAM/NOR-Flash write timing registers */
#define FSMC_BWTR_ACCMOD (0x3 << 28)
@ -280,8 +288,26 @@ typedef struct fsmc_nor_psram_reg_map {
/*
* SRAM/NOR Flash routines
*/
extern volatile uint16_t * fsmcData;
extern volatile uint16_t * fsmcCommand;
void fsmc_sram_init_gpios(void);
void fsmc_lcd_init(void);
static inline void fsmc_nor_psram_set_BCR(fsmc_nor_psram_reg_map *regs, uint32_t bcr) {
regs->BCR = bcr;
}
static inline void fsmc_nor_psram_set_BTR(fsmc_nor_psram_reg_map *regs, uint32_t btr) {
regs->BTR = btr;
}
static inline void fsmc_nor_psram_bank_enable(fsmc_nor_psram_reg_map *regs) {
regs->BCR |= FSMC_BCR_MBKEN;
}
static inline void fsmc_nor_psram_bank_disable(fsmc_nor_psram_reg_map *regs) {
regs->BCR ^= FSMC_BCR_MBKEN;
}
/**
* Set the DATAST bits in the given NOR/PSRAM register map's

View File

@ -457,19 +457,17 @@ uint8 SPIClass::dmaTransfer(void * transmitBuf, void * receiveBuf, uint16 length
spi_tx_dma_enable(_currentSetting->spi_d); // must be the last enable to avoid DMA error flag
uint32_t m = millis();
while ((b = dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set
if ( b&(DMA_ISR_TEIF|DMA_ISR_DMEIF|DMA_ISR_FEIF) ) { b = 1; break; } // break on any error flag
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
if (b & DMA_ISR_TCIF) b = 0;
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
// software disable sequence, see AN4031, chapter 4.1
spi_tx_dma_disable(_currentSetting->spi_d);
spi_rx_dma_disable(_currentSetting->spi_d);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiRxDmaStream);
dma_disable(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream);
return b;
}
@ -502,11 +500,9 @@ uint8 SPIClass::dmaSend(void * transmitBuf, uint16 length, bool minc)
spi_tx_dma_enable(_currentSetting->spi_d);
uint32_t m = millis();
while ((b = dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set
if ( b&(DMA_ISR_TEIF|DMA_ISR_DMEIF|DMA_ISR_FEIF) ) { b = 1; break; } // break on any error flag
while ((dma_get_isr_bits(_currentSetting->spiDmaDev, _currentSetting->spiTxDmaStream) & DMA_ISR_TCIF)==0 ) {// wait for completion flag to be set
if ((millis() - m) > DMA_TIMEOUT) { b = 2; break; }
}
if (b & DMA_ISR_TCIF) b = 0;
while (spi_is_tx_empty(_currentSetting->spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(_currentSetting->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."

View File

@ -87,7 +87,7 @@
#define BOARD_SPI2A_NSS_PIN PB9 //Port2Pin('B', 9)
#define BOARD_SPI2A_SCK_PIN PB10 //Port2Pin('B',10)
#define BOARD_SPI2A_MISO_PIN PC2 //Port2Pin('C', 2)
#define BOARD_SPI2A_MOSI_PIN pc3 //Port2Pin('C', 3)
#define BOARD_SPI2A_MOSI_PIN PC3 //Port2Pin('C', 3)
#define BOARD_SPI3_NSS_PIN PA15 //Port2Pin('A',15)
#define BOARD_SPI3_SCK_PIN PB3 //Port2Pin('B', 3)
@ -106,6 +106,35 @@
#define BOARD_SDIO_CK PC12 //Port2Pin('C',12)
#define BOARD_SDIO_CMD PD2 //Port2Pin('D', 2)
#define FSMC_NOE PD4
#define FSMC_NWE PD5
#define FSMC_NE1 PD7
#define FSMC_A18 PD13
#define FSMC_A17 PD12
#define FSMC_A16 PD11
#define FSMC_D0 PD14
#define FSMC_D1 PD15
#define FSMC_D2 PD0
#define FSMC_D3 PD1
#define FSMC_D4 PE7
#define FSMC_D5 PE8
#define FSMC_D6 PE9
#define FSMC_D7 PE10
#define FSMC_D8 PE11
#define FSMC_D9 PE12
#define FSMC_D10 PE13
#define FSMC_D11 PE14
#define FSMC_D12 PE15
#define FSMC_D13 PD8
#define FSMC_D14 PD9
#define FSMC_D15 PD10
#define BOARD_T_CS BOARD_SPI2_NSS_PIN
#define BOARD_T_SCK BOARD_SPI2_SCK_PIN
#define BOARD_T_MISO BOARD_SPI2_MISO_PIN
#define BOARD_T_MOSI BOARD_SPI2_MOSI_PIN
#define BOARD_T_PEN PC5
#define BOARD_NR_GPIO_PINS 80
#define BOARD_NR_PWM_PINS 22
#define BOARD_NR_ADC_PINS 16