[SOLVED] bluepill mcufriend special

altEnergy
Sat Oct 06, 2018 6:24 pm
Further to my introductory post, I am still having issues I ran lcd_id_readreg on my new wiring using the following defines

#define LCD_RST PA4
#define LCD_CS PA3
#define LCD_RS PA2
#define LCD_WR PA1
#define LCD_RD PA0

#define LCD_D0 PB10
#define LCD_D1 PB11
#define LCD_D2 PB12
#define LCD_D3 PB13
#define LCD_D4 PB14
#define LCD_D5 PB15
#define LCD_D6 PA8
#define LCD_D7 PA9


david.prentice
Sat Oct 06, 2018 7:22 pm
Ah-ha. I have a confession. I do not seem to have a readreg report for a 0x9302. It looks as if I have simply invented this line from the how_to file:
ILI9302 240x320 ID=0x9302

altEnergy
Sat Oct 06, 2018 7:26 pm
I didn’t realize i should put the defines and output in code aswell i see someone has been kind enough to correct this I will know next time. when compiling the graphic test sketch i copied and pasted all the compile info into gedit and noticed there was no mention of special or shield in search does this mean it has somehow not included them?

altEnergy
Sat Oct 06, 2018 7:30 pm
it said on the packet of the 3.5 screen it was ili9486 library if that help but the 2.4 worked on exactly the same bluepill without code change just using your mcufriend_shield.h

altEnergy
Sat Oct 06, 2018 7:34 pm
I promise to give any info you need no matter what if i miss something on the forum you are welcome to email me and I will give you any info I can.
I am currently trying to compile the sketch from within the mcufriend folder as i had saved it outside that may be an issue
Andy
and Many thanks David

altEnergy
Sat Oct 06, 2018 8:32 pm
I found this https://docs.google.com/spreadsheets/d/ … 1863870689which has links to a number of screen data sheets but not the 9302 unfortunately . I am confused with what you said about being interested to see readreg report and if graphicstest_kbv works as I thought that what i posted was the readreg reports and as I say the same screen is displaying fine with your wiring on the graphicstest_kbv. I have just tried all the things I thought could be causing my wiring not to work but to no avail. When i run grapficstest_kbv with the maple wiring I get the green rounded squares, the cyan triangle, the colour bars rotating 90deg for each colour – green -red- blue -grey , the yellow writing scroll. but just a grey screen fading and flashing bright and darker on my wiring.

altEnergy
Sat Oct 06, 2018 9:01 pm
Ok I either missed the bit in your post about the defines or you updated it and i never noticed. Anyway I have checked the wiring again and
A0 goes to LCD_RD
A1 goes to LCD_WR
A2 goes to LCD_RS
A3 goes to LCD_CS
A4 goes to LCD_RST

B10 goes to LCD_D0
B11 goes to LCD_D1
B12 goes to LCD_D2
B13 goes to LCD_D3
B14 goes to LCD_D4
B15 goes to LCD_D5
A8 goes to LCD_D6
A9 goes to LCD_D7
i have checked continuity again
could the port pins somehow be set to the wrong type or timing?


david.prentice
Sat Oct 06, 2018 9:54 pm
[altEnergy – Sat Oct 06, 2018 7:26 pm] –
I didn’t realize i should put the defines and output in code aswell i see someone has been kind enough to correct this I will know next time. when compiling the graphic test sketch i copied and pasted all the compile info into gedit and noticed there was no mention of special or shield in search does this mean it has somehow not included them?

You plug a Uno shield into Uno, Leo, Mega, Zero, Due, Nucleo, … Examples should build and run straight out of the box.
The same applies for BluePill, Teensy3.x, … if you use the “standard” wiring.
LCD_ID_readreg runs out of the box because the existing defines match the Shield wiring.

If you want to use a custom wiring scheme, you have to create a SPECIAL to match your wiring. This is hard-coded in mcufriend_special.h and you enable USE_xxx defines to configure how the library is built. This hard-coding is fiddly.
Sketches that use the library never alter. They simply link with the cofigured library.

LCD_ID_readreg is different. It uses no library. It is configured by defines for digitalWrite() etc.
You can edit the defines to match your custom wiring. And verify by comparing with the proper Uno+Shield report.
It is easy for anyone to edit a sketch. Hard-coding a SPECIAL is difficult. Hence I will do the hard-coding for you.

Life is much simpler if you just stick with the standard Shield wiring. It works.

[altEnergy – Sat Oct 06, 2018 7:34 pm] –
I promise to give any info you need no matter what if i miss something on the forum you are welcome to email me and I will give you any info I can.
I am currently trying to compile the sketch from within the mcufriend folder as i had saved it outside that may be an issue

The Library Manager puts libraries in User/libraries folder. The IDE will not let you save changes to examples. But you can save any changed example in your User/sketches folder.

[altEnergy – Sat Oct 06, 2018 8:32 pm] –
I am confused with what you said about being interested to see readreg report and if graphicstest_kbv works as I thought that what i posted was the readreg reports and as I say the same screen is displaying fine with your wiring on the graphicstest_kbv. I have just tried all the things I thought could be causing my wiring not to work but to no avail. When i run grapficstest_kbv with the maple wiring I get the green rounded squares, the cyan triangle, the colour bars rotating 90deg for each colour – green -red- blue -grey , the yellow writing scroll. but just a grey screen fading and flashing bright and darker on my wiring.

Just confirm that your bluepill wiring from mcufriend_shield.h in 6:24 pm BST post gives the SAME readreg result on a Uno/Mega.

And confirm that all the parts of graphictest_kbv work 100% with your 0x9302 controller.

I Googled 0x9302 and found posts written by me that say “I don’t know the maker”. But if it works on Uno, BluePill, … it should work on custom boards too. (when you get the wiring correct)

David.


altEnergy
Sat Oct 06, 2018 10:22 pm
I Have put the readreg sketch on a mega that had the graphictest_kbv sketch on it working with screen plugged in
the response was slightly different but same 9302 in places
Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 93 02 Manufacturer ID
reg(0x0009) 00 00 61 00 00 Status Register
reg(0x000A) 08 08 Get Power Mode
reg(0x000C) 66 66 Get Pixel Format
reg(0x0061) 00 00 RDID1 HX8347-G
reg(0x0062) 00 00 RDID2 HX8347-G
reg(0x0063) 00 00 RDID3 HX8347-G
reg(0x0064) 00 00 RDID1 HX8347-A
reg(0x0065) 00 00 RDID2 HX8347-A
reg(0x0066) 00 00 RDID3 HX8347-A
reg(0x0067) 00 00 RDID Himax HX8347-A
reg(0x0070) 00 00 Panel Himax HX8347-A
reg(0x00A1) 00 FF 00 FF 00 RD_DDB SSD1963
reg(0x00B0) 00 00 RGB Interface Signal Control
reg(0x00B4) 00 00 Inversion Control
reg(0x00B6) 00 00 00 00 00 Display Control
reg(0x00B7) 00 00 Entry Mode Set
reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
reg(0x00C0) 00 00 00 00 00 00 00 00 00 Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
reg(0x00CC) 00 00 Panel Control
reg(0x00D0) 40 40 01 Power Control
reg(0x00D2) 40 40 01 40 40 NVM Read
reg(0x00D3) 00 00 93 02 ILI9341, ILI9488
reg(0x00D4) 41 41 01 41 Novatek ID
reg(0x00DA) 00 00 RDID1
reg(0x00DB) 93 93 RDID2
reg(0x00DC) 02 02 RDID3
reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P
reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-N
reg(0x00EF) 00 00 00 00 00 00 ILI9327
reg(0x00F2) 00 00 00 00 00 00 00 00 00 00 00 00 Adjust Control 2
reg(0x00F6) 00 00 00 00 Interface Control


altEnergy
Sat Oct 06, 2018 10:29 pm
And this is from the 9486 3.5 on same mega same sketch
Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 54 80 66 Manufacturer ID
reg(0x0009) 00 00 61 00 00 Status Register
reg(0x000A) 00 08 Get Power Mode
reg(0x000C) 00 66 Get Pixel Format
reg(0x0061) 00 00 RDID1 HX8347-G
reg(0x0062) 00 00 RDID2 HX8347-G
reg(0x0063) 00 00 RDID3 HX8347-G
reg(0x0064) 00 00 RDID1 HX8347-A
reg(0x0065) 00 00 RDID2 HX8347-A
reg(0x0066) 00 00 RDID3 HX8347-A
reg(0x0067) 00 00 RDID Himax HX8347-A
reg(0x0070) 00 00 Panel Himax HX8347-A
reg(0x00A1) 00 93 30 93 30 RD_DDB SSD1963
reg(0x00B0) 00 00 RGB Interface Signal Control
reg(0x00B4) 00 00 Inversion Control
reg(0x00B6) 00 02 02 3B 3B Display Control
reg(0x00B7) 00 06 Entry Mode Set
reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
reg(0x00C0) 00 0E 0E 0E 0E 0E 0E 0E 0E Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
reg(0x00CC) 00 04 Panel Control
reg(0x00D0) 00 00 00 Power Control
reg(0x00D2) 00 00 00 00 00 NVM Read
reg(0x00D3) 00 00 94 86 ILI9341, ILI9488
reg(0x00D4) 00 00 00 00 Novatek ID
reg(0x00DA) 00 54 RDID1
reg(0x00DB) 00 80 RDID2
reg(0x00DC) 00 66 RDID3
reg(0x00E0) 00 0A 0D 2C 0D 0F 0C 7D A5 65 0E 1D 0B 14 24 05 GAMMA-P
reg(0x00E1) 00 01 27 21 0D 16 01 1B 96 77 02 1E 07 14 19 0C GAMMA-N
reg(0x00EF) 00 80 00 10 60 40 ILI9327
reg(0x00F2) 00 18 A3 12 02 B2 12 FF 10 00 00 00 Adjust Control 2
reg(0x00F6) 00 54 80 66 Interface Control


