[ATMEL]/SAMD212018. 6. 29. 15:58

[SAMD21E-S EVM] Atmel Start 에서 printf 사용하기 (float 변수 출력)

[SAMD21E-S EVM] Atmel Start 에서  printf 사용하기 (float 변수 출력)



Atmel START 개발환 경에서 시리얼 포트 출력에서 printf 를 사용하려면 _write(), _read() 함수를 원하는 포트로 재 정의 해 주면 된다.


int _write( int32_t file , uint8_t *ptr , int32_t len )
{
       /* Implement your write code here, this is used by puts and printf for example */
       for ( int16_t i = 0 ; i < len ; ++i )
       {
              //HAL_UART_Transmit( &hUART, ptr++, 1, 100);
              io_write(uart_io, ptr++, 1);
       }
       return len;
}

int _read( int32_t file , uint8_t *ptr , int32_t len )
{
       /* Implement your write code here, this is used by puts and printf for example */
       return len;
}




ATSAMD21에서 printf는 잘 동작 하긴 하는데...

문제는 printf 함수로 float 변수를 출력하면 정상 출력이 된다.



옵션에서 


-u_printf_float

를 추가 해 주면 된다고 한다.












ATSAMD21 printf 함수에서 float 변수 출력 예제 소스코드

#include <atmel_start.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

struct io_descriptor *uart_io;
       
int _write( int32_t file , uint8_t *ptr , int32_t len )
{
       /* Implement your write code here, this is used by puts and printf for example */
       for ( int16_t i = 0 ; i < len ; ++i )
       {
              //HAL_UART_Transmit( &hUART, ptr++, 1, 100);
              io_write(uart_io, ptr++, 1);
       }
       return len;
}

int _read( int32_t file , uint8_t *ptr , int32_t len )
{
       /* Implement your write code here, this is used by puts and printf for example */
       return len;
}


int main(void)
{
       /* Initializes MCU, drivers and middleware */
       atmel_start_init();

       usart_sync_get_io_descriptor(&USART_0, &uart_io);
       usart_sync_enable(&USART_0);

       printf("SAMD21 UART test\r\n");
       
       
       /* Replace with your application code */
       while (1) 
       {
              fcnt = fcnt + 0.1;

              printf("%d, %.2f\r\n", cnt++, fcnt);
              gpio_toggle_pin_level(LED1);
              
              delay_ms(500);
       }

}




ATSAMD21 printf 동작 출력 화면


Posted by nexp

댓글을 달아 주세요

[ATMEL]/SAMD212018. 6. 29. 15:58

[SAMD21E-S EVM] ATSAMD21 UART 테스트

[ATSAMD21E-S EVM] ATSAMD21 UART 테스트[SAMD21E-S EVM] ATSAMD21 UART 테스트

ATSAMD21 의 UART 실험을  Atmel Studio 에서 해보았다.
[SAMD21E-S EVM] 보드는 S-Type EVM 형태의 핀맵으로 표준화 되어 있고 Serial 핀이 PA10(TXD), PA11(RXD) 에 할당 되어 있다.

먼저 Atmel START로 프로젝트 생성하고 UART Component를 추가 한다.

 

UART 핀맵을 PA10, PA11에  할당하고 코드 생성 한다.

 

 

테스트는 S-Type - SSM-Type EVM 확장테스트 보드, USB C-type USB2UART 보드를 이용하여 진행 하였다.

 

 

Atmel START에서 자동 생선된 기본 코드에서 examlpe 를 참고 하여 간단히 UART로 출력 하는 코드를 작성하여 테스트 가능하다.

#include <atmel_start.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
 
struct io_descriptor *uart_io;
       
 
int main(void)
{
       /* Initializes MCU, drivers and middleware */
       atmel_start_init();
 
       usart_sync_get_io_descriptor(&USART_0, &uart_io);
       usart_sync_enable(&USART_0);
 
 
       
       /* Replace with your application code */
       while (1) 
       {

                io_write(uart_io, "a", 1);

              gpio_toggle_pin_level(LED1);
              delay_ms(500);
       }

}

 

Posted by nexp

댓글을 달아 주세요

[ATMEL]/SAMD212018. 6. 28. 01:17

[SAMD21E-S EVM] ATSAMD21 MCU 성능 측정 - ATSAMD21 48Mhz 클럭 설정 문제 발생 및 해결

[SAMD21E-S EVM] ATSAMD21 MCU 성능 측정 - ATSAMD21 48Mhz 클럭 설정 문제 발생 및 해결





SAMD21은 저렴한 가격에 소형이고 적당한 성능(48Mhz Cortex-M0)에 USB까지 있어 사용할 곳이 많을것 같은 MCU이다.

실제 성능을 한번 측정 해 보자.


우선 단순하게 GPIO 토글 속도를 측정해 봐야 할것 같다.


    // Set pin direction to output
    gpio_set_pin_direction(PA14, GPIO_DIRECTION_OUT);
    gpio_set_pin_function(PA14, GPIO_PIN_FUNCTION_OFF);

    /* Replace with your application code */
    while (1)
    {
        delay_ms(1);        
        PORT->Group[0].OUTSET.reg = 0x4000;
        PORT->Group[0].OUTCLR.reg = 0x4000;
    }


Atmel START에서 생성된 기본 코드로 동작 시켰더니 500ns 가 걸린다.
기본 설정이라 그런가... 
비슷한 코어의 STM32F0 EVM 보드와 비교해 보면 너려도 너무 느리다






우선 클럭 쪽을 좀 들여다 보자.
1Mhz 로 구동되도록 되어 있다.

아래와 같이 DFLL48M으로 설정하고 동작 시켰더니 CPU가 멈춰버린다.




디버깅 해 보면 외부 32khz 클럭을 사용하고 아래 코드에서 멈추는 현상이 있다. 
32khz 클럭 소스 자체가 잘못 되었나?


#if CONF_OSC32K_CONFIG == 1
#if CONF_OSC32K_ENABLE == 1
       while (!hri_sysctrl_get_PCLKSR_OSC32KRDY_bit(hw))
              ;
#endif


내부 32khz를 사용해 보자. 잘 동작한다.



외부 클럭만으로 사용해 보자. 잘 동작 한다.



클럭은 문제 없는것 같고...
클럭이 너무 높아서 그런가?

다시 한번 DFPLL48M 을 클럭 소스로 해서 동작 시키면 




아래와 같은 에러로 빠져 버린다.

FFFFFFFE  ???         Memory out of bounds or read error








DFPLL48M 설정에 문제가 있나?

FDPLL96M 을 사용해 보자. 여전히 같은 증상이다.





클럭을 clock Precalar를 이용하여 8Mhz 이하로 낮추면 정상 동작한다.
Atmel 홈페이지에서는 자료를 아무리 찾아도 설정 관련 내용이 없었는데...




문제 발생
클럭을 8Mhz 이상으로 설정하면 MCU(SAMD21)가 멈추는 현상 발생

항상 새로운 MCU를 사용할때는 문제가 발생 하는것 같다. 이런 문제들이 발생할때 해되면 그 행복감에 또 이런 일 하는 것 아닐까...




문제 해결
48Mhz로 구동시 NVM Wait States 항목을 1로 변경해 주어야 한다.

이것때문에 한참을 고생을 했네...









문제 발생

외부 32.768khz X-tal사용하니 또 멈춰 있는 현상이 발생한다.




문제 해결
X-Tal 사용하려면 "Enable 32KHz output" and "Enable XTAL" 옵션을 체크 해 주어야 한다.

디폴트로 설정되면 좋겠구만... 왜 이렇게 어렵게 해 놓은거야..





컴파일러의 옵티마이즈 옵션에도 성능 차이가 있다.


O-1
       while (1)
       {
              delay_ms(1);         
 6c2:  4e07          ldr    r6, [pc, #28] ; (6e0 <main+0x44>)
              PORT->Group[0].OUTSET.reg = 0x4000;
 6c4:  001d          movs   r5, r3
 6c6:  2480          movs   r4, #128      ; 0x80
 6c8:  01e4          lsls   r4, r4, #7
              delay_ms(1);         
 6ca:  2001          movs   r0, #1
 6cc:  47b0          blx    r6
              PORT->Group[0].OUTSET.reg = 0x4000;
 6ce:  61ac          str    r4, [r5, #24]
              PORT->Group[0].OUTCLR.reg = 0x4000;
 6d0:  616c          str    r4, [r5, #20]
 6d2:  e7fa          b.n    6ca <main+0x2e>
 6d4:  00000115      .word  0x00000115
 6d8:  41004400      .word  0x41004400
 6dc:  40004000      .word  0x40004000
 6e0:  000002d5      .word  0x000002d5



-O3
       while (1)
       {
              delay_ms(1);         
 65c:  2001          movs   r0, #1
 65e:  47b0          blx    r6
              PORT->Group[0].OUTSET.reg = 0x4000;
 660:  61a5          str    r5, [r4, #24]
              PORT->Group[0].OUTCLR.reg = 0x4000;
 662:  6165          str    r5, [r4, #20]
 664:  e7fa          b.n    65c <main+0x28>
 666:  46c0          nop                  ; (mov r8, r8)
 668:  00000115      .word  0x00000115
 66c:  41004400      .word  0x41004400
 670:  40004000      .word  0x40004000
 674:  00000295      .word  0x00000295




ATMEL Studio 에서 옵티마이즈 옵션 설정






ATSAMD21을 48Mhz로 구동하고 최종적으로 GPIO토글 속도를 측정해 보면 86ns로 측정 된다.



       atmel_start_init();
              
       gpio_set_pin_level(LED1, true);
       /* Replace with your application code */
       while (1) 
       {
              PORT->Group[0].OUTSET.reg = (0x1<<27);
              PORT->Group[0].OUTCLR.reg = (0x1<<27);
              delay_ms(1);
       }



Posted by nexp

댓글을 달아 주세요

[ATMEL]/SAMD212018. 6. 28. 01:17

[SAMD21E-S EVM] ATSAMD21 개발환경 설정 - Atmel Studio7 (ATMEL START)

[SAMD21E-S EVM] ATSAMD21 개발환경 설정 - Atmel Studio7 (ATMEL START)

ATSAMD21 의 개발환경으로 AtmelStudio7를 사용 하였다.


기존 AVR 컴파일에 사용 했던 Atmel START를 이용하면 쉽게 SAM 시리즈도 개발 할수 있어 장점인것 같다.




우선 새로운 프로젝트를 Atmel START로 생성한다. 




디바이스(ATSAMD21)를 선택하고 다음.






DASHBOARD 에서 필요한 Component를 추가 한다.







PINMUX 에서 프로젝트에 사용될 핀들을 할당하고 설정한다.







AtmelStudio START의 장점으로 생성된 코드에서 Atmel START 프로젝트 환경을 생성해 낼 수 있다. 즉 개발 도중에 추가 컴포넌트가 있거나 핀맵 변경이 있을 경우 프로젝트 파일을 새롭게 생성해 수정할수 있어 편한것 같다.

ST사의 CubeMx의 경우 컴포넌트 수정 반영하려면 상당히 고려해야 할 사항이 많아 불편했는데 이부분은 잘 되어 있는것 같다.






Posted by nexp

댓글을 달아 주세요

[ATMEL]/SAMD212018. 6. 27. 10:44

[SAMD21E-S EVM] ATSAMD21 미니보드 제작

[SAMD21E-S EVM] ATSAMD21 미니보드 제작



간단한 프로젝트 진행을 위해 소형 이면서 저렴하고 어느정도 성능도 보장하는 MCU를 찾게 되는데 ATSAMD21E는 QFN32의 소형 저가격(1$대)을 만족하는 칩 인것 같다.


핀맵도 간단하고 쉽게 제작 할 수 있어서 S-Type 형태의 소형으로 제작 해 보았다.





SM-Type 핀맵 회로도



간단히 테스트 해 볼수 있는 LED가 PA27에 할당 되어 있다.




QNF32의 작은 칩 이지만 DA출력도 있어 오디오 출력도 가능해 보드 내부에 Serial Flash 메모리도 실장 할수 있도록 했다.





S-Type 형태의표준 핀맵으로 제작해 다양한 확장 테스트 보드에서 테스트 가능하도록 했다











Posted by nexp

댓글을 달아 주세요