[SOLVED] ATTiny2313 and HD44780 almost works...

Go To Last Post
43 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, I searched a bunch on here, but I can't find a post that deals with my exact problem or offers any more advice than that which I've already tried.

I have an HD44780 display hooked up to my ATTiny2313. I can see garbage characters when the power is hooked up to it using my USBTinyISP - including some characters that I recognize - like the number 7. I can successfully initialize it and clear it using Fleury's library. I've modified the outputs in the header thusly:

#define LCD_PORT         PORTB        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    4            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    5            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    6            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    7            /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      PORTD        /**< port for RS line         */
#define LCD_RS_PIN       4            /**< pin  for RS line         */
#define LCD_RW_PORT      LCD_RS_PORT  /**< port for RW line         */
#define LCD_RW_PIN       5            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_RS_PORT  /**< port for Enable line     */
#define LCD_E_PIN        6            /**< pin  for Enable line     */

I have the chip in line with the LCD pins starting with the /ENABLE pin, and ending with the backlight +5V in line with the V(in) on the chip. I've attached the 2313 pinout for reference. This means I'm using PB4-7 as my DATA I/O pins in 4-bit mode, PD6 for /ENABLE, PD5 for RW, and PD4 for RS.

I can even write characters to it, and it seems to respond partially logically - it draws the right number of characters on the screen, but every character I write to it is a filled-in block.

I can even do display and cursor movement correctly - right now I have a bunch of squares bouncing back and forth using the following main:

#include 
#include 
#include "lcd.h"

int main(void)
{
    /* initialize display, cursor off */
    _delay_ms(200);
    lcd_init(LCD_DISP_ON);
    _delay_ms(10);
    lcd_command(LCD_FUNCTION_4BIT_2LINES );
    //lcd_command(1<<LCD_FUNCTION_10DOTS );
    lcd_clrscr();
    lcd_puts(" _=+123450:");
    lcd_command(LCD_MOVE_DISP_RIGHT);
    lcd_command(LCD_MOVE_DISP_RIGHT);
    for(;;) {
        lcd_command(LCD_MOVE_DISP_LEFT);
        _delay_ms(1000);
        lcd_command(LCD_MOVE_DISP_RIGHT);
        _delay_ms(1000);
    }
}

I thought it might be a contrast problem, so I hooked up a pot to pin 3, and it successfully adjusts the contrast, but apparently the characters are actually blocks.

I tried 10-dot characters, but it didn't have any effect. What's the next thing I should try? Oh, and the datasheet can be found here:

https://docs.google.com/viewer?a...

Thanks in advance for any advice!

UPDATE
All it was was avr-objcopy parameters the whole time! Make sure to copy the .text and .data sections!

Attachment(s): 

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

Last Edited: Sun. Feb 27, 2011 - 06:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you disconnect the programmer after you loaded the code?

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

floresta1212 wrote:
Did you disconnect the programmer after you loaded the code?

Don

Yeah, tried that. I just tried it again to make sure, and increased the startup delay to 5 seconds to make sure the LCD fully initializes. I then unhooked all the pins from the ISP except +5V and GND, since it's my power source currently. Thanks for the idea though!

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hank,

I have never used Peter's code or even looked at it, but ... in 4 bit mode, the lcd's D4, D5, D6 and D7 data lines on its pins 11, 12, 13 and 14 respectively are used. I don't see anything defining D4,D5,D6 or D7 above.

Cheers,

Ross

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought that I should try your program on a Tiny2313.

My LCD is actually wired: D4..7=PB4..7, E=PB3, RS=PB2, RW=PB2.

The Fleury example code works fine.
Your test program works fine too.

I suggest that you check your wiring. Mind you, if the 'move' works, you must have initialised.

I have destroyed several LCDs over the years. I presume because I have left them wired on a dev board while running inappropriate code. (e.g. RW=high, E=high, DDRx4..7=high)

Can you test your LCD on another board?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On my opinion the Fleury's library looks to overwhelmed.
I use this tiny and easy library:

http://www.avrfreaks.net/index.p...

Peter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
Hank,

I have never used Peter's code or even looked at it, but ... in 4 bit mode, the lcd's D4, D5, D6 and D7 data lines on its pins 11, 12, 13 and 14 respectively are used. I don't see anything defining D4,D5,D6 or D7 above.

Cheers,

Ross

That just depends on how you wire the board. I have the LCD pins 11, 12, 13 and 14 lined up with PB4, PB5, PB6 and PB7 respectively on the breadboard. Cheers!

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I thought that I should try your program on a Tiny2313.

My LCD is actually wired: D4..7=PB4..7, E=PB3, RS=PB2, RW=PB2.

The Fleury example code works fine.
Your test program works fine too.

I suggest that you check your wiring. Mind you, if the 'move' works, you must have initialised.

I have destroyed several LCDs over the years. I presume because I have left them wired on a dev board while running inappropriate code. (e.g. RW=high, E=high, DDRx4..7=high)

Can you test your LCD on another board?

David.

OK this may be a case of cheap eBay chinese LCD just not working in general (or not working like it should). I'll try another one I have around - just have to solder some header to it today. Thanks for trying the code - I'm glad it worked for someone at least!

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figured I'd post a quick picture of my wiring, since as far as I can tell it's air-tight.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK - it's "working" now, but I changed the code from this:

lcd_init(LCD_DISP_ON);
lcd_command(LCD_FUNCTION_4BIT_2LINES );
lcd_clrscr();
lcd_puts("OMG");
for(;;);

To this:

lcd_init(LCD_DISP_ON);
lcd_command(LCD_FUNCTION_4BIT_2LINES );
lcd_clrscr();
lcd_putc('O');
lcd_putc('M');
lcd_putc('G');
for(;;);

Now, this is bizarre. lcd_puts just puts blocks on the screen, while lcd_putc works exactly correctly! This must be an incompatibility with Fleury's library and my specific make/model LCD. Thanks for the help - maybe I'll patch lcd_puts and contribute it back to Fleury!

Attachment(s): 

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But doesn't lcd_puts() just call lcd_putc for each character in the string?

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK after trying to fix the code, I'm really confused - I think we're going to have to debug the generated assembly - it's that bad. This is essentially what the Fleury lcd_puts function does, and it gives the same terrible blocky output even if I do it inline:

const char * omg = "OMG";
char * j = (char *)omg;
while(*j) { lcd_putc(*j); j++; }
for(;;);

Yet, this works perfectly:

char * omg = "OMG";
int j = 0;
while(j < 3) lcd_putc(omg[j++]);
for(;;);

I'm new to all this AVR stuff, but I've been around the block with C, Intel asm and MIPS asm. It seems like it's an issue with dereferencing vs. array indexing into char*'s. What's the best way to extract the assembly for this? Cheers.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ya got RS defined twice instead of E. That a typo?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One silly question:
Have you #defined 'XTAL' correctly in "lcd.h"?

I assume you are running at 8MHz RC.
The virgin "lcd.h" assumes 4MHz XTAL.

You realise that lcd.c uses XTAL, _delay_ms() uses F_CPU.

All the same, your lcd_init() seems to work ok. That function is the most fussy about timing. Fleury uses the BUSY read, so lcd_put[cs] does not care about timing.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't understand why you allocate a char* in the first place. Why not

const char omg[] = "OMG";
char * j = omg;
while(*j) { lcd_putc(*j); j++; }
for(;;); 

AVR studio can step through in assembly view, debugging with simulator1 (or the hardware, if thats your wont). Don't know if Hapsim would simulate the LCD output.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bobgardner wrote:
Ya got RS defined twice instead of E. That a typo?

Do you mean this:

#define LCD_RS_PORT      PORTD
#define LCD_RS_PIN       4    
#define LCD_RW_PORT      LCD_RS_PORT 
#define LCD_RW_PIN       5          
#define LCD_E_PORT       LCD_RS_PORT 
#define LCD_E_PIN        6       

That just means PORTD 4, 5, and 6, which is the way it's hooked up on the board. Cheers :)

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
One silly question:
Have you #defined 'XTAL' correctly in "lcd.h"?
...
I assume you are running at 8MHz RC.

I'm compiling with F_CPU defined to 4Mhz. XTAL is indeed set to 4Mhz in lcd.h. That should work, right? Also, I turned off clock division in the fuses.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dak664 wrote:
I don't understand why you allocate a char* in the first place. Why not
const char omg[] = "OMG";
char * j = omg;
while(*j) { lcd_putc(*j); j++; }
for(;;); 

AVR studio can step through in assembly view, debugging with simulator1 (or the hardware, if thats your wont). Don't know if Hapsim would simulate the LCD output.

