Please run it on your NUCLEO-L152

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mcufriend_shield.h Source File

mcufriend_shield.h

00001 //#define USE_SPECIAL             //check for custom drivers
00002 
00003 #define WR_ACTIVE2  {WR_ACTIVE; WR_ACTIVE;}
00004 #define WR_ACTIVE4  {WR_ACTIVE2; WR_ACTIVE2;}
00005 #define WR_ACTIVE8  {WR_ACTIVE4; WR_ACTIVE4;}
00006 #define RD_ACTIVE2  {RD_ACTIVE; RD_ACTIVE;}
00007 #define RD_ACTIVE4  {RD_ACTIVE2; RD_ACTIVE2;}
00008 #define RD_ACTIVE8  {RD_ACTIVE4; RD_ACTIVE4;}
00009 #define RD_ACTIVE16 {RD_ACTIVE8; RD_ACTIVE8;}
00010 #define WR_IDLE2  {WR_IDLE; WR_IDLE;}
00011 #define WR_IDLE4  {WR_IDLE2; WR_IDLE2;}
00012 #define RD_IDLE2  {RD_IDLE; RD_IDLE;}
00013 #define RD_IDLE4  {RD_IDLE2; RD_IDLE2;}
00014 
00015 #if defined(USE_SPECIAL)
00016 #include "mcufriend_special.h"
00017 #if !defined(USE_SPECIAL_FAIL)
00018 #warning WE ARE USING A SPECIAL CUSTOM DRIVER
00019 #endif
00020 #endif
00021 #if !defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL)
00022 
00023 #if 0
00024 //################################### UNO ##############################
00025 #elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__)       //regular UNO shield on UNO
00026 #define RD_PORT PORTC
00027 #define RD_PIN  0
00028 #define WR_PORT PORTC
00029 #define WR_PIN  1
00030 #define CD_PORT PORTC
00031 #define CD_PIN  2
00032 #define CS_PORT PORTC
00033 #define CS_PIN  3
00034 #define RESET_PORT PORTC
00035 #define RESET_PIN  4
00036 
00037 #define BMASK         0x03              //more intuitive style for mixed Ports
00038 #define DMASK         0xFC              //does exactly the same as previous
00039 #define write_8(x)    { PORTB = (PORTB & ~BMASK) | ((x) & BMASK); PORTD = (PORTD & ~DMASK) | ((x) & DMASK); }
00040 #define read_8()      ( (PINB & BMASK) | (PIND & DMASK) )
00041 #define setWriteDir() { DDRB |=  BMASK; DDRD |=  DMASK; }
00042 #define setReadDir()  { DDRB &= ~BMASK; DDRD &= ~DMASK; }
00043 #define write8(x)     { write_8(x); WR_STROBE; }
00044 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00045 #define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
00046 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00047 
00048 #define PIN_LOW(p, b)        (p) &= ~(1<<(b))
00049 #define PIN_HIGH(p, b)       (p) |= (1<<(b))
00050 #define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))
00051 
00052 //################################### MEGA2560 ##############################
00053 #elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)       //regular UNO shield on MEGA2560
00054 #define RD_PORT PORTF
00055 #define RD_PIN  0
00056 #define WR_PORT PORTF
00057 #define WR_PIN  1
00058 #define CD_PORT PORTF
00059 #define CD_PIN  2
00060 #define CS_PORT PORTF
00061 #define CS_PIN  3
00062 #define RESET_PORT PORTF
00063 #define RESET_PIN  4
00064 
00065 #define EMASK         0x38
00066 #define GMASK         0x20
00067 #define HMASK         0x78
00068 #define write_8(x)   {  PORTH &= ~HMASK; PORTG &= ~GMASK; PORTE &= ~EMASK; \
00069                         PORTH |= (((x) & (3<<0)) << 5); \
00070                         PORTE |= (((x) & (3<<2)) << 2); \
00071                         PORTG |= (((x) & (1<<4)) << 1); \
00072                         PORTE |= (((x) & (1<<5)) >> 2); \
00073                         PORTH |= (((x) & (3<<6)) >> 3); \
00074                      }
00075 
00076 #define read_8()      ( ((PINH & (3<<5)) >> 5)\
00077                       | ((PINE & (3<<4)) >> 2)\
00078                       | ((PING & (1<<5)) >> 1)\
00079                       | ((PINE & (1<<3)) << 2)\
00080                       | ((PINH & (3<<3)) << 3)\
00081                       )
00082 #define setWriteDir() { DDRH |=  HMASK; DDRG |=  GMASK; DDRE |=  EMASK;  }
00083 #define setReadDir()  { DDRH &= ~HMASK; DDRG &= ~GMASK; DDRE &= ~EMASK;  }
00084 #define write8(x)     { write_8(x); WR_STROBE; }
00085 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00086 #define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
00087 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00088 
00089 #define PIN_LOW(p, b)        (p) &= ~(1<<(b))
00090 #define PIN_HIGH(p, b)       (p) |= (1<<(b))
00091 #define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))
00092 
00093 //################################### MEGA4809 NANO_EVERY  4808 ##############################
00094 #elif defined(__AVR_ATmega4808__)   // Thinary EVERY-4808 with Nano-Shield_Adapter
00095 #warning EVERY-4808 with Nano-Shield_Adapter
00096 #define RD_PORT VPORTD  //
00097 #define RD_PIN  0
00098 #define WR_PORT VPORTD
00099 #define WR_PIN  1
00100 #define CD_PORT VPORTD
00101 #define CD_PIN  2
00102 #define CS_PORT VPORTD
00103 #define CS_PIN  3
00104 #define RESET_PORT VPORTF
00105 #define RESET_PIN  2
00106 
00107 #define AMASK         0xFF
00108 #define write_8(x)    { VPORTA.OUT = ((x) << 6) | ((x) >> 2); }
00109 #define read_8()      ( (VPORTA.IN >> 6) | (VPORTA.IN << 2) )
00110 #define setWriteDir() { VPORTA_DIR |=  AMASK; }
00111 #define setReadDir()  { VPORTA_DIR &= ~AMASK; }
00112 
00113 //#define WRITE_DELAY   { WR_ACTIVE; WR_ACTIVE; }   //6.47s no_inline
00114 #define WRITE_DELAY   { WR_ACTIVE2; WR_ACTIVE; }   //-Os=5.43s @20MHz always_inline. (-O1=5.41s, -O3=5.25s) 
00115 #define READ_DELAY    { RD_ACTIVE4; }              //ID=0x7789
00116 #define write8(x)     { write_8(x); WRITE_DELAY; WR_STROBE; }
00117 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00118 #define READ_8(dst)   { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
00119 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00120 
00121 #define PIN_LOW(p, b)        (p).OUT &= ~(1<<(b))
00122 #define PIN_HIGH(p, b)       (p).OUT |= (1<<(b))
00123 #define PIN_OUTPUT(p, b)     (p).DIR |= (1<<(b))
00124 
00125 //################################### MEGA4809 NANO_EVERY ##############################
00126 #elif defined(__AVR_ATmega4809__) && defined(ARDUINO_AVR_NANO_EVERY)   // EVERY-4809 with Nano-Shield_Adapter
00127 #warning EVERY-4809 with Nano-Shield_Adapter using VPORT.OUT and BLD/BST
00128 #define RD_PORT VPORTD  //
00129 #define RD_PIN  3
00130 #define WR_PORT VPORTD
00131 #define WR_PIN  2
00132 #define CD_PORT VPORTD
00133 #define CD_PIN  1
00134 #define CS_PORT VPORTD
00135 #define CS_PIN  0
00136 #define RESET_PORT VPORTF
00137 #define RESET_PIN  2
00138 
00139 #define AMASK         (3<<0)
00140 #define BMASK         (5<<0)
00141 #define CMASK         (1<<6)
00142 #define EMASK         (1<<3)
00143 #define FMASK         (3<<4)
00144 static __attribute((always_inline))
00145 void write_8(uint8_t val)
00146 {
00147     asm volatile("in __tmp_reg__,0x01" "\n\t"    //VPORTA.OUT
00148                  "BST %0,2" "\n\t" "BLD __tmp_reg__,0" "\n\t"
00149                  "BST %0,7" "\n\t" "BLD __tmp_reg__,1" "\n\t"
00150                  "out 0x01,__tmp_reg__" : : "a" (val));
00151     asm volatile("in __tmp_reg__,0x05" "\n\t"    //VPORTB.OUT
00152                  "BST %0,1" "\n\t" "BLD __tmp_reg__,0" "\n\t"
00153                  "BST %0,5" "\n\t" "BLD __tmp_reg__,2" "\n\t"
00154                  "out 0x05,__tmp_reg__" : : "a" (val));
00155     asm volatile("in __tmp_reg__,0x09" "\n\t"    //VPORTC.OUT
00156                  "BST %0,4" "\n\t" "BLD __tmp_reg__,6" "\n\t"
00157                  "out 0x09,__tmp_reg__" : : "a" (val));
00158     asm volatile("in __tmp_reg__,0x11" "\n\t"    //VPORTE.OUT
00159                  "BST %0,0" "\n\t" "BLD __tmp_reg__,3" "\n\t"
00160                  "out 0x11,__tmp_reg__" : : "a" (val));
00161     asm volatile("in __tmp_reg__,0x15" "\n\t"    //VPORTF.OUT
00162                  "BST %0,3" "\n\t" "BLD __tmp_reg__,5" "\n\t"
00163                  "BST %0,6" "\n\t" "BLD __tmp_reg__,4" "\n\t"
00164                  "out 0x15,__tmp_reg__" : : "a" (val));
00165 }
00166 
00167 #define read_8()      ( 0 \
00168                         | ((VPORTA_IN & (1<<0)) << 2)\
00169                         | ((VPORTA_IN & (1<<1)) << 6)\
00170                         | ((VPORTB_IN & (1<<0)) << 1)\
00171                         | ((VPORTB_IN & (1<<2)) << 3)\
00172                         | ((VPORTC_IN & CMASK) >> 2)\
00173                         | ((VPORTE_IN & EMASK) >> 3)\
00174                         | ((VPORTF_IN & (1<<5)) >> 2)\
00175                         | ((VPORTF_IN & (1<<4)) << 2)\
00176                       )
00177 #define setWriteDir() { VPORTA_DIR |=  AMASK; VPORTB_DIR |=  BMASK; VPORTC_DIR |=  CMASK; VPORTE_DIR |=  EMASK; VPORTF_DIR |=  FMASK; }
00178 #define setReadDir()  { VPORTA_DIR &= ~AMASK; VPORTB_DIR &= ~BMASK; VPORTC_DIR &= ~CMASK; VPORTE_DIR &= ~EMASK; VPORTF_DIR &= ~FMASK; }
00179 
00180 //#define WRITE_DELAY   { WR_ACTIVE; WR_ACTIVE; }   //6.47s no_inline
00181 #define WRITE_DELAY   { WR_ACTIVE2; WR_ACTIVE; }   //-Os=5.43s @20MHz always_inline. (-O1=5.41s, -O3=5.25s) 
00182 #define READ_DELAY    { RD_ACTIVE4; }              //ID=0x7789
00183 #define write8(x)     { write_8(x); WRITE_DELAY; WR_STROBE; }
00184 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00185 #define READ_8(dst)   { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
00186 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00187 
00188 #define PIN_LOW(p, b)        (p).OUT &= ~(1<<(b))
00189 #define PIN_HIGH(p, b)       (p).OUT |= (1<<(b))
00190 #define PIN_OUTPUT(p, b)     (p).DIR |= (1<<(b))
00191 
00192 //################################### TEENSY++2.0 ##############################
00193 #elif defined(__AVR_AT90USB1286__)       //regular UNO shield on TEENSY++ 2.0 thanks tysonlt
00194 
00195 //LCD pins  |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
00196 //AVR   pin |PD7|PD6|PD5|PD4|PD3|PD2|PE1|PE0| |PF0|PF1|PF2|PF3|PF4|
00197 
00198 #define RD_PORT PORTF
00199 #define RD_PIN  0
00200 #define WR_PORT PORTF
00201 #define WR_PIN  1
00202 #define CD_PORT PORTF
00203 #define CD_PIN  2
00204 #define CS_PORT PORTF
00205 #define CS_PIN  3
00206 #define RESET_PORT PORTF
00207 #define RESET_PIN  4
00208 
00209 #define EMASK         0x03              //more intuitive style for mixed Ports
00210 #define DMASK         0xFC              //does exactly the same as previous
00211 #define write_8(x)    { PORTE = (PORTE & ~EMASK) | ((x) & EMASK); PORTD = (PORTD & ~DMASK) | ((x) & DMASK); }
00212 #define read_8()      ( (PINE & EMASK) | (PIND & DMASK) )
00213 #define setWriteDir() { DDRE |=  EMASK; DDRD |=  DMASK; }
00214 #define setReadDir()  { DDRE &= ~EMASK; DDRD &= ~DMASK; }
00215 #define write8(x)     { write_8(x); WR_STROBE; }
00216 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00217 #define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
00218 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00219 
00220 #define PIN_LOW(p, b)        (p) &= ~(1<<(b))
00221 #define PIN_HIGH(p, b)       (p) |= (1<<(b))
00222 #define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))
00223 
00224 //################################# ZERO and M0_PRO ############################
00225 #elif defined(__SAMD21G18A__)   //regular UNO shield on ZERO or M0_PRO
00226 #include "sam.h"
00227  // configure macros for the control pins
00228 #define RD_PORT PORT->Group[0]
00229 #define RD_PIN  2
00230 #define WR_PORT PORT->Group[1]
00231 #define WR_PIN  8
00232 #define CD_PORT PORT->Group[1]
00233 #define CD_PIN  9
00234 #define CS_PORT PORT->Group[0]
00235 #define CS_PIN  4
00236 #define RESET_PORT PORT->Group[0]
00237 #define RESET_PIN  5
00238  // configure macros for data bus
00239 #define DMASK 0x0030C3C0
00240  //  #define write_8(x) PORT->Group[0].OUT.reg = (PORT->Group[0].OUT.reg & ~DMASK)|(((x) & 0x0F) << 6)|(((x) & 0x30) << 10)|(((x) & 0xC0)<<14)
00241 #if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_ZERO)   // American ZERO
00242 #define write_8(x) {\
00243     PORT->Group[0].OUTCLR.reg = DMASK;\
00244     PORT->Group[0].OUTSET.reg = (((x) & 0x0B) << 6)\
00245                                |(((x) & (1<<2)) << 12)\
00246                                |(((x) & (1<<4)) << 4)\
00247                                |(((x) & (1<<5)) << 10)\
00248                                |(((x) & 0xC0) << 14);\
00249                    }
00250 #define read_8()   (((PORT->Group[0].IN.reg >> 6) & 0x0B)\
00251                    |((PORT->Group[0].IN.reg >> 12) & (1<<2))\
00252                    |((PORT->Group[0].IN.reg >> 4) &  (1<<4))\
00253                    |((PORT->Group[0].IN.reg >> 10) & (1<<5))\
00254                    |((PORT->Group[0].IN.reg >> 14) & 0xC0))
00255 #else   //default to an M0_PRO on v1.6.5 or 1.7.6
00256 #define write_8(x) {\
00257     PORT->Group[0].OUTCLR.reg = DMASK;\
00258     PORT->Group[0].OUTSET.reg = (((x) & 0x0F) << 6)\
00259                                |(((x) & 0x30) << 10)\
00260                                |(((x) & 0xC0) << 14);\
00261                    }
00262 #define read_8()   (((PORT->Group[0].IN.reg >> 6) & 0x0F)|((PORT->Group[0].IN.reg >> 10) & 0x30)|((PORT->Group[0].IN.reg >> 14) & 0xC0))
00263 #endif
00264 #define setWriteDir() { PORT->Group[0].DIRSET.reg = DMASK; \
00265                       PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (0<<22) | (1<<28) | (1<<30); \
00266                       PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (0<<22) | (1<<28) | (1<<30) | (1<<31); \
00267                         }
00268 #define setReadDir()  { PORT->Group[0].DIRCLR.reg = DMASK; \
00269                       PORT->Group[0].WRCONFIG.reg = (DMASK & 0xFFFF) | (1<<17) | (1<<28) | (1<<30); \
00270                       PORT->Group[0].WRCONFIG.reg = (DMASK>>16) | (1<<17) | (1<<28) | (1<<30) | (1<<31); \
00271                         }
00272 #define write8(x)     { write_8(x); WR_ACTIVE; WR_STROBE; }
00273 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00274 #define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
00275 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00276  // Shield Control macros.
00277 #define PIN_LOW(port, pin)    (port).OUTCLR.reg = (1<<(pin))
00278 #define PIN_HIGH(port, pin)   (port).OUTSET.reg = (1<<(pin))
00279 #define PIN_OUTPUT(port, pin) (port).DIR.reg |= (1<<(pin))
00280 
00281 //####################################### DUE ############################
00282 #elif defined(__SAM3X8E__)      //regular UNO shield on DUE
00283 #define WRITE_DELAY { WR_ACTIVE; }
00284 #define IDLE_DELAY  { WR_IDLE; }
00285 #define READ_DELAY  { RD_ACTIVE;}
00286  // configure macros for the control pins
00287 #define RD_PORT PIOA
00288 #define RD_PIN  16
00289 #define WR_PORT PIOA
00290 #define WR_PIN  24
00291 #define CD_PORT PIOA
00292 #define CD_PIN  23
00293 #define CS_PORT PIOA
00294 #define CS_PIN  22
00295 #define RESET_PORT PIOA
00296 #define RESET_PIN  6
00297  // configure macros for data bus
00298 #define BMASK         (1<<25)
00299 #define CMASK         (0xBF << 21)
00300 #define write_8(x)   {  PIOB->PIO_CODR = BMASK; PIOC->PIO_CODR = CMASK; \
00301                         PIOB->PIO_SODR = (((x) & (1<<2)) << 23); \
00302                         PIOC->PIO_SODR = (((x) & (1<<0)) << 22) \
00303                                        | (((x) & (1<<1)) << 20) \
00304                                        | (((x) & (1<<3)) << 25) \
00305                                        | (((x) & (1<<4)) << 22) \
00306                                        | (((x) & (1<<5)) << 20) \
00307                                        | (((x) & (1<<6)) << 18) \
00308                                        | (((x) & (1<<7)) << 16); \
00309                      }
00310 
00311 #define read_8()      ( ((PIOC->PIO_PDSR & (1<<22)) >> 22)\
00312                       | ((PIOC->PIO_PDSR & (1<<21)) >> 20)\
00313                       | ((PIOB->PIO_PDSR & (1<<25)) >> 23)\
00314                       | ((PIOC->PIO_PDSR & (1<<28)) >> 25)\
00315                       | ((PIOC->PIO_PDSR & (1<<26)) >> 22)\
00316                       | ((PIOC->PIO_PDSR & (1<<25)) >> 20)\
00317                       | ((PIOC->PIO_PDSR & (1<<24)) >> 18)\
00318                       | ((PIOC->PIO_PDSR & (1<<23)) >> 16)\
00319                       )
00320 #define setWriteDir() { PIOB->PIO_OER = BMASK; PIOC->PIO_OER = CMASK; }
00321 #define setReadDir()  { \
00322                           PMC->PMC_PCER0 = (1 << ID_PIOB)|(1 << ID_PIOC);\
00323                           PIOB->PIO_ODR = BMASK; PIOC->PIO_ODR = CMASK;\
00324                         }
00325 #define write8(x)     { write_8(x); WRITE_DELAY; WR_STROBE; IDLE_DELAY; }
00326 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00327 #define READ_8(dst)   { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; RD_IDLE; }
00328 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00329 
00330  // Shield Control macros.
00331 #define PIN_LOW(port, pin)    (port)->PIO_CODR = (1<<(pin))
00332 #define PIN_HIGH(port, pin)   (port)->PIO_SODR = (1<<(pin))
00333 #define PIN_OUTPUT(port, pin) (port)->PIO_OER = (1<<(pin))
00334 
00335 //################################### LEONARDO ##############################
00336 #elif defined(__AVR_ATmega32U4__)       //regular UNO shield on Leonardo
00337 #define RD_PORT PORTF
00338 #define RD_PIN  7
00339 #define WR_PORT PORTF
00340 #define WR_PIN  6
00341 #define CD_PORT PORTF
00342 #define CD_PIN  5
00343 #define CS_PORT PORTF
00344 #define CS_PIN  4
00345 #define RESET_PORT PORTF
00346 #define RESET_PIN  1
00347 
00348 #define BMASK         (3<<4)
00349 #define CMASK         (1<<6)
00350 #define DMASK         ((1<<7)|(1<<4)|(3<<0))
00351 #define EMASK         (1<<6)
00352 static inline                   //hope we use r24
00353 void write_8(uint8_t x)
00354 {
00355     PORTB &= ~BMASK;
00356     PORTC &= ~CMASK;
00357     PORTD &= ~DMASK;
00358     PORTE &= ~EMASK;
00359     PORTB |= (((x) & (3 << 0)) << 4);
00360     PORTD |= (((x) & (1 << 2)) >> 1);
00361     PORTD |= (((x) & (1 << 3)) >> 3);
00362     PORTD |= (((x) & (1 << 4)) << 0);
00363     PORTC |= (((x) & (1 << 5)) << 1);
00364     PORTD |= (((x) & (1 << 6)) << 1);
00365     PORTE |= (((x) & (1 << 7)) >> 1);
00366 }
00367 
00368 #define read_8()      ( ((PINB & (3<<4)) >> 4)\
00369 | ((PIND & (1<<1)) << 1)\
00370 | ((PIND & (1<<0)) << 3)\
00371 | ((PIND & (1<<4)) >> 0)\
00372 | ((PINC & (1<<6)) >> 1)\
00373 | ((PIND & (1<<7)) >> 1)\
00374 | ((PINE & (1<<6)) << 1)\
00375 )
00376 #define setWriteDir() { DDRB |=  BMASK; DDRC |=  CMASK; DDRD |=  DMASK; DDRE |=  EMASK;  }
00377 #define setReadDir()  { DDRB &= ~BMASK; DDRC &= ~CMASK; DDRD &= ~DMASK; DDRE &= ~EMASK;  }
00378 #define write8(x)     { write_8(x); WR_STROBE; }
00379 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00380 #define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
00381 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00382 
00383 #define PIN_LOW(p, b)        (p) &= ~(1<<(b))
00384 #define PIN_HIGH(p, b)       (p) |= (1<<(b))
00385 #define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))
00386 
00387 //################################### UNO SHIELD on BOBUINO ##############################
00388 #elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) //UNO shield on BOBUINO
00389 #warning regular UNO shield on BOBUINO
00390 
00391 //LCD pins  |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
00392 //AVR   pin |PB3|PB2|PB1|PB0|PD3|PD2|PD6|PD5| |PA7|PA6|PA5|PA4|PA3|
00393 
00394 #define RD_PORT PORTA
00395 #define RD_PIN  7
00396 #define WR_PORT PORTA
00397 #define WR_PIN  6
00398 #define CD_PORT PORTA
00399 #define CD_PIN  5
00400 #define CS_PORT PORTA
00401 #define CS_PIN  4
00402 #define RESET_PORT PORTA
00403 #define RESET_PIN  3
00404 
00405 #define BMASK         0x0F              //
00406 #define DMASK         0x6C              //
00407 #define write_8(x)    { PORTB = (PORTB & ~BMASK) | ((x) >> 4); \
00408         PORTD = (PORTD & ~DMASK) | ((x) & 0x0C) | (((x) & 0x03) << 5); }
00409 #define read_8()      ( (PINB << 4) | (PIND & 0x0C) | ((PIND & 0x60) >> 5) )
00410 #define setWriteDir() { DDRB |=  BMASK; DDRD |=  DMASK; }
00411 #define setReadDir()  { DDRB &= ~BMASK; DDRD &= ~DMASK; }
00412 #define write8(x)     { write_8(x); WR_STROBE; }
00413 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00414 #define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
00415 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00416 
00417 #define PIN_LOW(p, b)        (p) &= ~(1<<(b))
00418 #define PIN_HIGH(p, b)       (p) |= (1<<(b))
00419 #define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))
00420 
00421 //####################################### TEENSY ############################
00422 #elif defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) // regular UNO shield on a Teensy 3.x
00423 #warning regular UNO shield on a Teensy 3.x
00424 
00425 //LCD pins  |D7 |D6 |D5 |D4  |D3  |D2 |D1 |D0 | |RD |WR |RS |CS |RST|
00426 //MK20 pin  |PD2|PD4|PD7|PA13|PA12|PD2|PC3|PD3| |PD1|PC0|PB0|PB1|PB3|
00427 
00428 #if defined(__MK20DX128__) || defined(__MK20DX256__) // Teensy3.0 || 3.2 96MHz
00429 #define WRITE_DELAY { WR_ACTIVE2; }
00430 #define READ_DELAY  { RD_ACTIVE8; RD_ACTIVE; }
00431 #elif defined(__MK64FX512__) // Teensy3.5 120MHz thanks to PeteJohno
00432 #define WRITE_DELAY { WR_ACTIVE4; }
00433 #define READ_DELAY  { RD_ACTIVE8; }
00434 #elif defined(__MK66FX1M0__) // Teensy3.6 180MHz untested.   delays can possibly be reduced.
00435 #define WRITE_DELAY { WR_ACTIVE8; }
00436 #define READ_DELAY  { RD_ACTIVE16; }
00437 #else
00438 #error unspecified delays
00439 #endif
00440 
00441 #define RD_PORT GPIOD
00442 #define RD_PIN 1
00443 #define WR_PORT GPIOC
00444 #define WR_PIN 0
00445 #define CD_PORT GPIOB
00446 #define CD_PIN 0
00447 #define CS_PORT GPIOB
00448 #define CS_PIN 1
00449 #define RESET_PORT GPIOB
00450 #define RESET_PIN 3
00451 
00452 // configure macros for the data pins
00453 #define AMASK ((1<<12)|(1<<13))
00454 #define CMASK ((1<<3))
00455 #define DMASK ((1<<0)|(1<<2)|(1<<3)|(1<<4)|(1<<7))
00456 
00457 #define write_8(d) { \
00458         GPIOA_PCOR = AMASK; GPIOC_PCOR = CMASK; GPIOD_PCOR = DMASK; \
00459         GPIOA_PSOR = (((d) & (1 << 3)) << 9) \
00460                      | (((d) & (1 << 4)) << 9); \
00461         GPIOC_PSOR = (((d) & (1 << 1)) << 2); \
00462         GPIOD_PSOR = (((d) & (1 << 0)) << 3) \
00463                      | (((d) & (1 << 2)) >> 2) \
00464                      | (((d) & (1 << 5)) << 2) \
00465                      | (((d) & (1 << 6)) >> 2) \
00466                      | (((d) & (1 << 7)) >> 5); \
00467         }
00468 #define read_8() ((((GPIOD_PDIR & (1<<3)) >> 3) \
00469                    | ((GPIOC_PDIR & (1 << 3)) >> 2) \
00470                    | ((GPIOD_PDIR & (1 << 0)) << 2) \
00471                    | ((GPIOA_PDIR & (1 << 12)) >> 9) \
00472                    | ((GPIOA_PDIR & (1 << 13)) >> 9) \
00473                    | ((GPIOD_PDIR & (1 << 7)) >> 2) \
00474                    | ((GPIOD_PDIR & (1 << 4)) << 2) \
00475                    | ((GPIOD_PDIR & (1 << 2)) << 5)))
00476 #define setWriteDir() {GPIOA_PDDR |= AMASK;GPIOC_PDDR |= CMASK;GPIOD_PDDR |= DMASK; }
00477 #define setReadDir() {GPIOA_PDDR &= ~AMASK;GPIOC_PDDR &= ~CMASK;GPIOD_PDDR &= ~DMASK; }
00478 #define write8(x) { write_8(x); WRITE_DELAY; WR_STROBE; } //PJ adjusted
00479 #define write16(x) { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00480 #define READ_8(dst) { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; } //PJ adjusted
00481 #define READ_16(dst) { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00482 //#define GPIO_INIT() {SIM_SCGC5 |= 0x3E00;}  //PORTA-PORTE
00483 #define GPIO_INIT() {for (int i = 2; i <= 9; i++) pinMode(i, OUTPUT); for (int i = A0; i <= A4; i++) pinMode(i, OUTPUT);}
00484 
00485 #define PASTE(x, y) x ## y
00486 
00487 #define PIN_LOW(port, pin) PASTE(port, _PCOR) = (1<<(pin))
00488 #define PIN_HIGH(port, pin) PASTE(port, _PSOR) = (1<<(pin))
00489 #define PIN_OUTPUT(port, pin) PASTE(port, _PDDR) |= (1<<(pin))
00490 
00491 //####################################### STM32 ############################
00492 // NUCLEO:   ARDUINO_NUCLEO_xxxx from ST Core or ARDUINO_STM_NUCLEO_F103RB from MapleCore
00493 // BLUEPILL: ARDUINO_NUCLEO_F103C8 / ARDUINO_BLUEPILL_F103C8 from ST Core or ARDUINO_GENERIC_STM32F103C from MapleCore
00494 // MAPLE_REV3: n/a from ST Core or ARDUINO_MAPLE_REV3 from MapleCore
00495 // ST Core:   ARDUINO_ARCH_STM32
00496 // MapleCore: __STM32F1__
00497 #elif defined(__STM32F1__) || defined(ARDUINO_ARCH_STM32)   //MapleCore or ST Core
00498 #define IS_NUCLEO64 ( defined(ARDUINO_STM_NUCLEO_F103RB) \
00499                    || defined(ARDUINO_NUCLEO_F030R8) || defined(ARDUINO_NUCLEO_F091RC) \
00500                    || defined(ARDUINO_NUCLEO_F103RB) || defined(ARDUINO_NUCLEO_F303RE) \
00501                    || defined(ARDUINO_NUCLEO_F401RE) || defined(ARDUINO_NUCLEO_F411RE) \
00502                    || defined(ARDUINO_NUCLEO_F446RE) || defined(ARDUINO_NUCLEO_L053R8) \
00503                    || defined(ARDUINO_NUCLEO_L152RE) || defined(ARDUINO_NUCLEO_L476RG) \
00504                    || defined(ARDUINO_NUCLEO_F072RB) \
00505                     )
00506 #define IS_NUCLEO144 ( defined(ARDUINO_NUCLEO_F207ZG) \
00507                    || defined(ARDUINO_NUCLEO_F429ZI) || defined(ARDUINO_NUCLEO_F767ZI) \
00508                    || defined(ARDUINO_NUCLEO_L496ZG) || defined(ARDUINO_NUCLEO_L496ZG_P) \
00509                    || defined(ARDUINO_NUCLEO_H743ZI) \
00510                     )
00511 // F1xx, F4xx, L4xx have different registers and styles.  General Macros
00512 #if defined(__STM32F1__)   //weird Maple Core
00513 #define REGS(x) regs->x
00514 #else                      //regular ST Core
00515 #define REGS(x) x
00516 #endif
00517 #define PIN_HIGH(port, pin)   (port)-> REGS(BSRR) = (1<<(pin))
00518 #define PIN_LOW(port, pin)    (port)-> REGS(BSRR) = (1<<((pin)+16))
00519 #define PIN_MODE2(reg, pin, mode) reg=(reg&~(0x3<<((pin)<<1)))|(mode<<((pin)<<1))
00520 #define GROUP_MODE(port, reg, mask, val)  {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
00521 
00522 // Family specific Macros.  F103 needs ST and Maple compatibility
00523 // note that ILI9320 class of controller has much slower Read cycles
00524 #if 0
00525 #elif defined(__STM32F1__) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8) || defined(ARDUINO_NUCLEO_F103RB)
00526 #define WRITE_DELAY { }
00527 #define READ_DELAY  { RD_ACTIVE; }
00528 #if defined(__STM32F1__)  //MapleCore crts.o does RCC.  not understand regular syntax anyway
00529 #define GPIO_INIT()      
00530 #else
00531 #define GPIO_INIT()   { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; \
00532         AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
00533 #endif
00534 #define GP_OUT(port, reg, mask)           GROUP_MODE(port, reg, mask, 0x33333333)
00535 #define GP_INP(port, reg, mask)           GROUP_MODE(port, reg, mask, 0x44444444)
00536 #define PIN_OUTPUT(port, pin) {\
00537         if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
00538         else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));} \
00539     }
00540 #define PIN_INPUT(port, pin) { \
00541         if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); } \
00542         else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); } \
00543     }
00544 
00545 // should be easy to add F030, F091, F303, L053, ...
00546 #elif defined(STM32F030x8)
00547 #define WRITE_DELAY { }
00548 #define READ_DELAY  { RD_ACTIVE; }
00549 #define GPIO_INIT()   { RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; }
00550 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00551 
00552 #elif defined(STM32F072xB)
00553 #define WRITE_DELAY { }
00554 #define READ_DELAY  { RD_ACTIVE; }
00555 #define GPIO_INIT()   { RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; }
00556 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00557 
00558 #elif defined(STM32F091xC)
00559 #define WRITE_DELAY { }
00560 #define READ_DELAY  { RD_ACTIVE; }
00561 #define GPIO_INIT()   { RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; }
00562 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00563 
00564 #elif defined(STM32F207xx)
00565 #warning DELAY macros untested yet
00566 #define WRITE_DELAY { WR_ACTIVE8; } //120MHz
00567 #define IDLE_DELAY  { WR_IDLE2;WR_IDLE; }
00568 #define READ_DELAY  { RD_ACTIVE16;}
00569 #define GPIO_INIT()   { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN; }
00570 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00571 
00572 #elif defined(STM32F303xE)
00573 #define WRITE_DELAY { }
00574 #define READ_DELAY  { RD_ACTIVE8; }  //thanks MasterT
00575 #define GPIO_INIT()   { RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; \
00576                       /* AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1; */ }
00577 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1) //thanks fpiSTM
00578 
00579 #elif defined(STM32F401xE)
00580 #define WRITE_DELAY { WR_ACTIVE2; } //84MHz
00581 #define READ_DELAY  { RD_ACTIVE4; }
00582 #define GPIO_INIT()   { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; }
00583 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00584 
00585 #elif defined(STM32F411xE)
00586 #define WRITE_DELAY { WR_ACTIVE2; WR_ACTIVE; } //100MHz
00587 #define READ_DELAY  { RD_ACTIVE4; RD_ACTIVE2; }
00588 #define GPIO_INIT()   { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; }
00589 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00590 
00591 #elif defined(STM32F429xx)
00592 #warning DELAY macros untested yet
00593 #define WRITE_DELAY { WR_ACTIVE8; } //180MHz
00594 #define IDLE_DELAY  { WR_IDLE2;WR_IDLE; }
00595 #define READ_DELAY  { RD_ACTIVE16;}
00596 #define GPIO_INIT()   { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN; }
00597 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00598 
00599 #elif defined(STM32F446xx)
00600 #define WRITE_DELAY { WR_ACTIVE8; } //180MHz
00601 #define IDLE_DELAY  { WR_IDLE2;WR_IDLE; }
00602 #define READ_DELAY  { RD_ACTIVE16;}
00603 #define GPIO_INIT()   { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN; }
00604 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00605 
00606 #elif defined(STM32F767xx)
00607 #warning DELAY macros untested yet
00608 #define WRITE_DELAY { WR_ACTIVE8;WR_ACTIVE2; } //216MHz
00609 #define IDLE_DELAY  { WR_IDLE2;WR_IDLE; }
00610 #define READ_DELAY  { RD_ACTIVE16;RD_ACTIVE16;RD_ACTIVE4;}
00611 #define GPIO_INIT()   { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN; }
00612 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00613 
00614 #elif defined(STM32H743xx)   // thanks MagicianT
00615 #warning STM32H743xx< DELAY macros untested yet
00616 #define WRITE_DELAY { WR_ACTIVE8;WR_ACTIVE2; } //F_CPU=400MHz
00617 #define IDLE_DELAY  { WR_IDLE2;WR_IDLE; }
00618 #define READ_DELAY  { RD_ACTIVE16;RD_ACTIVE16;RD_ACTIVE4;}
00619 #define GPIO_INIT()   { RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN | RCC_AHB4ENR_GPIOCEN | RCC_AHB4ENR_GPIODEN | RCC_AHB4ENR_GPIOEEN | RCC_AHB4ENR_GPIOFEN; }
00620 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00621 
00622 #elif defined(STM32L053xx)
00623 #define WRITE_DELAY { } //32MHz M0+
00624 #define READ_DELAY  { RD_ACTIVE; }
00625 #define GPIO_INIT()   { RCC->IOPENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN; }
00626 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00627 
00628 #elif defined(STM32L152xE)
00629 #define WRITE_DELAY { } //32MHz M3
00630 #define READ_DELAY  { RD_ACTIVE; }
00631 #define GPIO_INIT()   { RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN; }
00632 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00633 
00634 #elif defined(STM32L476xx)
00635 #define WRITE_DELAY { WR_ACTIVE2; } //80MHz
00636 #define READ_DELAY  { RD_ACTIVE4; RD_ACTIVE; }
00637 #define GPIO_INIT()   { RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOBEN | RCC_AHB2ENR_GPIOCEN; }
00638 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00639 
00640 #elif defined(STM32L496xx)
00641 #warning DELAY macros untested yet
00642 #define WRITE_DELAY { WR_ACTIVE2; } //80MHz
00643 #define READ_DELAY  { RD_ACTIVE4; RD_ACTIVE; }
00644 #define GPIO_INIT()   { RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN | RCC_AHB2ENR_GPIOCEN | RCC_AHB2ENR_GPIODEN | RCC_AHB2ENR_GPIOEEN | RCC_AHB2ENR_GPIOFEN; }
00645 #define PIN_OUTPUT(port, pin) PIN_MODE2((port)->MODER, pin, 0x1)
00646 
00647 #else
00648 #error unsupported STM32
00649 #endif
00650 
00651 #if 0
00652 #elif defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_NUCLEO_F103C8) || defined(ARDUINO_BLUEPILL_F103C8)
00653 #warning Uno Shield on BLUEPILL
00654 
00655 //LCD pins  |D7 |D6 |D5 |D4 |D3 |D2 |D1 |D0 | |RD |WR |RS |CS |RST| |SD_SS|SD_DI|SD_DO|SD_SCK|
00656 //STM32 pin |PA7|PA6|PA5|PA4|PA3|PA2|PA1|PA0| |PB0|PB6|PB7|PB8|PB9| |PA15 |PB5  |PB4  |PB3   | **ALT-SPI1**
00657 
00658 #define RD_PORT GPIOB
00659 //#define RD_PIN  5
00660 #define RD_PIN  0  //hardware mod to Adapter.  Allows use of PB5 for SD Card
00661 #define WR_PORT GPIOB
00662 #define WR_PIN  6
00663 #define CD_PORT GPIOB
00664 #define CD_PIN  7
00665 #define CS_PORT GPIOB
00666 #define CS_PIN  8
00667 #define RESET_PORT GPIOB
00668 #define RESET_PIN  9
00669 
00670 // configure macros for the data pins
00671 #define write_8(d)    { GPIOA->REGS(BSRR) = 0x00FF << 16; GPIOA->REGS(BSRR) = (d) & 0xFF; }
00672 #define read_8()      (GPIOA->REGS(IDR) & 0xFF)
00673 //                                         PA7 ..PA0
00674 #define setWriteDir() {GP_OUT(GPIOA, CRL, 0xFFFFFFFF); }
00675 #define setReadDir()  {GP_INP(GPIOA, CRL, 0xFFFFFFFF); }
00676 
00677 #elif IS_NUCLEO64 // Uno Shield on NUCLEO-64
00678 #warning Uno Shield on NUCLEO-64
00679 #define RD_PORT GPIOA    //PA0
00680 #define RD_PIN  0
00681 #define WR_PORT GPIOA    //PA1
00682 #define WR_PIN  1
00683 #define CD_PORT GPIOA    //PA4
00684 #define CD_PIN  4
00685 #define CS_PORT GPIOB    //PB0
00686 #define CS_PIN  0
00687 #define RESET_PORT GPIOC //PC1
00688 #define RESET_PIN  1
00689 
00690 // configure macros for the data pins
00691 #define AMASK ((1<<9)|(1<<10)|(1<<8))        //#0, #2, #7
00692 #define BMASK ((1<<3)|(1<<5)|(1<<4)|(1<<10)) //#3, #4, #5, #6
00693 #define CMASK ((1<<7))                       //#1
00694 
00695 #define write_8(d) { \
00696         GPIOA->REGS(BSRR) = AMASK << 16; \
00697         GPIOB->REGS(BSRR) = BMASK << 16; \
00698         GPIOC->REGS(BSRR) = CMASK << 16; \
00699         GPIOA->REGS(BSRR) = (  ((d) & (1<<0)) << 9) \
00700                             | (((d) & (1<<2)) << 8) \
00701                             | (((d) & (1<<7)) << 1); \
00702         GPIOB->REGS(BSRR) = (  ((d) & (1<<3)) << 0) \
00703                             | (((d) & (1<<4)) << 1) \
00704                             | (((d) & (1<<5)) >> 1) \
00705                             | (((d) & (1<<6)) << 4); \
00706         GPIOC->REGS(BSRR) = (  ((d) & (1<<1)) << 6); \
00707     }
00708 
00709 #define read_8() (       (  (  (GPIOA->REGS(IDR) & (1<<9)) >> 9) \
00710                             | ((GPIOC->REGS(IDR) & (1<<7)) >> 6) \
00711                             | ((GPIOA->REGS(IDR) & (1<<10)) >> 8) \
00712                             | ((GPIOB->REGS(IDR) & (1<<3)) >> 0) \
00713                             | ((GPIOB->REGS(IDR) & (1<<5)) >> 1) \
00714                             | ((GPIOB->REGS(IDR) & (1<<4)) << 1) \
00715                             | ((GPIOB->REGS(IDR) & (1<<10)) >> 4) \
00716                             | ((GPIOA->REGS(IDR) & (1<<8))  >> 1)))
00717 
00718 
00719 #if defined(ARDUINO_NUCLEO_F103RB) || defined(ARDUINO_STM_NUCLEO_F103RB) //F103 has unusual GPIO modes
00720 //                                 PA10,PA9,PA8                       PB10                   PB5,PB4,PB3                             PC7
00721 #define setWriteDir() {GP_OUT(GPIOA, CRH, 0xFFF); GP_OUT(GPIOB, CRH, 0xF00); GP_OUT(GPIOB, CRL, 0xFFF000); GP_OUT(GPIOC, CRL, 0xF0000000); }
00722 #define setReadDir()  {GP_INP(GPIOA, CRH, 0xFFF); GP_INP(GPIOB, CRH, 0xF00); GP_INP(GPIOB, CRL, 0xFFF000); GP_INP(GPIOC, CRL, 0xF0000000); }
00723 #else      //F0xx, F3xx, F4xx, L0xx, L1xx, L4xx use MODER
00724 //                                   PA10,PA9,PA8           PB10,PB5,PB4,PB3                      PC7
00725 #define setWriteDir() { setReadDir(); \
00726                         GPIOA->MODER |=  0x150000; GPIOB->MODER |=  0x100540; GPIOC->MODER |=  0x4000; }
00727 #define setReadDir()  { GPIOA->MODER &= ~0x3F0000; GPIOB->MODER &= ~0x300FC0; GPIOC->MODER &= ~0xC000; }
00728 #endif
00729 
00730 #elif IS_NUCLEO144 // Uno Shield on NUCLEO-144
00731 #warning Uno Shield on NUCLEO-144
00732 #define RD_PORT GPIOA    //PA3
00733 #define RD_PIN  3
00734 #define WR_PORT GPIOC    //PC0
00735 #define WR_PIN  0
00736 #define CD_PORT GPIOC    //PC3
00737 #define CD_PIN  3
00738 #define CS_PORT GPIOF    //PF3
00739 #define CS_PIN  3
00740 #define RESET_PORT GPIOF //PF5
00741 #define RESET_PIN  5
00742 
00743 // configure macros for the data pins
00744 #define DMASK ((1<<15))                         //#1
00745 #define EMASK ((1<<13)|(1<<11)|(1<<9))          //#3, #5, #6
00746 #define FMASK ((1<<12)|(1<<15)|(1<<14)|(1<<13)) //#0, #2, #4, #7
00747 
00748 #define write_8(d) { \
00749         GPIOD->REGS(BSRR) = DMASK << 16; \
00750         GPIOE->REGS(BSRR) = EMASK << 16; \
00751         GPIOF->REGS(BSRR) = FMASK << 16; \
00752         GPIOD->REGS(BSRR) = (  ((d) & (1<<1)) << 14); \
00753         GPIOE->REGS(BSRR) = (  ((d) & (1<<3)) << 10) \
00754                             | (((d) & (1<<5)) << 6) \
00755                             | (((d) & (1<<6)) << 3); \
00756         GPIOF->REGS(BSRR) = (  ((d) & (1<<0)) << 12) \
00757                             | (((d) & (1<<2)) << 13) \
00758                             | (((d) & (1<<4)) << 10) \
00759                             | (((d) & (1<<7)) << 6); \
00760     }
00761 
00762 #define read_8() (       (  (  (GPIOF->REGS(IDR) & (1<<12)) >> 12) \
00763                             | ((GPIOD->REGS(IDR) & (1<<15)) >> 14) \
00764                             | ((GPIOF->REGS(IDR) & (1<<15)) >> 13) \
00765                             | ((GPIOE->REGS(IDR) & (1<<13)) >> 10) \
00766                             | ((GPIOF->REGS(IDR) & (1<<14)) >> 10) \
00767                             | ((GPIOE->REGS(IDR) & (1<<11)) >> 6) \
00768                             | ((GPIOE->REGS(IDR) & (1<<9))  >> 3) \
00769                             | ((GPIOF->REGS(IDR) & (1<<13)) >> 6)))
00770 
00771 
00772 //                                             PD15                PE13,PE11,PE9          PF15,PF14,PF13,PF12
00773 #define setWriteDir() { setReadDir(); \
00774                         GPIOD->MODER |=  0x40000000; GPIOE->MODER |=  0x04440000; GPIOF->MODER |=  0x55000000; }
00775 #define setReadDir()  { GPIOD->MODER &= ~0xC0000000; GPIOE->MODER &= ~0x0CCC0000; GPIOF->MODER &= ~0xFF000000; }
00776 
00777 #elif defined(ARDUINO_MAPLE_REV3) // Uno Shield on MAPLE_REV3 board
00778 #warning Uno Shield on MAPLE_REV3 board
00779 #define RD_PORT GPIOC
00780 #define RD_PIN  0
00781 #define WR_PORT GPIOC
00782 #define WR_PIN  1
00783 #define CD_PORT GPIOC
00784 #define CD_PIN  2
00785 #define CS_PORT GPIOC
00786 #define CS_PIN  3
00787 #define RESET_PORT GPIOC
00788 #define RESET_PIN  4
00789 
00790 // configure macros for the data pins
00791 #define write_8(d) { \
00792         GPIOA->REGS(BSRR) = 0x0703 << 16; \
00793         GPIOB->REGS(BSRR) = 0x00E0 << 16; \
00794         GPIOA->REGS(BSRR) = (  ((d) & (1<<0)) << 10) \
00795                             | (((d) & (1<<2)) >> 2) \
00796                             | (((d) & (1<<3)) >> 2) \
00797                             | (((d) & (1<<6)) << 2) \
00798                             | (((d) & (1<<7)) << 2); \
00799         GPIOB->REGS(BSRR) = (  ((d) & (1<<1)) << 6) \
00800                             | (((d) & (1<<4)) << 1) \
00801                             | (((d) & (1<<5)) << 1); \
00802     }
00803 
00804 #define read_8()  (     (   (  (GPIOA->REGS(IDR) & (1<<10)) >> 10) \
00805                             | ((GPIOB->REGS(IDR) & (1<<7)) >> 6) \
00806                             | ((GPIOA->REGS(IDR) & (1<<0)) << 2) \
00807                             | ((GPIOA->REGS(IDR) & (1<<1)) << 2) \
00808                             | ((GPIOB->REGS(IDR) & (1<<5)) >> 1) \
00809                             | ((GPIOB->REGS(IDR) & (1<<6)) >> 1) \
00810                             | ((GPIOA->REGS(IDR) & (1<<8)) >> 2) \
00811                             | ((GPIOA->REGS(IDR) & (1<<9)) >> 2)))
00812 
00813 //                                 PA10,PA9,PA8                   PA1,PA0                     PB7,PB6,PB5
00814 #define setWriteDir() {GP_OUT(GPIOA, CRH, 0xFFF); GP_OUT(GPIOA, CRL, 0xFF); GP_OUT(GPIOB, CRL, 0xFFF00000); }
00815 #define setReadDir()  {GP_INP(GPIOA, CRH, 0xFFF); GP_INP(GPIOA, CRL, 0xFF); GP_INP(GPIOB, CRL, 0xFFF00000); }
00816 
00817 #else
00818 #error REGS group
00819 #endif
00820 
00821 #ifndef IDLE_DELAY
00822 #define IDLE_DELAY    { WR_IDLE; }
00823 #endif
00824 
00825 #define write8(x)     { write_8(x); WRITE_DELAY; WR_STROBE; IDLE_DELAY; }
00826 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00827 #define READ_8(dst)   { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE2; RD_IDLE; }
00828 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00829 
00830 //################################### ESP32 ##############################
00831 #elif defined(ESP32)       //regular UNO shield on TTGO D1 R32 (ESP32)
00832 #define LCD_RD  2  //LED
00833 #define LCD_WR  4
00834 #define LCD_RS 15  //hard-wired to A2 (GPIO35) 
00835 #define LCD_CS 33  //hard-wired to A3 (GPIO34)
00836 #define LCD_RST 32 //hard-wired to A4 (GPIO36)
00837 
00838 #define LCD_D0 12
00839 #define LCD_D1 13
00840 #define LCD_D2 26
00841 #define LCD_D3 25
00842 #define LCD_D4 17
00843 #define LCD_D5 16
00844 #define LCD_D6 27
00845 #define LCD_D7 14
00846 
00847 #define RD_PORT GPIO.out
00848 #define RD_PIN  LCD_RD
00849 #define WR_PORT GPIO.out
00850 #define WR_PIN  LCD_WR
00851 #define CD_PORT GPIO.out
00852 #define CD_PIN  LCD_RS
00853 #define CS_PORT GPIO.out1.val
00854 #define CS_PIN  LCD_CS
00855 #define RESET_PORT GPIO.out1.val
00856 #define RESET_PIN  LCD_RST
00857 
00858 static inline uint32_t map_8(uint32_t d)
00859 {
00860     return (
00861                0
00862                | ((d & (1 << 0)) << (LCD_D0 - 0))
00863                | ((d & (1 << 1)) << (LCD_D1 - 1))
00864                | ((d & (1 << 2)) << (LCD_D2 - 2))
00865                | ((d & (1 << 3)) << (LCD_D3 - 3))
00866                | ((d & (1 << 4)) << (LCD_D4 - 4))
00867                | ((d & (1 << 5)) << (LCD_D5 - 5))
00868                | ((d & (1 << 6)) << (LCD_D6 - 6))
00869                | ((d & (1 << 7)) << (LCD_D7 - 7))
00870            );
00871 }
00872 
00873 static inline uint8_t map_32(uint32_t d)
00874 {
00875     return (
00876                0
00877                | ((d & (1 << LCD_D0)) >> (LCD_D0 - 0))
00878                | ((d & (1 << LCD_D1)) >> (LCD_D1 - 1))
00879                | ((d & (1 << LCD_D2)) >> (LCD_D2 - 2))
00880                | ((d & (1 << LCD_D3)) >> (LCD_D3 - 3))
00881                | ((d & (1 << LCD_D4)) >> (LCD_D4 - 4))
00882                | ((d & (1 << LCD_D5)) >> (LCD_D5 - 5))
00883                | ((d & (1 << LCD_D6)) >> (LCD_D6 - 6))
00884                | ((d & (1 << LCD_D7)) >> (LCD_D7 - 7))
00885            );
00886 }
00887 
00888 static inline void write_8(uint16_t data)
00889 {
00890     GPIO.out_w1tc = map_8(0xFF);  //could define once as DMASK
00891     GPIO.out_w1ts = map_8(data);
00892 }
00893 
00894 static inline uint8_t read_8()
00895 {
00896     return map_32(GPIO.in);
00897 }
00898 static void setWriteDir()
00899 {
00900     pinMode(LCD_D0, OUTPUT);
00901     pinMode(LCD_D1, OUTPUT);
00902     pinMode(LCD_D2, OUTPUT);
00903     pinMode(LCD_D3, OUTPUT);
00904     pinMode(LCD_D4, OUTPUT);
00905     pinMode(LCD_D5, OUTPUT);
00906     pinMode(LCD_D6, OUTPUT);
00907     pinMode(LCD_D7, OUTPUT);
00908 }
00909 
00910 static void setReadDir()
00911 {
00912     pinMode(LCD_D0, INPUT);
00913     pinMode(LCD_D1, INPUT);
00914     pinMode(LCD_D2, INPUT);
00915     pinMode(LCD_D3, INPUT);
00916     pinMode(LCD_D4, INPUT);
00917     pinMode(LCD_D5, INPUT);
00918     pinMode(LCD_D6, INPUT);
00919     pinMode(LCD_D7, INPUT);
00920 }
00921 
00922 #define WRITE_DELAY { }
00923 #define READ_DELAY  { }
00924 
00925 #define write8(x)     { write_8(x); WRITE_DELAY; WR_STROBE; }
00926 #define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
00927 #define READ_8(dst)   { RD_STROBE; READ_DELAY; dst = read_8(); RD_IDLE; }
00928 #define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }
00929 
00930 #define PIN_LOW(p, b)        (digitalWrite(b, LOW))
00931 #define PIN_HIGH(p, b)       (digitalWrite(b, HIGH))
00932 #define PIN_OUTPUT(p, b)     (pinMode(b, OUTPUT))
00933 
00934 #else
00935 #error MCU unsupported
00936 #endif                          // regular UNO shields on Arduino boards
00937 
00938 #endif                          //!defined(USE_SPECIAL) || defined (USE_SPECIAL_FAIL)
00939 
00940 #define RD_ACTIVE  PIN_LOW(RD_PORT, RD_PIN)
00941 #define RD_IDLE    PIN_HIGH(RD_PORT, RD_PIN)
00942 #define RD_OUTPUT  PIN_OUTPUT(RD_PORT, RD_PIN)
00943 #define WR_ACTIVE  PIN_LOW(WR_PORT, WR_PIN)
00944 #define WR_IDLE    PIN_HIGH(WR_PORT, WR_PIN)
00945 #define WR_OUTPUT  PIN_OUTPUT(WR_PORT, WR_PIN)
00946 #define CD_COMMAND PIN_LOW(CD_PORT, CD_PIN)
00947 #define CD_DATA    PIN_HIGH(CD_PORT, CD_PIN)
00948 #define CD_OUTPUT  PIN_OUTPUT(CD_PORT, CD_PIN)
00949 #define CS_ACTIVE  PIN_LOW(CS_PORT, CS_PIN)
00950 #define CS_IDLE    PIN_HIGH(CS_PORT, CS_PIN)
00951 #define CS_OUTPUT  PIN_OUTPUT(CS_PORT, CS_PIN)
00952 #define RESET_ACTIVE  PIN_LOW(RESET_PORT, RESET_PIN)
00953 #define RESET_IDLE    PIN_HIGH(RESET_PORT, RESET_PIN)
00954 #define RESET_OUTPUT  PIN_OUTPUT(RESET_PORT, RESET_PIN)
00955 
00956  // General macros.   IOCLR registers are 1 cycle when optimised.
00957 #define WR_STROBE { WR_ACTIVE; WR_IDLE; }       //PWLW=TWRL=50ns
00958 #define RD_STROBE RD_IDLE, RD_ACTIVE, RD_ACTIVE, RD_ACTIVE      //PWLR=TRDL=150ns, tDDR=100ns
00959 
00960 #if !defined(GPIO_INIT)
00961 #define GPIO_INIT()
00962 #endif
00963 #define CTL_INIT()   { GPIO_INIT(); RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; }
00964 #define WriteCmd(x)  { CD_COMMAND; write16(x); CD_DATA; }
00965 #define WriteData(x) { write16(x); }