Hey All,
I think this topic was broached before without solution, so I'd like to bring it up again, hopefully some of you have seen (and solved!) this problem.
I am using the Sparkfun Nokia knock-off, controlled by an Atmega64L on a custom board. I've made 3 of these boards.
My display never works on first power up. I have to externally reset the Atmega in order for the display to show the pic I have loaded into it.
At first, one reset would do. Now, I have to reset many many times to get it to the display to work. Once working, it may or may not continue working upon further resets. My problem occurs on all my boards. At different times, some behave better than others, requiring fewer resets. Again, there was a time when one reset would work reliably; that is no longer the case.
Has anybody had this reset problem? I really need to solve it, but I am at a loss. I don't want to have to ever externally reset my board to get it working.
Here are the things I've tried, to no avail:
+running the Atmega at both 4 and 8MHz,
+using different power supplies (STK500, LT1587 3.3V supply fed by either a 12V or 6V wall wart, each which can source more than an amp)
+there is no noise on the power line at any time, inc. during startup and reset
+not initializing the LCD until a second after the micro is powered up, waiting a long time between LCDInit and writing to the LCD RAM and turning the display on
+initializing the LCD twice, with pauses between each LCDInit
+ I have a 100uF bypass cap on Vdisplay, which is tied to Vdig (all 3.3V supplies are tied together), and a 1uF cap on VLED (used for the DC boost circuit)
+ possibly related weirdness: with the backlight 7V DC boost circuit disabled, my board draws 20mA (reasonable), with it on, it draws 150mA! I measure the Sparkfun carrier board also drawing 150mA (backlight is always enabled on that board). However, the reset problem occurs no matter if the backlight is enabled or not.
The reset problem also occurs with the Sparkfun carrier board, controlled by an Atmega sitting on an Atmel STK500 dev board. So I don't think hardware errors on my custom board are involved. ( In any case, my board is quite similar to the carrier board: it has a circuit that replicates the 7V DC boost circuit on the Sparkfun carrier board, save one exception -- my Atmega64L can enable and disable the backlight with a pin connected to the DC boost IC's enable pin.)
Help would be much appreciated! Find some of my code below.
thanks very much,
Jeevan
My initialization code is as follows; I got it from someone (I forget who --jiminy or seulater, apologies for my forgetfulness!) and made no real changes:
Code:
void LCDInit(void) {
int i;
//Set Port B data directions
// MOSI, SS, SCK and RESET are all OUT, everything else is IN
SPI_DDR = _BV(SPI_DDRMOSI) | _BV(SPI_DDRSS) | _BV(SPI_DDRSCK) | _BV(SPI_RESET); //set MOSI, ~SS, SCK to output, all else to input
//bring SCK (SCLK for the LCD) and MOSI (SDATA for the LCD) low
LCD_CLK(0);
LCD_DATA(0);
_delay_ms(10);
// reset display: reset or ~reset?? pretty sure it's ~reset
LCD_RESET(1); //start it off high
_delay_ms(2);
LCD_RESET(0); //put zero on the SPI_RESET pin (reset)
_delay_ms(20);
LCD_RESET(1); // put one on the SPI_RESET pin
_delay_ms(20);
SendLCDCommand(DISCTL); // display control: timing-related display setup
SendLCDData(0x03); // 4 CL(OCK)? divisions, 8H switching period
SendLCDData(0x20); //32); // duty of one line/data block? 1/160 duty
SendLCDData(0x0C);//12); // 12 inversely highlighted lines on display
//SendLCDData(0x00);
SendLCDCommand(COMSCN); // comscn: common scan direction
SendLCDData(0x01);
SendLCDCommand(OSCON); // oscon: oscillator on
SendLCDCommand(SLPOUT); // sleep out
SendLCDCommand(VOLCTR); // electronic volume, this is kinda contrast/brightness
SendLCDData(0xfd);//5); ff); // this might be different for individual LCDs
SendLCDData(0x01);//01); //
SendLCDCommand(PWRCTR); // power ctrl
//SendLCDData(0x00); //everything off
SendLCDData(0x0f); //everything on, no external reference resistors
_delay_ms(100);
SendLCDCommand(DISINV); // display mode
SendLCDCommand(DATCTL); // datctl
SendLCDData(0x00); //Normal display of page address, normal turn of column address, scan in column direction
SendLCDData(0x00); //SEG arranged as R,G,B
SendLCDData(0x01); // 8-gray scale mode: bytes are RRRGGGBB
//SendLCDData(0x00);
SendLCDCommand(RGBSET8); // setup color lookup table
// color table
//RED
SendLCDData(0);
SendLCDData(2);
SendLCDData(4);
SendLCDData(6);
SendLCDData(8);
SendLCDData(10);
SendLCDData(12);
SendLCDData(15);
// GREEN
SendLCDData(0);
SendLCDData(2);
SendLCDData(4);
SendLCDData(6);
SendLCDData(8);
SendLCDData(10);
SendLCDData(12);
SendLCDData(15);
//BLUE
SendLCDData(0);
SendLCDData(4);
SendLCDData(9);
SendLCDData(15);
SendLCDCommand(NOP); // nop
SendLCDCommand(PASET); // page start/end ram
SendLCDData(2); // for some reason starts at 2
SendLCDData(131);
SendLCDCommand(CASET); // column start/end ram
SendLCDData(0);
SendLCDData(131);
_delay_ms(200);
for (i = 0; i < 100; i++){ // i < 100 is good. this loop adjusts the contrast, change the number of iterations to get
SendLCDCommand(VOLUP); // desired contrast. This might be different for individual LCDs
_delay_ms(2);
}
}
here is how my main looks, complete with long delays. I've tried various permutations of these delays, as well...
Code:
int main (void) {
//...other UART, I2C, ADC, etc. init code omitted...
// wiat for LCD to "warm up"...
for (i = 0; i < 5; i++) {
_delay_ms(200);
}
//wait one second...
for (i=0;i<10;i++) {
_delay_ms(100);
}
LCDInit();
//wait one second...
for (i=0;i<10;i++) {
_delay_ms(100);
}
LCD_display_image(MICRO_IMG); //wrapper for a big RAMWR
//wait one second...
for (i=0;i<10;i++) {
_delay_ms(100);
}
SendLCDCommand(DISON);
//...the following code omitted...
}