Um, that's not any different in standard C - is it different in the AVR context? For instance, this:

char * abc = "def";

is the same as this:

char abc[] = "def";

If that's different in an AVR context, that would be really odd and require some justification. This should all be happening on the stack - no dynamic memory is being used.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Technically there is a difference, but in your usage it doesn't matter.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK - I dumped assembly for a version that works and a version that doesn't and attached them. It looks like the working one unrolled the loop and the broken one uses a branch not equal. I'm not sure why loop unrolling should effect the functionality of the program...

Anyone with a deep knowledge of AVR asm want to help? :)

Attachment(s): 

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am no c expert, but

const char * omg = "OMG";

looks like it is allocating a pointer to a string, leaving the string to be allocated wherever the compiler thinks best. What would sizeof(omg) be, 2 or 4? What would get allocated where with

const char * omg PROGMEM = "OMG";

or does that even compile?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dak664 wrote:
I am no c expert, but
const char * omg = "OMG";

looks like it is allocating a pointer to a string, leaving the string to be allocated wherever the compiler thinks best.

Generally, when you assign a pointer on the stack to a string constant like that, the compiler will just put it on the stack. I suppose it would be valid to put it in global memory too and keep just the pointer on the stack, but I don't think it could ever go out to the heap and allocate. Pointers can be tricky :P.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well one thing that is certain, it won't reference the string from program flash. There is a program size increase in putting the string on the stack when it could be directly referenced, which is partially compensated by not having the string permanently allocated to the preinitialized .data RAM segment. But in AVR you can avoid either by using a pointer to the string in program flash. You can always copy the string to RAM for routines that require a RAM pointer.

What would writing to *(char *)omg do when it is defined as const char * omg = "OMG"? I suspect stack overwrites, whereas for const char omg[]="OMG" an OS with memory management would give a more informative segment fault. AVR would cheerfully do an overwrite :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't see a crystal on your breadboard ... so depending upon your fuse settings, you are either running at 1MHz or 8MHz.

Cheers,

Ross (happy to be corrected)

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the 4-bit mode the LCD controller doesn't use the lower four bits and supposedly ignores them but most data sheets don't mention what you should do with them. I seem to remember reading somewhere that they should be grounded and somewhere else that they are internally pulled high. I typically leave them open and have had no problems.

In your case they are connected to the lower four bits of Port B so you might check and see what, if anything, the various programs you are using are doing with them. David successfully used your code but he probably used a different physical setup and those four bits may have been dealt with differently.

By the way, your breadboard is impossibly neat. Maybe that's the problem.

Don

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then it's not just me who suspected breadboard photoshopping :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
I don't see a crystal on your breadboard ... so depending upon your fuse settings, you are either running at 1MHz or 8MHz.

Cheers,

Ross (happy to be corrected)


This brings up an interesting question - I am using the internal crystal, and I've disabled the clock divider, so it should be native 8Mhz. But I'm compiling with F_CPU defined to 4Mhz, so I'm assuming that's the speed that the chip runs at. Am I wrong? Thanks Ross.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
I don't see a crystal on your breadboard ... so depending upon your fuse settings, you are either running at 1MHz or 8MHz.

Cheers,

Ross (happy to be corrected)

The tiny2313 can run at 4mhz internal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

floresta1212 wrote:
In the 4-bit mode the LCD controller doesn't use the lower four bits and supposedly ignores them but most data sheets don't mention what you should do with them. I seem to remember reading somewhere that they should be grounded and somewhere else that they are internally pulled high. I typically leave them open and have had no problems...

Well, it seems to work with lcd_putc, so I'm pretty much going to blame either my coding style or the avr-gcc toolchain at this point. Something is fishy with certain types of loops around lcd_putc not working, but other types of loops working perfectly...
Quote:

By the way, your breadboard is impossibly neat. Maybe that's the problem.

Don


Ha! Hopefully cleanliness is AVR godliness.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dak664 wrote:
What would get allocated where with
const char * omg PROGMEM = "OMG";

or does that even compile?

You inspired me to read about program memory here, and I ended up trying this:

lcd_puts_p(PSTR("abc"));

Which worked perfectly! I'm going to just use strings in program memory when writing to the LCD for now, but I am still curious on why it didn't work normally...

Thanks, Dak!

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dksmall wrote:
valusoft wrote:
I don't see a crystal on your breadboard ... so depending upon your fuse settings, you are either running at 1MHz or 8MHz.

