XMega can access data memory above 64KB, up to 16MB - Page 1
Forum section: electronics / general

author: happylex
author_rank: Contributor
timestamp: March 10, 2014, 10:39:20 pm
content: In order to access program memory or data memory above 64KB, the address pointer must be larger than 16 bits. This isdone by concatenating one register to one of the X-, Y-, or Z-registers. This register then holds the most-significant byte(MSB) in a 24-bit address or address pointer (Ref 1).When I try to access this memory using a normal pointer it doesn't work. However, I think I can use a uint32_t as pointer:Code:uint32_t address = 0x00010000; // > 0xFFFFuint8_t value = 5;*(uint8_t *)adres = value;uint_t read_value = 0;read_value = *(uint8_t *)adres // And indeed if I print read_value it shows 5.For PROGMEM this seems to be done well by the compiler, but when I use this pointer in functions it messes up. Probably because it is converted to a 16-bit pointer. Who can help me to put variables above 64kB? And access these variables via normal functions?I think it is a bit ridiculous to make products with 24-bit pointer hardware (Ref 1) and provide a compiler with 16-bit pointers (Ref 2). Probably the best solution is redesigning the board with an AVR32.References:1.http://www.atmel.com/images/atmel-8331-8-and-16-bit-avr-microcontroller-xmega-au_manual.pdf2.http://gcc.gnu.org/gcc-4.8/changes.html

author: andyturk
author_rank: Frequent Contributor
timestamp: March 11, 2014, 02:50:17 am
content: Quote from: happylex on March 10, 2014, 10:39:20 pmFixed it for 'ya. :-)

