| Author |
Message |
|
|
Posted: Jan 10, 2012 - 04:44 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
I am new to GCC for AVR so my question may seem a bit trivial but is stumping me. I am using an attiny5 and I am trying to access 1 byte of sram - which according to the datasheet I can do with STS/LDS. however the compiler is not generating the correct opcodes. BTW Most of my code is in assembler which is called from C code.
I use the following code to save a byte to $40
ldi r24,0x16
sts 0x40,r24
or in my c function:
asm("ldi r24,0x16");
asm("sts 0x40,r24");
the opcode generated for sts is:
80 93 40 00 which is not correct it should be 16 bit and more like: 80 a8
I have tried using .db 0x80,0x0a8 but the compiler does not seem to understand the .db.
So my question is - how can I directly enter opcodes inline in either C or asm - that way I can work around the compiler bug? |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:18 PM |
|


Joined: Sep 06, 2007
Posts: 129
|
|
| It sounds more like an avr-as bug in binutils. Are you sure the version you are using has full support for the brain dead tinys? |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:21 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
| I am using AVR Studio 5 - which I guess uses gcc. I have selected attiny5. Everything else works. |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:25 PM |
|


Joined: Sep 06, 2007
Posts: 129
|
|
| The release notes say something like the brain dead support is "tentative ". |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:26 PM |
|


Joined: Feb 19, 2001
Posts: 26102
Location: Wisconsin USA
|
|
|
|
|
|
|
Posted: Jan 10, 2012 - 05:26 PM |
|


Joined: Sep 06, 2007
Posts: 129
|
|
| The release notes say something like the brain dead support is "tentative ". |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:32 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
| I will give 4.7 a try. If it still fails does anyone have suggestions on entering opcodes directly inline? |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:35 PM |
|


Joined: Sep 06, 2007
Posts: 129
|
|
|
|
|
|
|
Posted: Jan 10, 2012 - 05:37 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
| Tried that I get an "unknown pseudo-op: `.dw'" error. |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:41 PM |
|


Joined: Feb 19, 2001
Posts: 26102
Location: Wisconsin USA
|
|
|
Quote:
Can you .dw the opcode?
If it were me, I'd think "Hmmm--I can hand-assemble this LDS, and make a macro. And for STS, too. But only for the one address space? And how many times will I need to repeat this as I find other gotchas?"
Quote:
brain dead support is "tentative ".
Might be good enough, if the problem areas have been addressed but not yet "proven".
{there are other toolchains with support.] |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 05:52 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
Tried 4.7 it will not compile for the attiny5.
As I only access the memory in 2 places - one to write one to read. I guess it will be easiest to just insert 2 nops at each place and patch the hex file before writing to the chip.
I will look into the other tools when I get some time. |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 06:18 PM |
|

Joined: Oct 29, 2006
Posts: 2689
|
|
|
gkarlsson wrote:
I use the following code to save a byte to $40
ldi r24,0x16
sts 0x40,r24
or in my c function:
asm("ldi r24,0x16");
asm("sts 0x40,r24");
the opcode generated for sts is:
80 93 40 00 which is not correct it should be 16 bit and more like: 80 a8
I have tried using .db 0x80,0x0a8 but the compiler does not seem to understand the .db.
The compiler should not reject any inline assembly.
Does it matter whether you have a leading blank?
A workaround would seem to be *((char*)0x40)=0x16 .
Also, your inline assembly should be a single statement and should indicate that it clobbers r24.
'Tis better to let the compiler pick the register.
asm(" sts 0x40, %0" : : "r" ((char)0x16))); |
_________________ Michael Hennebry
Iluvatar is the better part of Valar.
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 06:42 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
Setting the pointer directly does work, though 12 bytes - when you only have 512 bytes to work with is expensive. You need to set up the Z register and then transfer indirectly. I could set the register up once but then I might as well use it to store my variable.
Code:
*((char*)0x40)=0x16;
40: 80 e4 ldi r24, 0x40 ; 64
42: 90 e0 ldi r25, 0x00 ; 0
44: 26 e1 ldi r18, 0x16 ; 22
46: e8 2f mov r30, r24
48: f9 2f mov r31, r25
4a: 20 83 st Z, r18
And of course the inline asm still uses the 32bit sts instead of the 16bit. |
|
|
| |
|
|
|
|
|
Posted: Jan 10, 2012 - 08:25 PM |
|


