Hardware SPI used for the Taranis+ LCD. Thanks Mike!

This commit is contained in:
bsongis
2014-07-05 19:03:11 +02:00
parent 8200164797
commit 9337080307
7 changed files with 183 additions and 80 deletions
+1 -1
View File
@@ -676,7 +676,7 @@ ifeq ($(PCB), TARANIS)
EXTRAINCDIRS += targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Core/inc
EXTRAINCDIRS += targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/hid/inc
BOARDSRC = targets/taranis/board_taranis.cpp
EXTRABOARDSRC += targets/taranis/lcd_driver.cpp targets/taranis/flash_driver.cpp targets/taranis/aspi.c targets/taranis/i2c.c targets/taranis/delays.c
EXTRABOARDSRC += targets/taranis/configure_pins.cpp targets/taranis/lcd_driver.cpp targets/taranis/flash_driver.cpp targets/taranis/aspi.c targets/taranis/i2c.c targets/taranis/delays.c
SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c
SRC += targets/taranis/pwr_driver.c targets/taranis/usb_driver.c
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp eeprom_conversions.cpp
+2 -1
View File
@@ -163,10 +163,11 @@ SRC = ../targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/
../targets/taranis/pwr_driver.c
CPPSRC = ../targets/taranis/lcd_driver.cpp \
../targets/taranis/configure_pins.cpp \
../targets/taranis/keys_driver.cpp \
../targets/taranis/flash_driver.cpp \
../targets/taranis/diskio.cpp \
../targets/taranis/usbd_usr.cpp \
../targets/taranis/usbd_usr.cpp \
../targets/taranis/usbd_storage_msd.cpp \
../lcd_common.cpp \
../lcd_taranis.cpp \
+18 -1
View File
@@ -31,7 +31,23 @@
return readValue;
}*/
//Anolog spi
#if defined(REVPLUS)
void AspiCmd(uint8_t Command_Byte)
{
LCD_A0_LOW() ;
LCD_NCS_LOW() ;
while ( ( SPI3->SR & SPI_SR_TXE ) == 0 ) {
// wait
}
(void)SPI3->DR ; // Clear receive
SPI3->DR = Command_Byte ;
while ( ( SPI3->SR & SPI_SR_RXNE ) == 0 ) {
// wait
}
LCD_NCS_HIGH() ;
}
#else
// Analog SPI
void AspiCmd(u8 Command_Byte)
{
int i=8;
@@ -58,6 +74,7 @@ void AspiCmd(u8 Command_Byte)
LCD_NCS_HIGH();
LCD_A0_HIGH();
}
#endif
/**
@@ -44,52 +44,6 @@ extern "C" {
volatile uint32_t Tenms ; // TODO to remove everywhere / use a #define
#if !defined(SIMU)
void configure_pins( uint32_t pins, uint16_t config )
{
uint32_t address ;
GPIO_TypeDef *pgpio ;
uint32_t thispin ;
uint32_t pos ;
address = ( config & PIN_PORT_MASK ) >> 8 ;
address *= (GPIOB_BASE-GPIOA_BASE) ;
address += GPIOA_BASE ;
pgpio = (GPIO_TypeDef* ) address ;
/* -------------------------Configure the port pins---------------- */
/*-- GPIO Mode Configuration --*/
for (thispin = 0x0001, pos = 0; thispin < 0x10000; thispin <<= 1, pos +=1 )
{
if ( pins & thispin)
{
pgpio->MODER &= ~(GPIO_MODER_MODER0 << (pos * 2)) ;
pgpio->MODER |= (config & PIN_MODE_MASK) << (pos * 2) ;
if ( ( (config & PIN_MODE_MASK ) == PIN_OUTPUT) || ( (config & PIN_MODE_MASK) == PIN_PERIPHERAL) )
{
/* Speed mode configuration */
pgpio->OSPEEDR &= ~GPIO_OSPEEDER_OSPEEDR0 << (pos * 2) ;
pgpio->OSPEEDR |= ((config & PIN_SPEED_MASK) >> 13 ) << (pos * 2) ;
/* Output mode configuration*/
pgpio->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pos)) ;
if ( config & PIN_ODRAIN )
{
pgpio->OTYPER |= (GPIO_OTYPER_OT_0) << pos ;
}
}
/* Pull-up Pull down resistor configuration*/
pgpio->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pos * 2));
pgpio->PUPDR |= ((config & PIN_PULL_MASK) >> 2) << (pos * 2) ;
pgpio->AFR[pos >> 3] &= ~(0x000F << ((pos & 7)*4)) ;
pgpio->AFR[pos >> 3] |= ((config & PIN_PERI_MASK) >> 4) << ((pos & 7)*4) ;
}
}
}
#endif
void watchdogInit(unsigned int duration)
{
IWDG->KR = 0x5555 ; // Unlock registers
+87
View File
@@ -0,0 +1,87 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "../../opentx.h"
extern "C" {
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_dcd_int.h"
#include "STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc/usb_bsp.h"
#include "STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc/stm32f2xx_dbgmcu.h"
}
void configure_pins( uint32_t pins, uint16_t config )
{
uint32_t address ;
GPIO_TypeDef *pgpio ;
uint32_t thispin ;
uint32_t pos ;
address = ( config & PIN_PORT_MASK ) >> 8 ;
address *= (GPIOB_BASE-GPIOA_BASE) ;
address += GPIOA_BASE ;
pgpio = (GPIO_TypeDef* ) address ;
/* -------------------------Configure the port pins---------------- */
/*-- GPIO Mode Configuration --*/
for (thispin = 0x0001, pos = 0; thispin < 0x10000; thispin <<= 1, pos +=1 )
{
if ( pins & thispin)
{
pgpio->MODER &= ~(GPIO_MODER_MODER0 << (pos * 2)) ;
pgpio->MODER |= (config & PIN_MODE_MASK) << (pos * 2) ;
if ( ( (config & PIN_MODE_MASK ) == PIN_OUTPUT) || ( (config & PIN_MODE_MASK) == PIN_PERIPHERAL) )
{
/* Speed mode configuration */
pgpio->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pos * 2)) ;
pgpio->OSPEEDR |= ((config & PIN_SPEED_MASK) >> 13 ) << (pos * 2) ;
/* Output mode configuration*/
pgpio->OTYPER &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pos)) ;
if ( config & PIN_ODRAIN )
{
pgpio->OTYPER |= (GPIO_OTYPER_OT_0) << pos ;
}
}
/* Pull-up Pull down resistor configuration*/
pgpio->PUPDR &= ~(GPIO_PUPDR_PUPDR0 << ((uint16_t)pos * 2));
pgpio->PUPDR |= ((config & PIN_PULL_MASK) >> 2) << (pos * 2) ;
pgpio->AFR[pos >> 3] &= ~(0x000F << ((pos & 7)*4)) ;
pgpio->AFR[pos >> 3] |= ((config & PIN_PERI_MASK) >> 4) << ((pos & 7)*4) ;
}
}
}
+9 -4
View File
@@ -184,16 +184,19 @@
#define GPIOTRNDET GPIOA
#define PIN_TRNDET GPIO_Pin_8
// TODO merge these constants
#define PIN_PORTA 0x0000
#define PIN_PORTB 0x0100
#define PIN_PORTC 0x0200
#define PIN_PORTD 0x0300
#define PIN_PER_1 0x0010
#define PIN_PER_2 0x0020
#define PIN_PORTA 0x0000
#define PIN_PER_3 0x0030
#define PIN_PER_5 0x0050
#define PIN_PER_6 0x0060
// #define PIN_OS2 0x0000
#define PIN_OS25 0x2000
// #define PIN_OS50 0x4000
// #define PIN_OS100 0x6000
#define PIN_OS50 0x4000
#define PIN_OS100 0x6000
// Cppm
#define RCC_AHB1Periph_GPIO_INTPPM RCC_AHB1Periph_GPIOA
@@ -258,6 +261,8 @@
// LCD
#if defined(REVPLUS)
#define RCC_AHB1Periph_LCD (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD)
#define RCC_AHB1Periph_LCD_RST RCC_AHB1Periph_GPIOD
#define RCC_AHB1Periph_LCD_NCS RCC_AHB1Periph_GPIOA
#define GPIO_LCD_SPI GPIOC
#define GPIO_LCD_NCS GPIOA
#define GPIO_LCD_RST GPIOD
+66 -27
View File
@@ -32,6 +32,46 @@ void Delay(volatile unsigned int ms)
}
#if defined(REVPLUS)
static void LCD_Hardware_Init() ;
// New hardware SPI driver for LCD
void initLcdSpi()
{
// uint16_t temp ;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_LCD, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_LCD_RST, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_LCD_NCS, ENABLE);
RCC->APB1ENR |= RCC_APB1ENR_SPI3EN ; // Enable clock
// APB1 clock / 2 = 133nS per clock
SPI3->CR1 = 0 ; // Clear any mode error
SPI3->CR1 = SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_CPOL | SPI_CR1_CPHA ;
SPI3->CR2 = 0 ;
SPI3->CR1 |= SPI_CR1_MSTR ; // Make sure in case SSM/SSI needed to be set first
SPI3->CR1 |= SPI_CR1_SPE ;
configure_pins( PIN_LCD_NCS, PIN_OUTPUT | PIN_PORTA | PIN_PUSHPULL | PIN_OS25 | PIN_NO_PULLUP ) ;
configure_pins( PIN_LCD_RST, PIN_OUTPUT | PIN_PORTD | PIN_PUSHPULL | PIN_OS25 | PIN_NO_PULLUP ) ;
configure_pins( PIN_LCD_A0, PIN_OUTPUT | PIN_PORTC | PIN_PUSHPULL | PIN_OS50 | PIN_NO_PULLUP ) ;
configure_pins( PIN_LCD_MOSI|PIN_LCD_CLK, PIN_PORTC | PIN_PUSHPULL | PIN_OS50 | PIN_NO_PULLUP | PIN_PER_6 | PIN_PERIPHERAL ) ;
}
void setupSPIdma()
{
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock
// Chan 0, 8-bit wide, Medium priority, memory increments
DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA
DMA1->HIFCR = DMA_HIFCR_CTCIF7 | DMA_HIFCR_CHTIF7 | DMA_HIFCR_CTEIF7 | DMA_HIFCR_CDMEIF7 | DMA_HIFCR_CFEIF7 ; // Write ones to clear bits
DMA1_Stream7->CR = DMA_SxCR_PL_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 ;
DMA1_Stream7->PAR = (uint32_t) &SPI3->DR ;
DMA1_Stream7->M0AR = (uint32_t)displayBuf;
DMA1_Stream7->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ;
DMA1_Stream7->NDTR = LCD_W*LCD_H/8*4 ;
// NVIC_SetPriority( DMA1_Stream7_IRQn, 2 ) ; // Lower priority interrupt
// NVIC_EnableIRQ(DMA1_Stream7_IRQn) ;
}
static void LCD_Init()
{
WriteCommand(0x2F); //Internal pump control
@@ -122,34 +162,32 @@ void Set_Address(u8 x, u8 y)
#if defined(REVPLUS)
void lcdRefresh()
{
for (uint32_t y=0; y<LCD_H; y+=2) {
uint8_t *p = &displayBuf[y/2 * LCD_W];
{
Set_Address(0, 0);
LCD_NCS_LOW();
LCD_A0_HIGH();
Set_Address(0, y/2);
AspiCmd(0xAF);
setupSPIdma() ;
DMA1_Stream7->CR |= DMA_SxCR_EN ; // Enable DMA
SPI3->CR2 |= SPI_CR2_TXDMAEN ;
LCD_CLK_HIGH();
LCD_A0_HIGH();
LCD_NCS_LOW();
for (uint32_t x=0; x<LCD_W; x++) {
uint8_t a = p[x] ;
LCD_WRITE_BIT(a & 0x80);
LCD_WRITE_BIT(a & 0x40);
LCD_WRITE_BIT(a & 0x20);
LCD_WRITE_BIT(a & 0x10);
LCD_WRITE_BIT(a & 0x08);
LCD_WRITE_BIT(a & 0x04);
LCD_WRITE_BIT(a & 0x02);
LCD_WRITE_BIT(a & 0x01);
}
LCD_NCS_HIGH();
LCD_A0_HIGH();
WriteData(0);
while ( ( DMA1->HISR & DMA_HISR_TCIF7 ) == 0 ) {
// wait
}
SPI3->CR2 &= ~SPI_CR2_TXDMAEN ;
DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA
while ( ( SPI3->SR & SPI_SR_TXE ) == 0 ) {
// wait
} // Last byte being sent
while ( SPI3->SR & SPI_SR_BSY ) {
// wait
}
LCD_NCS_HIGH();
}
#else
void lcdRefresh()
@@ -270,6 +308,9 @@ void lcdInit()
{
LCD_BL_Config();
LCD_Hardware_Init();
#if defined(REVPLUS)
initLcdSpi() ;
#endif
LCD_RST_HIGH();
Delay(5);
@@ -285,8 +326,6 @@ void lcdInit()
LCD_Init();
Delay(120);
LCD_Init();
Delay(120);
AspiCmd(0xAF); //dc2=1, IC into exit SLEEP MODE, dc3=1 gray=ON, dc4=1 Green Enhanc mode disabled
}