Cheers,

Ross (happy to be corrected)

The tiny2313 can run at 4mhz internal.

... and I am very happy to be corrected ... and better informed now.

Cheers,

Ross

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hardwarehank wrote:
david.prentice wrote:
One silly question:
Have you #defined 'XTAL' correctly in "lcd.h"?
...
I assume you are running at 8MHz RC.

I'm compiling with F_CPU defined to 4Mhz. XTAL is indeed set to 4Mhz in lcd.h. That should work, right? Also, I turned off clock division in the fuses.

The important thing is be honest.

The ATtiny2313 will run at 8MHz if you have removed CKDIV8 and otherwise have default fuses. So you should be honest: say F_CPU is 8MHx, say XTAL is 8MHz.

My tiny was running at 8MHz. I lied and said 4MHz, and my LCD still worked ok. But that would be more luck than judgement. Bear in mind that this makes all the initialisation timing wrong.

Your experience seems to imply you are sending characters too fast. But the Fleury code checks the BUSY flag. So this should never be a problem.

Re-install the Fleury library. I would guess you have edited "lcd.c" somewhere.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hardwarehank wrote:
But I'm compiling with F_CPU defined to 4Mhz, so I'm assuming that's the speed that the chip runs at. Am I wrong? Thanks Ross.

Yes, you are wrong.
F_CPU tells the compiler, which frequency was used.
Its your part to tell the right value.
And its your part to apply this value (fuse setting, prescaler setting or external source).
No way for the compiler to set the value or to see, if you lie.

E.g. you connect a 10MHz crystal, set the fuses accordingly and set the prescaler to 2.
Then you must tell the compiler: F_CPU = 5MHz.

Peter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all - I will be correcting my F_CPU and XTAL settings.

I've made a few changes to the Fleury library, including making custom character generation a lot easier than it is in the test_lcd.c file. I added a few Makefiles and some plug-and-play compile-time custom character definitions. I've also added it to github to allow people to fork it, keep track of the forks, merge changes, etc. etc. I've named it lcdiesel, and it can be found here:

https://github.com/hank/lcdiesel

