UC3A1512 SPI won't get to work

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

Hi!
Just recently i've started fiddling with AT32UC3A1512 and hooked up a couple of SPI slaves to it to see how to work with this HW.

I've spent a couple of days trying to get the SPI in the uC to do something, but currently to no avail.

I'm using a 16MHz quartz.

Here is how I initialize the Power Manager clocks

	pm_switch_to_osc0(&AVR32_PM,16000000,1);
	pm_enable_osc0_crystal(&AVR32_PM,16000000);
	pm_wait_for_clk0_ready(&AVR32_PM);
	pm_pll_setup(&AVR32_PM,0,12,3,0,1);
	pm_pll_set_option(&AVR32_PM,0,0,0,0);
	pm_pll_enable(&AVR32_PM,0);
	pm_wait_for_pll0_locked(&AVR32_PM);
	pm_cksel(&AVR32_PM,1,0,0,0,1,0); 
	pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCSEL_PLL0);

with the help of an oscilloscope I see that the oscillation is there on both xin0 and xout0.

Next, I initialise SPI for two devices

	gpio_enable_module(timechip_spi_gpio_map,sizeof(timechip_spi_gpio_map)/sizeof(timechip_spi_gpio_map[0]));
	gpio_enable_module(mmc_spi_gpio_map,sizeof(mmc_spi_gpio_map)/sizeof(mmc_spi_gpio_map[0]));

	spi_initMaster(&AVR32_SPI0,&timechip_spi_options);
	spi_selectionMode(&AVR32_SPI0,0,0,0);
	spi_setupChipReg(&AVR32_SPI0,&timechip_spi_options,sysclk_get_pba_hz());
	spi_setupChipReg(&AVR32_SPI0,&mmc_spi_options,sysclk_get_pba_hz());
	spi_enable(&AVR32_SPI0);

	INTC_init_interrupts();
	Enable_global_interrupt();

The initialisation values for the SPI are as follows

static const gpio_map_t timechip_spi_gpio_map =
{
	{
		AVR32_SPI0_NPCS_2_0_PIN,
		AVR32_SPI0_NPCS_2_0_FUNCTION
	},
	{
		AVR32_SPI0_MOSI_0_0_PIN,
		AVR32_SPI0_MOSI_0_0_FUNCTION
	},
	{
		AVR32_SPI0_MISO_0_0_PIN,
		AVR32_SPI0_MISO_0_0_FUNCTION
	},
	{
		AVR32_SPI0_SCK_0_0_PIN,
		AVR32_SPI0_SCK_0_0_FUNCTION
	}
};

const spi_options_t timechip_spi_options	=
{
	.reg =			0,	//SPI channel to initialise
	.baudrate =		4000000,	// baudrate
	.bits =			8,
	.spck_delay =	0,		//delay before first clock pulse after selecting the slave (PBA clock periods)
	.trans_delay =	0,		//delay between each character/transfer (PBA clock periods)
	.stay_act =		1,		//whether to stay active after the last transfer to it
	.spi_mode =		0,		//
	.modfdis =		0		//whether to leave the SPI bus if another master is detected on the bus
};

static const gpio_map_t mmc_spi_gpio_map =
{
	{
		AVR32_PIN_PA09,
		AVR32_SPI0_NPCS_0_0_FUNCTION
	},
	{
		AVR32_PIN_PA12,
		AVR32_SPI0_MOSI_0_0_FUNCTION
	},
	{
		AVR32_PIN_PA11,
		AVR32_SPI0_MISO_0_0_FUNCTION
	},
	{
		AVR32_PIN_PA13,
		AVR32_SPI0_SCK_0_0_FUNCTION
	}
};

const spi_options_t mmc_spi_options	=
{
	.reg =			0,	//SPI channel to initialise
	.baudrate =		4000000,	// baudrate
	.bits =			8,
	.spck_delay =	0,		//delay before first clock pulse after selecting the slave (PBA clock periods)
	.trans_delay =	0,		//delay between each character/transfer (PBA clock periods)
	.stay_act =		1,		//whether to stay active after the last transfer to it
	.spi_mode =		0,		//
	.modfdis =		0		//whether to leave the SPI bus if another master is detected on the bus
};

And after all that I use things like that

	spi_selectChip(&AVR32_SPI0,2);

	while(!spi_is_tx_ready(&AVR32_SPI0));

	spi_put(&AVR32_SPI0,data);
	
	while(!spi_is_tx_empty(&AVR32_SPI0));
	
	while(!spi_is_rx_full(&AVR32_SPI0));
	
	res = (uint8_t)spi_get(&AVR32_SPI0);

	spi_unselectChip(&AVR32_SPI0,2);

and nothing happens. This will stop in checking !spi_is_tx_empty() and hang there forever. It will not even press down the appropriate chip select.

I suspect I've misconfigured the clock and that's why it won't start producing the synch on SCK. But how to explain that it won't even push down the CS leg, i don't know. Doesn't work for neither of the slaves. The measurements where taken with an oscilloscope. I've checked the power pins all around and they seem powered up.

