ATXMEGA128A1U EBI questions...

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

Having spent some time reading and rereading the datasheet, I've got a few questions for anyone in the know here!

 

I only need to access 64K of SRAM and don't want to use latches.  I think that means "4-port" EBI mode "NOALE".

 

Q#1 - There seems to be an option of using a chip select or not using a chip select.  I remember seeing this difference in some of the timing diagrams too.  Would you still set up the ASIZE/BASEADDR even if the CTRLA MODE=00 (DISABLE)?

 

Q#2 - Any reason to use a chip select unless you have multiple memory devices?  Is it a good idea to tie the SRAM /CE low and skip it or let the AVR generate it?

 

Q#3 - If ASIZE is smaller, does the EBI take over less address lines leaving them available for I/O ?

 

Q#4 - Does LPCMODE in CTRL not apply if you are not in "Low Pin Count Mode" - ther only options are ALE1 or ALE12.  I would set SRMODE=11 (NOALE) and IFMODE=10 (4PORT).

 

Q#5 - If I set BASEADDR if set to 0x10000 would put the SRAM at 0x10000.  I saw the __far_mem_read(addr) and __far_mem_write(addr, data) function access to the memory.  Is there any gcc pointer access that is also workable?

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

alank2 wrote:
Q#2 - Any reason to use a chip select unless you have multiple memory devices?
Power (de-selected RAM may reduce current consumption)

alank2 wrote:
Is it a good idea to tie the SRAM /CE low and skip it or let the AVR generate it?
AVR

alank2 wrote:
I saw the __far_mem_read(addr) and __far_mem_write(addr, data) function access to the memory.
... and Huge Memory in ASF3.

alank2 wrote:
Is there any gcc pointer access that is also workable?
No as AVR GCC RAM pointers are 16 bit.

DMA is 24 bit and there are 24 bit types in AVR GCC.

 


AN_8058 AVR1312: Using the XMEGA External Bus Interface (page 5 for "2.1.3.2 Four-port SRAM")

via ATxmega128A1U - 8-bit AVR Microcontrollers

https://gcc.gnu.org/wiki/avr-gcc#Types

 

edit : https://asf.microchip.com/docs/latest/xmegaau/html/group__hugemem__group.html

via Advanced Software Framework (ASF) | Microchip Technology

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Wed. Apr 17, 2019 - 04:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you gchapman!

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

So if I use 4 port mode and set EBIOUT to put A15:A8 on PORTF, but I only want to access 64K addresses (A15:A0), can A21:A16 be repurposed for other tasks?  What I am wondering is if the direction of these pins is set to input, not output, will the EBI control them?

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

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf

(page 326, bottom)

27.9 I/O Pin and Pin-out Configuration

...

I/O pins for unused EBI address and control lines can be used as normal I/O pins or for other alternate functions on the pins.

 

...

via ATxmega128A1U - 8-bit AVR Microcontrollers

 

"Dare to be naïve." - Buckminster Fuller

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

Interesting, so does this mean that it uses the size window specified and knows which address pins are in use and which are not?  So the A21:A16 could be used for output or input?

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

External data must be chip select-able in a data address range dependent on BASEADDR and ASIZE.

(page 320)

Figure 27-1. Base Address

 

"Dare to be naïve." - Buckminster Fuller

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

I'm not following that diagram at all and I don't see any reference to it to explain it...

 

What is n-1 ?

Last Edited: Thu. Apr 18, 2019 - 06:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EBI's most significant address bit

 

"Dare to be naïve." - Buckminster Fuller

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

We are talking about the baseaddr, but does that relate to the address pins it uses, or is it the address size that determines them?  Isn't there 4 ranges for that?  Does EBI's most significant address bit depend on all 4 ranges?

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

alank2 wrote:
We are talking about the baseaddr, but does that relate to the address pins it uses, or is it the address size that determines them?
address size; ASIZE has 17 valid values.

 

"Dare to be naïve." - Buckminster Fuller

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

I wonder if it looks at all 4 ASIZE values to determine the highest EBI address pin, or if each one while being used sets the highest address pin.

 

Is it better to use CS0 or CS3?  The chart where it is redefining CS for address would suggest it might be better to start at CS3 and go downward.

 

