Port manipulation - LCD 8bit parallel

Working libraries, libraries being ported and related hardware
Post Reply
wizarcl
Posts: 12
Joined: Tue Aug 04, 2015 4:06 pm

Port manipulation - LCD 8bit parallel

Post by wizarcl » Thu Aug 06, 2015 11:51 pm

Hi everyone.
I'm trying to port Adafruit_TFTLCD library (for 8bit parallel LCD) and inside in library, control lines is controlled by macros, using port manipulation, but STM32 has a different method to make this. Using AVR, library make control using DDRA and PORTA, for example, to control port direction and values. How can I make this manipulations? Using GPIOA_BASE.CRL, GPIOA_BASE.CRH, GPIOA_BASE.IDR and GPIOA_BASE.ODR?

Follow a piece of code in pin_magic.h:

Code: Select all

	#define write8inline(d) {                          \
	PORTD = (PORTD & B00000011) | ((d) & B11111100); \
	PORTB = (PORTB & B11111100) | ((d) & B00000011); \
	WR_STROBE; }
	#define read8inline(result) {                       \
	RD_ACTIVE;                                        \
	DELAY7;                                           \
	result = (PIND & B11111100) | (PINB & B00000011); \
	RD_IDLE; }
	#define setWriteDirInline() { DDRD |=  B11111100; DDRB |=  B00000011; }
	#define setReadDirInline()  { DDRD &= ~B11111100; DDRB &= ~B00000011; }
I need change this part to work with STM32.

User avatar
RogerClark
Posts: 5923
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Port manipulation - LCD 8bit parallel

Post by RogerClark » Fri Aug 07, 2015 12:49 am

The hardware is not that hard to control

Each port has multiple registers, but I think the ones you are interested in is the Output Data Register (ODR) (Not there are also a separate high speed register to Set bits, Reset bits)

If you look in system/libmaple/include/libmaple/gpio.h there is a function to toggle a single bit

static inline void gpio_toggle_bit(gpio_dev *dev, uint8 pin) {
dev->regs->ODR = dev->regs->ODR ^ (1U << pin);
}


So if you do

dev->regs->ODR = 0x1234

it will set whichever port to 0x1234

Note the ports are 16 bits wide, so you will need to read / mask / write to just update just 8 bits, so thinking about it, it may actually be quicker to write to the BSSR register, e.g. something like

dev->regs->BSRR = (youNum & 0x0F) | ~(yourNum & 0x0F)<<16;

You'd need to double check this code, but I think you'll probably get the idea.

The device "dev->" have defines in the code already

GPIOA, GPIOB, GPIOC etc etc


Anyway, that should give you a head start ..

wizarcl
Posts: 12
Joined: Tue Aug 04, 2015 4:06 pm

Re: Port manipulation - LCD 8bit parallel

Post by wizarcl » Fri Aug 07, 2015 3:57 pm

RogerClark wrote:
Anyway, that should give you a head start ..
Yes. You give a direction. I was looking this files in core files and I need change port directions also but, thank you so much. I'll try to port this library, test and post here.

Sorry for my bad english.

zmemw16
Posts: 1156
Joined: Wed Jul 08, 2015 2:09 pm
Location: St Annes, Lancs,UK

Re: Port manipulation - LCD 8bit parallel

Post by zmemw16 » Fri Aug 07, 2015 8:02 pm

RogerClark wrote: Note the ports are 16 bits wide, so you will need to read / mask / write to just update just 8 bits, so thinking about it, it may actually be quicker to write to the BSSR register, e.g. something like

dev->regs->BSRR = (youNum & 0x0F) | ~(yourNum & 0x0F)<<16;
my braincell is overloaded and it's been a long night/day, but where do the 0x0f masks and the << 16 come from?
0xff's and << 8 are what i'd expect?

stephen

User avatar
mrburnette
Posts: 1783
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Port manipulation - LCD 8bit parallel

Post by mrburnette » Fri Aug 07, 2015 8:21 pm

zmemw16 wrote: <...>
my braincell is overloaded and it's been a long night/day, but where do the 0x0f masks and the << 16 come from?
0xff's and << 8 are what i'd expect?

stephen
32-bit word, upper 16 bits and lower 16-bits

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: Port manipulation - LCD 8bit parallel

