Porting LUFA to Codevision

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

Hello,

I am trying to get LUFA to work under Codevision.

One of the problems I run into is, that a number of used functions are actually not part of LUFA. I think they are probably part of GCC.

These are a few of them:

eeprom_read_byte
eeprom_write_byte
pgm_read_word
void pgm_write_word
boot_page_write
boot_page_fill

Are these indeed from WinAVR libraries? Can I get the source code somewhere without having to install WinAVR?

Edit: one more question:

Where is BOOT_START_ADDR defined? How can this be fixed? Doesn't it depend on the fuse bit setting?

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

Quote:
I think they are probably part of GCC.
To be precise, they are part of avr-gcc.
Quote:
Can I get the source code somewhere without having to install WinAVR?
You don't need the source of them. CodeVision has built in functionality for reading and writing both flash (the pgm_ functions) and eeprom. Simply define the variables with the proper qualifier, then access them as you would any variable.

I'm not sure about the boot_page ones though, I have never seen them.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:

Quote:
You don't need the source of them. CodeVision has built in functionality for reading and writing both flash (the pgm_ functions) and eeprom. Simply define the variables with the proper qualifier, then access them as you would any variable.

I'm not sure about the boot_page ones though, I have never seen them.

I know it is easy to access EEPROM with CV. I don't think that there is a similar mechanism for writing FLASH.

Still, of course there are may more of these functions, and it is not obvious for all of them how exactly they carry out their tasks. Therefore I think it could be useful to look into them for inspiration.

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

Dean uses quite a lot of avr-gcc 'features' in LUFA.

If you are just down to needing:

Quote:
eeprom_read_byte
eeprom_write_byte
pgm_read_word
void pgm_write_word
boot_page_write
boot_page_fill

then I can send you the relevant CodeVision macros and functions.

Things like BOOT_START_ADDR are either known at Compile time, or you can use boot_fuse_read() at Run time.

Shout if you want help. IMHO, it is too much like hard work. Since CV can't be driven by Make, it would be a nightmare to maintain.

However if we ever get command line compilation, I would go for it.

David.

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

Well one of my drives to use Codevision is, that I like to view and edit project settings in a user friendly way. In my opinion editing makefiles does not qualify.
Still it would have been handy if the settings were eventually stored in Makefiles instead of CV-specific project files.

For me the choice is either to port my existing software to AVR-GCC, or to port LUFA to CV. As I prefer CV, will try this first.

I think the safest way to handle BOOT_START_ADDR is, to read the fuse bits, but as the syntax very much implies that it is a constant, it might be linked to the fuse bits from the IDE.

I will get back to you if I have the complete list of missing functions.

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

Quote:

Well one of my drives to use Codevision is, that I like to view and edit project settings in a user friendly way. In my opinion editing makefiles does not qualify.
Still it would have been handy if the settings were eventually stored in Makefiles instead of CV-specific project files.

That goal could probably be more easily attained using an IDE as a front end to GCC. Maybe AS4/5/6 or Eclipse or Netbeans or Code::Blocks or similar.

My prediction for likelihood of success with porting LUFA to a non GCC environment is about 5% but major kudos to you if you achieve it! I think you are going to have to have a serious dialogue with Dean to get you over the "humps" in your journey.

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

Quote:

I think the safest way to handle BOOT_START_ADDR is, to read the fuse bits, but as the syntax very much implies that it is a constant, it might be linked to the fuse bits from the IDE.

It's in the makefile, and is user-settable - the reason it's there is it is then used by the AVR-GCC linker to relocate the entire bootloader application into the bootloader section of the microcontroller.

I'd love to make LUFA cross-compiler friendly, but making it interrupt driven higher on my list of priorities. Perhaps I can do both at once.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

LUFA on CV sounds nice!

Good speed....:)

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

