Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
March 28, 2024, 03:25:46 15:25


Login with username, password and session length


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

Posts: 19

Thank You
-Given: 22
-Receive: 3


« 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
schisanoa
Newbie
*
Offline Offline

Posts: 10

Thank You
-Given: 3
-Receive: 5


« Reply #1 on: May 15, 2022, 01:47:21 13:47 »

I am not expert in ATMEL studio, but, did you try in debug to check if the peripheral register are set up in the same way? Is clock of DMA enabled? Without DMA does the shift register work properly  also with KEIL?

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