ATXMEGA64A1U SPI

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

Hello,

I want to use SPI on my Atxmega64A1U, but it doesnt work. I measure it with osciloscope and any signals appear on MOSI, MISO or SCK.
I dont have many experience with xmega, but everything exept SPI works.

Only SS goes LOW and then HIGH.

#define MOSI PIN5_bm
#define MISO PIN6_bm
#define SCK PIN7_bm
#define SS PIN4_bm

char spi_write(char data)
{
	SPID.DATA = data; //send

	while(!(SPID.STATUS & SPI_IF_bm)); //wait completion
	
	return SPID.DATA;
}

void RC522_write(char reg, char value)
{
	SPID.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_CLK2X_bm | SPI_MODE_0_gc; // set SPI comunication with RFID
	PORTD.OUTCLR = SS; //slave select (inverted)
	
	spi_write(reg & 0x7E);
	spi_write(value);
	
	PORTD.OUTSET = SS;
	SPIC.CTRL = 0;
}

void init_RC522()
{
	PORTD.DIRSET = (MOSI | SCK | SS);
	PORTD.DIRCLR = MISO;
	PORTD.PIN6CTRL = PORT_OPC_PULLUP_gc;
	PORTD.OUTSET = SS; //slave unselect (inverted)
	
	SPID.INTCTRL = 0x00;
}

void main()
{
    init_RC522();
    
    RC522_write(0xFF, 0xFF);
    
    return 0;
}

Thank you for your time.
Best Regards,
Petrlinux

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

If you use a Atmel ASF example, the SPI port D could be in power reduction mode until you unset the appropriate bit. (You can check whether SPI is operating by checking the content of SPI.CTRL register after writing to it. If it is still 0, it is in power reduction.)
PR.PRPD &= ~PR_SPI_bm;SPI

Please check the line "SPIC.CTRL = 0;" in RC522_write, because you seem to use SPI port D.

If nothing works, try an ASF example in Atmel Studio.

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

You seem  to be re-initializing the SPI with every read.

 

SPID.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_CLK2X_bm | SPI_MODE_0_gc; // set SPI comunication with RFID

I think this code should be in your init function vice your write function.

 

Also, you are not waiting for transmission to be complete. After spi_write, insert

while(!(SPID.STATUS & 0x80)); // wait for transmit complete

 

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

So i changed program according to your ideas and nothing changed.

 

#define MOSI PIN5_bm
#define MISO PIN6_bm
#define SCK PIN7_bm
#define SS PIN4_bm

char spi_write(char data)
{
	SPID.DATA = data; //send

	while(!(SPID.STATUS & 0x80)); //wait completion
	
	return SPID.DATA;
}

void RC522_write(char reg, char value)
{
	PORTD.OUTCLR = SS; //slave select (inverted)
	
	spi_write(reg & 0x7E);
	spi_write(value);
	
	PORTD.OUTSET = SS;
}

void init_RC522()
{
	PORTD.DIRSET = (MOSI | SCK | SS);
	PORTD.DIRCLR = MISO;
	//PORTD.PIN6CTRL = PORT_OPC_PULLUP_gc;
	PORTD.OUTSET = SS; //slave unselect (inverted)
	PR.PRPD	&= ~PR_SPI_bm;

	SPID.CTRL = 0x40; // set SPI comunication with RFID
	SPID.INTCTRL = 0x00;
}

void main()
{
    init_RC522();
    
    RC522_write(0xFF, 0xFF);
    
    return 0;
}

Thanks for any next ideas.

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

The following enables SPID in slave mode:

SPID.CTRL = 0x40; // set SPI comunication with RFID

Try this:

SPID.CTRL = 0x50; // set SPI comunication with RFID

Edit: or even this:

SPID.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_0_gc;

 

Greg Muth

Portland, OR, US

Atmel Studio 7.0 on Windows 10

Xplained/Pro/Mini Boards mostly

 

 

Last Edited: Tue. Dec 5, 2017 - 07:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, but nothing helps me. Finally i solve it by writing SPI softwareatically.