Post by madias » Fri Aug 07, 2015 8:25 pm

Wizarcl please refer to my st7781 TFT library. Use the search function in this forum for my Google Drive url. I've done this for a similar maybe the same library you need

wizarcl
Posts: 12
Joined: Tue Aug 04, 2015 4:06 pm

Re: Port manipulation - LCD 8bit parallel

Post by wizarcl » Sun Aug 23, 2015 3:35 pm

Hi friends... I tried to port Adafruit TFT LCD library to work with STM32 but I can't control LCD. This library control 8 bit parallel LCD's. I'm including codes for you appreciate. Changes:
In pin_magic.h:

Code: Select all

#elif defined(__STM32F1__)
	
	// Data pins is PA4 PA5 PA6 PA7 - PB12 PB13 PB14 PB15
	#define write8inline(d) { \
		GPIOA->regs->ODR = ((GPIOA->regs->ODR & 0xFF0F) | ((d << 4) & 0x00F0)); \
		GPIOB->regs->ODR = ((GPIOB->regs->ODR & 0x0FFF) | ((d << 8) & 0xF000)); \
		WR_STROBE; }

	#define read8inline(result) { \
		RD_ACTIVE;   \
		delayMicroseconds(1);      \
		result = (((GPIOA->regs->IDR & 0x00F0) >> 4) | ((GPIOB->regs->IDR & 0xF000) >> 8)); \
		RD_IDLE;}

	#define setWriteDirInline() { \
        GPIOA->regs->CRL = ((GPIOA->regs->CRL &= 0xFFFF) | 0x33330000);	\
        GPIOB->regs->CRH = ((GPIOB->regs->CRH &= 0xFFFF) | 0x33330000);	\
		}
	
	#define setReadDirInline() { \
        GPIOA->regs->CRL = ((GPIOA->regs->CRL &= 0xFFFF) | 0x44440000);	\
        GPIOB->regs->CRH = ((GPIOB->regs->CRH &= 0xFFFF) | 0x44440000);	\
		}
		
	// When using the TFT breakout board, control pins are configurable.
	#define RD_ACTIVE	rdPort->regs->BRR  |= rdPinSet		//PIO_Clear(rdPort, rdPinSet)
	#define RD_IDLE		rdPort->regs->BSRR |= rdPinSet		//PIO_Set(rdPort, rdPinSet)	
	#define WR_ACTIVE	wrPort->regs->BRR  |= wrPinSet		//PIO_Clear(wrPort, wrPinSet)
	#define WR_IDLE		wrPort->regs->BSRR |= wrPinSet		//PIO_Set(wrPort, wrPinSet)
	#define CD_COMMAND	cdPort->regs->BRR  |= cdPinSet		//PIO_Clear(cdPort, cdPinSet)
	#define CD_DATA		cdPort->regs->BSRR |= cdPinSet		//PIO_Set(cdPort, cdPinSet)
	#define CS_ACTIVE	csPort->regs->BRR  |= csPinSet		//PIO_Clear(csPort, csPinSet)
	#define CS_IDLE		csPort->regs->BSRR |= csPinSet		//PIO_Set(csPort, csPinSet)

	
	// As part of the inline control, macros reference other macros...if any
	// of these are left undefined, an equivalent function version (non-inline)
	// is declared later.  The Uno has a moderate amount of program space, so
	// only write8() is inlined -- that one provides the most performance
	// benefit, but unfortunately also generates the most bloat.  This is
	// why only certain cases are inlined for each board.
	#define write8 write8inline
	
	
#else
In Adafruit-TFTLCD.h

Code: Select all

  #if defined(__STM32F1__)
    gpio_dev		 *csPort    , *cdPort    , *wrPort    , *rdPort;
	uint32_t          csPinSet  ,  cdPinSet  ,  wrPinSet  ,  rdPinSet  ,
					  csPinUnset,  cdPinUnset,  wrPinUnset,  rdPinUnset,
					  _reset;
  #endif 
In Adafruit-TFTLCD.cpp

Code: Select all

#if defined(__STM32F1__)
	#include <wirish_types.h>
	#define PROGMEM __FLASH__
    #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
    #define pgm_read_word(addr) (*(const unsigned short *)(addr))	
