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