david.prentice
Sat Oct 06, 2018 11:23 pm
Here are the interesting locations:
reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 93 02 Manufacturer ID
reg(0x0009) 00 00 61 00 00 Status Register
reg(0x000A) 08 08 Get Power Mode
reg(0x000C) 66 66 Get Pixel Format
...
reg(0x00D3) 00 00 93 02 ILI9341, ILI9488
reg(0x00DA) 00 00 RDID1
reg(0x00DB) 93 93 RDID2
reg(0x00DC) 02 02 RDID3

altEnergy
Sun Oct 07, 2018 12:15 am
well I have also had my own faith restored , I knew my wiring was correct
new blue pill
same wiring same defines
here is the results
Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 93 02 Manufacturer ID
reg(0x0009) 00 00 61 00 00 Status Register
reg(0x000A) 08 08 Get Power Mode
reg(0x000C) 66 66 Get Pixel Format
reg(0x0061) 00 00 RDID1 HX8347-G
reg(0x0062) 00 00 RDID2 HX8347-G
reg(0x0063) 00 00 RDID3 HX8347-G
reg(0x0064) 00 00 RDID1 HX8347-A
reg(0x0065) 00 00 RDID2 HX8347-A
reg(0x0066) 00 00 RDID3 HX8347-A
reg(0x0067) 00 00 RDID Himax HX8347-A
reg(0x0070) 00 00 Panel Himax HX8347-A
reg(0x00A1) 00 FF 00 FF 00 RD_DDB SSD1963
reg(0x00B0) 00 00 RGB Interface Signal Control
reg(0x00B4) 00 00 Inversion Control
reg(0x00B6) 00 00 00 00 00 Display Control
reg(0x00B7) 00 00 Entry Mode Set
reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
reg(0x00C0) 00 00 00 00 00 00 00 00 00 Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
reg(0x00CC) 00 00 Panel Control
reg(0x00D0) 40 40 01 Power Control
reg(0x00D2) 40 40 01 40 40 NVM Read
reg(0x00D3) 00 00 93 02 ILI9341, ILI9488
reg(0x00D4) 41 41 01 41 Novatek ID
reg(0x00DA) 00 00 RDID1
reg(0x00DB) 93 93 RDID2
reg(0x00DC) 02 02 RDID3
reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P
reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-N
reg(0x00EF) 00 00 00 00 00 00 ILI9327
reg(0x00F2) 00 00 00 00 00 00 00 00 00 00 00 00 Adjust Control 2
reg(0x00F6) 00 00 00 00 Interface Control


altEnergy
Sun Oct 07, 2018 3:56 am
Well it didn’t work in fact this time I did not even get the flickers I got when it was giving wrong id output.
So I tried replacing just the masks, writes, reads,setWriteDir, setReadDir, in your special with the ones i had worked out but still nothing
so I would like to know how to do it but if it is to much to explain, I will settle with your new special based on my defines.
Have you looked at the last code I came up with to see where i am going wrong? Anyway off to bed now, I have been up too long again.
Andy

david.prentice
Sun Oct 07, 2018 8:01 am
Here is a SPECIAL
#elif defined(USE_ALTENERGY_BLUEPILL) && (defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8))
#warning Uno Shield on ALTENERGY_BLUEPILL

#if defined(ARDUINO_NUCLEO_F103C8) //regular CMSIS libraries
#define REGS(x) x
#define GPIO_INIT() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; \
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
#else //weird Maple libraries
#define REGS(x) regs->x
#endif

#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; }
#define GROUP_MODE(port, reg, mask, val) {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
#define GP_OUT(port, reg, mask) GROUP_MODE(port, reg, mask, 0x33333333)
#define GP_INP(port, reg, mask) GROUP_MODE(port, reg, mask, 0x44444444)
#define PIN_OUTPUT(port, pin) {\
if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));} \
}
#define PIN_INPUT(port, pin) { \
if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); } \
else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); } \
}
#define PIN_HIGH(port, pin) (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin) (port)-> REGS(BSRR) = (1<<((pin)+16))

#define RD_PORT GPIOA
#define RD_PIN 0
#define WR_PORT GPIOA
#define WR_PIN 1
#define CD_PORT GPIOA
#define CD_PIN 2
#define CS_PORT GPIOA
#define CS_PIN 3
#define RESET_PORT GPIOA
#define RESET_PIN 4

// configure macros for the data pins
#define AMASK 0x0300
#define BMASK 0xFC00
#define write_8(d) { GPIOA->REGS(BSRR) = AMASK << 16; GPIOB->REGS(BSRR) = BMASK << 16; \
GPIOA->REGS(BSRR) = (((d) & 3) << 8); \
GPIOB->REGS(BSRR) = (((d) & 0xFC) << 8); \
}
#define read_8() (((GPIOA->REGS(IDR) & AMASK) >> 8) | ((GPIOB->REGS(IDR) & BMASK) >> 8))
// PA9,PA8 PB15-PB10
#define setWriteDir() {GP_OUT(GPIOA, CRH, 0x0FF); GP_OUT(GPIOB, CRH, 0xFFFFFF00); }
#define setReadDir() {GP_INP(GPIOA, CRH, 0x0FF); GP_INP(GPIOB, CRH, 0xFFFFFF00); }

#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }


altEnergy
Sun Oct 07, 2018 10:10 am
Thankyou Thankyou So much David I was so close yet so far away. I have not tested it yet but can see sense in the changes except GP_INP(GPIOA, CRH, 0xFFFFFF00);

david.prentice
Sun Oct 07, 2018 11:01 am
CRH is a 32-bit register with 4 bits per PORT pin. Hence the top 6 PORTBH bits use 0xFFFFFF00 mask. The bottom 2 PORTAH bits use 0x000000FF mask. The 16-bit GPIO port needs 64 mode bits e.g. two 32bit registers CRL, CRH

There are several ways of setting the 4 mode bits for each GPIO pin. Roger has a library call. However I need to work with Keil, Rowley, Arduino, … So I do not want to be tied to a weird Maple library.

My macro is fairly easy to maintain but it is not very intuitive for a newcomer to the vagaries of the F103.
Most ARM manufacturers arrange their mode bits in a more convenient manner.
ST introduced MODER very swiftly. This forum is dedicated to a first generation M3 chip that was superceded years ago.

David.


altEnergy
Sun Oct 07, 2018 11:08 am
So i have added your special in just before the end code#else
#define USE_SPECIAL_FAIL
#endif

altEnergy
Sun Oct 07, 2018 11:13 am
Thanks for explanation but its the Bport that uses the 6 upper bits not A that’s what I can’t understand
your code has GP_INP(GPIOA, CRH, 0xFFFFFF00);

david.prentice
Sun Oct 07, 2018 11:44 am
Oops. I did say Untested. I have corrected my original code and explanation.

I can fully understand my original typo. What is naughty was that I copied it in my “explanation”.

Hey-ho. We are all human. Please tell me how you get on. I am just about to make a bacon sandwich.

David.


altEnergy
Sun Oct 07, 2018 11:48 am
Lovely enjoy if you was to share the bacon as much as you share here you”ll need a lot of pigs!!

altEnergy
Sun Oct 07, 2018 12:57 pm
I must have something wrong somewhere. I had mcufriend_shield.h set to use special and put the special in a hidden folder to make sure it was looking for it and sure enough I got the error on compile so put it back in utility hit upload and went off to make a corned beef sandwich just to be consistent with my slight differences lol came back it had all compiled and uploaded via maple serial but nothing on screen except light grey pushed reset on bluepill still nothing reloaded lcd_id_readreg without disconnecting any wiring and got the sameRead Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 93 02 Manufacturer ID
reg(0x0009) 00 00 61 00 00 Status Register
reg(0x000A) 08 08 Get Power Mode
reg(0x000C) 66 66 Get Pixel Format
reg(0x0061) 00 00 RDID1 HX8347-G
reg(0x0062) 00 00 RDID2 HX8347-G
reg(0x0063) 00 00 RDID3 HX8347-G
reg(0x0064) 00 00 RDID1 HX8347-A
reg(0x0065) 00 00 RDID2 HX8347-A
reg(0x0066) 00 00 RDID3 HX8347-A
reg(0x0067) 00 00 RDID Himax HX8347-A
reg(0x0070) 00 00 Panel Himax HX8347-A
reg(0x00A1) 00 FF 00 FF 00 RD_DDB SSD1963
reg(0x00B0) 00 00 RGB Interface Signal Control
reg(0x00B4) 00 00 Inversion Control
reg(0x00B6) 00 00 00 00 00 Display Control
reg(0x00B7) 00 00 Entry Mode Set
reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
reg(0x00C0) 00 00 00 00 00 00 00 00 00 Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
reg(0x00CC) 00 00 Panel Control
reg(0x00D0) 40 40 01 Power Control
reg(0x00D2) 40 40 01 40 40 NVM Read
reg(0x00D3) 00 00 93 02 ILI9341, ILI9488
reg(0x00D4) 41 41 01 41 Novatek ID
reg(0x00DA) 00 00 RDID1
reg(0x00DB) 93 93 RDID2
reg(0x00DC) 02 02 RDID3
reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P
reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-N
reg(0x00EF) 00 00 00 00 00 00 ILI9327
reg(0x00F2) 00 00 00 00 00 00 00 00 00 00 00 00 Adjust Control 2
reg(0x00F6) 00 00 00 00 Interface Control


altEnergy
Sun Oct 07, 2018 1:11 pm
All these pills the blue one is getting me down, uploaded with corrected special not changed any wiring since getting the lcd_ID_readreg output correct again i’ll burnout the memory at this rate … 100,000 writes naa should be fine for a while yet. More like my own brain that will burn out. Its driving me a bit crazy again.
Andy

altEnergy
Sun Oct 07, 2018 1:37 pm
I can not think what to try next may be a serial upload on pins PA9 and PA10 incase boatloader is messing it up although the readreg works fine on usb without even unplugging screen but I will try it. What are the pin_shield_1.h and pin_shield_8.h files are they used in my compile? do you have and ideas what else i can do as a process of elimination?

altEnergy
Sun Oct 07, 2018 1:53 pm
The reason I could understand some of the direct port manipulation is I bought 10 mega 88p’s about two years ago and had some code to run a dds as frequency gen that would not fit and was also a bit slow on 328p so I learned how to squeeze it down and make it run faster using direct port manipulation so made my own boards and programmed them, but forgot most of what I learned but it comes back easier than first learning.

altEnergy
Sun Oct 07, 2018 2:32 pm
Well its running the code to print the serial monitor
Serial took 5000ms to start
ID = 0x0

david.prentice
Sun Oct 07, 2018 3:24 pm
You have chosen PA8-PA9, PB10-PB15 for the data bus. I do not see any obvious problems with any of those port pins.
You are using PA0-PA4 for the control pins. They seem fine too.

You have verified the actual wiring. So that should be ok.

The “BLUEPILL ADAPTER” uses PA0-PA7 for data, PB0, PB6-PB9 for control.
The “NUCLEO64” uses PA9,PC7,PA10,PB3,PB5,PB4,PB10,PA8 for data, PA0,PA1,PA4,PB0,PC1 for control.
The “MAPLE_REV3” uses PA10,PB7,PA0,PA1,PB5,PB6,PA8,PA9 for data, PC0-PC4 for control.

The “MY_BLUEPILL” SPECIAL uses PA0-PA3,PA9,PA10,PB6,PB7 for data, PA5-PA7,PB0-PB1 for control.

I have written several other SPECIALS for people over the years. Using different combinations of port pins. I even have a 8080-16 driver.

I can only suggest that you run LCD_ID_readreg again to confirm wiring. Then run graphictest_kbv sketch without disturbing your wires.

What ID is reported on the Serial Terminal ?
What happens if you force ID = 0x 9302 ?
What happens if you run the BluePill at 24MHz or 16MHz ?

David.


altEnergy
Sun Oct 07, 2018 3:39 pm
nothing is being reported on terminal for ID
and the force 9302 made no diference so I just need to figure how to change clock to 24 or 16 mega hertz could only be timing may be those pins run faster but I doubt it, its last thing I can try I have tried everything else you said multiple times to no avail! thanks for all your help David.
Andy

david.prentice
Sun Oct 07, 2018 7:29 pm
I thought that I should double-check the first defines in your original post. I hope that is what you are currently using in the successful LCD_ID_readreg sketch.

I had misread your mapping e.g. thinking your DB0 was in PA8 and DB7 in PB15 like Uno shield mapping

On further study, DB0 maps to PB10 and DB7 maps to PA9. So my “shifts” were completely wrong e.g. should be 2,10 not 8,8

// configure macros for the data pins
#define AMASK 0x0300
#define BMASK 0xFC00
#define write_8(d) { GPIOA->REGS(BSRR) = AMASK << 16; GPIOB->REGS(BSRR) = BMASK << 16; \
GPIOA->REGS(BSRR) = (((d) & 0x3F) << 10); \
GPIOB->REGS(BSRR) = (((d) & 0xC0) << 2); \
}
#define read_8() (((GPIOA->REGS(IDR) & AMASK) >> 2) | ((GPIOB->REGS(IDR) & BMASK) >> 10))


altEnergy
Sun Oct 07, 2018 8:24 pm
Oh Thank you so much David not because i have tried it, that will come in next 15 minute but because you went the extra mile, I was never to sure what i was shifting where, so in a way i misled you.Being as I have tried everything except changing frequency, and had fun reading about rogers radio experiments whilst searching for ways to change frequency , my bet is this will be solved in a few minutes again can’t thank you enough, even if that does not fix it but I feel very sure it will, being as I can get a display from a bluepill that cant even read id correctly and this one matches mega everytime! back soon!
Andy

altEnergy
Sun Oct 07, 2018 8:56 pm
oh dear I uploaded it didn’t work so changed the force id back as it was, Just in case that had some effect on sketch locking up , still no joy so loaded the lcd_id_readreg sketch everything still perfect there and have not touched wiring throughout, I need an exorcist on this one, I mean each of the first two bluepills are behaving very strange one more so than the other. This one is acting like its ok till I run a graphicstest_kbv sketch.
Sorry to be bearer of more bad news.
Andy

altEnergy
Sun Oct 07, 2018 9:20 pm
David I think I have spotted another typo GPIOA->REGS(BSRR) = (((d) & 0x3F) << 10); \
GPIOB->REGS(BSRR) = (((d) & 0xC0) << 2); \

altEnergy
Sun Oct 07, 2018 9:36 pm
That was it :D Finally perfect display colours shapes lines 1.91 seconds good job there is only two ports to mess with lol especially at weekend. I Think I could write a special myself now you made it much easier using PortMASK variable rather than shifting numbers all over the place and the shifts make so much more sense now, what confused me is I was working with a hitachi 16×2 display once that split two lots of 4 bits in a different way and can never remember weather I am starting at msb or lsb and how many bits nibbles and bytes I am working with to put it in words lol not to mention the double DD words its easy to get side tracked :lol: I understand you are working blind folded in a way not seeing whats happening this end!
Andy

altEnergy
Sun Oct 07, 2018 10:22 pm
So if anyone needs 5 analog pins and spi on a blue pill with a mcufriend display Here is the fully tested working Special thanks to David Prentice#define SSD1289_JUMPERS 2 //Uno Shield with VERY different pin-out to Mcufriend
// only define one "USE_XXX" macro at any time
//#define USE_SSD1289_SHIELD_UNO
//#define USE_SSD1289_SHIELD_MEGA
//#define USE_SSD1289_SHIELD_DUE
//#define USE_MEGA_8BIT_PROTOSHIELD
//#define USE_MEGA_8BIT_SHIELD // 4.7sec Mega2560 Shield
//#define USE_MEGA_16BIT_SHIELD // 2.14sec Mega2560 Shield
//#define USE_BLD_BST_MEGA32U4
//#define USE_BLD_BST_MEGA2560 // 12.23sec Uno Shield (17.38s C)
//#define USE_DUE_8BIT_PROTOSHIELD
//#define USE_DUE_16BIT_SHIELD //RD on PA15 (D24)
//#define USE_BOBCACHELOT_TEENSY
//#define USE_FRDM_K20
//#define USE_OPENSMART_SHIELD_PINOUT //thanks Michel53
//#define USE_ELECHOUSE_DUE_16BIT_SHIELD //Untested yet
//#define USE_MY_BLUEPILL
#define USE_ALTENERGY_BLUEPILL

#if 0
#elif defined(__AVR_ATmega328P__) && defined(USE_SSD1289_SHIELD_UNO) //on UNO
#warning using SSD1289 Shield for mega328
#define RD_PORT PORTC
#define RD_PIN 3
#define WR_PORT PORTC
#define WR_PIN 2
#define CD_PORT PORTC
#define CD_PIN 1
#define CS_PORT PORTC
#define CS_PIN 0
#define RESET_PORT PORTB
#define RESET_PIN 1 //actually SD_CS

