SAME70 Xplained USART0 SPI mode

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

 

Hello,

 

I'm trying to make use of the USART0 SPI master on the SAME70 Xplained board, but I must be missing something in the setup as I'm not seeing anything on the MOSI line. The clock line, slave select and MISO lines are all working as expected.

 

Note, I have moved the 0 ohm resistor from R230 to R229 to expose PD13 on EXT2. 

My slave SPI device is hooked up as follows:

MOSI -> PB1

MISO -> PB0

SCK -> PB13

nCS -> PB3

 

I am using ASF version 3.31.0. Using the ASF wizard I have added the "SPI - Serial Peripheral Interface Master (Common API) (service) usart spi" module.

 

In conf_board.h I have added the following defines to set the above pins correctly:

/* Configure USART0 SPI pins */
#define CONF_BOARD_USART_RXD
#define CONF_BOARD_USART_TXD
#define CONF_BOARD_USART_SCK
#define CONF_BOARD_USART_RTS

My main.c is as follows:

int main (void) {
 // Initialize the SAM system
 sysclk_init();
 board_init();

 configure_console();

 struct usart_spi_device spi_device_conf = {
  .id = PIO_PB3_IDX
 }; //not used so not important

 usart_spi_init(USART0);
 usart_spi_setup_device(USART0, &spi_device_conf, SPI_MODE_0, 1000000, 0); //1MHz
 usart_spi_enable(USART0);
   
 usart_spi_select_device(USART0, &spi_device_conf); //second parameter is not used

 uint8_t data = 0;
 for(uint8_t i=0; i<=20; i++) {
        usart_spi_write_single(USART0, ((address<<1)|0x40));
        usart_spi_read_single(USART0, &value);

        printf("Address: 0x%02x Data: 0x%02x\r\n", i, data);
 }
 usart_spi_deselect_device(USART0, &spi_device_conf);

 
   while(1) {}
}

When I use a logic analyzer and run this code I see the clock line as being (mostly) correct (I say mostly as it is only 500kHz rather than 1MHz), the MISO is correct (although I can only read register 0 of the device) and the chip select line is correct. However, MOSI never changes (stuck at 0x00).

 

I also see in the I/O window that USART0->US_THR->TXCHR never changes (when it is supposed to be set in the usart_putchar() function in usart.c).

 

Does anybody see a step I'm missing to get this working?

 

Thanks in advance,

JJ   

 

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

Hi,

 

You are using a SAME70 that is having a SPI & the ASF do have a sample code for SPI communication.

Why don't you refer that at first place?

Silly beans are always silly
:)

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