Also:

 

The right-hand column shows that all four CS
lines are used as address lines when only CS3 is enabled.
Figure 27-

 

Why would all 4 be address lines if only CS3 is enabled?  Is CS3 not needed?  What becomes CS3 in this case?

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

Also - gchapman - thanks for your patience - I know I'm asking a lot of questions.

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


alank2 wrote:
I wonder if it looks at all 4 ASIZE values ...
ASIZE has one value of 17 valid values.

alank2 wrote:
Is it better to use CS0 or CS3?
CS0; leaves CS3 as spare to mix SRAM and SDRAM.

If external RAM is two 32KB then CS1 and CS2; if one 128KB then CS2.

alank2 wrote:
The chart where it is redefining CS for address would suggest it might be better to start at CS3 and go downward.

alank2 wrote:
Why would all 4 be address lines if only CS3 is enabled?
SDRAM

The blocks can be configured independently, but only the CS3 block supports SDRAM.

 


AN_8058 AVR1312: Using the XMEGA External Bus Interface

 

"Dare to be naïve." - Buckminster Fuller

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

You're welcome and thanks for the mind stretch.

 

"Dare to be naïve." - Buckminster Fuller

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

gchapman wrote:

alank2 wrote:

I wonder if it looks at all 4 ASIZE values ...

 

ASIZE has one value of 17 valid values.

 

Each ASIZE does have that range of values, but there is an ASIZE for CS0, an ASIZE for CS1, an ASIZE for CS2, and an ASIZE for CS3, correct?  If CS0 is set to "256 bytes" and CS1 is set to "65536" bytes then one uses 8 address lines and the other 16 address lines.  If both CS0 and CS1 are configured for use, how many address pins will the EBI use?  16 all the time?  Or 8 when accessing CS0 and 16 when accessing CS1?

 

gchapman wrote:

CS0; leaves CS3 as spare to mix SRAM and SDRAM.

If external RAM is two 32KB then CS1 and CS2; if one 128KB then CS2.

 

I am completely lost.  If you have one memory device (one CS line), then CS0, right?  if you have two memory devices (two CS lines), why CS1 and CS2 instead of CS0 and CS1?

 

gchapman wrote:

alank2 wrote:

The chart where it is redefining CS for address would suggest it might be better to start at CS3 and go downward.

 

 

 

If you choose CS0, then is A16:A17 available for 18 bit memory?  Wouldn't it be better if you have one memory device to use CS2 for it leaving A16:A17 available?

Last Edited: Thu. Apr 18, 2019 - 08:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alank2 wrote:
Each ASIZE does have that range of values, but there is an ASIZE for CS0, an ASIZE for CS1, an ASIZE for CS2, and an ASIZE for CS3, correct?
Yes (I see your point)

alank2 wrote:
I am completely lost.

2.1.3 Four-port Interface

The four-port mode allows for 8-bit SDRAM operation and SDRAM together with SRAM and SRAM LPC. Of course, SRAM and SRAM LPC operation without SDRAM is also supported in four-port mode.

Note that the connections for SRAM LPC and SRAM are slightly different if SDRAM is enabled.

alank2 wrote:
If you choose CS0, then is A16:A17 available for 18 bit memory?
No

alank2 wrote:
Wouldn't it be better if you have one memory device to use CS2 for it leaving A16:A17 available?
Yes

 

"Dare to be naïve." - Buckminster Fuller

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

Parts are finally in and I have the EBI working in 4 port mode with 16 address lines (64K).  I've got it working with the FRAM (150ns) and SRAM (55ns), but I can't get it to be solid and reliable with SRAM (10ns).  It will appear to work, but when I put it through a bunch of tests, it will fail.  Sometimes randomly, sometimes not randomly.  I've attached my code if anyone wants to look through it, but it works great with the FRAM and 55ns SRAM, but it is always possible there is a bug.

 

The sram_read/sram_write are just kludges to let my sram functions written with something else work without redirecting them to the __far_mem_read/write functions.

 

I put the 64K at 0x10000 using CS0 for now.

 

I tried slew rate limiting (I know there is a better way to set all pins at once), but it did not have an effect.

 

I added a ton of decoupling to the solderless breadboards, did seem to make things a little better, but the SRAM 10ns still fails.

 