It would be neat to add a bunch more custom characters if anyone knows of a good repository of them. Different languages, for example (you could have blocks of PROGMEM #defines for those).

The LCD is working perfectly using PROGMEM, but puts still doesn't work. I don't really care about that at the moment, though since PROGMEM is more efficient, and I don't need to generate character strings for printing on the fly in RAM at this point. Maybe the problems will go away when I set these clock speed correctly :).

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK - just tried setting XTAL and F_CPU to 8Mhz, which is what my fuses are set to, and I still get the nasty block characters using regular character strings in lcd_puts.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I've made a few changes to the Fleury library, including making custom character generation a lot easier than it is in the test_lcd.c file.

At least I suppose that this little revelation is preferable to the magic word Proteus!

People put effort into helping others, only to find that the goalposts were in a different place altogether.

It is totally useless to have some fancy characters if you cannot do a basic lcd_puts() properly.

Please compile your test program with honest values of F_CPU and XTAL and the genuine unchanged "lcd.c".

David.

Edit. From your github site: You are not incrementing the char*

// WARNING: Doesn't work on some LCDs
// Reason: unknown
// Workaround: use lcd_putc/lcd_puts_P
void lcd_puts(const char *s)
/* print string on lcd (no auto linefeed) */
{
    char c;
    while((c = *s)) {
        lcd_putc(c);
    }

}/* lcd_puts */

I have diff'ed your file and cannot see any other significant change. But quite honestly, that is your job not ours.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Please compile your test program with honest values of F_CPU and XTAL and the genuine unchanged "lcd.c".

Did that. lcd_puts still doesn't work.

avr-gcc -c -Os -I.. -DF_CPU=8000000 -DXTAL=8000000 -mmcu=attiny2313a -I../include -o lcd.o lcd.c

And I changed the headers to respect outside defines of XTAL.
Doing and lcd_puts on "Test" produces 6 0xFF characters on the screen. Doing an lcd_puts_p(PSTR("Test")) works in the same file on the next line.

For you, I went back and tried what I originally tried - Fleury's library and Fleury's test_lcd.c. I set XTAL in the file to 8Mhz and F_CPU to 8Mhz. I set the pins. That's the only changes I made. I compiled thusly:

avr-gcc -mmcu=attiny2313a -Os -DF_CPU=8000000 test_lcd.c -o test_lcd.o lcd.c
avr-objcopy -j .text -O ihex test_lcd.o test_lcd.hex
sudo avrdude -p t2313 -c usbtiny -e -U flash:w:test_lcd.hex 

It ran! And it ... surprise! ... doesn't work! I have a whole bunch of 0xFF characters and a single colon on the screen (that colon used lcd_putc instead of lcd_puts, which brings us back to the original weirdness).

It is totally useless to have some fancy characters if you cannot do a basic lcd_puts() properly.

Well, I've been trying to fix that, and I'm going to change the code for that function back to the original Fleury version now that you pointed out that I screwed up the incrementing.

I've been able to work around lcd_puts issues with program memory, so I started learning more about custom characters. In retrospect, maybe you're right and I should have just continued to be hung up on lcd_puts. I'll remember that next time.

Quote:
I have diff'ed your file and cannot see any other significant change. But quite honestly, that is your job not ours.

Well, I thank you for your effort and post. I'm sorry to have inconvenienced you. Feel free to ignore this thread from now on...

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry. I must have been a bit grumpy yesterday!

I see that you have selected ATtiny2313A rather than the regular ATtiny2313. So I compiled the same. I had to call it tiny2313 when I used avrdude.

AFIK, the 2313A should be identical to the 2313. However the A header files are vastly different. And avr-gcc generates two completely different HEX files. OTOH, my 2313A hex works fine too.

I can only assume that you are using a different avr-gcc to me. (I am using 20100110)

I am always suspicious of 'new releases'. They often include 'features'.

So please can you try calling your chip a regular ATtiny2313.

I am intrigued by your problem. Unfortunately I cannot reproduce it for myself. It appears that you are calling lcd_putc() too fast. Your lcd_puts_P() function is marginally slower than lcd_puts() at calling lcd_putc(). As I said earlier, the BUSY test should ensure the timing.

I am moving house on Wednesday, so I will be dismantling my study tomorrow. It would be nice if you get it cracked this evening!

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Sorry. I must have been a bit grumpy yesterday!

Don't worry - we all have our days, and I'm sure this board has no shortage of very stupid questions from people unwilling to try and solve their own problems :P.

I fixed the bug - it was AMAZINGLY simple, and extremely hard for a novice (like me) to debug. Here's my original avr-objcopy:

avr-objcopy -j .text -O ihex test_lcd.o test_lcd.hex

And the new:

avr-objcopy -j .text -j .data -O ihex test_lcd.o test_lcd.hex

Apparently, if you store the string in PROGMEM, it goes in the .text section, so all that was working fine. If you don't, and it's to be loaded into RAM at init, it goes in the .data section, which I was omitting from my objcopy. It all makes sense now, and I wish I would have checked something like that earlier.

I was tipped to this conclusion because in another program, my designated initializers for my struct weren't working - which apparently also has to do with the .data section. See this thread. The following was revealed:

clawson wrote:
Surely this is the classic avr-objcopy error where the .data initialisers are not copied into flash? Are you using -j's or -R's on the objcopy?

This fixed both bugs. Thanks all who helped me in this thread, and clawson for pointing out my idiotic error.

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hardwarehank wrote:

avr-objcopy -j .text -j .data -O ihex test_lcd.o test_lcd.hex

Whats the reason to use the -j switch at all ?
I use:

avr-objcopy -O ihex test_lcd.o test_lcd.hex

Peter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, Peter. But you write your makefiles from a template instead of making it up as you go along.

And of course if you use Windows you can Simulate or Debug quite painlessly.

One day there will be a Linux equivalent to Studio. Mind you, if I was determined to use Linux exclusively, I would buy Rowley Crossworks immediately.

I presume that Eclipse could work. I will just wait until someone can point me to an Eclipse IDE that actually does Debug seamlessly etc.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Whats the reason to use the -j switch at all ?

Because you don't want .eeprom, .fuse and .lock going into the .hex

Mfile uses -R rather than -j to say what to throw away rather than what to include. That is:

# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
	@echo
	@echo $(MSG_FLASH) $@
	$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock $< $@

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Mfile uses -R rather than -j to say what to throw away rather than what to include.

I will start doing that instead of the 2 -js. Thanks for the discussion!

Mistakes I've made

  • Not copying the .data section to hex using avr-objcopy
  • Overflowing RAM in an ATtiny2313 (128 Bytes)