SPI0 is working as expected for me. The SPI1 pins are used for the external RAM. I need multiple SPI ports (4 in total) so I need to get the USART SPI working aswell. There is an example of how to use SPI0 in ASF (which I've used), but there is no example code that I can find that shows how to make use of the USART SPI.

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

Hi, 

 

Any update on this problem? Can you show the code for the following functions:

usart_spi_init(USART0);
usart_spi_setup_device(USART0, &spi_device_conf, SPI_MODE_0, 1000000, 0);
usart_spi_enable(USART0);
  
usart_spi_select_device(USART0, &spi_device_conf);
usart_spi_write_single(USART0, ((address<<1)|0x40));
usart_spi_read_single(USART0, &value);

usart_spi_deselect_device(USART0, &spi_device_conf);

 

 

Last Edited: Wed. Jul 19, 2017 - 06:31 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JJult wrote:

 

Hello,

 

I'm trying to make use of the USART0 SPI master on the SAME70 Xplained board, but I must be missing something in the setup as I'm not seeing anything on the MOSI line. The clock line, slave select and MISO lines are all working as expected.

 

...

I have the SAME70N21B with a custom hardware and have exactly the same problem, but not using ASF but my own init, but also read there source and did the same as they do. I really tested so many settings and SCK is running but nothing on MOSI (but i think its high impedance, looked at it on the DSO). I start thinking its just impossible because the USART unit just don't work in SPI mode... I already needed to make so many redesigns because the atmel controllers didn't work as they should and not a word of it in the errata. Even not after reporting the problem and got it confirmed... Too bad :/

But i still hope it is not the case this time.

 

Even its long time ago you asked, maybe this AppNote is fine for the same70 too... There is a example in the document.

http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42185-SAM-NS-Series-Software-Migration-Guide_AP-Note_AT03786.pdf

 

Did somebody managed to get usart in spi master mode work?

 

Regards

Last Edited: Mon. Sep 9, 2019 - 03:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I start thinking its just impossible because the USART unit just don't work in SPI mode...

 

The USART module on the SAME70 does work, as specified in the product datasheet, in SPI master mode. Unfortunately I don't have a cut-down code example I can share immediately.

Josh @ CIHOLAS Inc - We fill the gaps from chips to apps

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

josh.w wrote:

Quote:

I start thinking its just impossible because the USART unit just don't work in SPI mode...

 

 

The USART module on the SAME70 does work, as specified in the product datasheet, in SPI master mode. Unfortunately I don't have a cut-down code example I can share immediately.

Thank you,

that gives hope!

I still have no success, is there maybe somebody out there with a working example of the init and transmit function for USART in SPI Master mode?

This is an example of what i tried:

void usart_spi_master_init()
{
//Setting alternative functions for the pins
	io_alt_set_abcd(IO_PIO_PD15_ALTB);
	io_alt_set_abcd(IO_PIO_PD16_ALTB);
	io_alt_set_abcd(IO_PIO_PD17_ALTB);
	io_alt_set_abcd(IO_PIO_PD18_ALTB);

	periph_clk_enable(15);

	USART2->US_WPMR = US_WPMR_WPKEY_PASSWD;

	USART2->US_CR = US_CR_RSTTX | US_CR_TXDIS | US_CR_RSTRX | US_CR_RXDIS;

	USART2->US_MR = 0;
	USART2->US_RTOR = 0;
	USART2->US_TTGR = 0;
	USART2->US_CR = US_CR_RSTSTA;

	USART2->US_CR = US_CR_RXEN;
	USART2->US_CR = US_CR_TXEN;

	USART2->US_MR = US_MR_USART_MODE_SPI_MASTER
		| US_MR_USCLKS_MCK
		| US_MR_CHRL_8_BIT
		| US_MR_WRDBT
		| US_MR_CLKO
		| US_MR_CPHA
		| US_MR_CHMODE_NORMAL;

	USART2->US_BRGR = US_BRGR_CD(((160000000 + BAUD/2) / BAUD) & ~1ul);
}

 

uint8_t spi_master_usart_send_byte(uint8_t byte)
{
	while (!(USART2->US_CSR & US_CSR_TXRDY))
		;
	USART2->US_THR = US_THR_TXCHR(byte);

	while(!(USART2->US_CSR & US_CSR_RXRDY))
		;
	return (uint8_t)USART2->US_RHR;
}

Maybe somebody can see my mistake or something i missing.
The behavior is: SCK gives CLK output. But MOSI is high impedance. The receiver gets 0xFF only, but ofc in the correct length. An individual hardware problem is unlikely, because i have build the hardware twice and tested both modules.

 

Using SAME70N21B.

 

Regards and thank you!

Last Edited: Mon. Sep 9, 2019 - 05:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Additional i observed that:

US_MR_CHMODE_AUTOMATIC and US_MR_CHMODE_REMOTE_LOOPBACK works.

Both are forwarding the data from the SLAVE.
And the SCK clk source is forbidden for spi master mode. Now i use MCK or DIV (MCK/8), still the same problem.

Last Edited: Tue. Sep 10, 2019 - 12:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I managed it, i already did longer time ago, but my the forum was on maintenance and i lost my post.

The problem was not the UART controller, but the programmer. I programmed a SAM-BA programmer for wireless programming and it worked fine. But my testing firmware was only 32 pages big and i used the EWP command for erasing and writing pages. What i didn't know was that this only works for the first 32 pages. And my firmware had 33 pages after completing the SPI Master USART driver.... Now everything working fine. Here is my simplified code for everybody who are trying to run the USART in SPI Master Mode.

 

Important!

NOT use the SCK source for Master mode.

 

void spi_master_usart_init(void)
{
	io_alt_set_abcd(IO_PIO_PD15_ALTB);
	io_alt_set_abcd(IO_PIO_PD16_ALTB);
	io_alt_set_abcd(IO_PIO_PD17_ALTB);
	io_alt_set_abcd(IO_PIO_PD18_ALTB);

	periph_clk_enable(15);
	
	pck_enable(4, SPI_SCK_PREDIV, PMC_PCK_CSS_UPLL_CLK);


	USART2->US_WPMR = US_WPMR_WPKEY_PASSWD;
	
	USART2->US_CR = US_CR_RXEN;
	USART2->US_CR = US_CR_TXEN;
	

	

	USART2->US_BRGR = US_BRGR_CD(480000000 / SPI_SCK_PREDIV / BAUD); //Value must be even CD==100 with 3000 baud
	
	USART2->US_MR = US_MR_USART_MODE_SPI_MASTER
		| US_MR_USCLKS_DIV
		| US_MR_CHRL_8_BIT
		| US_MR_CLKO
		| US_MR_CPHA
		| US_MR_CHMODE_NORMAL
		;
	
	USART2->US_CR = US_CR_TXEN;
	USART2->US_CR = US_CR_RXEN /*0b11111111111100111111111000000011 |*/ /*US_CR_FCS*/;
	
}



uint8_t spi_master_usart_trans_byte(uint8_t byte)
{
	while (!(USART2->US_CSR & US_CSR_TXRDY))
		;
	USART2->US_THR = US_THR_TXCHR(byte);

	while(!(USART2->US_CSR & US_CSR_RXRDY))
		;

	return (uint8_t)USART2->US_RHR;
}

I hope this can help somebody!

And sorry for blaming you Atmel.