SOLVED: Reading User Signature Pages (C)

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

First: Apology if this has been asked here before.  I am still not proficient searching the new forum.  Google has not been tremendously helpful either.

 

I am playing with a ATZB-S1-256-S-0-C (Zigbit module built around an ATMEGA256RFR2).  Per the data sheet for the module, every module has a unique MAC address programmed into its user signature data (page 1).  The data sheet actually calls it "Persistence Memory" and references quite a lot of information stored in there (see Table 5-1 on p. 17).

 

I would like to be able to read this data out from within my program -- specifically, I would like to be able to read it out in C (not assembly).  The only example I was able to find in the ATMEGA256RFR2 data sheet was in assembly -- on p. 494.  Even this example seems like not exactly what I want, because it is actually reading the Signature Bytes (not the "User Signature Data").

 

Can anyone point me in the right direction for doing this?  Is it even possible to do in C (w/o inline assembly)?

 

Edit:

The note in the Zigbit module data sheet is less than helpful:

 

Special commands are available to erase and write data to user signature pages via the JTAG interface (see section on
"Programming via the JTAG Interface” in Atmega256RFR2 datasheet [1] for details). User signature rows can be read
from software in the same way as the device and JTAG identifiers (see section "Reading the Signature Row from
Software" of Atmega256RFR2 datasheet[1]).

 

I do NOT need to erase/write to these pages -- just read...  Everything I can find online is for Xmegas, not AVRs.

Science is not consensus. Science is numbers.

Last Edited: Sat. May 30, 2015 - 02:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am guessing that this is simply some extra SPM command functionality.

Yes,   to read the Fuses or Signature on a Mega or Tiny requires a specific ABI.   i.e. which machine register(s) to write and return.

 

GCC has got a suitable header that provides this functionality :  <avr/boot.h>

Codevision has got an example program (I think)

I have certainly published Arduino sketches and C programs that do this.

 

Your data sheet will tell you the details of your specific SPM command.

 

I suggest that you try the Fuse reading first.   i.e. Google for example programs.

 

David.

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

David -- thanks for the response.  After perusing boot.h, I came across the following: 

 

/** \ingroup avr_boot
    \def boot_signature_byte_get(address)

    Read the Signature Row byte at \c address.  For some MCU types,
    this function can also retrieve the factory-stored oscillator
    calibration bytes.

    Parameter \c address can be 0-0x1f as documented by the datasheet.
    \note The values are MCU type dependent.
*/

#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))

#define boot_signature_byte_get(addr) \
(__extension__({                      \
      uint8_t __result;                         \
      __asm__ __volatile__                      \
      (                                         \
        "sts %1, %2\n\t"                        \
        "lpm %0, Z" "\n\t"                      \
        : "=r" (__result)                       \
        : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \
          "r" ((uint8_t)(__BOOT_SIGROW_READ)),  \
          "z" ((uint16_t)(addr))                \
      );                                        \
      __result;                                 \
}))

 

I have two questions -- first, regarding the comment about "Parameter \c" being between 0-0x1f "as documented by the datasheet.  If I want to read user signature rows, it will be up in the 0x100 - 0x1FF range.  I can test to see if that works easily enough.  By just looking at the code, is there any reason it won't work?  I know zero assembly, but it looks like it is casting addr as a UINT16...

 

Second: how do I actually get the result?  Am I correct in assuming it is just "returned"

 

i.e.:  myByte = boot_signature_byte_get(0x100); will return the byte located at user signature data row 1 (addr 0x100)?

 

Science is not consensus. Science is numbers.

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

Am I correct in assuming it is just "returned"

Yes, the inline asm macro is defined to act like a function.

 

My reading of 30.6.10 in the datasheet suggests that this function should work just as well for the 3 user pages as it does for the "normal" signature stuff.

 

I think the comment in boot.h is saying that usually, for "normal" AVRs, the address range is more limited and it doesn't make sense to stray beyond the given limit - but it looks like it will cater for it anyway.

Last Edited: Fri. May 29, 2015 - 11:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Officially,   most AVRs only have the Signature and Calibration bytes in the Signature Row.

I was looking at the ATmega32U2 data sheet:

Table 23-6. Signature Row Addressing
Signature Byte Z-Pointer Address
Device Signature Byte 1 0x0000
Device Signature Byte 2 0x0002
Device Signature Byte 3 0x0004
RC Oscillator Calibration Byte 0x0001
Unique Serial Number From 0x000E to 0x0018

Other chips might have Temperature Calibration.    As I said,  I have not looked at your data sheet.   I guess it will be similar.   There are no unused bits in SPMCSR.

Just try it and see.

 

I guess that some of the undocumented locations might hold something useful.   OTOH,   if undocumented,   it is unwise (tm) to make any use of it.

 

David.

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

As I said,  I have not looked at your data sheet.   I guess it will be similar. 

Yup, pretty much...

 

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

Tried and seen -- it works.

 

Thanks again for the tip to look into boot.h

Science is not consensus. Science is numbers.