Koshchi wrote:
Quote:
I think they are probably part of GCC.
To be precise, they are part of avr-gcc.
No. They are part of AVR-Libc. See respective headers like avr/eeprom.h, avr/pgmspace.h, etc. see http://svn.savannah.nongnu.org/v...

avr-gcc dependent parts are only non-standard-C extentions (after macro resulution, of course), namely __attribute__, __asm__ and __builtin functions.

avrfreaks does not support Opera. Profile inactive.

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

clawson wrote:
Quote:

My prediction for likelihood of success with porting LUFA to a non GCC environment is about 5% but major kudos to you if you achieve it! I think you are going to have to have a serious dialogue with Dean to get you over the "humps" in your journey.

Any specific humps you're thinking of?

At the moment I found:

- Dependancy to external functions
- preprocessor directives not understood by Codevision
- Macros (like BOOT_START_ADDR) that need to be resolved

For the rest of it I guess (not bothered by any knowledge) that it is mainly search and replace.

Anyway, I think there is no easy way out. Either I port my existing software to AVR-GCC (and learn to use AVR-GCC), or I port LUFA, or I write my own stack.
None of them are a walk in the park.

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

How far have you got?

Do you want any help?

It is very easy to port the Atmel USB app note code to CodeVision. ( or ImageCraft, Rowley, ... )
LUFA requires quite a lot more work.

Yes. It would be nice to have LUFA as a Compiler-independent project. However it would be preferable to do it with a "compiler.h" set of macros rather than hand edits.

David.

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

Ok, if I make the dummy definitions as shown below I get it compiled without errors.

So next action point would be to define the defines and implement the functions.
If you could help me to the AVR-Libc source code of these functions that would be very helpful.

Also, GCC has a mechanism (void) for telling the compiler that variable is used. CV does not understand this, so I removed this. of course now I get the warnings that the variables are unused. Is there a way to make these warnings disappear?

uint8 eeprom_read_byte(uint8* iReadAddress);
void eeprom_write_byte(uint8* iWriteAddress, uint8 iWriteByte);

uint16 pgm_read_word(uint16* iReadAddress);
void pgm_write_word(uint16* iWriteAddress, uint16 iWriteWord);
uint8 pgm_read_byte(uint8 *iAddress);

void boot_page_write(uint16* iWriteAddress);
void boot_page_fill(uint16* iWriteAddress, uint8 iWriteByte);
void boot_page_erase(uint16* iWriteAddress);

void boot_spm_busy_wait();
void boot_rww_enable();

#define GET_LOCK_BITS            1
#define GET_LOW_FUSE_BITS        2
#define GET_HIGH_FUSE_BITS       3
#define GET_EXTENDED_FUSE_BITS   4

uint8 boot_lock_fuse_bits_get(uint8 iTypeOfBits);
void boot_lock_bits_set(uint8 iValue);


void wdt_enable(uint8 iArgs);
void 	wdt_disable();
void wdt_reset();

#define WDTO_1S      1


void clock_prescale_set(uint8 iArg);

#define clock_div_1     1


#define sei()  EnableInterrupts()
#define cli()  DisableInterrupts()



//////////////////////////////////////////////////////////////////////////////////////
//

#define REGCR  (*(unsigned char *) 0x60)
#define REGDIS  (*(unsigned char *) 0x60)
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So next action point would be to define the defines and implement the functions.
If you could help me to the AVR-Libc source code of these functions that would be very helpful.

http://svn.savannah.nongnu.org/v...

Quote:

Is there a way to make these warnings disappear?

Sledgehammer to crack a nut: make them "volatile".

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

portab macros:

#include 