// SSD1289 shield has LCD_D0 on RXD0. Fine for write-only
// For any Read operations, put jumper from D0 to D8, Switch #2 to OFF.
// If using Serial, jumper D1 to A5, Switch #1 to OFF
#if SSD1289_JUMPERS == 0
#warning no jumpers. Switch #1=ON, #2=ON
#define BMASK 0x00 //0x00 for output, 0x01 for Read + Serial
#define CMASK 0x00 //0x20 for Read + Serial
#define DMASK (~BMASK)
#define write8(x) { PORTD = x; WR_STROBE; }
#define read_8() ( PIND )
#elif SSD1289_JUMPERS == 1
#warning jumper D0 to D8. Switch #1=ON, #2=OFF
#define BMASK 0x01 //0x00 for output, 0x01 for Read + Serial
#define CMASK 0x00 //0x20 for Read + Serial
#define DMASK (~BMASK)
#define write8(x) { PORTD = (PORTD & ~DMASK) | (x & DMASK); PORTB = (PORTB & ~BMASK) | (x & BMASK); WR_STROBE; }
#define read_8() ( (PIND & DMASK)|(PINB & BMASK) )
#elif SSD1289_JUMPERS == 2
#warning jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF
#define BMASK (1<<0) //0x00 for output, 0x01 for Read + Serial
#define CMASK (1<<5) //0x20 for Read + Serial
#define DMASK (0xFC)
#define write8(x) { PORTC = (PORTC & ~CMASK) | ((x<<4) & CMASK);\
PORTD = (PORTD & ~DMASK) | (x & DMASK);\
PORTB = (PORTB & ~BMASK) | (x & BMASK); WR_STROBE; }
#define read_8() ( ((PINC & CMASK)>>4)|(PIND & DMASK)|(PINB & BMASK) )
#endif
#define setWriteDir() { DDRC |= CMASK; DDRD |= DMASK; DDRB |= BMASK; }
#define setReadDir() { DDRC &= ~CMASK; DDRD &= ~DMASK; DDRB &= ~BMASK; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATxmega128A1__) // Home made shield with Xplained
#warning Home made shield with Xplained
#define RD_PORT VPORT0 //PF0. VPORT0=F, 1=B, 2=C, 3=D
#define RD_PIN 0
#define WR_PORT VPORT0
#define WR_PIN 1
#define CD_PORT VPORT0
#define CD_PIN 2
#define CS_PORT VPORT0
#define CS_PIN 3
#define RESET_PORT VPORT0
#define RESET_PIN 4

// VPORTs are very fast. CBI, SBI are only one cycle. Hence all those RD_ACTIVEs
// ILI9320 data sheet says tDDR=100ns. We need 218ns to read REGs correctly.
#define write_8(x) { VPORT2.OUT = x; }
#define read_8() ( VPORT2.IN )
#define setWriteDir() { PORTCFG.VPCTRLA=0x15; PORTCFG.VPCTRLB=0x32; VPORT2.DIR = 0xFF; }
#define setReadDir() { VPORT2.DIR = 0x00; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b) (p).OUT &= ~(1<<(b))
#define PIN_HIGH(p, b) (p).OUT |= (1<<(b))
#define PIN_OUTPUT(p, b) (p).DIR |= (1<<(b))
#elif defined(__AVR_ATxmega32A4U__) || defined(__AVR_ATxmega128A4U__) // Home made shield with Batsocks module
#warning Home made shield with Batsocks module
#define RD_PORT VPORT1 //PB0. VPORT0=A, 1=B, 2=C, 3=D
#define RD_PIN 0
#define WR_PORT VPORT1
#define WR_PIN 1
#define CD_PORT VPORT1
#define CD_PIN 2
#define CS_PORT VPORT1
#define CS_PIN 3
#define RESET_PORT PORTE
#define RESET_PIN 0

// VPORTs are very fast. CBI, SBI are only one cycle. Hence all those RD_ACTIVEs
// ILI9320 data sheet says tDDR=100ns. We need 218ns to read REGs correctly.
// S6D0154 data sheet says tDDR=250ns. We need ~500ns to read REGs correctly.
// ST7789 data sheet says tRC=450ns. We need ~167ns to read REGs correctly. (10 cycles @ 60MHz )
// ST7789 says tRC=160ns for ID and tRC=450ns for Frame Memory
// ILI9341 says tRC=160ns for ID and tRC=450ns for Frame Memory. They are FASTER
#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; }
#define write_8(x) { VPORT2.OUT = x; }
#define read_8() ( VPORT2.IN )
#define setWriteDir() { PORTCFG.VPCTRLA=0x10; PORTCFG.VPCTRLB=0x32; VPORT2.DIR = 0xFF; }
#define setReadDir() { VPORT2.DIR = 0x00; }
#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b) (p).OUT &= ~(1<<(b))
#define PIN_HIGH(p, b) (p).OUT |= (1<<(b))
#define PIN_OUTPUT(p, b) (p).DIR |= (1<<(b))

#elif defined(__AVR_ATmega2560__) && defined(USE_BLD_BST_MEGA2560) //regular UNO shield on MEGA2560 using BLD/BST
#warning regular UNO shield on MEGA2560 using BLD/BST
#define RD_PORT PORTF
#define RD_PIN 0
#define WR_PORT PORTF
#define WR_PIN 1
#define CD_PORT PORTF
#define CD_PIN 2
#define CS_PORT PORTF
#define CS_PIN 3
#define RESET_PORT PORTF
#define RESET_PIN 4

#define EMASK 0x38
#define GMASK 0x20
#define HMASK 0x78
static __attribute((always_inline)) void write_8(uint8_t val)
{
asm volatile("lds __tmp_reg__,0x0102" "\n\t"
"BST %0,0" "\n\t" "BLD __tmp_reg__,5" "\n\t"
"BST %0,1" "\n\t" "BLD __tmp_reg__,6" "\n\t"
"BST %0,6" "\n\t" "BLD __tmp_reg__,3" "\n\t"
"BST %0,7" "\n\t" "BLD __tmp_reg__,4" "\n\t"
"sts 0x0102,__tmp_reg__" : : "a" (val));
asm volatile("in __tmp_reg__,0x0E" "\n\t"
"BST %0,2" "\n\t" "BLD __tmp_reg__,4" "\n\t"
"BST %0,3" "\n\t" "BLD __tmp_reg__,5" "\n\t"
"BST %0,5" "\n\t" "BLD __tmp_reg__,3" "\n\t"
"out 0x0E,__tmp_reg__" : : "a" (val));
asm volatile("in __tmp_reg__,0x14" "\n\t"
"BST %0,4" "\n\t" "BLD __tmp_reg__,5" "\n\t"
"out 0x14,__tmp_reg__" : : "a" (val));
}

#define read_8() ( ((PINH & (3<<5)) >> 5)\
| ((PINE & (3<<4)) >> 2)\
| ((PING & (1<<5)) >> 1)\
| ((PINE & (1<<3)) << 2)\
| ((PINH & (3<<3)) << 3)\
)
#define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRE |= EMASK; }
#define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRE &= ~EMASK; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega2560__) && defined(USE_SSD1289_SHIELD_MEGA) //on MEGA2560
#warning using SSD1289 Shield for mega2560
#define RD_PORT PORTF
#define RD_PIN 3 //A3
#define WR_PORT PORTF
#define WR_PIN 2 //A2
#define CD_PORT PORTF
#define CD_PIN 1 //A1
#define CS_PORT PORTF
#define CS_PIN 0 //A0
#define RESET_PORT PORTH
#define RESET_PIN 6 //D9 DS_CS, D10=T_CS, D9=SD_CS, D8=n.c.

// only for SSD1289 data bus on D2..D9 UNTESTED
#if (SSD1289_JUMPERS == 0) //Switch #1=ON, #2=ON
#warning no jumpers Switch #1=ON, #2=ON
#define EMASK 0x3B
#define FMASK 0x00
#define HMASK 0x18
#define GMASK 0x20
#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \
PORTE |= (((x) & (1<<0)) << 0); \
PORTE |= (((x) & (1<<1)) << 0); \
PORTE |= (((x) & (3<<2)) << 2); \
PORTG |= (((x) & (1<<4)) << 1); \
PORTE |= (((x) & (1<<5)) >> 2); \
PORTH |= (((x) & (3<<6)) >> 3); \
}

#define read_8() ( ((PINE & (1<<0)) >> 0)\
| ((PINE & (1<<1)) >> 0)\
| ((PINE & (3<<4)) >> 2)\
| ((PING & (1<<5)) >> 1)\
| ((PINE & (1<<3)) << 2)\
| ((PINH & (3<<3)) << 3)\
)
#elif (SSD1289_JUMPERS == 1) //jumper D0 to D8. Switch #1=ON, #2=OFF
#warning jumper D0 to D8. Switch #1=ON, #2=OFF
#define EMASK 0x3A
#define FMASK 0x00
#define HMASK 0x38
#define GMASK 0x20
#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \
PORTH |= (((x) & (1<<0)) << 5); \
PORTE |= (((x) & (1<<1)) << 0); \
PORTE |= (((x) & (3<<2)) << 2); \
PORTG |= (((x) & (1<<4)) << 1); \
PORTE |= (((x) & (1<<5)) >> 2); \
PORTH |= (((x) & (3<<6)) >> 3); \
}

#define read_8() ( ((PINH & (1<<5)) >> 5)\
| ((PINE & (1<<1)) >> 0)\
| ((PINE & (3<<4)) >> 2)\
| ((PING & (1<<5)) >> 1)\
| ((PINE & (1<<3)) << 2)\
| ((PINH & (3<<3)) << 3)\
)
#elif (SSD1289_JUMPERS == 2) //jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF
#warning jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF
#define FMASK 0x20
#define EMASK 0x38
#define HMASK 0x38
#define GMASK 0x20
#define write_8(x) { PORTH &= ~HMASK; PORTG &= ~GMASK; PORTF &= ~FMASK; PORTE &= ~EMASK; \
PORTH |= (((x) & (1<<0)) << 5); \
PORTF |= (((x) & (1<<1)) << 4); \
PORTE |= (((x) & (3<<2)) << 2); \
PORTG |= (((x) & (1<<4)) << 1); \
PORTE |= (((x) & (1<<5)) >> 2); \
PORTH |= (((x) & (3<<6)) >> 3); \
}