Would be grateful for a sound suggestion!

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

According to the spi_options structures you have configured chip-select 0 for the timer and chip-select 0 for the MMC
but according to the GPIO mapping you are using chip-select 2 for the timer and 0 for the MMC.

The SPI has no configuration for chip-select 2 therefore it cannot do anything usefull when you call spi_selectChip(&AVR32_SPI0,2);

Change timechip_spi_options to use .reg = 2,

Side-issue, I would set .modfdis = 1

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

I found elsewhere on the forum that if you set .modfdis it won't switch between slaves on the same channel. I wasn't able to find any note on that in the official documentation but since nothing works anyway :) I cleared that byte.

Regarding the .reg i thought that was the byte determining the UC3's SPI channel number. I'll give it a try tomorrow and tell you if that worked.

Thank you very much for the help!:)

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

update. I've got SCK coming up on the SPI line and there is also signal on the MOSI towards the slave. For that to happen I've changed .reg as suggested above and also changed the .modfdis to 1 (do not know if that brought effect).
But the CS line isn't moving. I've got a 10k pullup on the board for the CS line. If i take out the pull-up from the CS line, it turns out that the CS is at 0 all the time (doesn't ever move up), although I do both selects and deselects of the slave.

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

Okay, finally i found out where the core of the problem was.
If you declare AVR32_PIN_PA09 in gpio_map_t it won't work, but if you write it AVR32_SPI0_NPCS_2_0_PIN the CS leg begins to work.
Hope it will be helpful and someone won't spend as much time as i did :)

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

?
AVR32_PIN_PA09 is defined as 9
AVR32_SPI0_NPCS_2_0_PIN is also 9

I am confused as to what chip-selects you are using.

If you are using PA09 (pin 30 on the package) for chip-select 2 then you need to set the GPIO multiplexing to function B for that pin, ie AVR32_SPI0_NPCS_2_0_FUNCTION

PA10 is chip-select 0 and you use AVR32_SPI0_NPCS_0_0_FUNCTION

It would be simpler if you did all the GPIO multiplexing for SPI0 in one operation instead of duplicating the SCK, MOSI and MISO definitions.

I find the AVR32_xxx_a_b_FUNCTION definitions very confusing.

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

Thank you for the answer, the SPI pins are now working as expected. I've got a different problem though. The ENC28j60 chip that I am using to send/receive data seems to be sending the wrong data. I am attaching a couple of images to show that the oscillograms look quite OK. But the data received is wrong.
Here is the request:
[img]http://doc.xcs.com.ua/enc28j60/SPI_CMD.jpg[/img]
Here is the answer:
[img]http://doc.xcs.com.ua/enc28j60/SPI_RSP.jpg[/img]

Everything looks quite OK, but I receive broken ethernet data. The same functional code worked with my previous board on a Atmega128.

I read on another forum, that the ENC28j60 chip has a bug that shows up when the clocking frequency on SCK isn't in the range 8-10 MHz. But the thing is that the ASF allows to change the baud rate, but you can't affect the clocking speed (to my knowledge).


const spi_options_t eth_spi_options =
{
.reg = 1, //SPI channel to initialise
.baudrate = 10000000UL, // baudrate
.bits = 8,
.spck_delay = 0, //delay before first clock pulse after selecting the slave (PBA clock periods)
.trans_delay = 0, //delay between each character/transfer (PBA clock periods)
.stay_act = 1, //whether to stay active after the last transfer to it
.spi_mode = 1, //
.modfdis = 1 //whether to leave the SPI bus if another master is detected on the bus
};

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

Here come a couple of screenshots for the PHA0 (the upper ones are for PHA1).
Request:
[img]http://doc.xcs.com.ua/enc28j60/SPI_CMD_PHA0.jpg[/img]
Responce:
[img]http://doc.xcs.com.ua/enc28j60/SPI_RSP_PHA0.jpg[/img]
By looking and the response it is obvious that the ENC28j60 sends everything in PHA1, not PHA0. Although the docs say "SPI 0,0" (not sure what the seconds zero means, i thought it meant to be the phase).

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

The ENC28j60 datasheet says that it only operates in SPI Mode 0.
It also says to have 50nS between CS going low and the first SCK pulse, so you may need to change .spck_delay = 0,

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

I've tried both SPI 0 modes with phase=0 and with phase=1. None helped. I've also checked the table 16.6 of the datasheet for the enc28j60 where it says that the time interval after the CS before the first wave on the SCK should be at least 100 ns (CS Setup Time, see fiure 16-1). I've put a delay and measured with an o-scope that I've got a 340ns delay before the tide of the first SCK wave.
I found a mistake where I didn't put a pull-up for the SO line to 3.3v and added a 10kOhm pull-up. Didn't help either.
I keep looking for a solution to this.

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

Damn. Now I understand where the problem is.
This CPU stores data in the big-endian fashion.