Using SAM D20 DSU CRC32 feature

Discussions around product based on ARM Cortex M0+ core.

Moderator: nferre

Posts: 3
Joined: Tue Mar 11, 2014 4:35 pm

Using SAM D20 DSU CRC32 feature

Wed Mar 12, 2014 6:36 am


I am trying to use the CRC32 feature in the DSU module to write a function to perform a CRC32 over a section of Flash (fuses are not configured to use EEPROM). I can get it to perform an operation but I always see the STATUSA.BERR bit set. The code for this function currently looks like this:

Code: Select all

uint32_t calculate_crc32_nvm(uint32_t start_address, uint32_t num_bytes)
    uint32_t crc = ~0;
    /* Set up DSU bus clocks */
    /* Disable write protection for DSU module */
    PAC1->WPCLR.reg = PAC_WPCLR_WP(0x1);
    /* Reset the DSU module */
    /* Configure CRC check - give address and number of bytes */
    DSU->ADDR.reg = DSU_ADDR_ADDR(start_address) | DSU_ADDR_AMOD(0);
    DSU->LENGTH.reg = DSU_LENGTH_LENGTH(num_bytes);
    /* Seed the CRC value with 0xFFFFFFFF for start of the calculation*/
    DSU->DATA.reg = 0xFFFFFFFF;
    /* Start the CRC */
    while(!(DSU->STATUSA.reg & DSU_STATUSA_DONE));
    crc = DSU->DATA.reg;
    /* Re-enable write protection for DSU module. This must be re-enabled
	 * because consecutive writes to disable write protection result in a
	 * processor exception. 
    PAC1->WPSET.reg = PAC_WPSET_WP(0x1);

    return crc;
} /* end function calculate_crc32_nvm */
A sample call would look something like:

Code: Select all

uint32_t crc = calculate_crc32_nvm(0x16000, 65536);
I'm guessing the clock generator is set correctly because I can perform other operations such NVM read/write. The PM DSU bus clocks are already set to 1 prior to entering this function, but I set them here just to be sure. Any ideas as to what could be causing the Bus Error?

Posts: 3
Joined: Tue Mar 11, 2014 4:35 pm

Re: Using SAM D20 DSU CRC32 feature

Wed Apr 02, 2014 5:23 pm

For anyone interested, I got a reply from Atmel support. Its seems as though I should have read the documentation a little more carefully. The SAM D20 datasheet clearly states for the ADDR register "Initial word start address needed for memory operations" and LENGTH register "Length in words needed for memory operations." So based on this, changed two lines in my code to:

Code: Select all

    /* Configure CRC check - give address and number of bytes in WORDS */
    DSU->ADDR.reg = DSU_ADDR_ADDR(start_address / 4) | DSU_ADDR_AMOD(0);
    DSU->LENGTH.reg = DSU_LENGTH_LENGTH(num_bytes / 4);
Magic. Now it works. Hope that helps.


Return to “SAM D20 Cortex-M0+ MCU”

Who is online

Users browsing this forum: No registered users and 1 guest