#define read_8() ( ((PINH & (1<<5)) >> 5)\
| ((PINF & (1<<5)) >> 4)\
| ((PINE & (3<<4)) >> 2)\
| ((PING & (1<<5)) >> 1)\
| ((PINE & (1<<3)) << 2)\
| ((PINH & (3<<3)) << 3)\
)
#endif
#define setWriteDir() { DDRH |= HMASK; DDRG |= GMASK; DDRF |= FMASK; DDRE |= EMASK; }
#define setReadDir() { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRF &= ~FMASK; DDRE &= ~EMASK; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega2560__) && defined(USE_MEGA_16BIT_SHIELD)
#warning USE_MEGA_16BIT_SHIELD
#define USES_16BIT_BUS
#define RD_PORT PORTL
#define RD_PIN 6 //PL6 (D43). Graham has PA15 (D24) on Due Shield
#define WR_PORT PORTG
#define WR_PIN 2 //D39 CTE
#define CD_PORT PORTD
#define CD_PIN 7 //D38 CTE
#define CS_PORT PORTG
#define CS_PIN 1 //D40 CTE
#define RESET_PORT PORTG
#define RESET_PIN 0 //D41 CTE

#define write_8(x) { PORTC = x; }
#define write_16(x) { PORTA = (x) >> 8; PORTC = x; }

#define read_16() ( (PINA<<8) | (PINC) )
#define setWriteDir() { DDRC = 0xFF; DDRA = 0xff; }
#define setReadDir() { DDRC = 0x00; DDRA = 0x00; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { write_16(x); WR_STROBE; }
#define READ_16(dst) { RD_STROBE; dst = read_16(); RD_IDLE; }
#define READ_8(dst) { READ_16(dst); dst &= 0xFFFF; }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega2560__) && defined(USE_MEGA_8BIT_SHIELD)
#warning USE_MEGA_8BIT_SHIELD for vagos21
#define RD_PORT PORTL
#define RD_PIN 6 //PL6 (D43). Graham has PA15 (D24) on Due Shield
#define WR_PORT PORTG
#define WR_PIN 2 //D39 CTE
#define CD_PORT PORTD
#define CD_PIN 7 //D38 CTE
#define CS_PORT PORTG
#define CS_PIN 1 //D40 CTE
#define RESET_PORT PORTG
#define RESET_PIN 0 //D41 CTE

#define write_8(x) { PORTA = x;}

#define read_8() ( PINA )
#define setWriteDir() { DDRA = 0xFF; }
#define setReadDir() { DDRA = 0x00; }
#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; } // HX8357-D is slower
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega2560__) && defined(USE_MEGA_8BIT_PROTOSHIELD)
#warning USE_MEGA_8BIT_PROTOSHIELD
#define RD_PORT PORTF
#define RD_PIN 0
#define WR_PORT PORTF
#define WR_PIN 1
#define CD_PORT PORTF
#define CD_PIN 2
#define CS_PORT PORTF
#define CS_PIN 3
#define RESET_PORT PORTF
#define RESET_PIN 4

#define write_8(x) { PORTA = x;}

#define read_8() ( PINA )
#define setWriteDir() { DDRA = 0xFF; }
#define setReadDir() { DDRA = 0x00; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega32U4__) && defined(USE_BLD_BST_MEGA32U4) //regular UNO shield on Leonardo using BST/BLD
#warning regular UNO shield on Leonardo using BST/BLD
#define RD_PORT PORTF
#define RD_PIN 7
#define WR_PORT PORTF
#define WR_PIN 6
#define CD_PORT PORTF
#define CD_PIN 5
#define CS_PORT PORTF
#define CS_PIN 4
#define RESET_PORT PORTF
#define RESET_PIN 1

#define BMASK (3<<4)
#define CMASK (1<<6)
#define DMASK ((1<<7)|(1<<4)|(3<<0))
#define EMASK (1<<6)
static __attribute((always_inline)) void write_8(uint8_t val)
{
asm volatile("in __tmp_reg__,0x05" "\n\t"
"BST %0,0" "\n\t" "BLD __tmp_reg__,4" "\n\t"
"BST %0,1" "\n\t" "BLD __tmp_reg__,5" "\n\t"
"out 0x05,__tmp_reg__" : : "a" (val));
asm volatile("in __tmp_reg__,0x0B" "\n\t"
"BST %0,2" "\n\t" "BLD __tmp_reg__,1" "\n\t"
"BST %0,3" "\n\t" "BLD __tmp_reg__,0" "\n\t"
"BST %0,4" "\n\t" "BLD __tmp_reg__,4" "\n\t"
"BST %0,6" "\n\t" "BLD __tmp_reg__,7" "\n\t"
"out 0x0B,__tmp_reg__" : : "a" (val));
asm volatile("in __tmp_reg__,0x08" "\n\t"
"BST %0,5" "\n\t" "BLD __tmp_reg__,6" "\n\t"
"out 0x08,__tmp_reg__" : : "a" (val));
asm volatile("in __tmp_reg__,0x0E" "\n\t"
"BST %0,7" "\n\t" "BLD __tmp_reg__,6" "\n\t"
"out 0x0E,__tmp_reg__" : : "a" (val));
}
#define read_8() ( ((PINB & (3<<4)) >> 4)\
| ((PIND & (1<<1)) << 1)\
| ((PIND & (1<<0)) << 3)\
| ((PIND & (1<<4)) >> 0)\
| ((PINC & (1<<6)) >> 1)\
| ((PIND & (1<<7)) >> 1)\
| ((PINE & (1<<6)) << 1)\
)
#define setWriteDir() { DDRB |= BMASK; DDRC |= CMASK; DDRD |= DMASK; DDRE |= EMASK; }
#define setReadDir() { DDRB &= ~BMASK; DDRC &= ~CMASK; DDRD &= ~DMASK; DDRE &= ~EMASK; }
#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__SAMD21J18A__) //regular UNO shield on D21_XPRO
#warning regular UNO shield on D21_XPRO
#include "samd21.h"
// configure macros for the control pins
#define RD_PORT PORT->Group[1] #define RD_PIN 0
#define WR_PORT PORT->Group[1] #define WR_PIN 1
#define CD_PORT PORT->Group[0] #define CD_PIN 10
#define CS_PORT PORT->Group[0] #define CS_PIN 11
#define RESET_PORT PORT->Group[0] #define RESET_PIN 8
// configure macros for data bus
#define AMASK 0x00220000
#define BMASK 0x0000C0E4
#define write_8(d) { \
PORT->Group[0].OUT.reg = (PORT->Group[0].OUT.reg & ~AMASK) \
| (((d) & (1<<5)) << 16) \
| (((d) & (1<<7)) << 10); \
PORT->Group[1].OUT.reg = (PORT->Group[1].OUT.reg & ~BMASK) \
| (((d) & (3<<0)) << 6) \
| (((d) & (1<<2)) << 12) \
| (((d) & (1<<3)) >> 1) \
| (((d) & (1<<4)) << 1) \
| (((d) & (1<<6)) << 9); \
}
#define read_8() ( (((PORT->Group[0].IN.reg & (1<<21)) >> 16) \
| ((PORT->Group[0].IN.reg & (1<<17)) >> 10) \
| ((PORT->Group[1].IN.reg & (3<<6)) >> 6) \
| ((PORT->Group[1].IN.reg & (1<<14)) >> 12) \
| ((PORT->Group[1].IN.reg & (1<<2)) << 1) \
| ((PORT->Group[1].IN.reg & (1<<5)) >> 1) \
| ((PORT->Group[1].IN.reg & (1<<15)) >> 9)))
#define setWriteDir() { \
PORT->Group[0].DIRSET.reg = AMASK; \
PORT->Group[1].DIRSET.reg = BMASK; \
PORT->Group[0].WRCONFIG.reg = (AMASK>>16) | (0<<22) | (0<<28) | (1<<30) | (1<<31); \
PORT->Group[1].WRCONFIG.reg = (BMASK & 0xFFFF) | (0<<22) | (0<<28) | (1<<30); \
}
#define setReadDir() { \
PORT->Group[0].DIRCLR.reg = AMASK; \
PORT->Group[1].DIRCLR.reg = BMASK; \
PORT->Group[0].WRCONFIG.reg = (AMASK>>16) | (1<<17) | (0<<28) | (1<<30) | (1<<31); \
PORT->Group[1].WRCONFIG.reg = (BMASK & 0xFFFF) | (1<<17) | (0<<28) | (1<<30); \
}