#include 
#include 
#define DELAY_US(us)		delay_us(us)
#define DELAY_MS(ms)		delay_ms(ms)
#define _BV(x)			(1<<(x))
#define PGM_P  			char flash *
#define PGM_UC_P  		unsigned char flash *
#define PROGMEM			flash
#define PSTR(x)			x
#define pgm_read_byte(x)	(*((uint8_t flash *)(x)))
#define pgm_read_word(x)	(*((uint16_t flash *)(x)))
#define EEMEM			eeprom
#define eeprom_read_byte(ads)	(*((uint8_t eeprom *)(ads)))
#define eeprom_write_byte(ads,x) (*((uint8_t eeprom *)(ads))) = x
#define eeprom_write_word(ads,x) (*((uint16_t eeprom *)(ads))) = x
#define WDT_RESET()     	#asm("wdr")
#define SLEEP()			#asm("sleep")
#define NOP()			#asm("nop")
#define SEI()			#asm("sei")
#define CLI()			#asm("cli")

spm_boot.h

#ifndef SPM_BOOT_H
#define SPM_BOOT_H

#include 

void boot_spm_busy_wait(void);
void boot_page_fill(uint16_t ads, uint16_t val);
void boot_page_erase(uint16_t page);
void boot_page_write(uint16_t page);
void boot_rww_enable(void);
void boot_lock_bits_set(uint8_t val);
uint8_t boot_lock_fuse_bits_get(uint16_t address);
uint8_t boot_signature_byte_get(uint16_t address);		// n/a with many AVR's

#endif

spm_boot.c

#include "spm_boot.h"
#include 

#if defined(_CHIP_ATMEGA168_)||defined(_CHIP_ATMEGA328P_)
#define SPMCR SPMCSR
#define SPMEN SELFPRGEN
#endif
#if defined(_CHIP_ATTINY2313_) || defined(_CHIP_ATTINY4313_) || defined(_CHIP_AT90USB1287_)||defined(_CHIP_ATTINY85_)||defined(_CHIP_ATMEGA1284P_)
#define SPMCR SPMCSR
#endif

#pragma warn-

#if defined(_CHIP_ATMEGA16_)||defined(_CHIP_ATMEGA164_)||defined(_CHIP_ATMEGA168_)
#asm(".equ SPM_LOCATION = 0x2000")
#elif defined(_CHIP_ATMEGA32_)||defined(_CHIP_ATMEGA324PA_)||defined(_CHIP_ATMEGA328P_)
#asm(".equ SPM_LOCATION = 0x4000")
#elif defined(_CHIP_ATMEGA644_)
#asm(".equ SPM_LOCATION = 0x8000")
#elif defined(_CHIP_ATMEGA128_)||defined(_CHIP_ATMEGA1284P_)||defined(_CHIP_AT90USB1287_)
#asm(".equ SPM_LOCATION = 0x10000")
#endif

#if defined(_CHIP_ATMEGA128_)
#asm
        .equ SPMEN = 0
;		.equ SPMCR = 0x68
		.equ SPMCRAddr = 0x68
#endasm
#else
#asm
        .equ SPMEN = 0
;		.equ SPMCR = 0x37
		.equ SPMCRAddr = 0x57
#endasm
#endif

void boot_spm_busy_wait(void)
{
#asm
; we can force the three instructions into the boot section,  and still have an app.
; however we get a massive HEX file with the gap zero-padded.
		.set oldpc = PC
                .org SPM_LOCATION-4    // make sure we are in boot section   
do_spm:
                sts SPMCRAddr, r26;     //move spmcrval to SPM control register
                spm;            	//store program memory
				ret
                .org oldpc
#endasm
		while (SPMCR & (1<<SPMEN)) ;
/*
#asm
do_spm_wait:
                lds r30, SPMCRAddr
                sbrc r30, SPMEN
                rjmp do_spm_wait
#endasm
*/
}

void boot_page_fill(uint16_t ads, uint16_t val)
{
#asm
                ldd r31, y+3
                ldd r30, y+2 ;   //move CurrentAddress to Z pointer   
                ldd r1, y+1;    //move Pagedata MSB reg 1
                ldd r0, y+0;    //move Pagedata LSB reg 1  
                ldi r26, 1;
                call do_spm
#endasm
                boot_spm_busy_wait();
}

