This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DMA doesn't work in Keil, but it works in Atmel Studio

Hello to all,
I' using Keil MDK ARM IDE to work on a a project with an ATSAML21E18B connected to a shift register. I want to use DMA to send data through SCLK and MOSI pins. To configure my project i used the AtmelStart online platform.
I connected the SPI pins to a digital signal analyzer and I program/debugg it with the Segger J-Link.
The test program I'm working on is simple:
1- init the hardware
2- fill an array with fixed value
3- send it using DMA
4- a callback function blinks a LED when DMA has finished the data sending
5- loop 2,3,4 forever

Everything seems correct, instead it doesn't work: using Keil ARM 5.29 my code compiles (compilation without optimizations) then runs, it seems to set up all hardware devices correctly, but when my code calls the "spi_m_dma_transfer(...)" function (line 65) nothing flows out from SPI pins, and the DMA callback is never called.
I couldn't understand where the problem was until I tried to compile the exact same project with AtmelStudio: it worked!
I setted up a Keil project in the same folder with the AtmelStudio project: compiling with keil does not work, compiling with AtmelStudio works.

After two week of sleepless nights I can't understand how the same code could work differently using two IDEs and I don't know which test can still be done.
I attach here the project (Keil and AtmelStudio project) and I hope some of you can help me.
Thanks!

/* Transfer completed callback */
static void vUtil_DMA_transfer_SPI_LED( struct _dma_resource *resource ) {
	while( hri_sercomspi_get_INTFLAG_TXC_bit( SERCOM0 ) == 0 );					// wait for the last bit is sent

	gpio_set_pin_level( STAT_LED, true );												// turn ON the status LED
	delay_short();																				// wait
	gpio_set_pin_level( STAT_LED, false );												// turn OFF the status LED
	delay_short();																				// wait
}

int main( void ) {
	init_mcu();																					// system_init
	// SPI_LED_CLOCK_init
	hri_gclk_write_PCHCTRL_reg( GCLK, SERCOM0_GCLK_ID_CORE, CONF_GCLK_SERCOM0_CORE_SRC | ( 1 << GCLK_PCHCTRL_CHEN_Pos ) );
	hri_gclk_write_PCHCTRL_reg( GCLK, SERCOM0_GCLK_ID_SLOW, CONF_GCLK_SERCOM0_SLOW_SRC | ( 1 << GCLK_PCHCTRL_CHEN_Pos ) );
	hri_mclk_set_APBCMASK_SERCOM0_bit( MCLK );
	// SPI_LED_init
	spi_m_dma_init( &SPI_LED, SERCOM0 );												// init the DMA using HAL function
	// SPI_LED_PORT_init
	gpio_set_pin_direction( LED_MISO, GPIO_DIRECTION_IN );
	gpio_set_pin_pull_mode( LED_MISO, GPIO_PULL_OFF );
	gpio_set_pin_function( LED_MISO, PINMUX_PA04D_SERCOM0_PAD0 );
	gpio_set_pin_level( LED_SCLK, false );
	gpio_set_pin_direction( LED_SCLK, GPIO_DIRECTION_OUT );
	gpio_set_pin_function( LED_SCLK, PINMUX_PA05D_SERCOM0_PAD1 );
	gpio_set_pin_level( LED_MOSI, false );
	gpio_set_pin_direction( LED_MOSI, GPIO_DIRECTION_OUT );
	gpio_set_pin_function( LED_MOSI, PINMUX_PA07D_SERCOM0_PAD3 );
	// status LED init
	gpio_set_pin_function( STAT_LED, GPIO_PIN_FUNCTION_OFF );					// no special function on PIN
	gpio_set_pin_direction( STAT_LED, GPIO_DIRECTION_OUT );						// PIN setted as OUT
	gpio_set_pin_level( STAT_LED, false );												// turn OFF the status LED
	//
	spi_m_dma_register_callback( &SPI_LED, SPI_M_DMA_CB_TX_DONE, vUtil_DMA_transfer_SPI_LED );	// set the callback function for DMA operations
	spi_m_dma_enable( &SPI_LED );															// enable the DMA

	while( 1 ) {
		tx_stream[0] = 0x00;
		tx_stream[1] = 0x01;
		tx_stream[2] = 0x04;
		tx_stream[3] = 0x01;
		tx_stream[4] = 0x00;
		tx_stream[5] = 0x01;
		tx_stream[6] = 0x00;
		tx_stream[7] = 0x01;
		tx_stream[8] = 0x00;
		tx_stream[9] = 0x01;
		spi_m_dma_transfer( &SPI_LED, tx_stream, NULL, 10 );
		delay_short();
	}

	return 0;
}