I had a similar problem with some other ISSI 10ns memory with another AVR using its memory interface in the past.  Could it be that 10ns SRAM is just not going to work on a breadboard because of the capacitance or something?

 

I can see that the 10ns does indeed drive the i/o pins in around 10ns.  You can see some oddities in the sram_cell test where I am reading the byte twice, this was a mod to try to figure out what it was doing.  An error I was able to capture showed the write, and then the two reads.  Both reads should have been the same, but the first one the SRAM drove the line high when it should not have and the second one it look the line back low which was correct.  At this point there was no memory location in the memory that should have had that bit on - the cell test was transitioning it between two values and both values have this particular bit set the same.  So it shouldn't have mattered what any of the 16 address lines were doing, it should have been low the first time and the second time.

 

Maybe I should try to design a quick test board to get it off the solderless BB and see what it does there...

#include <avr/io.h>
#include "util/atomic.h"
#include <stdio.h>
#include "avr/pgmspace.h"

#include "cdelay.h"

#define sram_read(x) __far_mem_read(0x10000+x)
#define sram_write(x,y) __far_mem_write(0x10000+x,y)

#define __far_mem_read(addr)                            \
        (__extension__({                                \
    uint32_t temp32 = (uint32_t)(addr);     \
    uint8_t result;                         \
    asm volatile(                           \
      "in __tmp_reg__, %2"     "\n\t" \
      "out %2, %C1"            "\n\t" \
      "movw r30, %1"           "\n\t" \
      "ld %0, Z"               "\n\t" \
      "out %2, __tmp_reg__"    "\n\t" \
      : "=r" (result)                 \
      : "r" (temp32),                 \
        "I" (_SFR_IO_ADDR(RAMPZ))     \
      : "r30", "r31"                  \
    );                                      \
    result;                                 \
  }))

#define __far_mem_write(addr, data)                     \
        (__extension__({                                \
    uint32_t temp32 = (uint32_t)(addr);     \
    asm volatile(                           \
      "in __tmp_reg__, %1"     "\n\t" \
      "out %1, %C0"            "\n\t" \
      "movw r30, %0"           "\n\t" \
      "st Z, %2"               "\n\t" \
      "out %1, __tmp_reg__"           \
      :                               \
      : "r" (temp32),                 \
        "I" (_SFR_IO_ADDR(RAMPZ)),    \
        "r" ((uint8_t)data)           \
      : "r30", "r31"                  \
    );                                      \
  }))

char s1[128];

void uart_putc(uint8_t AByte)
  {
    //wait until ready
    while ((USARTD0_STATUS & USART_DREIF_bm)!=USART_DREIF_bm)
      ;

    //tx
    USARTD0_DATA=AByte;
  }

void uart_puts(char *AString)
  {
    uint8_t c1;

    for (c1=0;AString[c1];c1++)
      uart_putc(AString[c1]);
  }

void uart_puts_P(const char *AString)
  {
    uint8_t c1;

    for (c1=0;pgm_read_byte(AString+c1);c1++)
      uart_putc(pgm_read_byte(AString+c1));
  }

void dump(uint32_t AAddress, uint16_t ALines)
  {
    uint8_t c1,c2;
    uint32_t ui1;

    for (ui1=AAddress;;)
      {
        sprintf(s1,"%08lx: ",ui1);
        uart_puts(s1);

        for (c2=0;c2<16;c2++)
          {
            c1=__far_mem_read(ui1+c2);
            //c1=*(volatile uint8_t*)((ui1+c2) | _BV(15));

            sprintf(s1,"%02x ",c1);
            uart_puts(s1);
          }
        uart_puts("\n\r");

        ui1+=16;
        ALines--;
        if (ALines==0)
          break;
      }
  }

const char PROGMEM MSG_TESTING[]="Testing Static RAM";
const char PROGMEM MSG_DATATESTFAIL[]="\n\rData line test fail.\n\r";
const char PROGMEM MSG_ADDRTESTFAIL[]="\n\rAddress line test fail.\n\r";
const char PROGMEM MSG_LATCHTESTFAIL[]="\n\rLatch test fail.\n\r";
const char PROGMEM MSG_CELLTESTFAIL[]="\n\rCell test fail.\n\r";
const char PROGMEM crlf[]="\r\n";

void sram_datatest()
  {
    uint8_t c1,c2;

    //datatest
    for (c1=0,c2=1;c1<8;c1++)
      {
        sram_write(0,c2);
        sram_write(1,0x00);
        sram_write(2,0xff);
        if (sram_read(0)!=c2)
          {
            uart_puts_P(MSG_DATATESTFAIL);

            //halt
            for(;;)
              ;
          }
        c2<<=1;
      }
  }

void sram_addrtest()
  {
    uint8_t c1,c2;
    uint16_t ui1;

    //addrtest
    for (c1=0,c2=0xa3,ui1=1;c1<16;c1++)
      {
        sram_write(ui1,c2++);
        ui1<<=1;
      }

    //verify values

    //addrtest
    for (c1=0,c2=0xa3,ui1=1;c1<16;c1++)
      {
        if (sram_read(ui1)!=c2++)
          {
            fail:
            uart_puts_P(MSG_ADDRTESTFAIL);

            //halt
            for(;;)
              ;
          }
        ui1<<=1;
      }
  }

void sram_celltest()
  {
    uint16_t ui1;
    uint8_t c1,c2;

    uart_puts_P(MSG_TESTING);

    //pass 1 : fill with 0x55
    for(ui1=0x0000;;)
      {
        sram_write(ui1,0x55);
        ui1++;
        if (ui1==0)
          break;
      }
    uart_putc('.');

    //pass 2 : verify 0x55, fill with 0xaa (UP)
    for(ui1=0x0000;;)
      {
        c1=sram_read(ui1);
        c2=sram_read(ui1);

        if (c1!=0x55 || c1!=c2)
          {
            //fail:
            uart_puts_P(MSG_CELLTESTFAIL);
            sprintf(s1,"%08lx %02x!=55 (%02x/%02x/%02x) %02x",ui1+0x10000L,c1,sram_read(ui1),sram_read(ui1),sram_read(ui1),c2);
            uart_puts(s1);

            //halt
            for(;;)
              ;
          }
        sram_write(ui1,0xaa);

        ui1++;
        if (ui1==0)
          break;
      }
    uart_putc('.');

    //pass 3 : verify 0xaa, fill with 0x00 (DOWN)
    for(ui1=0xffff;;)
      {

        c1=sram_read(ui1);
        c2=sram_read(ui1);
        if (c1!=0xaa || c1!=c2)
          {
            uart_puts_P(MSG_CELLTESTFAIL);
            sprintf(s1,"%08lx %02x!=aa (%02x/%02x/%02x) %02x",ui1+0x10000L,c1,sram_read(ui1),sram_read(ui1),sram_read(ui1),c2);
            uart_puts(s1);

            //halt
            for(;;)
              ;
          }
        sram_write(ui1,0x00);

        ui1--;
        if (ui1==0xffff)
          break;

      }
    uart_putc('.');
    uart_puts_P(crlf);
  }