#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { RD_STROBE; dst = read_8(); RD_IDLE; RD_STROBE; dst = (dst<<8) | read_8(); RD_IDLE; }
// Shield Control macros.
#define PIN_LOW(port, pin) (port).OUTCLR.reg = (1<<(pin))
#define PIN_HIGH(port, pin) (port).OUTSET.reg = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_SSD1289_SHIELD_DUE) // on DUE
#warning USE_SSD1289_SHIELD_DUE
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 22 //A3
#define WR_PORT PIOA
#define WR_PIN 23 //A2
#define CD_PORT PIOA
#define CD_PIN 24 //A1
#define CS_PORT PIOA
#define CS_PIN 16 //A0
#define RESET_PORT PIOC
#define RESET_PIN 21 //D9 Touch CS
// configure macros for data bus
// only for SSD1289 data bus on D2..D9 UNTESTED
#if SSD1289_JUMPERS == 0
#warning no jumpers Switch #1=ON, #2=ON
#define AMASK (3<<8)
#define BMASK (1<<25)
#define CMASK (0xBC << 21)
#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
PIOA->PIO_SODR = (((x) & (1<<0)) << 8); \
PIOA->PIO_SODR = (((x) & (1<<1)) << 8); \
PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \
PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \
PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
}

#define read_8() ( ((PIOA->PIO_PDSR & (1<<8)) >> 8)\
| ((PIOA->PIO_PDSR & (1<<9)) >> 8)\
| ((PIOB->PIO_PDSR & (1<<25)) >> 23)\
| ((PIOC->PIO_PDSR & (1<<28)) >> 25)\
| ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
| ((PIOC->PIO_PDSR & (1<<25)) >> 20)\
| ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
| ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
)
#elif SSD1289_JUMPERS == 1
#warning jumper D0 to D8. Switch #1=ON, #2=OFF
#define AMASK (1<<9)
#define BMASK (1<<25)
#define CMASK (0xBE << 21)
#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \
PIOA->PIO_SODR = (((x) & (1<<1)) << 8); \
PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \
PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \
PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
}

#define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\
| ((PIOA->PIO_PDSR & (1<<9)) >> 8)\
| ((PIOB->PIO_PDSR & (1<<25)) >> 23)\
| ((PIOC->PIO_PDSR & (1<<28)) >> 25)\
| ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
| ((PIOC->PIO_PDSR & (1<<25)) >> 20)\
| ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
| ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
)
#elif SSD1289_JUMPERS == 2
#warning jumper D0 to D8, D1 to A5. Switch #1=OFF, #2=OFF
#define AMASK (1<<4)
#define BMASK (1<<25)
#define CMASK (0xBE << 21)
#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \
PIOA->PIO_SODR = (((x) & (1<<1)) << 3); \
PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
PIOC->PIO_SODR = (((x) & (1<<3)) << 25); \
PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<5)) << 20); \
PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
}

#define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\
| ((PIOA->PIO_PDSR & (1<<4)) >> 3)\
| ((PIOB->PIO_PDSR & (1<<25)) >> 23)\
| ((PIOC->PIO_PDSR & (1<<28)) >> 25)\
| ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
| ((PIOC->PIO_PDSR & (1<<25)) >> 20)\
| ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
| ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
)
#endif
#define setWriteDir() { PIOA->PIO_OER = AMASK; PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; }
#define setReadDir() { \
PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC);\
PIOA->PIO_ODR = AMASK; PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\
}
#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_DUE_8BIT_PROTOSHIELD) //regular UNO shield on DUE
#warning USE_DUE_8BIT_PROTOSHIELD
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 16 //A0
#define WR_PORT PIOA
#define WR_PIN 24 //A1
#define CD_PORT PIOA
#define CD_PIN 23 //A2
#define CS_PORT PIOA
#define CS_PIN 22 //A3
#define RESET_PORT PIOA
#define RESET_PIN 6 //A4
// configure macros for data bus
#define DMASK (0xFF<<0)
#define write_8(x) { PIOD->PIO_CODR = DMASK; PIOD->PIO_SODR = x; }

#define read_8() ( PIOD->PIO_PDSR & DMASK)
#define setWriteDir() { PIOD->PIO_OER = DMASK; PIOD->PIO_PER = DMASK; }
#define setReadDir() { PMC->PMC_PCER0 = (1 << ID_PIOD); PIOD->PIO_ODR = DMASK;}
#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_DUE_16BIT_SHIELD) //regular CTE shield on DUE
#warning USE_DUE_16BIT_SHIELD
#define USES_16BIT_BUS
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 15 //D24 Graham
#define WR_PORT PIOD
#define WR_PIN 1 //D26
#define CD_PORT PIOD
#define CD_PIN 0 //D25
#define CS_PORT PIOD
#define CS_PIN 2 //D27
#define RESET_PORT PIOD
#define RESET_PIN 3 //D28
// configure macros for data bus
// DB0..DB7 on PIOC1..PIOC8, DB8..DB15 on PIOC12..PIOC19
//
#define CMASKH (0xFF00<<4)
#define CMASKL (0x00FF<<1)
#define CMASK (CMASKH | CMASKL)
#define write_8(x) { PIOC->PIO_CODR = CMASKL; PIOC->PIO_SODR = (((x)&0x00FF)<<1); }
#define write_16(x) { PIOC->PIO_CODR = CMASK; \
PIOC->PIO_SODR = (((x)&0x00FF)<<1)|(((x)&0xFF00)<<4); }
#define read_16() (((PIOC->PIO_PDSR & CMASKH)>>4)|((PIOC->PIO_PDSR & CMASKL)>>1) )
#define read_8() (read_16() & 0xFF)
#define setWriteDir() { PIOC->PIO_OER = CMASK; PIOC->PIO_PER = CMASK; }
#define setReadDir() { PMC->PMC_PCER0 = (1 << ID_PIOC); PIOC->PIO_ODR = CMASK; }
#define write8(x) { write16(x & 0xFF); }
#define write16(x) { write_16(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; }
#define READ_16(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_8(dst) { READ_16(dst); dst &= 0xFF; }

// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_ELECHOUSE_DUE_16BIT_SHIELD) //ELECHOUSE_DUE shield on DUE
#warning USE_ELECHOUSE_DUE_16BIT_SHIELD
#define USES_16BIT_BUS
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 15 //D24 Graham
#define WR_PORT PIOA
#define WR_PIN 14 //D23
#define CD_PORT PIOB
#define CD_PIN 26 //D22
#define CS_PORT PIOA
#define CS_PIN 7 //D31
#define RESET_PORT PIOC
#define RESET_PIN 1 //D33
// configure macros for data bus
// DB0..DB7 on PIOC2..PIOC9, DB8..DB15 on PIOC12..PIOC19
//
#define CMASKH (0xFF00<<4)
#define CMASKL (0x00FF<<2)
#define CMASK (CMASKH | CMASKL)
#define write_8(x) { PIOC->PIO_CODR = CMASKL; PIOC->PIO_SODR = (((x)&0x00FF)<<2); }
#define write_16(x) { PIOC->PIO_CODR = CMASK; \
PIOC->PIO_SODR = (((x)&0x00FF)<<2)|(((x)&0xFF00)<<4); }
#define read_16() (((PIOC->PIO_PDSR & CMASKH)>>4)|((PIOC->PIO_PDSR & CMASKL)>>2) )
#define read_8() (read_16() & 0xFF)
#define setWriteDir() { PIOC->PIO_OER = CMASK; PIOC->PIO_PER = CMASK; }
#define setReadDir() { PMC->PMC_PCER0 = (1 << ID_PIOC); PIOC->PIO_ODR = CMASK; }
#define write8(x) { write16(x & 0xFF); }
#define write16(x) { write_16(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; }
#define READ_16(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_8(dst) { READ_16(dst); dst &= 0xFF; }

// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_MEGA_16BIT_SHIELD) //regular MEGA shield on DUE
#warning USE_MEGA_16BIT_SHIELD
#define USES_16BIT_BUS
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 20 //D43
#define WR_PORT PIOC
#define WR_PIN 7 //D39
#define CD_PORT PIOC
#define CD_PIN 6 //D38
#define CS_PORT PIOC
#define CS_PIN 8 //D40
#define RESET_PORT PIOC
#define RESET_PIN 9 //D41
// configure macros for data bus
//
#define AMASK ((1<<7)|(3<<14)) //PA7, PA14-PA15
#define BMASK (1<<26) //PB26
#define CMASK (31<<1) //PC1-PC5
#define DMASK ((15<<0)|(1<<6)|(3<<9)) //PD0-PD3, PD6, PD9-PD10

#define write_16(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \
PIOA->PIO_SODR = (((x)&(1<<6))<<1)|(((x)&(3<<9))<<5); \
PIOB->PIO_SODR = (((x)&(1<<8))<<18); \
PIOC->PIO_SODR = (((x)&(1<<0))<<5); \
PIOC->PIO_SODR = (((x)&(1<<1))<<3); \
PIOC->PIO_SODR = (((x)&(1<<2))<<1); \
PIOC->PIO_SODR = (((x)&(1<<3))>>1); \
PIOC->PIO_SODR = (((x)&(1<<4))>>3); \
PIOD->PIO_SODR = (((x)&(1<<7))<<2)|(((x)&(1<<5))<<5)|(((x)&(15<<11))>>11)|(((x)&(1<<15))>>9); \
}