author: TerminalJack505
author_rank: Super Contributor
timestamp: March 11, 2014, 03:56:11 am
content: You might look intonamed address spacesand see if they help.Here are a couple of threads (#1,#2) on AVRFreaks that discuss them.A 32-bit MCU will probably be the simplest solution, however.

author: dannyf
author_rank: Super Contributor
timestamp: March 11, 2014, 11:35:58 am
content: QuoteTo be fair to Atmel, they didn't exactly produce that compiler.On the flip side, you can always use IAR-AVR.

author: westfw
author_rank: Super Contributor
timestamp: March 14, 2014, 12:44:13 am
content: gcc has a "model" of a CPU that it supports, and it pretty much requires any target support that model. The model wants a "flat" address space with fixed size pointers and does NOT include "paged" memory architectures, which is why you'll never see gcc for an 8bit PIC. The AVR is sort-of "barely" supported - one of the few 8bit micros that works at all. Their implementation of more than 64k program space is kludgey, and their implementation of more than 64k of program space is essentially non-existent (as you noticed.)I suppose that you could create an avr-gcc "variant" with 24 or 32bit pointers that handled the extended address space, but it would be using 24/32bit pointers and addresses everywhere, which would be unlikely to make anyone happy.(This is essentially my decision path for 32-bit micros. "Am I using enough memory that the address space issues become painful due to banking, paging, and etc?")

author: dannyf
author_rank: Super Contributor
timestamp: March 14, 2014, 10:58:54 am
content: How's this different from making DOS go over 640K?I don't know the exact addressing framework on xmega but if it is done on x/y/z registers, could you just set the msb register to the right value (think of it as "paging") and use a 16-bit pointer as the offset within that page?

author: Rick Law
author_rank: Super Contributor
timestamp: March 24, 2014, 03:59:58 am
content: Quote from: dannyf on March 14, 2014, 10:58:54 amDOS is ran in the 1Meg mode and is not capable of 24bit addressing. For DOS to get extra memory, a part of memory below 1Meg is assigned for for EMM - typically 16K to 64K. That part of memory would be divided into pages. When EMM is used, a call is first made to map a selected page of the extra memory into the below-1M (visible) block. So, for the duration of that mapping, the extra memory is in an address below 1M.For 8088 and up, that mapping could be done within the CPU since 8088 and up has 24 bit addressing. Prior to that with 8080/8085/z80 (16bits address), the add-on hardware in the EMM memory board does the mapping. The number of pages will vary depending on your total extra memory available.

author: westfw
author_rank: Super Contributor
timestamp: March 24, 2014, 04:59:38 am
content: QuoteYou are mistaken, and probably mean 80386.The 8088 was the same cpu (and timeframe) as the original 8086, and had a 1M address space (in fact, it was the 8088 that was used in the original IBM PC.)The 80286 had 24bit (physical) addresses, but it had a really awful MMU organization that made it hard to use. (IIRC, "segment numbers" were put IN THE MIDDLE of an address, right about the time that everyone was agreeing that segments were dead and pages were the future.)

author: miguelvp
author_rank: Super Contributor
timestamp: March 24, 2014, 05:28:33 am
content: Quote from: westfw on March 24, 2014, 04:59:38 amYou are right on the 1MB address space (2^20), the nightmares!!! It was all segmented in 64KB linear address spaces and it was a real PITA.But even so, the 640KB limit could be changed to 704KB if there was memory present between the video card and the ram. I still have the code to switch it (not my code might be borlands or masm sample)Code:PAGE,132TITLE704K - set memory to 704K bytesCOMMENT *Increase memory to 704K bytes by changingBIOS data word at 40:13 hexSet new memory to zeroApril 14,1987*INCLUDE mylib.equIF1INCLUDE mylib.macENDIFold_sizEQU640;old mem sizenew_sizEQU704;new mem sizenew_segEQU0A000h;704K segment; BIOS data areabios_dSEGMENT AT 40hORG13hmem_sizLABELWORD;memory sizebios_dENDScodeSEGMENTASSUMECS:code, DS:code, ES:bios_dORG100hstrt:@head' MEM704,04.14.87 '; point to memory size in BIOS data areaMOVAX,bios_d;zeroMOVES,AXMOVSI,OFFSET mem_siz; check if already runCMPWORD PTR ES:,new_sizJNEok@go_dos;quit; check for memory at A000 hexok:MOVBX,ES;save ESMOVAX,new_segMOVES,AX;ES=A000XORDI,DI;offsetMOVES:,AH;55 hexCMPAH,ES:;ok?JNZno_mem;noMOVES:,AL;AA hexCMPAL,ES:;ok?JNZno_mem;no; set memory size for 704K bytesMOVCX,ES;save ESMOVES,BX;ES=40MOVWORD PTR ES:,new_sizMOVES,CX;ES=A000; fill new memory with zerosXORAX,AX;zero wordMOVDI,AX;zero locationMOVCX,8000h;32K wordsREPSTOSW;do it@write<' Memory now 704K bytes',cr,lf>INT19h;reboot system; no memoty at A000 hex, terminate without changeno_mem:@write'no memory at A000 hex, aborting'@go_doscodeENDSENDstrtEdit: but that was IBM's implementation not sure if you could change the memory architecture to increase the number of segments, will have to look it up if the segments could be changed to go from 20 bit address space to 24 bits, but the PC used 20 bits total after segmentation.Edit answer: after a short research, it couldn't go past 20 bits address space so 1MB was the limit with the rom living on the higher area. (and yes, I have the complete disassemble of the original IBM Rom in some binder in my office)Edit2: apparently that code came from Byte Magazine but it mentions 1986 mine says 1987.https://archive.org/stream/198610ByteMagazineVol1111InsideTheIBMPC/198610%20Byte%20Magazine%20Vol%2011-11%20Inside%20the%20IBM%20PC_djvu.txt#BYTE 1 986 Extra Edition • Inside the IBM PCsIsn't google wonderful that you can look for code that is older than the internet?But back to topic, unless you don't have physical address pins that you can segment and combine with the standard address spaces using multiplexers to get to the right banks you can't go over the limit.And that doesn't take into account code and data prefetching because the fabric of the processor might not allow you to use some io pins to multiplex external chip selects to increase memory but I have not look at the datasheet to see if the XMega has prefetching built in and what the implications are for the toolchain etc.

author: miguelvp
author_rank: Super Contributor
timestamp: March 24, 2014, 06:41:49 am
content: Took a quick look at the xmega manual linked above and it seems it does support up to 16MB external SRAM, SDRAM and Peripheral and other memory mapped devices via an External Bus Interface. Look in section:27. EBI – External Bus InterfaceEdit: there is also reference to the RAMPD register for accessing data with a 24 bit address, not sure if related to the EBI.

author: westfw
author_rank: Super Contributor
timestamp: March 24, 2014, 08:08:42 am
content: QuoteYes. But it's only accessible via a banking scheme, and the avr-gcc C compiler doesn't support it and only has 16bit pointers, so it's not much good. I thought that's what this conversation was about?!

author: dannyf
author_rank: Super Contributor
timestamp: March 24, 2014, 11:03:57 am
content: Looks like the limitless gcc-avr finally met its limits. Maybe you can try a real compiler, like iar?seriously, RAMPx is the way to go.

author: dannyf
author_rank: Super Contributor
timestamp: March 24, 2014, 05:24:30 pm
content: Aside from iar, cvavr also supports 16bit or more pointers. They are considerably more affordable, however.not sure about iccavr. Also worth checking our mikroe or Rowley ...no need to hang yourself in gcc.

author: dannyf
author_rank: Super Contributor
timestamp: March 25, 2014, 01:08:23 pm
content: ICCAVR doesnot handle 24-bit pointers directly. However, it offers an approach to page through those RAMPx registers (similar to what I suggested earlier) and offers a set of routines that read from / write to the space.Both ICCAVR and CVAVR are fairly inexpensive (vs. IAR).

author: Rick Law
author_rank: Super Contributor
timestamp: March 26, 2014, 04:06:16 pm
content: Quote from: westfw on March 24, 2014, 04:59:38 amYou are absolutely right. Finger faster than brain problem here.The 8088 is the 8086 with 8 bit lines rather than 16 lines and both are 20-bit addressing. I hated that segment registers so much I just can't get it out of my head. I would have preferred the "segment" to be just the most-significant-bits of the second word.The 80286 has another problem I recall : to switch mode, you have to reset (reboot the CPU). The 386 was when it really begin to grow up.