SPI on 24MHz (D09)

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

Hi. I need an SPI running at 24MHz (on the D09, but the SPi is the same across many devices, ex D20). That should be possible in Slave mode, using an external 24MHz clock. It seems 24Mhz can be output on a pin easily enough. 

 

My questions:

- do the pins actually support a 24MHz toggle rate? 

- SPI in Slave mode will work when clocked at 24MHz? 

- does DMA work at this rate for the receive stream? 

 

Any code would be great. Thanks! 

Last Edited: Wed. Apr 13, 2016 - 11:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to find this out myself. The SPI can be clocked at up to 24MHz but the pin toggle frequency seems to max. out at 12MHz. Crazy. As for slave mode, the 12MHz limit may be a problem there too. The DMA can do *any* rate you attempt. It is far, far faster than the SPI controller.
 

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

mrfirmware wrote:

I'm trying to find this out myself. The SPI can be clocked at up to 24MHz but the pin toggle frequency seems to max. out at 12MHz. Crazy. As for slave mode, the 12MHz limit may be a problem there too. The DMA can do *any* rate you attempt. It is far, far faster than the SPI controller.

 

So the pin will be the problem. Could strong outputs be faster?

3-way majority voting should not be a limiting factor for inputs. 

 

In particular this comment mentions limits, including on DMA:

  https://community.atmel.com/comme...

 

 

 

Yes, I've seen this mentioned in the other threads relevant to this:

  https://community.atmel.com/forum...

  https://community.atmel.com/forum...

 

 

Thanks. 

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

My DMA controller works fine for SPI. Two channels allocated, using scatter/gather for multiple register accesses to an SPI slave. I've run the SPI up to 18MHz and the DMA worked fine. The two channels should be configured to move the same amount of data, the Rx channel should be armed first followed by the Tx channel to start the process. The entire transfer should complete on the final buffer descriptor for the Rx channel completing. The DMA ISR calls back to the SPI driver which waits for INTFLAG[TXC] to set to ensure that the SPI controller is really done.

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

mrfirmware wrote:

My DMA controller works fine for SPI [...] 18MHz [...]

 

Glad to hear it! 

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

I hope that didn't come across as a brag! I meant that the DMA should and does work for any supported SPI speed.

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

No bragging, you were just trying to not waste any time. Welcome info for sure :)

 

 

Last Edited: Thu. Apr 14, 2016 - 01:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did some testing simply outputting a clock on PA10 (on D09 QFN24) with the below code (called output_clock(4,4)).

 

The output was disappointing: a sine wave of 12Mhz 2Vpp between 0.6V and 2.6V. Setting .DRVSTR=1 did not change this. 

 

At 16Mhz the amplitude is just 1.2Vpp, between 1.1V and 2.3V. Setting .DRVSTR=1 did change this a little bit (ca 0.15Vpp better, with 0.9V low). 

 

I guess low-power is the name of the game. 

 

void output_clock(u32 gclk, i32 divisor)
{
    GCLK_GENDIV_Type gendiv =
    {
        .bit.DIV = divisor,      // divider, linear or 2^(.DIV+1)
        .bit.ID  = gclk,         // GCLK_GENERATOR_X
    };
    GCLK->GENDIV.reg = gendiv.reg;

    // setup Clock Generator
    GCLK_GENCTRL_Type genctrl =
    {
        .bit.RUNSTDBY = 0,        // Run in Standby
        .bit.DIVSEL = 0,          // .DIV (above) Selection: 0=linear 1=powers of 2
        .bit.OE = 1,              // Output Enable to observe on a port pin
        .bit.OOV = 0,             // Output Off Value
        .bit.IDC = 1,             // Improve Duty Cycle
        .bit.GENEN = 1,           // enable this GCLK
        // select GCLK source
        //.bit.SRC = GCLK_SOURCE_OSC8M,
        .bit.SRC = GCLK_SOURCE_DFLL48M,
        // select GCLK2 to output on
        .bit.ID = gclk,           // GCLK_GENERATOR_X
    };
    GCLK->GENCTRL.reg = genctrl.reg;
}

 

Last Edited: Thu. Apr 14, 2016 - 05:07 PM