SAMD20: Help init USART without ASF

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

Hi, I want to modify the SAM-BA bootloader so that it uses pins PB08 and PB09 instead of PA24 and PA25.

 

This is the original code that works; I know it works by looking at the scope and adding that while(1) at the end.   I'm using a custom board that gives me access to PA24, the Tx.

 

        /* Enable & configure alternate function C for pins PA24 & PA25 */
        PORT->Group[0].PINCFG[24].bit.PMUXEN = 1;
        PORT->Group[0].PINCFG[25].bit.PMUXEN = 1;
        PORT->Group[0].PMUX[12].reg = 0x22;
        /* Enable APB clock for SERCOM3 */
        PM->APBCMASK.reg |= (1u << 5);
        /* Configure GCLK generator 0 as clock source for SERCOM3 */
        GCLK->CLKCTRL.reg = 0x4010;
        /* Configure SERCOM3 USART with baud 115200 8-N-1 settings */
        BOOT_USART_MODULE->USART.CTRLA.reg = SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO | SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD;
	while(BOOT_USART_MODULE->USART.STATUS.bit.SYNCBUSY);
	BOOT_USART_MODULE->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0);
	BOOT_USART_MODULE->USART.BAUD.reg = 50436;
	while(BOOT_USART_MODULE->USART.STATUS.bit.SYNCBUSY);
	BOOT_USART_MODULE->USART.CTRLA.bit.ENABLE = 1;

    while(1)
        usart_putc('U');

 

 

And here is my attempt at initializing PB08 and PB09.  It seemed straight forward but it doesn't work so now I'm clueless.  Can anyone help please?

Note that I did set #define BOOT_USART_MODULE SERCOM4

Also note that I am NOT using ASF.  I started with a File->New->Project->GCC Executable Project

 

        /* Enable & configure alternate function C for pins PB08 & PB09 */
        PORT->Group[1].PINCFG[8].bit.PMUXEN = 1;
        PORT->Group[1].PINCFG[9].bit.PMUXEN = 1;
        PORT->Group[1].PMUX[4].reg = 0x22;
        /* Enable APB clock for SERCOM4 */
        PM->APBCMASK.reg |= (1u << 6);
        /* Configure GCLK generator 0 as clock source for SERCOM4 */
        GCLK->CLKCTRL.reg = 0x4011;
        /* Configure SERCOM4 USART with baud 115200 8-N-1 settings */
        BOOT_USART_MODULE->USART.CTRLA.reg = SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD;
        while(BOOT_USART_MODULE->USART.STATUS.bit.SYNCBUSY);
        BOOT_USART_MODULE->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0);
        BOOT_USART_MODULE->USART.BAUD.reg = 50436;
        while(BOOT_USART_MODULE->USART.STATUS.bit.SYNCBUSY);
        BOOT_USART_MODULE->USART.CTRLA.bit.ENABLE = 1;

	while(1)
		usart_putc('U');
		

 

Thanks

Last Edited: Tue. Oct 20, 2015 - 01:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still many hardcoded values - hard to read. I don't see you setting PORT->Group[n].DIR.reg for the TX line.

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

wow I'm dumb.  Turns out I misread the "I/O Multiplexing and Considerationschart.

 

I was supposed to use peripheral mux D, ie.

PORT->Group[1].PMUX[4].reg = 0x33;

 

No setting of DIR register necessary.

 

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	BOOT_USART_MODULE->USART.BAUD.reg = 50436;

 BTW, I've recently noticed that while "fraction baud rate generator" might SOUND more complex that "integral BRG", that's not actually the case.

The fractional BRG turns out to be much easier to calculate the BAUD register contents, and for common bitrates and clockrate (48MHz), you won't need the "fraction" part.

int brgval = 65536ULL * (F_CPU - 16ULL * baud) / F_CPU;    // integral BRG
  ... or
int brgval = (F_CPU/16)/baud;    // fraction BRG (not including fraction)