Background: I'm trying to get a gLCD working with an Atmega328p. I got it to work quite easily, but there was one catch: the library that I found, used portB for the datapins. This was unacceptable, because I had an external oscillator hooked up, which already uses PB6 and PB7. I modified the library to use portD instead. Now everything worked flawlessly, but... RX and TX are on PD0 and PD1. So if I use this port, I can no longer use U(S)ART. That leaves portC, but sadly, this port only has 7 pins, instead of the usual 8 (and I need all 8 of them to drive the LCD). So, that forces me to use pins of two different ports.
This was the original code (snippet):
#define GLCD_IO_DATA_OUTPUT(data) PORTD = (data) #define GLCD_IO_DATA_DIR_INPUT() DDRD = 0x00; #define GLCD_IO_DATA_DIR_OUTPUT() DDRD = 0xFF;
The last two lines are used to switch the Data Direction, I'm guessing for some kind of feedback. The first line places a full byte in the dataregister for the lcd to use. I want to free up PD0 and PD1, and use PC0 and PC1 instead (because I figured this would be the easiest).
I tried this:
#define GLCD_IO_DATA_OUTPUT(data) PORTD |= (data & 0b11111100);\ PORTC |= (data & 0b00000011) #define GLCD_IO_DATA_DIR_INPUT() DDRD &= ~(0b11111100); DDRC &= ~(0b00000011) #define GLCD_IO_DATA_DIR_OUTPUT() DDRD |= 0b11111100; DDRC |= 0b00000011
Sadly, this didn't work.
Because I have nothing else hooked up (for now), I guessed there is no reason to not use the full port, for now:
#define GLCD_IO_DATA_OUTPUT(data) PORTD = (data); PORTC = (data) #define GLCD_IO_DATA_DIR_INPUT() DDRD = 0x00; \ DDRC = 0x00 #define GLCD_IO_DATA_DIR_OUTPUT() DDRD = 0xFF; \ DDRC = 0xFF
It places the full databyte in both ports, but only the relevant pins (PC0-1, PD2-PD7) are connected.
I guessed this HAD to work, but it didn't. Maybe there's something obvious I'm missing, or some hardware limitation that prevents this method from working?
So... What would be the best way to implement a change like this, and what did I do wrong in the code above?