Joined: Sep 06, 2007
Posts: 129
|
|
| That code looks like -O0 which would be very unwise on a 512 byte chip in C! |
|
|
| |
|
|
|
|
|
Posted: Jan 11, 2012 - 12:03 AM |
|

Joined: Oct 29, 2006
Posts: 2689
|
|
|
WrightFlyer wrote:
That code looks like -O0 which would be very unwise on a 512 byte chip in C!
It's gross even for -O0.
I'd have expected four instructions at most. |
_________________ Michael Hennebry
Iluvatar is the better part of Valar.
|
| |
|
|
|
|
|
Posted: Jan 11, 2012 - 08:42 AM |
|

Joined: Jun 19, 2002
Posts: 983
Location: SF Bay area
|
|
|
Quote:
Tried [.dw to generate the instruction] and I get an "unknown pseudo-op: `.dw'" error.
The gnu assembler uses ".word" rather than ".dw" |
|
|
| |
|
|
|
|
|
Posted: Jan 11, 2012 - 04:32 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
|
Quote:
The gnu assembler uses ".word" rather than ".dw"
Perfect, that works.
Thank you. |
|
|
| |
|
|
|
|
|
Posted: Jan 11, 2012 - 06:08 PM |
|


Joined: Jan 23, 2004
Posts: 9878
Location: Trondheim, Norway
|
|
Your ticket was forwarded to the tools team this morning, so hopefully they'll be able to figure out a fix for the next release or so.
- Dean  |
_________________ Atmel Studio 6.1 is now released, grab it here.
Report AS6/ASF bugs here.
|
| |
|
|
|
|
|
Posted: Jan 13, 2012 - 12:10 PM |
|

Joined: Dec 08, 2004
Posts: 4719
Location: Nova Scotia, Canada
|
|
Dean,
Is this a support ticket about making it easier to enter op-codes as explicit hexadecimal constants inside an inline assembly block (addressing the thread's initial topic)? Or is it a more fundamental support ticket about the fact that the GNU tool chain doesn't know how to automatically handle the different size/encoding of the LDS and STS op-codes used in reduced-core AVRs such as the ATtiny4/5/9/10 and the ATtiny20/40?
- Luke |
|
|
| |
|
|
|
|
|
Posted: Jan 13, 2012 - 01:01 PM |
|

Joined: Dec 21, 2011
Posts: 15
Location: Jupiter, FL
|
|
|
Quote:
Is this a support ticket about making it easier to enter op-codes as explicit hexadecimal constants inside an inline assembly block (addressing the thread's initial topic)? Or is it a more fundamental support ticket about the fact that the GNU tool chain doesn't know how to automatically handle the different size/encoding of the LDS and STS op-codes used in reduced-core AVRs such as the ATtiny4/5/9/10 and the ATtiny20/40?
I guess IMHO the latter as I opened a ticket for the wrong opcodes being generated for the ATtiny 4/5/9/10. If I had RTFM I would have seen that .byte and .word are used instead of .db and .dw, and this thread would never have existed.
However I think there is a deeper problem with supporting these chips.
Take changing the clock registers we all know that we have to do this:
Code:
CCP=0xD8;
CLKMSR=0x00;
The caveat is that the second instruction needs to occur within 4 clock cycles. The problem is that each command generates 6 ASM instructions (12 bytes). There is no way in which the 2nd instruction will be executed in time. The compiler never generates an 'out' instruction, everything moved to a register memory position uses the z register and st. Don't even get me started on what happens when you define ISR routines.
I rewrote all my functions in ASM to ensure that I was getting the correct code. Someone pointed me towards CodeVisorAVR, I can say that it at least generated what I expected but had a different annoying habit of using the y register to pass parameters to functions. It would also not compile my asm file, it only wants C source files, and I was not feeling up to taking my optimized ASM and converting it back to C.
I do know however what I will be using for my next ATtiny 5 project.
Thanks to everyone for their input, I have managed to complete the project I was working on. I do hope the ATtiny 4-10 chips are supported soon by gcc. |
|
|
| |
|
|
|
|
|