16-bit Host Wierdness

Ok, I am working in 16-bit mode, and trying to ge the point I am writing the firmware to the ADV212.  At the moment I have a simple loop that writes the values 0x0000 to 0x000f to the first 16 locations at address 0x00050000 in the ADV212, and then I read it back.  I am doing the following in my code:

  *adv212_register_BUSMODE = 0x0005;

  *adv212_register_MMODE = 0x0005;

  *adv212_register_STAGE = 0x0005;

  *adv212_register_IADDR = 0x0000;

adv212_firmware_num_words = 16;

  for (t=0;t<adv212_firmware_num_words;t++)

  {

    *adv212_register_IDATA = adv212_firmware_data[t];

  }


  *adv212_register_STAGE = 0x0005;

  *adv212_register_IADDR = 0x0000;

  for (t=0;t<adv212_firmware_num_words;t++)

  {

      tempData[t] = *adv212_register_IDATA;

  }

I then dump both the original and the read back arrays. These arrays are 16 bit unsigned values.

Here's what I wrote:

0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000a 000b 000c 000d 000e 000f

And here is what I read back:

0000 0002 0001 0004 0003 0006 0005 0008 0007 000a 0009 000c 000b 000e 000d 000f


I would have expected to read back 0x1, 0x0, 0x3, 0x2, and so on, ending with a 0xe.  In other words, we should have seen the data half-word swapped.  The fact is that it seems that way for the 2nd to the 15th read back, but what is confusing me is the first and the sixteenth word read back are NOT swapped.

Can anyone give me a hint what I might be doing wrong in the above sequence?

Help is greatly appreciated. Thanks!

  • I guess its unfortunate that the subject did not include ADV212, as that is what I am using. Does anyone have any thoughts yet on what might be going on to cause the order issues I see on read back of the ADV212 memory?  Am I missing something with the 16 bit host access to the bus that could cause the first and last half words to be where they are when I read data back, and everything else in between word swapped?

  • 0
    •  Analog Employees 
    on Oct 16, 2015 4:10 AM

    Hi Jim,

    Looks like you have an endianess issue. The ADV212 is Big endian. The pattern you are showing doesn't look like the obvious sort of endianess error but I can't think of anything else that would swap like that and otherwise be correct.

    Dave

  • Dave,

    Sorry for opening multiple threads - I was asking specifically in the 2nd one which edge of WE was used to latch data into the ADV212, so its a slightly different question.

    Anyway, The issue is really stumping me. I've been looking at things on a logic analyzer this morning and it *SEEMS* that the write and read cycles all look like what I would expect.  Maybe it is an endianness issue, but the ARM is big-endian as well.  I am seeing this when reading back the firmware written to the IDATA register. This is the first 16 locations at 0x00050000:

    0000 E59F F018 E59F F018 E59F F018 E59F F018 E1A0 F018 E59F 0000 E59F F018 0005

    What was written in order was:

    E59F F018 E59F F018 E59F F018 E59F F018 E59F F018 E1A0 0000 E59F F018 E59F F018 0005

    I showed the first 17 words written as that shows where the 0005 in the read back came from.

    The only thing I can think of is that the value IMMEDIATELY BEFORE the writes to IDATA was the 0x0000 written to IADDR.  If the ADV212 is latching data on the FALLING EDGE of the WE signal, then the data bus value could still have been 0x0000 from the write to STAGE (0x0005) and IADDR (0x0000).  I've seen on the analyzer that the data lines are in fact changing and stable well before the WE rising edge.  I'm unfortunately with clips only able to attach to every other pin on my processor, so i can show bits 0, 2, 4 and 6 for example, as I cannot get the clips on adjacent processor pins.  I am fixing to attach some scanned images - I thought to print some logic analyzer images out but did not think to save the screen shots.

    Ok in the PDF, the first two cycles are of WRITE cycles.  The second two are of READ cycles.  Note that the processor in use has a "MUXED" address/data bus. In 16 bit bus mode, which I am in, the AD31..0 lines drive the full 32 bit address for one processor bus clock cycle - about 20s in this case.  At the rising edge of the SECOND bus cycle, the AD31..16 lines are driving (or reading) 16 bit bus data, while the AD15..0 lines continue driving the 16 LSB's of the address, only the lowest 4 of which are connected to the ADV212.

    I've verified for my code loop that writes the data that it appears to be writing the correct patterns to the D6/4/2/0 lines that are in the trace.  But as you can see in the second write bus cycle, which we don't see on the first due to triggering on the falling edge of CS, the data lines are changing as WE falls.  This is the reason for my question.  I don't think this is the issue.

    One question is this. Do I need to do a 32-bit write somehow to IADDR, rather than just a 16 bit single write?

  • Ok, I just made a change that made all the difference in the world.

    I've been writing 0x0005 to the MMODE register - 16-bit indirect access, 16-bit auto increment.  I just changed to 32-bit indirect access and 32-bit auto increment by writing a value of 0x000A to MMODE.  Now my code does a write to STAGE and a write to IDATA to load each 32-bits of the encode sea file, versus just a bunch of 16-bit writes to IDATA.

    I also changed my read back to read from IDATA then STAGE for the high 16-bits and low 16-bits of each word of the program.

    BOOM. I now read back exactly what is expected!

    So I went from this (things are off a half word either on write or read - not sure which):

      *adv212_register_MMODE = 0x0005;

      *adv212_register_STAGE = 0x0005;

      *adv212_register_IADDR = 0x0000;

      for (t=0;t<adv212_firmware_num_words;t++)

      {

        *adv212_register_IDATA = adv212_firmware_data[t];

      }

    To this:

      *adv212_register_MMODE = 0x000A;

      *adv212_register_STAGE = 0x0005;

      *adv212_register_IADDR = 0x0000;

      for (t=0;t<adv212_firmware_num_words;t+=2)

      {

        *adv212_register_STAGE = adv212_firmware_data[t];

        *adv212_register_IDATA = adv212_firmware_data[t+1];

      }

    Can someone explain to me how I am misunderstanding the way the MMODE register and indirect access for a 16-bit host work?

  • Ok - well, for whatever reason, using MMODE = 0xA seems to let me write and verify both my encode program and the parameters I am loading. I then wait for the ADV212 to generate an IRQ, but am getting a SWFLAG value of 0x500, so now I am on to debug that.  I am not sure I have valid parameters loading, so need to double check all that  that next.

    Yep just checked and the guy who wrote this code for me (contractor) has just 0x1 to 0x4 (4 16 bit words) writing to the params memory at 0x0005 0x7f00.   I am off to set up for NTSC encoding and will fill in a proper array of params for the encode.  I am assuming that the program dos not start and run and write its signature to SWFLAG if the parameters are bad?