Spark Logic

Port manipulation – LCD 8bit parallel

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:

#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; }

Replies

diger67 Wed Aug 03, 2016 9:23 pm

Hi!
I do not work in an environment with Arduino STM. But can someone come in handy. Here are a few defines. Their work is checked in Keil. Binding conclusions made to the standard location pins Shild TFT for Arduino. New definition write8inline (d) is faster than the previous version.

//Port data |D7 | D6 |D5 |D4 |D3 | D2 |D1 |D0 |
//Pin stm32 |PA8|PB10|PB4|PB5|PB3|PA10|PC7|PA9|
//control port |RST| CS | RS | WR| RD|
//Pin stm32 |PC0|PB0|PA4|PA1|PA0|

#define write8inline(d) {\
GPIOA->BSRR = (data & (1<<0)) ? GPIO_BSRR_BS9 : GPIO_BSRR_BR9;\
GPIOC->BSRR = (data & (1<<1)) ? GPIO_BSRR_BS7 : GPIO_BSRR_BR7;\
GPIOA->BSRR = (data & (1<<2)) ? GPIO_BSRR_BS10 : GPIO_BSRR_BR10;\
GPIOB->BSRR = (data & (1<<3)) ? GPIO_BSRR_BS3 : GPIO_BSRR_BR3;\
GPIOB->BSRR = (data & (1<<4)) ? GPIO_BSRR_BS5 : GPIO_BSRR_BR5;\
GPIOB->BSRR = (data & (1<<5)) ? GPIO_BSRR_BS4 : GPIO_BSRR_BR4;\
GPIOB->BSRR = (data & (1<<6)) ? GPIO_BSRR_BS10 : GPIO_BSRR_BR10;\
GPIOA->BSRR = (data & (1<<7)) ? GPIO_BSRR_BS8 : GPIO_BSRR_BR8;\
WR_STROBE;\
}

#define enportrcc() {\
RCC->APB2ENR |= ((RCC->APB2ENR &= 0xFFFFFFFF) | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN);\
AFIO->MAPR |= ((AFIO->MAPR &= 0xFFFFFFFF) | AFIO_MAPR_SWJ_CFG_JTAGDISABLE);\
GPIOA->CRL = ((GPIOA->CRL &= 0xFFF0FF00) | 0x00030033); \
GPIOC->CRL = ((GPIOC->CRL &= 0xFFFFFF0F) | 0x00000030); \
GPIOB->CRL = ((GPIOB->CRL &= 0xFFFFFFF0) | 0x00000003); \
}

#define setWriteDirInline() { \
GPIOA->CRH = ((GPIOA->CRH &= 0xFFFFF000) | 0x00000333); \
GPIOC->CRL = ((GPIOC->CRL &= 0x0FFFFFFF) | 0x30000000); \
GPIOB->CRL = ((GPIOB->CRL &= 0xFF000FFF) | 0x00333000); \
GPIOB->CRH = ((GPIOB->CRH &= 0xFFFFF0FF) | 0x00000300); \
}

#define setReadDirInline() { \
GPIOA->CRH = ((GPIOA->CRH &= 0xFFFFF000) | 0x00000444); \
GPIOC->CRL = ((GPIOC->CRL &= 0x0FFFFFFF) | 0x40000000); \
GPIOB->CRL = ((GPIOB->CRL &= 0xFF000FFF) | 0x00444000); \
GPIOB->CRH = ((GPIOB->CRH &= 0xFFFFF0FF) | 0x00000400); \
}

Rick Kimball Wed Aug 03, 2016 10:57 pm

… this line:

#define enportrcc() {\
RCC->APB2ENR |= ((RCC->APB2ENR &= 0xFFFFFFFF) | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN);\
AFIO->MAPR |= ((AFIO->MAPR &= 0xFFFFFFFF) | AFIO_MAPR_SWJ_CFG_JTAGDISABLE);\
Are you trying to clear the APB2ENR register with the &= ((RCC->APB2ENR &= 0xFFFFFFFF) ?

It is probably easier to set it to zero or use &= ((RCC->APB2ENR &= ~0xFFFFFFFF)

Or maybe I misunderstand what you are doing there.

-rick

diger67 Wed Aug 03, 2016 11:22 pm

Rick Kimball wrote:

Are you trying to clear the APB2ENR register with the &= ((RCC->APB2ENR &= 0xFFFFFFFF) ?

It is probably easier to set it to zero or use &= ((RCC->APB2ENR &= ~0xFFFFFFFF)

Or maybe I misunderstand what you are doing there.

-rick

stevestrong Fri Aug 26, 2016 11:14 pm

Well, I had to reinvent the wheel and adapt the original lib TFTLCD lib from Adafruit for STM32, because my LCD was an ILI9328, not an ILI9341, as iwalpola’s lib.
Also, I had to stick to digital write and read functions, because the pure register writes for pin toggling was too fast and the screen went blank!
Here my benchmark using Adafruit original graphic test ino:
TFT LCD test
TFT size is 240x320
Found ILI9328 LCD driver

Benchmark Time (microseconds)
Screen fill 1019555
Text 115645
Lines 719977
Horiz/Vert Lines 96056
Rectangles (outline) 69857
Rectangles (filled) 2155387
Circles (filled) 843279
Circles (outline) 313036
Triangles (outline) 228363
Triangles (filled) 993928
Rounded rects (outline) 146794
Rounded rects (filled) 2514008
Done!

stevestrong Sat Sep 03, 2016 12:50 pm

After getting the LCD reset to work correctly, this is what I achieve using the Adafruit lib ported to STM32:
TFT LCD test
TFT size is 240x320
Found ILI9328 LCD driver
Benchmark Time (microseconds)
Screen fill 65561
Text 24708
Lines 141805
Horiz/Vert Lines 8723
Rectangles (outline) 7335
Rectangles (filled) 155516
Circles (filled) 134162
Circles (outline) 60283
Triangles (outline) 45012
Triangles (filled) 115087
Rounded rects (outline) 24511
Rounded rects (filled) 206878
Done!
rotation: 0, text runtime: 24708
rotation: 1, text runtime: 24972
rotation: 2, text runtime: 24973
rotation: 3, text runtime: 24985

VadimEL Sat Sep 03, 2016 5:44 pm

C:\Documents and Settings\Vadim\Мои документы\Arduino\hardware\Arduino_STM32\STM32F1\libraries\Adafruit_TFTLCD_8bit_STM32\Adafruit_TFTLCD_8bit_STM32.h

line 84
#define read8(x) { x = read8_() ;}
===================================

stevestrong Sat Sep 03, 2016 7:03 pm

VadimEL wrote:Adafruit_TFTLCD_8bit_STM32.h
line 84
#define read8(x) { x = read8_() ;}

Itudylla Wed Feb 15, 2017 7:32 am

thanks a lot for letting us know about these manipulations, they make the workers’ lives easier!

Sign in to reply