#endif

Code: Select all

		#if defined(__STM32F1__)
			csPort     = digitalPinToPort(cs);
			cdPort     = digitalPinToPort(cd);
			wrPort     = digitalPinToPort(wr);
			rdPort     = digitalPinToPort(rd);
			csPort->regs->ODR  |=  csPinSet; // Set all control bits to HIGH (idle)
			cdPort->regs->ODR  |=  cdPinSet; // Signals are ACTIVE LOW
			wrPort->regs->ODR  |=  wrPinSet;
			rdPort->regs->ODR  |=  rdPinSet;			
		#endif	
		
Sketch:

Code: Select all

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library

#define LCD_CS PA0			// Chip Select
#define LCD_CD PA1			// Command/Data
#define LCD_WR PA2 			// LCD Write
#define LCD_RD PA3 			// LCD Read 
#define LCD_RESET PC15 	        	// Reset

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

void setup(void) {
  Serial.begin(9600);
  Serial.println("TFT LCD test");
//  pinMode(PC13, OUTPUT); // I don't know why, but when I set PC13 to OUTPUT, LED is turned on (ok),  but micro-controller stop running. 
  digitalWrite(PC13, HIGH);
  delay(1000);
  digitalWrite(PC13, LOW);
  delay(1000);
  digitalWrite(PC13, HIGH);
  delay(1000);  
  
#ifdef USE_ADAFRUIT_SHIELD_PINOUT
  Serial.println("Using Adafruit 2.8\" TFT Arduino Shield Pinout");
#else
  Serial.println("Using Adafruit 2.8\" TFT Breakout Board Pinout");
#endif
  digitalWrite(PC13, LOW);
  delay(1000);
  Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

  tft.reset();
  digitalWrite(PC13, HIGH);
  delay(1000);
  
  digitalWrite(PC13, LOW);
  delay(1000);

  //tft.begin(identifier);
  tft.begin();

  Serial.println("Benchmark                Time (microseconds)");

  Serial.print("Screen fill              ");
  Serial.println(testFillScreen());
  delay(500);
}

void loop(void) {
  digitalWrite(PC13, HIGH);
  for(uint8_t rotation=0; rotation<4; rotation++) {
    tft.setRotation(rotation);
    testFillScreen();
    delay(2000);
  }
  digitalWrite(PC13, LOW);
  delay(1000);
}

unsigned long testFillScreen() {
  unsigned long start = micros();
  tft.fillScreen(BLACK);
  tft.fillScreen(RED);
  tft.fillScreen(GREEN);
  tft.fillScreen(BLUE);
  tft.fillScreen(BLACK);
  return micros() - start;
}
I don't know why, but when I set PC13 to OUTPUT, LED is turned on (ok), but micro-controller stop running.


Can anyone help me?
Attachments
Adafruit-TFTLCD-Modified.rar
(135.6 KiB) Downloaded 150 times
Adafruit-TFTLCD-Original.rar
(138.45 KiB) Downloaded 85 times

madias
Posts: 813
Joined: Mon Apr 27, 2015 11:26 am
Location: Vienna, Austria

Re: Port manipulation - LCD 8bit parallel

Post by madias » Sun Aug 23, 2015 7:53 pm

...and what is connected to PC13?
If it's the backlight than connect it to VCC, the STM32 cannot give enough power for driving the backlight for the LCD via a single pin without additional hardware.

wizarcl
Posts: 12
Joined: Tue Aug 04, 2015 4:06 pm

Re: Port manipulation - LCD 8bit parallel

Post by wizarcl » Sun Aug 23, 2015 9:36 pm

madias wrote:...and what is connected to PC13?
If it's the backlight than connect it to VCC, the STM32 cannot give enough power for driving the backlight for the LCD via a single pin without additional hardware.
PC13 is conected in LED on STM board, just to test. LCD power supply is provide USB 5V power, like STM.

User avatar
RogerClark
Posts: 5923
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Port manipulation - LCD 8bit parallel

Post by RogerClark » Mon Aug 24, 2015 3:45 am

Do you mean you are powering the whole LCD from 5V, e.g. including the chips etc

This is likely to cause problems, because the STM32 is a 3.3V device not 5V device.

I recommend you power the LCD from 3.3V

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest