AT32UC3A0512 with external SDRAM not working

adissida wrote on Tuesday, September 08, 2015:

Hi! New with FreeRTOS, and so far it is impressive! Love it.
Now I want to make use of the external SDRAM. I have a rutine that check the SDRAM and it works grate when using heap_3. I have also two leds blinking independently different freq. So freertos works grate. Now I add heap_5 and define the SDRAM start and size (0x7A12000, 16MB of SDRAM):

'#include “FreeRTOS.h”
'#include “task.h”

int main (void)
{
const HeapRegion_t xHeapRegions[] =
{
{ ( uint8_t * ) 0xD0000000UL, 0x7A12000 },
{ NULL, 0 }
};
void vPortDefineHeapRegions(xHeapRegions);

trvInitHercules();

xTaskCreate( trvBlinkMCULED,		(const signed portCHAR *)"Blink MCU",	configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY1, NULL );
xTaskCreate( trvBlinkAlarmLED,		(const signed portCHAR *)"Blink Alarm", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY2, NULL );

vTaskStartScheduler();

return 0;

}

The memory test in trvInit() passes, and then should leds start blinking, but no. I have followed all instructions that I found regardingn external SDRAM. What could be wrong?

heinbali01 wrote on Wednesday, September 09, 2015:

Hi Adis,

Using Atmel’s UC3A0512 :

{ ( uint8_t * ) 0xD0000000UL, 0x7A12000 },

My calculator says that ‘0x7A12000’ equals 128000000, which is about 122 MB. Accessing non-existent memory might lead to a crash (hardware exception). You write that you have 16MB of SDRAM, which corresponds to 0x1000000.

The heap regions are described in an array of:

/* Used by heap_5.c. */
typedef struct HeapRegion
{
    uint8_t *pucStartAddress;
    size_t xSizeInBytes;
} HeapRegion_t;

You could write it like this:


#incluide <avr32/io.h>
/*
which includes "uc3a0512.h" with this declaration:

#define AVR32_EBI_CS1_ADDRESS              0xD0000000
*/

#define SDRAM_ADDRESS     ( AVR32_EBI_CS1_ADDRESS )
#define SDRAM_SIZE        ( 16ul * 1024 * 1024 )

/*
 * What is the clock speed of your CPU: 48, 60 or 66 MHz ?
 * The HSB (High-Speed-Bus) is equal to the CPU speed,
 * they're coupled.
 */

#define CLOCK_HSB_HZ    48000000

const HeapRegion_t xHeapRegions[] =
{
    { ( uint8_t * ) SDRAM_ADDRESS, ( size_t ) SDRAM_SIZE },
    { ( uint8_t * ) NULL, ( size_t ) 0 }
};

/* or if you like, a less-used C syntax: */

const HeapRegion_t xHeapRegions[] =
{
    [0] = {
        .pucStartAddress = ( uint8_t * ) SDRAM_ADDRESS,
        .xSizeInBytes = ( size_t ) SDRAM_SIZE
    },
    [1] = {
        .pucStartAddress = ( uint8_t * ) NULL,
        .xSizeInBytes = ( size_t ) 0
    }
};

void main()
{
    /* Initialise the SDRAM. */
    /* See "EBI/SDRAMC/sdramc.c" */
    sdramc_init( CLOCK_HSB_HZ );

    /* Tell heap_5 which heap area(s) can be used. */
    vPortDefineHeapRegions( xHeapRegions );

    /* Your code: */
    trvInitHercules();

    /* The string "Blink MCU" doesn't need a cast to
    because now xTaskCreate() takes a const char* */
    xTaskCreate( trvBlinkMCULED, "Blink MCU", configMINIMAL_STACK_SIZE,
        NULL, mainLED_TASK_PRIORITY1, NULL );
    xTaskCreate( trvBlinkAlarmLED, "Blink Alarm", configMINIMAL_STACK_SIZE,
        NULL, mainLED_TASK_PRIORITY2, NULL );

    vTaskStartScheduler();
}

Will that work?

Regards.

adissida wrote on Wednesday, September 09, 2015:

Hi

Nope, still dead. This is what my main.c contais now:


'#include <board.h>
'#include <compiler.h>
'#include <stdio.h>
'#include <stdlib.h>
'#include <string.h>

'#include “gpio.h”
'#include “trv_apps.h”

'#define SDRAM_ADDRESS AVR32_EBI_CS1_ADDRESS
'#define SDRAM_SIZE_A ( 16ul * 1024 * 1024 )

'#include “FreeRTOS.h”
'#include “task.h”

const HeapRegion_t xHeapRegions[] =
{
{ ( uint8_t * ) SDRAM_ADDRESS, ( size_t ) SDRAM_SIZE_A },
{ NULL, ( size_t ) 0 }
};

int main (void)
{
trvInitHercules();

void vPortDefineHeapRegions(xHeapRegions);

xTaskCreate( trvBlinkMCULED, "Blink MCU",	configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY1, NULL );
xTaskCreate( trvBlinkAlarmLED, "Blink Alarm", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY2, NULL );

vTaskStartScheduler();

return 0;

}


and this is where my trvInitHercules(); is:


'#include <board.h>
'#include <compiler.h>
'#include <stdio.h>
'#include <stdlib.h>
'#include <string.h>

'#include “gpio.h”
'#include “sdramc.h”
'#include “trv_apps.h”
'#include “power_clocks_lib.h”

'#include “FreeRTOS.h”
'#include “task.h”

volatile unsigned long *sdram = SDRAM;
volatile unsigned long *sdram_work = SDRAM;

void trvInitHercules(void)
{
/* This function is meant to contain board-specific initialization code
* for, e.g., the I/O pins. The initialization can rely on application-
* specific board configuration, found in conf_board.h.
*/

pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

static pcl_freq_param_t pcl_freq_param =
{
	.cpu_f        = 66000000,
	.pba_f        = 66000000,
	.osc0_f       = FOSC0,
	.osc0_startup = OSC0_STARTUP
};

// Configure system clock
if (pcl_configure_clocks(&pcl_freq_param) != PASS)
{
	gpio_clr_gpio_pin(HER_LED_MCU);
}

sdramc_init(F_CPU); // F_CPU is 66000000

//trvSDRAMSelfTest(sdram);

}


Dont know why it doeset work.

adissida wrote on Wednesday, September 09, 2015:

My fault, i entered void vPortDefineHeapRegions(xHeapRegions); instead of just vPortDefineHeapRegions(xHeapRegions);… Now it works. Thank you Hein!

heinbali01 wrote on Thursday, September 10, 2015:

I already looked at your:

    main()
    {
        void vPortDefineHeapRegions(xHeapRegions);
    }

and I wondered how the compiler would interpret that line.

It is not a function call because of the word “void”.
It is not a function declaration because it misses a parameter type.

Now it works. Thank you Hein!

If you have any more questions, don’t hesitate to write.

Regards.