void boot_page_erase(uint16_t page)
{
#asm
                ldd r1, y+1;    //move Pagedata MSB reg 1
                ldd r0, y+0;    //move Pagedata LSB reg 1  
                ldi r26, 3;
                call do_spm
#endasm
                boot_spm_busy_wait();
}

void boot_page_write(uint16_t page)
{
#asm
                ldd r1, y+1;    //move Pagedata MSB reg 1
                ldd r0, y+0;    //move Pagedata LSB reg 1  
                ldi r26, 5;
                call do_spm
#endasm
                boot_spm_busy_wait();
}

void boot_rww_enable(void)
{
#asm
                ldi r26, 0x11;
                call do_spm
#endasm
                boot_spm_busy_wait();
}

void boot_lock_bits_set(uint8_t val)
{
#asm
                ldd r0, y+0;    //move Pagedata LSB reg 1  
                ldi r26, 9;
                call do_spm
#endasm
                boot_spm_busy_wait();
}

uint8_t boot_lock_fuse_bits_get(uint16_t address)
{
#asm
                ldd r31, y+1;    //move Pagedata MSB reg 1
                ldd r30, y+0;    //move Pagedata LSB reg 1  
                ldi r26, 9;
                sts SPMCRAddr, r26;     //move spmcrval to SPM control register
                lpm r30, z;            	//store program memory
#endasm
}

uint8_t boot_signature_byte_get(uint16_t address)
{
#asm
                ldd r31, y+1;    //move Pagedata MSB reg 1
                ldd r30, y+0;    //move Pagedata LSB reg 1  
                ldi r26, 33;
                sts SPMCRAddr, r26;     //move spmcrval to SPM control register
                lpm r30, z;            	//store program memory
#endasm
}

I think you can work out void clock_prescale_set(uint8 iArg); for yourself.
Hint. See what the Wizard does.

David.

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

Sledgehammer to crack a nut 2: make CVAVR not report unused variables

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

Quote:

Also, GCC has a mechanism (void) for telling the compiler that variable is used. CV does not understand this, so I removed this. of course now I get the warnings that the variables are unused. Is there a way to make these warnings disappear?


Use the mechanism provided in CV?

Quote:
The #pragma keep+ directive forces a function, global variable or global constant to be linked even if it wasn’t used anywhere in the program.

I'd have to run a test, though, to see if it suppresses the warning as well as "keeps" the allocation for the variable.

