Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
August 09, 2020, 11:49:16 11:49


Login with username, password and session length


Pages: [1]
Print
Author Topic: Different DMA behavior using Keil or Atmel Studio  (Read 459 times)
0 Members and 1 Guest are viewing this topic.
StefDrums
Newbie
*
Offline Offline

Posts: 18

Thank You
-Given: 19
-Receive: 2


« on: January 30, 2020, 08:13:20 08:13 »

Hello to all,
I made a project with ATSAML21E18B connected to a shift register, using only SCLK and MOSI pins. I want to use the DMAC to send datas.
I connected the SPI pins to a signal analyzer and I program/debugg it with the Segger J-Link.
I noticed a strange behavior that I can't solve:  using Atmel Studio the firmware works, but if I use Keil ARM 5.29 the DMA doesn't work.
Everything is compiled and started, it seems to set up all hardware devices correctly, but when my code calls the "spi_m_dma_transfer(...)" function (line 65) with Keil nothing flows out from SPI pins.
spi_m_dma_transfer (...) source code is in \hal\src\hal_spi_m_dma.c and it calls _spi_m_dma_transfer (...) in \hpl\sercom\hpl_sercom.c
with the debugger I can see that the function returns ERR_NONE, but nothing flows out the SPI PINs, connected to the logic analyzer.
I'm trying to understand how the same code could work differently using two IDEs.
I thought it depended on the compiler so I did a further test: used Keil with the GCC.
after a week of sleepless nights I can say that:
Atmel Studio + GCC: works
Keil + ARMCC 5.06: does not work
Keil + GCC: it does not work

I don't know what test it can still do. I am attaching the main.c file and the three different projects. I hope some of you can help me!

Code:
#include <atmel_start.h>

#define DELAY_SHORT 50
#define SPI_LED_HARDWARE SERCOM0 // value UART hardware peripheral

static uint8_t tx_stream[10] = {0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81};
struct spi_m_dma_descriptor SPI_LED;

/* simple delay made by while loop */
static void delay_short( void ) {
volatile uint32_t t = 0;

while( t < DELAY_SHORT ) { t++; }

return;
}

/* Transfer completed callback */
static void vUtil_DMA_transfer_SPI_LED( struct _dma_resource *resource ) {
while( hri_sercomspi_get_INTFLAG_TXC_bit( SPI_LED_HARDWARE ) == 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 ); // this function does not work well in KEIL
// I connected a logic analyzer on SPI pins, and I use J-Link debugger
// this is what i see:
// calls spi_m_dma_transfer (...) is in \hal\src\hal_spi_m_dma.c
// then calls _spi_m_dma_transfer (...) in \hpl\sercom\hpl_sercom.c
// returns ERR_NONE
// but nothing flow out the SPI PINs, connected to a logic analyzer
// also with keil the CPU never calls vUtil_DMA_transfer_SPI_LED
delay_short();
}

return 0;
}
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC