SAML11 UART Problem

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi All,

 

I have been trying to break away from using ASF and learn more by programming all of the peripheral features of a device myself. I am using the XPlained SAML11 development board as my aim in the future is to understand how the Trustzone features work and test test out the other security features.

 

I am having a problem setting up the UART. My code is below. All I am trying to do initially is a basic setup where the device repeatedly sends a character to my laptop via serial.  I have reviewed my UART for hours and can't seem to spot anything wrong. My though is that writes to the DATA reg are being ignored because the SERCOM is enabled as a secure peripheral by default. I don't know how to get around this currently. I guess the first question is does anybody see anything basic that I have messed up on, and secondly if not how do I get around this issue? 

 

#include "sam.h"
#include "stdint.h"
#include "stdio.h"
#include "hal_delay.h"
#include "toms_setup.h"
#include "hal_io.h"
#include "hpl_usart_async.h"

#define peripheral_clock 32000000 
#define desired_baudrate 115200 

void setup(void){

	ext_clock_16MHz();
	trustzone_setup();
	setup_pins();
	delay_driver_init();
	setup_USART();
}

int main(void)
{
	setup();

	while(1){
		
		if (SERCOM0->USART.INTFLAG.bit.DRE==1){
    	SERCOM0->USART.DATA.reg = 'w';
		delay_ms(500);
        }

	}

	return 0;
}


void setup_USART(){
	
MCLK -> APBCMASK.reg = MCLK_APBCMASK_SERCOM0 ;				//enable APB Bus clock for SERCOM0
GCLK -> PCHCTRL[SERCOM0_GCLK_ID_CORE].bit.GEN = 0x2;		//select GCLK2 for SERCOM0_core peripheral clock, index 11  32MHz
GCLK -> PCHCTRL[SERCOM0_GCLK_ID_CORE].bit.CHEN = 1;			//enable peripheral clock for SERCOM0_core, index 11			//max sercom core freq 48MHz
GCLK -> PCHCTRL[SERCOM0_GCLK_ID_SLOW].bit.GEN = 0x3;		//select GCLK3 for SERCOM0_slow peripheral clock, index 10   4Mhz
GCLK -> PCHCTRL[SERCOM0_GCLK_ID_SLOW].bit.CHEN = 1;			//enable peripheral clock for SERCOM0_slow, index 10			//max sercom slow 6MHz
	
SERCOM0 ->USART.CTRLA.bit.ENABLE = 0x0; 
while(SERCOM0->USART.SYNCBUSY.bit.ENABLE){};
		
SERCOM0 ->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(0x1)     |		//use internal clock 
								SERCOM_USART_CTRLA_RXPO(0x1) |		//set Sercom PAD for Rx (PAD[1])
								SERCOM_USART_CTRLA_TXPO(0x0) |		//set Sercom PAD for Rx (PAD[0])
								SERCOM_USART_CTRLA_DORD		 ;		//transmit LSB first
								
SERCOM0 ->USART.CTRLB.reg = SERCOM_USART_CTRLB_CHSIZE(0x0)   |		//char size 8
								SERCOM_USART_CTRLB_RXEN		 |		//enable Rx
								SERCOM_USART_CTRLB_TXEN		 ;		//enable Tx
								

while(SERCOM0->USART.SYNCBUSY.bit.CTRLB){};						    //wait while CTRLB syncs 
	
SERCOM0 ->USART.BAUD.bit.BAUD = 65535.0f * ( 1.0f - (float)(16) * (float)(desired_baudrate) / (float)(peripheral_clock));;	
	

for(int i=1; i<5;i++){
NVIC_EnableIRQ((21+i));}										//enable NVIC SERCOM0 interrupts 

SERCOM0->USART.INTENSET.reg = SERCOM_USART_INTFLAG_RXC;			//enable receive interrupt 
	
SERCOM0 ->USART.CTRLA.bit.ENABLE = 0x1;							//enable USART
while(SERCOM0->USART.SYNCBUSY.bit.ENABLE){};					//wait for sync 

PORT_SEC ->Group[0].PINCFG[22].bit.PMUXEN = 1;			  //enable PA25 peripheral function
PORT_SEC ->Group[0].PINCFG[23].bit.PMUXEN = 1;			  //enable PA24 peripheral function
PORT_SEC ->Group[0].PMUX[11].bit.PMUXO = 0x2;			  //select peripheral function C for odd pins in Group0
PORT_SEC ->Group[0].PMUX[11].bit.PMUXE = 0x2;			  //select peripheral function C for even pins in Group0

/*
PORT ->Group[0].PINCFG[22].bit.PMUXEN = 1;			  //enable PA25 peripheral function
PORT ->Group[0].PINCFG[23].bit.PMUXEN = 1;			  //enable PA24 peripheral function
PORT ->Group[0].PMUX[11].bit.PMUXO = 0x2;			  //select peripheral function C for odd pins in Group0
PORT->Group[0].PMUX[11].bit.PMUXE = 0x2;			  //select peripheral function C for even pins in Group0
	*/
}
					

cheers,

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've managed to find the solution, and its kind of annoying. The PMUX reg  only works if you have the full pin number i.e. PMUX[23>>1]. can anyone explain this? As the PMUX reg has both the odd and even pin then i assumed the step would be half? 

 

Cheers,

Tom 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Tom,

 

Just came across your post as I am having problems getting a UART to work on the same dev board.

 

I have tried the Atmel Start Example Project route to no avail and I am interested in how you have gone about it.

 

Are you using AVR Studio 7 (aka Microchip studio)?, if so could you give a an idea of how to go about creating a project that could use your code example.

 

Any help would be much appreciated

 

Ian