int main(void)
  {
    //disable wdt
    ATOMIC_BLOCK(ATOMIC_FORCEON)
      {
        CCP=CCP_IOREG_gc;
        WDT_CTRL=WDT_WCEN_bm;
      }

    //switch to external oscillator
    ATOMIC_BLOCK(ATOMIC_FORCEON)
      {
        //enable external oscillator
        CCP=CCP_IOREG_gc;
        OSC_CTRL|=OSC_XOSCEN_bm;

        //wait for it to be ready
        while (!(OSC_STATUS & OSC_XOSCRDY_bm))
          ;

        //switch to external oscillator
        CCP=CCP_IOREG_gc;
        CLK_CTRL=CLK_SCLKSEL_XOSC_gc;

        //wait until we are switched
        while ((CLK_CTRL & CLK_SCLKSEL_gm)!=CLK_SCLKSEL_XOSC_gc)
          ;

        //disable internal oscillator
        CCP=CCP_IOREG_gc;
        OSC_CTRL&=~OSC_RC2MEN_bm;

        //lock
        CCP=CCP_IOREG_gc;
        CLK_LOCK=CLK_LOCK_bm;
      }

    //configure usart (pd2 rxd, pd3 txd)
    PORTD_DIRSET=_BV(3);
    USARTD0_CTRLB=USART_RXEN_bm | USART_TXEN_bm;

    //2mhz 57600
    //USARTD0_BAUDCTRLA=150;
    //USARTD0_BAUDCTRLB=0b10010000;

    //57600 baud
    USARTD0_BAUDCTRLA=31;
    USARTD0_BAUDCTRLB=0;

    //115200 baud
    /*USARTD0_BAUDCTRLA=15;
    USARTD0_BAUDCTRLB=0;*/

    //110 baud
    /*USARTD0_BAUDCTRLA=130;
    USARTD0_BAUDCTRLB=112;*/

    //slew rate
    /*
    PORTH_PIN0CTRL=_BV(PORT_SRLEN_bm);
    PORTH_PIN1CTRL=_BV(PORT_SRLEN_bm);
    PORTH_PIN4CTRL=_BV(PORT_SRLEN_bm);

    PORTK_PIN0CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN1CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN2CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN3CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN4CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN5CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN6CTRL=_BV(PORT_SRLEN_bm);
    PORTK_PIN7CTRL=_BV(PORT_SRLEN_bm);

    PORTF_PIN0CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN1CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN2CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN3CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN4CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN5CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN6CTRL=_BV(PORT_SRLEN_bm);
    PORTF_PIN7CTRL=_BV(PORT_SRLEN_bm);

    PORTJ_PIN0CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN1CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN2CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN3CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN4CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN5CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN6CTRL=_BV(PORT_SRLEN_bm);
    PORTJ_PIN7CTRL=_BV(PORT_SRLEN_bm);
    */

    //configure EBI
    PORTH_DIRSET=_BV(0) | _BV(1) | _BV(4); //we, /re, /cs0
    PORTK_DIRSET=0xff; //a0-a7
    PORTF_DIRSET=0xff; //a8-a15

    EBI_CTRL=EBI_SRMODE_NOALE_gc | EBI_IFMODE_4PORT_gc;

    EBI_CS0_CTRLA=EBI_CS_ASPACE_64KB_gc | EBI_CS_MODE_SRAM_gc;
    EBI_CS0_CTRLB=EBI_CS_SRWS_1CLK_gc;
    EBI_CS0_BASEADDR=0x10000 >> 8;

    for(;;)
    {
    sram_datatest();
    sram_addrtest();
    sram_celltest();

    Delay_s(1);
    }

    __far_mem_write(0x10000,0x21);
    __far_mem_write(0x10001,0x43);
    __far_mem_write(0x1fffe,0x65);
    __far_mem_write(0x1ffff,0x87);

    for(;;)
      {
        dump(0x10000,4);
        dump(0x1ffc0,4);
        Delay_ms(1000);
      }

    //halt
    for(;;)
      ;
  }

 

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

Attaching a logic analyzer screen shot from the working SRAM (55ns).  It takes around 30ns to read.  The 10ns stuff that fails is 3 times faster and actually takes 10ns like it is rated.

Attachment(s): 

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

alank2 wrote:
Parts are finally in and I have the EBI working in 4 port mode with 16 address lines (64K).
Well done!

alank2 wrote:
I tried slew rate limiting (I know there is a better way to set all pins at once), but it did not have an effect.
Slew rate reduction isn't necessary for EBI; would be if the signal is leaving the PCB.

alank2 wrote:
I added a ton of decoupling to the solderless breadboards, did seem to make things a little better, but the SRAM 10ns still fails.
Add some series termination to that SRAM's signals; 10ns cycle time means strong drivers so ground bounce is likely.

alank2 wrote:
Could it be that 10ns SRAM is just not going to work on a breadboard because of the capacitance or something?
Inductance too.

Likewise, have had ISSI SRAM but it was on a protoboard that had a ground plane (IIRC, from Vector Electronics)

Some breadboards are on a metal plate that might be close enough to the breadboard's strips.

Brad (AtomicZombie) has his breadboards on a wide aluminum plate.

alank2 wrote:
I can see that the 10ns does indeed drive the i/o pins in around 10ns.
Probe effects will affect the measurement.

Low capacitance probe ... 1K ohm resistor, coax, scope's 50 ohm input.

