WinAVR bug/oversight for XMEGA128A1

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

In the latest release of WinAVR, 20090313, in the file iox128a1.h, there is no prototype for CPU_t. I'm assuming this is where it should be, as in any case the typedef is called at line 2544

#define CPU    (*(CPU_t *) 0x0030)  /* CPU Registers */

So if you're trying to compile in support for the XMEGA software reset, you might take note of this, as the CPU.CPP register must be set to 0xD8 in order to "enable change of the protected register".

In any case, use this code for a software reset:

CPU_CCP=0xD8;
RST.CTRL=RST_SWRST_bm;

Also, it would seem to me that #defines to the effect of CPU_CCP_IOREG 0xD8 and CPU_CCP_SPM 0x9D might be handy.

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

Quote:

Also, it would seem to me that #defines to the effect of CPU_CCP_IOREG 0xD8 and CPU_CCP_SPM 0x9D might be handy.

If the _bm etc. "conventions are to be followed, then wouldn't it be

#define CCP_SPM_gc 0x9D // SPM Instruction Protection
#define CCP_IOREG_gc 0xD8 // IO Register Protection

?

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

Thanks for catching that so quickly. I'm still new to these conventions, and they're kind of driving me insane because they're such mouthfuls.

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

The use of CPU_t is interesting, as I'd think that the rather "fragmented" CPU area has little use in practice of using that module, but the important pieces such as SREG & SP will be hammered hard, directly on occasion but mostly indirectly (e.g., CLI).

For completeness, though, you'd think the constructor of the headers woudl run through all of Peripheral Module Address Map and make corresponding definitions.

Hmmmm--I haven't poked at XMLCONVERT lately to see if it is now happy with Xmega .XML files--it used to gag violently when trying to swallow one. It would be interesting to poke at a recent ATxmega128A1.XML to see if it has the _t type for CPU. If not, then the "fix" would go back to Atmel to update the .XML so processors of the XML give the consistent results. (Right?)

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

the _t is for the typedef of the CPU [class] structure that is created. (standard C naming convention for typedefs) I don't think that comes from the XML file, not directly anyway.

From the xmega128a1.xml file:


	
		
		
		
		
		
			
		
		
		
		
		
		
		
		
		
		
		
		
			
			
			
			
			
			
			
			
		
	
	
		
		
	


Note that the [general purpose] registers section is actually commented out.

Bottom line: report it as a bug on the AVR-libc site/list.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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

Quote:

Bottom line: report it as a bug on the AVR-libc site/list.

Perhaps certainly an inconsistency. As kubark said
Quote:

I'm still new to these conventions,
as are we all. I don't know what the "right" way is. What is the purpose/use of the _t for CPU? In the one set of Xmega chip include that I have access to, none of the modules/classes have an _t.

In some of the app note "drivers" I saw some enums that I thought would prevent you from using e.g. timer _bm on UART registers. But then I also see a series of _bm as simple #define. At this point, I'm only seeing a peephole of info at a time and it is hard to generalize. Blind men and an elephant...

[ http://en.wikipedia.org/wiki/Bli...

Quote:
The Buddha here tells the story of a king who had six blind men gathered together to examine an elephant.

"When the blind men had each felt a part of the elephant, the king went to each of them and said to each: 'Well, blind man, have you seen the elephant? Tell me, what sort of thing is an elephant

The six blind men assert the elephant is either like a pot (the blind man who felt the elephants' head), wicket basket (ear), ploughshare (tusk), plough (trunk), granary (body), pillar (foot), mortar (back), pestle (tail) or brush (tip of the tail).

The men cannot agree with one another and come to blows over the question of what an elephant really is like, and this delights the king.


]

Now, we can easily here come to figurative blows over the topic--we certainly have before. :twisted: The interesting question is who here represents the "delighted king" in the above. ;)

Lee

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

well it is a bug, if later in that header they reference the typedef which is not there.

as I said the _t suffix indicates that it is a typedef, _s would indicate that it was a struct (not typedef'd) This is a 'standard' naming convention, used in C/C++, to help distinguish between types, structures, and actual instantiated objects. xxx_t, and xxx_s do not exist yet until they have been instantiated. [it's the same reasoning for the uint8_t and uint_16t naming]

Example from the iox128a1.h file I have on my system:

/*
--------------------------------------------------------------------------
MCU - MCU
--------------------------------------------------------------------------
*/

/* MCU */
typedef struct MCU_struct
{
    register8_t DEVID0; /* Device ID byte 0 */
    register8_t DEVID1; /* Device ID byte 1 */
    register8_t DEVID2; /* Device ID byte 2 */
    register8_t REVID; /* Revision ID */
    register8_t JTAGUID; /* JTAG User ID */
    register8_t reserved_0x05;
    register8_t MCUCR; /* MCU Control */
    register8_t reserved_0x07;
    register8_t EVSYSLOCK; /* Event System Lock */
    register8_t AWEXLOCK; /* AWeX Lock */
    register8_t reserved_0x0A;
    register8_t reserved_0x0B;
} MCU_t;

and then later:

#define MCU      (*(MCU_t *) 0x0090)      /* MCU Revision */

and even later

// MCU - MCU Revision
#define MCU_DEVID0 MCU.DEVID0
#define MCU_DEVID1 MCU.DEVID1
#define MCU_DEVID2 MCU.DEVID2
#define MCU_REVID MCU.REVID
#define MCU_JTAGUID MCU.JTAGUID
#define MCU_MCUCR MCU.MCUCR
#define MCU_EVSYSLOCK MCU.EVSYSLOCK
#define MCU_AWEXLOCK MCU.AWEXLOCK

The first block defines the shape of the structure. [creates a new type called MCU_t with members....]

The second block instantiates it at a specific address.
[defines MCU to be a dereferenced pointer to a MCU_t object located at address...]

The third block simply promotes the members of the structure to global scope, by hiding the structure access.

Interestingly the names get redefined again later:

/* MCU - MCU Revision */
#define MCU_DEVID0 _SFR_MEM8(144)
#define MCU_DEVID1 _SFR_MEM8(145)
#define MCU_DEVID2 _SFR_MEM8(146)
#define MCU_REVID _SFR_MEM8(147)
#define MCU_JTAGUID _SFR_MEM8(148)
#define MCU_MCUCR _SFR_MEM8(150)
#define MCU_EVSYSLOCK _SFR_MEM8(152)
#define MCU_AWEXLOCK _SFR_MEM8(153)

I'd consider the above a bug, but may have been fixed by now, my version of AVR-GCC is relatively old.

---

I'd show the CPU one, but my version doesn't have CPU_t or any references to it, it just calls out the individual sub-registers as normal SFR's with defines.

/* CPU - CPU Registers */
#define CPU_CCP _SFR_MEM8(52)
#define CPU_RAMPD _SFR_MEM8(56)
#define CPU_RAMPX _SFR_MEM8(57)
#define CPU_RAMPY _SFR_MEM8(58)
#define CPU_RAMPZ _SFR_MEM8(59)
#define CPU_EIND _SFR_MEM8(60)
#define CPU_SPL _SFR_MEM8(61)
#define CPU_SPH _SFR_MEM8(62)
#define CPU_SREG _SFR_MEM8(63)

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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

Hi All,

This has already been reported. IIRC, the CPU_t definition should go away.