/*
#define write_16(VL) { PIOA->PIO_CODR = AMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \
REG_PIOA_SODR=((((VL)>>8) & 0x06)<<13) | ((VL & 0x40)<<1);\
if ((VL)&(1<<8)) REG_PIOB_SODR=(1<<26); else REG_PIOB_CODR=(1<<26);\
REG_PIOC_SODR=((VL & 0x01)<<5) | ((VL & 0x02)<<3) | ((VL & 0x04)<<1) | ((VL & 0x08)>>1) | ((VL & 0x10)>>3);\
REG_PIOD_SODR=((((VL)>>8) & 0x78)>>3) | ((((VL)>>8) & 0x80)>>1) | ((VL & 0x20)<<5) | ((VL & 0x80)<<2);\
}
*/
#define read_16() ( 0\
|((PIOC->PIO_PDSR & (1<<5))>>5)\
|((PIOC->PIO_PDSR & (1<<4))>>3)\
|((PIOC->PIO_PDSR & (1<<3))>>1)\
|((PIOC->PIO_PDSR & (1<<2))<<1)\
|((PIOC->PIO_PDSR & (1<<1))<<3)\
|((PIOD->PIO_PDSR & (1<<10))>>5)\
|((PIOA->PIO_PDSR & (1<<7))>>1)\
|((PIOD->PIO_PDSR & (1<<9))>>2)\
|((PIOB->PIO_PDSR & (1<<26))>>18)\
|((PIOA->PIO_PDSR & (3<<14))>>5)\
|((PIOD->PIO_PDSR & (15<<0))<<11)\
|((PIOD->PIO_PDSR & (1<<6))<<9)\
)
#define read_8() (read_16() & 0xFF)
#define setWriteDir() {\
PIOA->PIO_OER = AMASK; PIOA->PIO_PER = AMASK; \
PIOB->PIO_OER = BMASK; PIOB->PIO_PER = BMASK; \
PIOC->PIO_OER = CMASK; PIOC->PIO_PER = CMASK; \
PIOD->PIO_OER = DMASK; PIOD->PIO_PER = DMASK; \
}
#define setReadDir() { \
PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC)|(1 << ID_PIOD); \
PIOA->PIO_ODR = AMASK; \
PIOB->PIO_ODR = BMASK; \
PIOC->PIO_ODR = CMASK; \
PIOD->PIO_ODR = DMASK; \
}
#define write8(x) { write16(x & 0xFF); }
// ILI9486 is slower than ILI9481
#define write16(x) { write_16(x); WR_ACTIVE; WR_ACTIVE; WR_STROBE; }
#define READ_16(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_8(dst) { READ_16(dst); dst &= 0xFF; }

// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_MEGA_8BIT_SHIELD) //regular CTE shield on DUE
#warning USE_MEGA_8BIT_SHIELD for peloxp
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 20 //D43
#define WR_PORT PIOC
#define WR_PIN 7 //D39
#define CD_PORT PIOC
#define CD_PIN 6 //D38
#define CS_PORT PIOC
#define CS_PIN 8 //D40
#define RESET_PORT PIOC
#define RESET_PIN 9 //D41
// configure macros for data bus
//
#define AMASK ((3<<14)) //PA14-PA15 D23-D24
#define BMASK (1<<26) //PB26 D22
#define DMASK ((15<<0)|(1<<6)) //PD0-PD3, PD6 D25-D28,D29

#define write_8(x) { PIOA->PIO_CODR = AMASK; PIOB->PIO_CODR = BMASK; PIOD->PIO_CODR = DMASK; \
PIOB->PIO_SODR = (((x)&(1<<0))<<26); \
PIOA->PIO_SODR = (((x)&(3<<1))<<13); \
PIOD->PIO_SODR = (((x)&(15<<3))>>3); \
PIOD->PIO_SODR = (((x)&(1<<7))>>1); \
}

#define read_8() ( 0\
|((PIOB->PIO_PDSR & (1<<26))>>26)\
|((PIOA->PIO_PDSR & (3<<14))>>13)\
|((PIOD->PIO_PDSR & (15<<0))<<3)\
|((PIOD->PIO_PDSR & (1<<6))<<1)\
)

#define setWriteDir() {\
PIOA->PIO_OER = AMASK; PIOA->PIO_PER = AMASK; \
PIOB->PIO_OER = BMASK; PIOB->PIO_PER = BMASK; \
PIOD->PIO_OER = DMASK; PIOD->PIO_PER = DMASK; \
}
#define setReadDir() { \
PMC->PMC_PCER0 = (1 << ID_PIOA)|(1 << ID_PIOB)|(1 << ID_PIOC)|(1 << ID_PIOD); \
PIOA->PIO_ODR = AMASK; \
PIOB->PIO_ODR = BMASK; \
PIOD->PIO_ODR = DMASK; \
}

// ILI9486 is slower than ILI9481. HX8357-D is slower
#define write8(x) { write_8(x); WR_ACTIVE; WR_ACTIVE; WR_ACTIVE; WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__SAM3X8E__) && defined(USE_OPENSMART_SHIELD_PINOUT) //OPENSMART shield on DUE
#warning USE_OPENSMART_SHIELD_PINOUT on DUE
// configure macros for the control pins
#define RD_PORT PIOA
#define RD_PIN 16
#define WR_PORT PIOA
#define WR_PIN 24
#define CD_PORT PIOA
#define CD_PIN 23
#define CS_PORT PIOA
#define CS_PIN 22
#define RESET_PORT PIOA
#define RESET_PIN 24 // n/a. so mimic WR_PIN
// configure macros for data bus
#define BMASK (1<<27)
#define CMASK (0x12F << 21)
#define DMASK (1<<7)
#define write_8(x) { PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; PIOD->PIO_CODR = DMASK; \
PIOC->PIO_SODR = (((x) & (1<<0)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<1)) << 20); \
PIOC->PIO_SODR = (((x) & (1<<2)) << 27); \
PIOD->PIO_SODR = (((x) & (1<<3)) << 4); \
PIOC->PIO_SODR = (((x) & (1<<4)) << 22); \
PIOB->PIO_SODR = (((x) & (1<<5)) << 22); \
PIOC->PIO_SODR = (((x) & (1<<6)) << 18); \
PIOC->PIO_SODR = (((x) & (1<<7)) << 16); \
}

#define read_8() ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\
| ((PIOC->PIO_PDSR & (1<<21)) >> 20)\
| ((PIOC->PIO_PDSR & (1<<29)) >> 27)\
| ((PIOD->PIO_PDSR & (1<<7)) >> 4)\
| ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
| ((PIOB->PIO_PDSR & (1<<27)) >> 22)\
| ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
| ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
)
#define setWriteDir() { PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; PIOD->PIO_OER = DMASK; }
#define setReadDir() { \
PMC->PMC_PCER0 = (1 << ID_PIOB)|(1 << ID_PIOC)|(1 << ID_PIOD);\
PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK; PIOD->PIO_ODR = DMASK;\
}
#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; }
//#define write8(x) { write_8(x); WR_ACTIVE; WR_STROBE; WR_IDLE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE; dst = read_8(); RD_IDLE; RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
// Shield Control macros.
#define PIN_LOW(port, pin) (port)->PIO_CODR = (1<<(pin))
#define PIN_HIGH(port, pin) (port)->PIO_SODR = (1<<(pin))
#define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))

#elif defined(__MK20DX256__) && defined(USE_BOBCACHELOT_TEENSY) // special for BOBCACHEALOT_TEENSY
#warning special for BOBCACHEALOT_TEENSY
#define RD_PORT GPIOD
#define RD_PIN 1
#define WR_PORT GPIOC
#define WR_PIN 0
#define CD_PORT GPIOB
#define CD_PIN 0
#define CS_PORT GPIOB
#define CS_PIN 1
#define RESET_PORT GPIOB
#define RESET_PIN 3

// configure macros for the data pins
#define CMASK ((1<<3))
#define DMASK ((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))

#define write_8(d) { \
GPIOC_PCOR = CMASK; GPIOD_PCOR = DMASK; \
GPIOC_PSOR = (((d) & (1<<1)) << 2); \
GPIOD_PSOR = (d) & DMASK; \
}
#define read_8() ( (GPIOD_PDIR & DMASK) | (GPIOC_PDIR & (1<<3)) >> 2 )
#define setWriteDir() {GPIOC_PDDR |= CMASK;GPIOD_PDDR |= DMASK; }
#define setReadDir() {GPIOC_PDDR &= ~CMASK;GPIOD_PDDR &= ~DMASK; }

#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PASTE(x, y) x ## y

#define PIN_LOW(port, pin) PASTE(port, _PCOR) = (1<<(pin))
#define PIN_HIGH(port, pin) PASTE(port, _PSOR) = (1<<(pin))
#define PIN_OUTPUT(port, pin) PASTE(port, _PDDR) |= (1<<(pin))

#elif defined(__MK20DX128__) && defined(USE_FRDM_K20) // Uno Shield on FRDM-K20
#warning Uno Shield on FRDM-K20
#define RD_PORT GPIOC
#define RD_PIN 0
#define WR_PORT GPIOC
#define WR_PIN 1
#define CD_PORT GPIOD
#define CD_PIN 6
#define CS_PORT GPIOD
#define CS_PIN 5
#define RESET_PORT GPIOB
#define RESET_PIN 1