XMEGA and ISSI SRAM both have more than enough drive for a 1K ohm load.

alank2 wrote:
Maybe I should try to design a quick test board to get it off the solderless BB and see what it does there...
or protoboard with a ground plane (an answer in a day or two) though the quick-turn PCB fabs are GREAT!

 

edit : Surface Mount Prototyping PCBs | BusBoard Prototype Systems

 

edit2 : Brad's breadboards are from Twin Industries

Radical Brad Hacks – Vulcan-74 Page 1 | AtomicZombie DIY Plans

(before mid-page)

The individual breadboards are North American made units, and the base plate is quarter inch thick aluminum plate. The difference between the ten dollar Twin Industries boards I purchase from Digikey (Part #438-1045-ND) and the five dollar China made EBay deal boards is often the difference between success and failure.

TW-E40-1020 Twin Industries | Prototyping, Fabrication Products | DigiKey

Twin Industries: Hardware Prototyping and Development Tools.

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Fri. May 3, 2019 - 01:27 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What's the logic analyzer's make and model?

Reason : its input impedance

Thanks!

 

"Dare to be naïve." - Buckminster Fuller

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

One thing to consider with the 10ns ram is the data setup/hold times. The xmega may require the data to be held longer than what the fast sram is providing. This might entail a RC delay on the cs to the ram. You need to look at the timing specs for the xmega and ensure the ram complies or your logic ensures that it complies.

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

gchapman wrote:

What's the logic analyzer's make and model?

Reason : its input impedance

Thanks!

 

 

It is a Saleae Logic Pro 16 - website says input resistance 2M, input capacitance 10pF.  I only have it connected to 4 pins though (ce/rd/wr/d0).  I'll try removing it to see if the results are different.

 

Memory is https://www.mouser.com/ProductDe...

 

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

gchapman wrote:

No as AVR GCC RAM pointers are 16 bit.

Not entirely true. __memx gives 23 bit pointers (the 24th bit says RAM or ROM).

 

Having said that any variable of any width can be a "pointer". The only thing that matters (that even makes it a pointer) is how you finally dereference it. Obviously the preferred dereference is the * operator but that's not necessaily the only way to dereference a pointer - think pgm_*() or eeprom_*() in the AVR-LibC library. Their first parameter is effectively some kind of uint but is used as a "pointer".

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

Pulling the LA off of it seems to make the failure take a couple more tests (6-7 instead of 1-3), but it still fails.

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

clawson wrote:
Not entirely true. __memx gives 23 bit pointers (the 24th bit says RAM or ROM).

Using the GNU Compiler Collection (GCC): AVR Named Address Spaces

...

 

__memx

This is a 24-bit address space that linearizes flash and RAM: If the high bit of the address is set, data is read from RAM using the lower two bytes as RAM address. If the high bit of the address is clear, data is read from flash with RAMPZ set according to the high byte of the address. See __builtin_avr_flash_segment.

Objects in this address space are located in .progmemx.data.

 

...

AVR GCC data pointers are 16-bit with by __memx accessing read-only data from program space.

https://gcc.gnu.org/wiki/avr-gcc#Type_Layout

clawson wrote:
Having said that any variable of any width can be a "pointer".
A 24-bit type was added to FSF AVR GCC when XMEGA was added to it (GCC 4.7); 24b for XMEGA DMA controller.

AVR GCC Wiki, Extensions - Types

GCC 4.7 Release Series — Changes, New Features, and Fixes - GNU Project - Free Software Foundation (FSF)

...

 

AVR

  • GCC now supports the XMEGA architecture. This requires GNU binutils 2.22 or later.

[several other changes including __memx]

...

 

"Dare to be naïve." - Buckminster Fuller

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

If you guys have a better/more optimal way for me to read/write to this memory space than

__far_mem_read(addr)

I'd love to do it!

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

Nice LA!

 

Some series termination should improve that (signal's driver, small value resistor, cable to LA, LA input)

Signal integrity is usually evaluated by an oscilloscope; in this case, scope's 50-ohm input or via 50-ohm impedance match to 1-Megaohm input.

Once a signal is verified as correct then the signal can be evaluated by a logic analyzer (within reason; impedance match)

Have a ground in close proximity to the signal :

Saleae - Logic-to-2x4 Header (Gen 2)

Some logic analyzers have a mating connector such that the logic analyzer can be directly connected to the DUT PCBA (signals are almost totally over a ground plane)

 


Terminator feed-through 50-ohm BNC

Adaptor 50 Ohm ($18.00) : Saelig Online Store

IIRC, Pomona Electronics also has one.

 

"Dare to be naïve." - Buckminster Fuller

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

That __far_mem_read() is a misnomer - it should not have two leading underscores (that namespace is reserved for the internals of the compiler), as it appears in an ebi.h file I guess one might argue that is part of the C lib? In that case it might be permitted a _far_mem_read() name (that is with a single leading underscore as that namespace is reserved for the C lib). But anyway it appears that all it does is split what's actually a U32 do that bits 16 to 23 go to RAMPZ and bits 0 to 15 go to the index register then does a LD/ST Z from that. All that one might do with __memx is use it very much like the U32. I thought that __memx handled RAMPZ but maybe I am mistaken? If not then one would still need to do the split/write separately.

 

(off to try an experiment in AS7...)

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

gchapman wrote:
Nice LA!

 

Thanks; I bought it before the prices went up thankfully!

 

I'm going to hook up a scope and see what the signals look like with it next.

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

newfile2 is with 20M bandwidth limiter on the scope enabled, newfile2 is no bandwidth limiting.  10X probes, no special grounding, just using the long lead.

 

Both examples show the back to back reads on the same address, but the results (ch4) are different.

 

ch1=cs, ch2=re, ch3=wr, ch4=4d0

 

Attachment(s): 

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

Connected the SRAM CS to ground so it would always be enabled - same result.  It may run a couple of passes, but then it will fail.

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

Thanks!

alank2 wrote:
10X probes, no special grounding, just using the long lead.
and ground bounce on Newfile3.png

BNC-to-probe adapters can be soldered onto the board to minimize the ground lead's inductance.

TEX-BA - BNC TO PROBE TIP ADAPTER | Tyrosys Online Shop | Tyrosys Corp | Apple Authorized Service Provider

Your preferred distributor likely has similar.

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Wed. Apr 24, 2019 - 02:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is on a solderless breadboard right now with the small wire leads that have tiny pin connectors on the end.  Here is my question - if this were on a proper pcb, would it still be happening?  I'm surprised that going to the length of 7 wait cycles doesn't allow it plenty of time, but this is what I saw last time I messed with this (on another breadboard with another 10ns ISSI SRAM), it is giving the wrong results.

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

alank2 wrote:
Here is my question - if this were on a proper pcb, would it still be happening?
maybe yes as a PCB reduces the effects but not the parts.

Will get a quicker answer to your question by moving from a breadboard to a protoboard with ground plane; XMEGA EBI isn't that wide so there's not many wires to solder.

Value of quick-turn (overnight or two day) PCB fab might not be a match for your question; the pitch capability of some PCB self-fab might be a match.

alank2 wrote:
... , it is giving the wrong results.
incorrect results as there's likely no significant defect with either the ISSI SRAM or the Microchip XMEGA128A1U.

Will read that ISSI SRAM's datasheet and create thoughts.

Question I will answer :

Does XMEGA A1U EBI "need" a 10ns access cycle time SRAM?

edit : No; write cycle is 63ns minimum

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Thu. Apr 25, 2019 - 02:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks good to go for XMEGA A1U from a skim of its datasheet.

Thank you ... was unaware of SRAM in SOJ; SOJ's pitch is a match for 1.27mm (50mil) pitch protoboard.

XMEGA A1U (100 pins) - would be some work to fit it on 50mil protoboard but it's doable.

512Kx8 in SOJ :

https://www.mouser.com/ProductDetail/Alliance-Memory/AS7C34096A-20JCN?qs=sGAEpiMZZMt9mBA6nIyysDfDw0vDQxSw2bj1NWNbwJ8%3D

There's Alliance Memory 128Kx8 SRAM in SOJ but couldn't quickly locate stock.

 

edit :

P.S.

64Kx16 SRAM would be a match for PIC24 or dsPIC PMP if want to consider MPLAB XC16 instead of AVR GCC.

That PMP is multiplexed though PIC24/dsPIC are significantly faster and wider than XMEGA.

To mate to SRAM, latches or cPLD or a small FPGA.

64Kx16 MRAM :

MR0A16A | Everspin

 

edit2 :

1.27mm pitch, SOIC or TSOP-II, 512Kx8 SRAM with ECC :

https://www.mouser.com/datasheet/2/100/001-95415_CY62148G_MoBL_R_4-Mbit_512K_words_x_8_bi-972393.pdf

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Thu. Apr 25, 2019 - 02:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SRAM with ECC?  Interesting.  Does SRAM have enough uncorrectable errors to make such a thing practical?

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

ECC with EEPROM from some manufacturers; MRAM has inherent ECC.

IIRC, an SRAM bit is by six transistors; more radiation-tolerant than flash.

Some high temperature MCU have zero flash and load SRAM from ECC'd NOR flash or ECC'd EEPROM.

ECC, EDC, or CRC is becoming somewhat common for MCU flash.

 

An uncorrectable error may be corrected by a reboot though that's likely a system failure (defects : lack of ECC, lack of CRC with exception handling)

 


SEMPER NOR Flash

 

"Dare to be naïve." - Buckminster Fuller

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

I'm going to put together a real deal PCB to get to the bottom of it.  Should I put a place in the lines between the uC and SRAM for a solder bridge that can be undone to put a resistor in the line?

 

Also, I got my first mock test board that only has the LED's and keyboard on it along with some fet drivers.  So far so good.

 

Displays on the data side are intentionally red/orange/yellow/green to evaluate different displays.  The green is disappointing in how dim it is; I would have liked to had red for address and green for data, but I don't want to deal with different brightness levels for each side.

Attachment(s): 

Last Edited: Thu. Apr 25, 2019 - 05:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

<duplicate removed>

"Dare to be naïve." - Buckminster Fuller

Last Edited: Thu. Apr 25, 2019 - 06:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alank2 wrote:
Should I put a place in the lines between the uC and SRAM for a solder bridge that can be undone to put a resistor in the line?
Easier is a trace jump that can be cut with an Xacto knife, or, a zero-ohm resistor of your preferred size.

Add test points with "nearby" ground test points (inductance reduction for probes), or pads at PCB edge for BNC-to-probe adapters, or 953 ohm resistors at PCB edge with pads for BNC connectors.

Patches can be added if don't want to run traces (a patch is wire tacked or glued to PCB's surface; close to PCB's ground plane to reduce patch's impedance)

Trace's solder resist can be scraped to create a test point; ideally, ground is nearby.

alank2 wrote:
So far so good.
smiley

 


Scrape It

There's a post here on that method where one stated use of their pocket knife laugh

 

edit : syntax errors

edit2 : operator headroom error

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Thu. Apr 25, 2019 - 06:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So - a question about avr1312 - why does the ebi_driver.h want you to :

 

         *  \note If interrupts are used, add the _far_mem_enter_ISR() and
         *        _far_mem_exit_ISR() in the interrupt routine to avoid reading
         *        or writing to the wrong location.


	#define _far_mem_enter_ISR()  uint8_t volatile saved_rampz = RAMPZ; \
                                      RAMPZ = 0;


	#define __far_mem_exit_ISR()   RAMPZ = saved_rampz;

Why should the ISR assume anything about RAMPZ?  Shouldn't it assume RAMPZ could be anything and that if it needs to do something involving RAMPZ, then it would save/set and restore it?  Or is this because gcc doesn't really know about RAMPZ?

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

alank2 wrote:
Or is this because gcc doesn't really know about RAMPZ?
yes, an assumption, as AVR GCC RAM pointers are 16-bit.

Couldn't locate RAMP in avr-gcc - GCC Wiki

XMEGA AU manual :

3.10 RAMP and Extended Indirect Registers

...

3.10.1 RAMPX, RAMPY and RAMPZ Registers

The RAMPX, RAMPY and RAMPZ registers are concatenated with the X-, Y-, and Z-registers, respectively, to enable indirect addressing of the whole data memory space above 64KB and up to 16MB.

 

"Dare to be naïve." - Buckminster Fuller