UC3L System clock and SPI...

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

Before I ask a long and complex question about SPI, I'd like to have one last go at figuring this out myself with a nudge in the right direction :)

I'm trying to use the SPI on an AT32UC3L0256 and keeping space and cost down by just using the internal RC CLOCK.

 

My question is: Is there any reason why I can't use the SPI with just the RC CLOCK?

Is it too slow, is the peripheral clock not enabled etc?

 

I'm getting no output at all from the SPI pins when looked at on a scope (detail on THAT later if I needed - for now I'm looking in to clock issues).

 

my conf_clock.h has the following definititions from the defaults.

 

#define CONFIG_SYSCLK_SOURCE          SYSCLK_SRC_RCSYS

/* Fbus = Fsys / (2 ^ BUS_div) */
#define CONFIG_SYSCLK_CPU_DIV         0
#define CONFIG_SYSCLK_PBA_DIV         0
#define CONFIG_SYSCLK_PBB_DIV         0

#if UC3L3_L4

//#define CONFIG_USBCLK_SOURCE        USBCLK_SRC_OSC0
#define CONFIG_USBCLK_SOURCE        USBCLK_SRC_PLL0

/* Fusb = Fsys / USB_div */
#define CONFIG_USBCLK_DIV           1

#define CONFIG_PLL0_SOURCE          PLL_SRC_OSC0

/* Fpll0 = (Fclk * PLL_mul) / PLL_div */
#define CONFIG_PLL0_MUL             (48000000UL / BOARD_OSC32_HZ)
#define CONFIG_PLL0_DIV             1

#endif

 

My CPU seems to run nicely with a 1hz flashing light as expected with delay_ms() finctions.

I'm also pushing a byte out with spi_write() in that loop ... now, if that has a wait for completion in it, I'd have expected it to hang if my peripheral clocks were messed up, right?

Do I need to do anything special to get the SPI to work (other than all the stuff I've tried from dozens of examples).

The baudrate field in my spiOptions struct that I'm passing to spi_initMaster() is set to 1mhz... does that matter? Is there another internal clock looking after that or will the SPI bus just run proportionately slower due to my slow RC clock?

 

Supplemental question: Is my only INTERNAL clock option the SYSCLK_SRC_RCSYS (115khz?) or is there a faster internal option without adding a crystal? I recall getting ATMEGA chips to run at a decent rate with just internal clocks.

 

Cheers!

 

 

 

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

The PLLMUL field in the SCIF PLL register is only 4 bits wide, so the maximum main clock frequency that you could get from the 115 kHz RC oscillator would be about 1.8 MHz
(The PLL module has a minimum input frequency of 4 MHz)


Quote:
I'm also pushing a byte out with spi_write() in that loop ... now, if that has a wait for completion in it, I'd have expected it to hang if my peripheral clocks were messed up, right?
No.
The ASF spi_write() has a crude timeout that will stop a permanent 'hang'.
Unlike the AVR8s you must select a chip-select before you try to get data in or out.
The 'chip select' loads one of 4 possible configurations, it also drives the physical CS pin if you've configured the GPIO to do that.


Quote:
The baudrate field in my spiOptions struct that I'm passing to spi_initMaster() is set to 1mhz... does that matter? Is there another internal clock looking after that or will the SPI bus just run proportionately slower due to my slow RC clock?
The clock chain is ; selected main clock -> division in the PM -> division in the SPI (divisions can be 1).
The ASF often uses a structure for several functions., the SPI baudrate is set in spi_setup_ChipReg()
(uhhmm, 1mhz ?)


There is an internal 120 MHz RC clock (SYSCLK_SRC_RC120M)

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

Okay, I've been through this carefully now and I think the no output may be down to pin configuration.

I tried killing the peripheral clock and I get a timeout error on the spi_write function - which is good.

 

Here's where I set up the SPI pins...

 

  static const gpio_map_t SPI_GPIO_MAP =
  {
    {AVR32_SPI_SCK_0_0_PIN, AVR32_SPI_SCK_0_0_FUNCTION }, //SCK
    {AVR32_SPI_MISO_0_0_PIN, AVR32_SPI_MISO_0_0_FUNCTION}, //MISO
    {AVR32_SPI_MOSI_0_0_PIN, AVR32_SPI_MOSI_0_0_FUNCTION}, //MOSI
  };

  if (gpio_enable_module(SPI_GPIO_MAP, sizeof(SPI_GPIO_MAP) / sizeof(SPI_GPIO_MAP[0])) != GPIO_SUCCESS) flash_error(50);

Now, tracing this through in the debugger, I don't see the pin direction set, just the function=0

gpio_enable_module calls gpio_enable_pin which CLEARS the gpio enable which seems odd... or do we need to disable gpio for spi functions to work?
 

    /* Disable GPIO control. */
    gpio_port->gperc = 1 << (pin & 0x1F);

I also tried this afterwards to try to set the pins for output but no good.

 

	gpio_enable_gpio_pin(PORT_OLED_SPI_CLK);
	gpio_configure_pin(PORT_OLED_SPI_CLK,GPIO_DIR_OUTPUT);

 

This is starting to get to me now... can anyone point me in the right direction as to why my SPI isn't outputting anything?

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

The 'chip select' loads one of 4 possible configurations, it also drives the physical CS pin if you've configured the GPIO to do that.

 

Chip select you say? Hmmm.... where's that? This sounds promising. And thanks for the rest of the advice.

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

Quote:
static const gpio_map_t SPI_GPIO_MAP =
{
{AVR32_SPI_SCK_0_0_PIN, AVR32_SPI_SCK_0_0_FUNCTION }, //SCK
{AVR32_SPI_MISO_0_0_PIN, AVR32_SPI_MISO_0_0_FUNCTION}, //MISO
{AVR32_SPI_MOSI_0_0_PIN, AVR32_SPI_MOSI_0_0_FUNCTION}, //MOSI
};
I hate that ASF redefinition of the physical pins and actions, because it takes me ages to find which _0_0_ or _0_1_ or ... variant to use.

static const gpio_map_t SPI_GPIO_MAP =
{
{ AVR32_PIN_PA06, 0 }, //SCK
{ AVR32_PIN_PA04, 0 }, //MISO
{ AVR32_SPI_PA05, 0 }, //MOSI
};
is (IMHO) simpler to read.


moving on ....
If you want an internal module to access physical pins then you have to tell the GPIO module to ;
1) disconnect the GPIO functionality from a pin, (set the GPER bit to 0)
2) select which one of (in your case upto 8) modules to control that pin (set the multiplexing value in the PMRx registers).
gpio_enable_module() (which calls gpio_enable_module_pin() ) will do all that for you.
If a pin is not used for GPIO then you do not need to set a direction for it, the internal module will do whatever is appropriate.


The ASF has many functions and often they overlap in functionality.
gpio_enable_gpio_pin(); configures a pin as a GPIO output. (blindingly obvious is it not ? :irony:)
gpio_configure_pin() allows you more configurability of a GPIO pin.

As for the chip selects, configure it (them) with spi_setupChipReg() and then use spi_selectChip() and spi_unselectChip()

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

Fantastic! I now have data coming out of my ports.

Trouble is I'd been poking about so much with this that I'm not entirely sure what the eureka moment was but I'm entirely sure that it was something that you put me on to!

Thanks. I'll post my code back here for the "solved" reference once I#m happy it's all working properly and my connected device is listening.