(there formerly was "#pragma used+" but IIRC it is deprecated and I don't know whether it has any effect)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

VHPonline wrote:

Also, GCC has a mechanism (void) for telling the compiler that variable is used. CV does not understand this, so I removed this. of course now I get the warnings that the variables are unused. Is there a way to make these warnings disappear?

You can go to Project|Configure|C Compiler|Messages and disable the options:
local variable was declared but not referenced

and

global variable/constant was declared but not referenced.

Or you can do like this:


int i;

void main(void)
{
#pragma warn-
(void) i;
#pragma warn+
}

The #pragma warn- disables the warning about expression without effect.

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

david.prentice wrote:
portab macros:
code...

I think you can work out void clock_prescale_set(uint8 iArg); for yourself.
Hint. See what the Wizard does.

David.

Many thanks.

Is spm_boot.c something you made yourself earlier? I noticed that it provides definitions of about all FLASH/EEPROM read/write except for pgm_write_word()

Is there a logic in the choice SPMCR and SPMCSR? My testpart is Mega32U4, which is not in the list.
For now I just made the define myself.

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

hpinfotech wrote:


int i;

void main(void)
{
#pragma warn-
(void) i;
#pragma warn+
}

The #pragma warn- disables the warning about expression without effect.

Yes, I prefer this. Usually it is useful to warn for this, only not here.

Thanks

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

Quote:
Is spm_boot.c something you made yourself earlier? I noticed that it provides definitions of about all FLASH/EEPROM read/write except for pgm_write_word()

Is there a logic in the choice SPMCR and SPMCSR? My testpart is Mega32U4, which is not in the list.
For now I just made the define myself.


I can't remember whether I adapted the code from Pavel. (In which case, all credit to Pavel, and I hope it was ok to publish)
Or just wrote the functions myself.

I needed the functions for bootloader or paged_eeprom emulation or something. It should be pretty simple to add pgm_write_word().

The SPMCR thing is purely the names used by the chips at the time. e.g. t85, t2313, m328p, m32 ...

Conditional code can be a sod.

How far have you got with the port?
Is it doable? I am interested if we can make it completely compiler independent.

David.

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

Well, I made it compile without errors now. I am not yet ready for testing as I also need to download it to the Mattairtech demo board. This has the LUFA CDC bootloader preinstalled. Of course AVRDuDe does not support the Mega32U4 and communication with AVROSP fails completely. So my next step would be to find the AVROSP source code and start debugging what goes wrong.
This sounds easier than it is. I found plenty of links for AVROSP the executable, but not for the source code.

My first intention was to make LUFA work in my context, so I don't think it is very portable at the moment.

There are few issues I would like to solve differently. There is a number of occasions in which LUFA uses #ifdef __ATMEGAxxx__ Of course this only works of all these files are kept up to date. Personally I prefer an approach where these can be resolved externally. I mean: let the user #define MEM_TOP 0xFFFF etc. This means that each project requires a header with such define specifically for the used part, but I think this is better than the situation that a part is either supported, or it isn't.

The assembler part is another horror. Assembler code will never be portable. As you see there are even differences within the AVR8 family for <=64K and larger. Also not all registers have the same name (eg. SPMCR, SPMCSR).

I think the best approach is the pragmatical approach. Try to split the code in a portable part and a part that will have to be solved by the user. As long as the users knows what needs to be done, this is a workable situation.

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

My approach is to replace common 'inconsistencies' with macros. e.g. SEI(), DELAY_MS()
Then resolve 99.9% with a "compiler.h". e.g. those portab macros. They actually come from a larger "portab_mcu.h" file.

Of course there will always be a small amount of ASM source code. e.g. you have "spm_boot.c" or "spm_boot.S" files.

My portability macros also contain IS_MEGA() which can resolve #if IS_MEGA(32U4) for at least five different compilers.

If you reckon the port is doable, we can see if compatibility is achievable too. Only then can I think of asking Dean about using SEI(), IS_MEGA() etc. (and hope he is not too grumpy)

David.

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

Well basically it was pretty portable. Of course first I made the mistake of deleting all GNU compiler keywords that CV does not understand. In hindsight it was so much easier to just #define them away. Who knows I might even start over one day.

Though we have to keep in mind that it compiles now. I don't know yet if it will actually run.

Anybody knows where to find the source code for AVROSP?

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

AVROSP is in an app note AVR911.

You should be able to drive it with avrdude -c avr911

Or with some horrible PC program.
I am not very good with PC Windows stuff.

David.

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

david.prentice wrote:
AVROSP is in an app note AVR911.

David.

Yes, I know. AVR911 also mentions that it is open source and modular, and that source code is available. This is the source I am looking for.

As Windows supports 100% of the software I need, and any other platform at most 90%, I prefer Windows.
Also I like my software to know what goes on during programming. This is difficult with commandline programmers. I prefer to call a function "Program_flash()" and let a callback function keep me informed about the progress.

Also in this particular case I want to know why it says that the programmer is not giving the desired responses. The text window doesn't give any clue as to what might be the problem.

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

As I said, AVR911 has the source code. Download both the PDF and the ZIP from Atmel.

Shout if you can't find at Atmel. I can email both to you.

I also like to know what is going on. I am a lot happier with something like avrdude that will tell me.

Other people like GUIs that generally report nothing.

David.

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

Ah, found it now. I just didn't recognize the CD icon as another downloadable next to the PDF icon.