Using the MSU's CRC32 engine

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

Does anybody have any experience working with the AVR32 UC3's built-in CRC32 computation engine? I'm hoping to use it to save some code size and complexity performing an integrity check of applications loaded through an in-house bootloader.

 

I'm working with an AT32UC3A0152. So far, I've tried code that looks like this:

#define AVR32_MSU_STATUS_RESULT_BUSY	1
#define AVR32_MSU_STATUS_RESULT_DONE	0
#define AVR32_MSU_CTRL_OP_NONE			0
#define AVR32_MSU_CTRL_OP_CRC			1
static void wait_for_msu(void)
{
	uint32_t status;
	do
	{
		status = Get_system_register(AVR32_MSU_STATUS);
	} while ((status & AVR32_MSU_STATUS_RESULT_MASK) == AVR32_MSU_STATUS_RESULT_BUSY);
}

static void wait_for_msu_done(void)
{
	volatile uint32_t status;
	do
	{
		status = Get_system_register(AVR32_MSU_STATUS);
	} while ((status & AVR32_MSU_STATUS_RESULT_MASK) != AVR32_MSU_STATUS_RESULT_DONE);
}

static uint32_t msu_compute_crc(uint32_t start, size_t length, uint32_t initial)
{
	Set_system_register(AVR32_MSU_CTRL, AVR32_MSU_CTRL_OP_NONE);
	wait_for_msu();
	Set_system_register(AVR32_MSU_ADDRHI, 0);
	Set_system_register(AVR32_MSU_ADDRLO, start);
	Set_system_register(AVR32_MSU_LENGTH, length);
	Set_system_register(AVR32_MSU_DATA, initial);
	Set_system_register(AVR32_MSU_CTRL, AVR32_MSU_CTRL_OP_CRC);
	wait_for_msu_done();
	return Get_system_register(AVR32_MSU_DATA);
}

I'm passing in a start address equal to the beginning of my application section (0x80004000) and a length equal to half of the remaining flash in the device (253952).

What I'm finding is that wait_for_msu_done() is getting stuck because the status register is reporting a BUS_ERR condition.

Has anybody worked with this module before? Are there any other hardware modules or clock domains I need to ensure are enabled before I can use it? Where else should I look for pointers on how to work with it correctly?

Last Edited: Wed. Oct 19, 2016 - 02:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Double checking the documentation, I note that the MSU related registers are listed as being present in the system register memory map provided in the AVR32 UC Technical Reference Manual (http://www.atmel.com/Images/doc3...) table 2-2.

But the MSU registers are NOT listed in the system register memory map provided in the AT32UC3A0152 datasheet (http://www.atmel.com/Images/doc3...) table 9-3.

 

Maybe the MSU registers aren't actually mapped into the system register space in this particular variant of the UC3 architecture?

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

A CRC16 function is 6 statements in C. (4 if you use the faster but larger table-driven method)

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

Oh, I know *how* to do a CRC. But I was hoping to use hardware acceleration if possible. Primarily for speed, but also because I have a philosophy of not doing something in software that's already done for me in hardware.

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

I totally agree !


From my interpretation of the datasheets, I think you can only get to the Memory Service Unit from the Service Address Bus, but the Service Address Bus appears to only be accessible via the JTAG.

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

Hi,

 

I have been using the MSU CRC with success on other UC3 devices. I think the problem you have is that you are not using the correct 36 bit SAB address. You need to set the ADDRHI register to 0x4 or 0x5 to reach the HSB memory space. (see the SAB address map section of the datasheet) 

 

 

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

Thank you lfmorrison and numakk.


I did some experimentation with a UC3Lxx and found ;
- the CRC uses the 32 bit polynomial 0x04C11DB7 with no XOR of the final result.
- it is roughly x3 faster than a software table-lookup routine with maximum compiler optimisation, and about x8 faster with no compiler optimisation.
- it returns an incorrect crc32 if used with less than 16 bytes.