// configure macros for the data pins
#define AMASK ((1<<12)|(1<<5)|(1<<2)|(1<<1))
#define CMASK ((1<<8)|(1<<4)|(1<<3))
#define DMASK ((1<<4))
#define write_8(d) { \
GPIOA_PCOR = AMASK; GPIOC_PCOR = CMASK; GPIOD_PCOR = DMASK; \
GPIOA_PSOR = (((d) & (1<<0)) << 12) \
| (((d) & (1<<1)) << 1) \
| (((d) & (1<<2)) << 3) \
| (((d) & (1<<5)) >> 4); \
GPIOC_PSOR = (((d) & (1<<4)) << 4) \
| (((d) & (3<<6)) >> 3); \
GPIOD_PSOR = (((d) & (1<<3)) << 1); \
}
#define read_8() ( (((GPIOA_PDIR & (1<<5)) >> 3) \
| ((GPIOA_PDIR & (1<<1)) << 4) \
| ((GPIOA_PDIR & (1<<12)) >> 12) \
| ((GPIOA_PDIR & (1<<2)) >> 1) \
| ((GPIOC_PDIR & (1<<8)) >> 4) \
| ((GPIOC_PDIR & (3<<3)) << 3) \
| ((GPIOD_PDIR & (1<<4)) >> 1)))
#define setWriteDir() {GPIOA_PDDR |= AMASK;GPIOC_PDDR |= CMASK;GPIOD_PDDR |= DMASK; }
#define setReadDir() {GPIOA_PDDR &= ~AMASK;GPIOC_PDDR &= ~CMASK;GPIOD_PDDR &= ~DMASK; }

#define write8(x) { write_8(x); WR_ACTIVE; WR_ACTIVE; WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PASTE(x, y) x ## y

#define PIN_LOW(port, pin) PASTE(port, _PCOR) = (1<<(pin))
#define PIN_HIGH(port, pin) PASTE(port, _PSOR) = (1<<(pin))
#define PIN_OUTPUT(port, pin) PASTE(port, _PDDR) |= (1<<(pin))

#elif defined(__AVR_ATmega328P__) && defined(USE_OPENSMART_SHIELD_PINOUT)
#define RD_PORT PORTC
#define RD_PIN 0
#define WR_PORT PORTC
#define WR_PIN 1
#define CD_PORT PORTC
#define CD_PIN 2
#define CS_PORT PORTC
#define CS_PIN 3
#define RESET_PORT PORTC
#define RESET_PIN 1 // n/a. so mimic WR_PIN

#define BMASK B00101111
#define DMASK B11010000

#define write_8(x) { \
PORTD = (PORTD & ~DMASK) | ((x) & DMASK); \
PORTB = (PORTB & ~BMASK) | ((x) & BMASK);} // STROBEs are defined later

#define read_8() ((PIND & DMASK) | (PINB & BMASK))

#define setWriteDir() { DDRD |= DMASK; DDRB |= BMASK; }
#define setReadDir() { DDRD &= ~DMASK; DDRB &= ~BMASK; }

#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(__AVR_ATmega2560__) && defined(USE_OPENSMART_SHIELD_PINOUT)
#define RD_PORT PORTF
#define RD_PIN 0
#define WR_PORT PORTF
#define WR_PIN 1
#define CD_PORT PORTF
#define CD_PIN 2
#define CS_PORT PORTF
#define CS_PIN 3
#define RESET_PORT PORTF
#define RESET_PIN 1 // n/a. so mimic WR_PIN

#define BMASK B10110000 //D13, D11, D10
#define GMASK 0x20 //D4
#define HMASK 0x78 //D6, D7, D8, D9

#define write_8(x) { \
PORTH = (PORTH&~HMASK)|(((x)&B11000000)>>3)|(((x)&B00000011)<<5); \
PORTB = (PORTB&~BMASK)|(((x)&B00101100)<<2); \
PORTG = (PORTG&~GMASK)|(((x)&B00010000)<<1); \
}
#define read_8()(\
((PINH & B00011000) << 3) | ((PINB & BMASK) >> 2) | \
((PING & GMASK) >> 1) | ((PINH & B01100000) >> 5) )
#define setWriteDir() { DDRH |= HMASK; DDRB |= BMASK; DDRG |= GMASK; }
#define setReadDir() { DDRH &= ~HMASK; DDRB &= ~BMASK; DDRG &= ~GMASK; }

#define write8(x) { write_8(x); WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b) (p) &= ~(1<<(b))
#define PIN_HIGH(p, b) (p) |= (1<<(b))
#define PIN_OUTPUT(p, b) *(&p-1) |= (1<<(b))

#elif defined(USE_MY_BLUEPILL) && (defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8))
#warning Uno Shield on MY BLUEPILL

#if defined(ARDUINO_NUCLEO_F103C8) //regular CMSIS libraries
#define REGS(x) x
#define GPIO_INIT() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; \
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
#else //weird Maple libraries
#define REGS(x) regs->x
#endif

#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; }
#define GROUP_MODE(port, reg, mask, val) {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
#define GP_OUT(port, reg, mask) GROUP_MODE(port, reg, mask, 0x33333333)
#define GP_INP(port, reg, mask) GROUP_MODE(port, reg, mask, 0x44444444)
#define PIN_OUTPUT(port, pin) {\
if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));} \
}
#define PIN_INPUT(port, pin) { \
if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); } \
else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); } \
}
#define PIN_HIGH(port, pin) (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin) (port)-> REGS(BSRR) = (1<<((pin)+16))

#define RD_PORT GPIOB
#define RD_PIN 1
#define WR_PORT GPIOB
#define WR_PIN 0
#define CD_PORT GPIOA
#define CD_PIN 7
#define CS_PORT GPIOA
#define CS_PIN 6
#define RESET_PORT GPIOA
#define RESET_PIN 5

// configure macros for the data pins
#define AMASK 0x060F
#define BMASK 0x00C0
#define write_8(d) { GPIOA->REGS(BSRR) = AMASK << 16; GPIOB->REGS(BSRR) = BMASK << 16; \
GPIOA->REGS(BSRR) = (((d) & 3) << 9) | (((d) & 0xF0) >> 4); \
GPIOB->REGS(BSRR) = (((d) & 0x0C) << 4); \
}
#define read_8() (((GPIOA->REGS(IDR) & (3<<9)) >> 9) | ((GPIOA->REGS(IDR) & (0x0F)) << 4) | ((GPIOB->REGS(IDR) & (3<<6)) >> 4))
// lcd d7 d6 PA10,PA9 lcd d5-d2 PA3-PA0 lcd d1 d0 PB7,PB6
#define setWriteDir() {GP_OUT(GPIOA, CRH, 0xFF0); GP_OUT(GPIOA, CRL, 0xFFFF); GP_OUT(GPIOB, CRL, 0xFF000000); }
#define setReadDir() {GP_INP(GPIOA, CRH, 0xFF0); GP_INP(GPIOA, CRL, 0xFFFF); GP_INP(GPIOB, CRL, 0xFF000000); }

#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#elif defined(USE_ALTENERGY_BLUEPILL) && (defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8))
#warning Uno Shield on ALTENERGY_BLUEPILL

#if defined(ARDUINO_NUCLEO_F103C8) //regular CMSIS libraries
#define REGS(x) x
#define GPIO_INIT() { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; \
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
#else //weird Maple libraries
#define REGS(x) regs->x
#endif

#define WRITE_DELAY { }
#define READ_DELAY { RD_ACTIVE; }
#define GROUP_MODE(port, reg, mask, val) {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
#define GP_OUT(port, reg, mask) GROUP_MODE(port, reg, mask, 0x33333333)
#define GP_INP(port, reg, mask) GROUP_MODE(port, reg, mask, 0x44444444)
#define PIN_OUTPUT(port, pin) {\
if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));} \
}
#define PIN_INPUT(port, pin) { \
if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); } \
else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); } \
}
#define PIN_HIGH(port, pin) (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin) (port)-> REGS(BSRR) = (1<<((pin)+16))

#define RD_PORT GPIOA
#define RD_PIN 0
#define WR_PORT GPIOA
#define WR_PIN 1
#define CD_PORT GPIOA
#define CD_PIN 2
#define CS_PORT GPIOA
#define CS_PIN 3
#define RESET_PORT GPIOA
#define RESET_PIN 4

// configure macros for the data pins
#define AMASK 0x0300
#define BMASK 0xFC00
#define write_8(d) { GPIOA->REGS(BSRR) = AMASK << 16; GPIOB->REGS(BSRR) = BMASK << 16; \
GPIOA->REGS(BSRR) = (((d) & 0xC0) << 2); \
GPIOB->REGS(BSRR) = (((d) & 0x3F) << 10); \
}
#define read_8() (((GPIOA->REGS(IDR) & AMASK) >> 2) | ((GPIOB->REGS(IDR) & BMASK) >> 10))

// PA9,PA8 PB15-PB10
#define setWriteDir() {GP_OUT(GPIOA, CRH, 0x0FF); GP_OUT(GPIOB, CRH, 0xFFFFFF00); }
#define setReadDir() {GP_INP(GPIOA, CRH, 0x0FF); GP_INP(GPIOB, CRH, 0xFFFFFF00); }

#define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; }
#define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
#define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#else
#define USE_SPECIAL_FAIL
#endif


Leave a Reply

Your email address will not be published. Required fields are marked *