K66 Beta Test

Status
Not open for further replies.
Christoph DMA_SPI post linked on p_8 last update, thanks for the PM.

Link above for manitou 'ethernet and lwIP DHCP' down farther on p_8 with the added hardware. Manitou - if there is something I can test without building IwIP let me know. The etherraw being stable to run and restart. Still running the Serial Loop through test in parallel 8K cps while being ping'd - not combined displays to it yet. Unplanned trip to other coast for 3 weeks will take minimal hardware - hoping to have downtime for K66.
 
The bare PCBs for round 3 arrived. They're over at the contract manufacturer to be soldered, hopefully sometime this week. If I didn't make any horrible mistakes (this is far far the hardest PCB routing I've ever done), with a little luck we may have round 3 betas to ship next week.

At this moment I'm frantically working on a bed-of-nails test fixture. That PCB also arrived just a few days ago.

Sorry I haven't been more active here recently.
 
I may have fixed the problem with the vocoder crashing and generating lots of processes but don't know why it is happening.
In setup() I was calling usbMIDI.setHandleNoteOff and usbMIDI.setHandleNoteOn before AudioMemory() and audioShield.enable(). In most instances this didn't cause a problem but it really showed up when I added a delay object. That just crashed the code before it could print any debugging output but I found that moving the usbMIDI stuff after enabling the audio cleared up the problem. The note on and note off handlers do call the audio stuff but there shouldn't be any note on/off messages until after I have started up the separate PC process which routes the M-Audio keyboard to the Teensy USB and I don't do that until the Teensy code is up and running.

I haven't figured out why the microphone audio doesn't work at higher clock speeds.

Pete
 
The bare PCBs for round 3 arrived. They're over at the contract manufacturer to be soldered, hopefully sometime this week. If I didn't make any horrible mistakes (this is far far the hardest PCB routing I've ever done), with a little luck we may have round 3 betas to ship next week.

At this moment I'm frantically working on a bed-of-nails test fixture. That PCB also arrived just a few days ago.

Sorry I haven't been more active here recently.

No probs Paul. Take your time :)
 
So looks like DMA Spi is working for SPI, but so far can not define SPI1 or SPI2 with it. Currently that code is only configure for LC

DMASPI1 is implemented now, but still untested.

SPI2 is not defined for Teensy 3.5 and 3.6, but SPI2Class is. From the pinout table in one of the earliest posts I conclude that SPI2 might be available on the inside pads, but Paul doesn't know yet. Is that table up to date? DMASPI2 code is there and commented out, so it can just be activated when appropriate.
 
From the pinout table in one of the earliest posts I conclude that SPI2 might be available on the inside pads, but Paul doesn't know yet. Is that table up to date?

Yes, the table in #93 is up to date. We're still waiting on the BGA soldering, but with any luck we should have the round 3 boards sometime next week.
 
DMASPI1 is implemented now, but still untested.

With 1.6.9 and 1.29beta4, I cloned in the latest teensy core and SPI library, along with latest DmaSpi. Confirmed SPI0 worked as above with pin 11 to 12. Then changed example to use SPI1 for SPI and DMASPI1 for DMASPI0, jumpering pin 0 to 1. The SPI1 test was OK, but DMASPI1 hung??

Code:
Hi!
Buffers are prepared
Time for non-DMA transfer: 234us
src and dest match

Press a key to continue

Testing src -> dest, single transfer
--------------------------------------------------
I could be missing some steps or a version skew??
 
Depends on when exactly you checked out dmaspi, I made a change a few hours ago because the previous code used SPI instead of SPI1 for DMASPI1
 
I just synced up to DMASPI and did like manitou and have the same output...
Code:
Hi!
Buffers are prepared
Time for non-DMA transfer: 226us
src and dest match

Press a key to continue

Testing src -> dest, single transfer
--------------------------------------------------

Edit: Forgot to change the initial SPI to SPI1 in the initial test, plus

Wondering if I am missing something, that is in your example I changed the DMASPI0 to DMASPI1

But wonder in the code:
Code:
  DMASPI1.begin();
  DMASPI1.start();


  DmaSpi::Transfer trx(nullptr, 0, nullptr);

  Serial.println("Testing src -> dest, single transfer");
  Serial.println("--------------------------------------------------");
  trx = DmaSpi::Transfer(src, DMASIZE, dest);
  clrDest((uint8_t*)dest);
  DMASPI1.registerTransfer(trx);
  while(trx.busy())
  {
  }

Edit2: Changing the earlier code to do SPI1 instead of SPI helped do the trick!
Code:
Press a key to continue

Testing src -> dest, single transfer
--------------------------------------------------
Finished DMA transfer
src and dest match
==================================================


Testing src -> discard, single transfer
--------------------------------------------------
Finished DMA transfer
last discarded value is 0x63
That appears to be correct
==================================================


Testing 0xFF dummy data -> dest, single transfer
--------------------------------------------------
Finished DMA transfer
src and dest match
==================================================


Testing multiple queued transfers
--------------------------------------------------
Finished DMA transfer
Finished DMA transfer1
src and dest match
src and dest match
==================================================


Testing pause and restart
--------------------------------------------------
Time until stopped: 220 us
Finished DMA transfer
DMA SPI appears to have stopped (this is good)
restarting
Finished DMA transfer1
src and dest match
src and dest match
==================================================


Testing src -> dest, with chip select object
--------------------------------------------------

If there is something that I need to do to the DmaSpi::Transfer to tell it to use SPI1?

Note: I then tried editing test case again to initialize both SPI and SPI1 like:
Code:
//#include <WProgram.h>

#include <SPI.h>
#include <DmaSpi.h>

/** Important
  The sketch waits for user input through Serial (USB) before it starts the setup.
  After any key was pressed, it should begin to work. It will ask for a second keypress later.
**/

/** Hardware setup:
 plain Teensy 3.1 with DOUT (11) connected to DIN (12)
 nothing else
**/

/** buffers to send from and to receive to **/
#define DMASIZE 100
uint8_t src[DMASIZE];
volatile uint8_t dest[DMASIZE];
volatile uint8_t dest1[DMASIZE];

/** Wait for and consume a keypress over USB **/
void waitForKeyPress()
{
  Serial.println("\nPress a key to continue\n");
  while(!Serial.available());
  while(Serial.available())
  {
    Serial.read();
  }
}

void dumpBuffer(const volatile uint8_t* buf, const char* prefix)
{
  Serial.print(prefix);
  for (size_t i = 0; i < DMASIZE; i++)
  {
    Serial.printf("0x%02x ", buf[i]);
  }
  Serial.print('\n');
}
/** Compare the buffers and print the destination contents if there's a mismatch **/
void compareBuffers(const uint8_t* src_, const uint8_t* dest_)
{
  int n = memcmp((const void*)src_, (const void*)dest_, DMASIZE);
  if (n == 0)
  {
    Serial.println("src and dest match");
  }
  else
  {
    Serial.println("src and dest don't match");
    dumpBuffer(src_, " src: " );
    dumpBuffer(dest_, "dest: ");
  }
}

void setSrc()
{
  for (size_t i = 0; i < DMASIZE; i++)
  {
    src[i] = i;
  }
}

void clrDest(uint8_t* dest_)
{
  memset((void*)dest_, 0x00, DMASIZE);
}

void setup()
{
  waitForKeyPress();
  Serial.println("Hi!");

  /** Prepare source and destination **/
  setSrc();
  clrDest((uint8_t*)dest);
  Serial.println("Buffers are prepared");Serial.flush();

  /** set up SPI **/
  SPISettings spiSettings;
  SPI1.begin();
  SPI.begin();

  // transmit 10 bytes and measure time to get a feel of how long that takes
  SPI1.beginTransaction(spiSettings);
  elapsedMicros us;
  for (size_t i = 0; i < DMASIZE; i++)
  {
    dest[i] = SPI1.transfer(src[i]);
  }
  uint32_t t = us;
  Serial.print("Time for non-DMA transfer: ");Serial.print(t);Serial.println("us");
  SPI1.endTransaction();
  compareBuffers(src, (const uint8_t*)dest);

  waitForKeyPress();

  DMASPI1.begin();
  DMASPI1.start();


  DmaSpi::Transfer trx(nullptr, 0, nullptr);

  Serial.println("Testing src -> dest, single transfer");
  Serial.println("--------------------------------------------------");
  trx = DmaSpi::Transfer(src, DMASIZE, dest);
  clrDest((uint8_t*)dest);
  DMASPI1.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);
  Serial.println("==================================================\n\n");


  Serial.println("Testing src -> discard, single transfer");
  Serial.println("--------------------------------------------------");
  trx = DmaSpi::Transfer(src, DMASIZE, nullptr);
  DMASPI1.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  Serial.printf("last discarded value is 0x%02x\n", DMASPI1.devNull());
  if (DMASPI1.devNull() == src[DMASIZE-1])
  {
    Serial.println("That appears to be correct");
  }
  else
  {
    Serial.printf("That appears to be wrong, it should be src[DMASIZE-1] which is 0x%02x\n", src[DMASIZE-1]);
  }
  Serial.println("==================================================\n\n");


  Serial.println("Testing 0xFF dummy data -> dest, single transfer");
  Serial.println("--------------------------------------------------");
  trx = DmaSpi::Transfer(nullptr, DMASIZE, dest, 0xFF);
  memset((void*)src, 0xFF, DMASIZE); // we need this for checking the dest buffer
  clrDest((uint8_t*)dest);
  DMASPI1.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);
  Serial.println("==================================================\n\n");


  Serial.println("Testing multiple queued transfers");
  Serial.println("--------------------------------------------------");
  trx = DmaSpi::Transfer(src, DMASIZE, dest, 0xFF);
  setSrc();
  clrDest((uint8_t*)dest);
  clrDest((uint8_t*)dest1);
  DmaSpi::Transfer trx1(src, DMASIZE, dest1);
  DMASPI1.registerTransfer(trx);
  DMASPI1.registerTransfer(trx1);
  while(trx.busy());
  Serial.println("Finished DMA transfer");
  while(trx1.busy());
  Serial.println("Finished DMA transfer1");
  compareBuffers(src, (const uint8_t*)dest);
  compareBuffers(src, (const uint8_t*)dest1);
  Serial.println("==================================================\n\n");


  Serial.println("Testing pause and restart");
  Serial.println("--------------------------------------------------");
  clrDest((uint8_t*)dest);
  clrDest((uint8_t*)dest1);
  DMASPI1.registerTransfer(trx);
  DMASPI1.registerTransfer(trx1);
  DMASPI1.stop();
  us = elapsedMicros();
  while(!DMASPI1.stopped());
  t = us;
  while(trx.busy());
  Serial.printf("Time until stopped: %lu us\n", t);
  Serial.println("Finished DMA transfer");

  if (DMASPI1.stopped())
  {
    Serial.println("DMA SPI appears to have stopped (this is good)\nrestarting");
  }
  else
  {
    Serial.println("DMA SPI does not report stopped state, but it should. (this is bad)");
  }

  DMASPI1.start();
  while(trx1.busy());
  Serial.println("Finished DMA transfer1");
  compareBuffers(src, (const uint8_t*)dest);
  compareBuffers(src, (const uint8_t*)dest1);
  Serial.println("==================================================\n\n");


  Serial.println("Testing src -> dest, with chip select object");
  Serial.println("--------------------------------------------------");
  ActiveLowChipSelect cs(0, SPISettings());
//  DebugChipSelect cs;
  trx = DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);
  clrDest((uint8_t*)dest);
  DMASPI1.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);
  Serial.println("==================================================\n\n");


  DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);

  if (DMASPI1.stopped())
  {
    Serial.println("DMA SPI stopped.");
  }
  else
  {
    Serial.println("DMA SPI is still running");
  }
  DMASPI1.stop();
  if (DMASPI1.stopped())
  {
    Serial.println("DMA SPI stopped.");
  }
  else
  {
    Serial.println("DMA SPI is still running");
  }

  DMASPI1.end();
  SPI.end();
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  digitalWriteFast(LED_BUILTIN, true);
  delay(500);
  digitalWriteFast(LED_BUILTIN, false);
  delay(500);
}

And then ran the test and saw:
Code:
Hi!
Buffers are prepared
Time for non-DMA transfer: 226us
src and dest match

Press a key to continue

Testing src -> dest, single transfer
--------------------------------------------------
Finished DMA transfer
src and dest match
==================================================


Testing src -> discard, single transfer
--------------------------------------------------
Finished DMA transfer
last discarded value is 0x63
That appears to be correct
==================================================


Testing 0xFF dummy data -> dest, single transfer
--------------------------------------------------
Finished DMA transfer
src and dest match
==================================================


Testing multiple queued transfers
--------------------------------------------------
Finished DMA transfer
Finished DMA transfer1
src and dest match
src and dest match
==================================================


Testing pause and restart
--------------------------------------------------
Time until stopped: 220 us
Finished DMA transfer
DMA SPI appears to have stopped (this is good)
restarting
Finished DMA transfer1
src and dest match
src and dest match
==================================================


Testing src -> dest, with chip select object
--------------------------------------------------
Finished DMA transfer
src and dest don't match
 src: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 
dest: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
==================================================


DMA SPI is still running
DMA SPI stopped.
Note: I removed the jumper for SPI0...

EDIT3: Sorry I have not done anything with DMA on Teensy, so not sure of stuff. Things I had to play with when testing out SPI1 and SPI2 stuff to use with ILI9341 display was only SPI has 4 entry queue, SPI1 and SPI2 both have 1 entry queue.

Things I wonder about, which may be perfectly good are, you cast the SPI0_PUSHR (or SPI1_PUSHR) and likewise the POPR registers you cast to be 8 bit registers, when they are actually 32 bit registers so not sure what that does...

Anyway probably best left to someone who knows it...

Edit4: Problem is in ActiveLowChipSelect cs(0, SPISettings());

Problem 1 is I believe the 0 is for IO pin 0, which we are using for SPI1...

Problem 2 is in the code where it assumes SPI
Code:
    void select() override
    {
      SPI.beginTransaction(settings_);
      digitalWriteFast(pin_, 0);
    }

    /** \brief deselects the chip (sets the pin to high) and ends the SPI transaction
    **/
    void deselect() override
    {
      digitalWriteFast(pin_, 1);
      SPI.endTransaction();
    }
 
Last edited:
OK, fetched the latest DmaSpi from github, and DMASPI1 is working. :D
You might want to try what I did, which is after you do.
SPI1.begin();

Add
SPI.begin();

It will fail in the CS test case as the code in Chipselect.h is hard coded to SPI.beginTransaction/SPI.endTransaction

Kurt

Christoph:
Edit: Also wish there was a way for me to specify non-default transfer settings.... That is you have the code like:
Code:
      else
      {
        m_Spi.beginTransaction(SPISettings());
      }
This is in beginPendingTransfer as well as in the CS objects. Now suppose I am trying to talk to a device that does not like 4MBS for SPI... Or in my case my Logic Analyzer does not want to get high enough speed....

(Side note: Logic Pro 8 ordered so hopefully soon will be able to debug higher speed)
 
Last edited:
Christoph:

On 2nd part of last message, I see I have the option for CS object to pass in SPISettings that it uses.

So main issue left is that ActiveLowChipSelect has SPI hard coded.

I see several ways to fix. One is to create a ActiveLowChipSelect1 cs(0, SPISettings()); object which uses SPI1 and likewise 2 for SPI2...

Or Could change your ChipSelect class such that it passes in a pointer to your DmaSpi object in the select and deselect methods, and then add some membersto your dmaSPI class like beginTransaction/endTransaction, which call off to the appropriate SPI/SPI1/SPI2... methods.

or ...

Now off to some other stuff
 
Christoph, Paul: Still playing here with DMASPI... Will follow up more on other thread, but decided to enable SPI2 in DMASPI to try it out on the board.

Did not compile, needed an extern ... SPI2 in spi.h. So issued pull request: https://github.com/PaulStoffregen/SPI/pull/18

Will test it out, using my own ChipSelect classes...
 
DMA SPI2 update...

With the above changes (add extern for SPI2 in the SPI2.h file and optionally add SPI2 to the keywords file), I was able to make a version of the DMA SPI test program that at least appears to show that SPI2 can work...

However note: Earlier when I defined the SPI2 object I choose the default IO pins (for MISO/MOSI) that are not on the Beta1/2 boards, so to get the DMASPI stuff to work on these boards I had to add calls for:
SPI2.setMOSI(52);
SPI2.setMISO(51);

Pins 51/52 are on the unpopulated 10 pin connector on the beta boards near the SDCARD and 51/52 are on the 2nd to bottom row...

My hacked up version of the test program, tries to use normal SPI/SPI1/SPI2 loops at start, plus for each also does the simple DMA SPI single calls, but with CS objects, such that I will be able to capture stuff on all channels using logic analyzer...

Then did a loop where it output one dma transfer to each of the DMA channels...
Code:
Code:
//#include <WProgram.h>

#include <SPI.h>
#include <DmaSpi.h>

/** Important
  The sketch waits for user input through Serial (USB) before it starts the setup.
  After any key was pressed, it should begin to work. It will ask for a second keypress later.
**/
class ActiveLowChipSelect1 : public AbstractChipSelect
{
  public:
    /** Configues a chip select pin for OUTPUT mode,
     * manages the chip selection and a corresponding SPI transaction
     *
     * The chip select pin is asserted \e after the SPI settings are applied
     * and deasserted before the SPI transaction ends.
     * \param pin the CS pin to use
     * \param settings which SPI settings to apply when the chip is selected
    **/
    ActiveLowChipSelect1(const unsigned int& pin, const SPISettings& settings)
      : pin_(pin),
      settings_(settings)
    {
      pinMode(pin, OUTPUT);
      digitalWriteFast(pin, 1);
    }

    /** \brief begins an SPI transaction selects the chip (sets the pin to low) and
    **/
    void select() override
    {
      SPI1.beginTransaction(settings_);
      digitalWriteFast(pin_, 0);
    }

    /** \brief deselects the chip (sets the pin to high) and ends the SPI transaction
    **/
    void deselect() override
    {
      digitalWriteFast(pin_, 1);
      SPI1.endTransaction();
    }
  private:
    const unsigned int pin_;
    const SPISettings settings_;

};

class ActiveLowChipSelect2 : public AbstractChipSelect
{
  public:
    /** Configues a chip select pin for OUTPUT mode,
     * manages the chip selection and a corresponding SPI transaction
     *
     * The chip select pin is asserted \e after the SPI settings are applied
     * and deasserted before the SPI transaction ends.
     * \param pin the CS pin to use
     * \param settings which SPI settings to apply when the chip is selected
    **/
    ActiveLowChipSelect2(const unsigned int& pin, const SPISettings& settings)
      : pin_(pin),
      settings_(settings)
    {
      pinMode(pin, OUTPUT);
      digitalWriteFast(pin, 1);
    }

    /** \brief begins an SPI transaction selects the chip (sets the pin to low) and
    **/
    void select() override
    {
      SPI2.beginTransaction(settings_);
      digitalWriteFast(pin_, 0);
    }

    /** \brief deselects the chip (sets the pin to high) and ends the SPI transaction
    **/
    void deselect() override
    {
      digitalWriteFast(pin_, 1);
      SPI2.endTransaction();
    }
  private:
    const unsigned int pin_;
    const SPISettings settings_;

};

/** Hardware setup:
 plain Teensy 3.1 with DOUT (11) connected to DIN (12)
 nothing else
**/

/** buffers to send from and to receive to **/
#define DMASIZE 100
uint8_t src[DMASIZE];
volatile uint8_t dest[DMASIZE];
volatile uint8_t dest1[DMASIZE];
volatile uint8_t dest2[DMASIZE];

/** Wait for and consume a keypress over USB **/
void waitForKeyPress()
{
  Serial.println("\nPress a key to continue\n");
  while(!Serial.available());
  while(Serial.available())
  {
    Serial.read();
  }
}

void dumpBuffer(const volatile uint8_t* buf, const char* prefix)
{
  Serial.print(prefix);
  for (size_t i = 0; i < DMASIZE; i++)
  {
    Serial.printf("0x%02x ", buf[i]);
  }
  Serial.print('\n');
}
/** Compare the buffers and print the destination contents if there's a mismatch **/
void compareBuffers(const uint8_t* src_, const uint8_t* dest_)
{
  int n = memcmp((const void*)src_, (const void*)dest_, DMASIZE);
  if (n == 0)
  {
    Serial.println("src and dest match");
  }
  else
  {
    Serial.println("src and dest don't match");
    dumpBuffer(src_, " src: " );
    dumpBuffer(dest_, "dest: ");
  }
}

void setSrc()
{
  for (size_t i = 0; i < DMASIZE; i++)
  {
    src[i] = i;
  }
}

void clrDest(uint8_t* dest_)
{
  memset((void*)dest_, 0x00, DMASIZE);
}

void setup()
{
  waitForKeyPress();
  Serial.println("Hi!");

  /** Prepare source and destination **/
  setSrc();
  clrDest((uint8_t*)dest);
  Serial.println("Buffers are prepared");Serial.flush();

  /** set up SPI **/
  SPISettings spiSettings(400000, MSBFIRST, SPI_MODE0);
  // BUGBUG:: Probably should 
  SPI2.setMOSI(52);
  SPI2.setMISO(51);
  SPI2.begin();
  SPI1.begin();
  SPI.begin();

  // transmit 10 bytes and measure time to get a feel of how long that takes
  // Lets do for all three SPI busses
 SPI.beginTransaction(spiSettings);
  elapsedMicros us;
  for (size_t i = 0; i < DMASIZE; i++)
  {
    dest[i] = SPI.transfer(src[i]);
  }
  uint32_t t = us;
  Serial.print("SPI: Time for non-DMA transfer: ");Serial.print(t);Serial.println("us");
  SPI.endTransaction();
  compareBuffers(src, (const uint8_t*)dest);

//-------------------------------------------------------------
 SPI1.beginTransaction(spiSettings);
  for (size_t i = 0; i < DMASIZE; i++)
  {
    dest[i] = SPI1.transfer(src[i]);
  }
  Serial.print("SPI1: Time for non-DMA transfer: ");Serial.print(t);Serial.println("us");
  SPI1.endTransaction();
  compareBuffers(src, (const uint8_t*)dest);

  //---------------------------------------------------------
  SPI2.beginTransaction(spiSettings);
  for (size_t i = 0; i < DMASIZE; i++)
  {
    dest[i] = SPI2.transfer(src[i]);
  }
  Serial.print("SPI2: Time for non-DMA transfer: ");Serial.print(t);Serial.println("us");
  SPI1.endTransaction();
  compareBuffers(src, (const uint8_t*)dest);

  //---------------------------------------------------------
  waitForKeyPress();

  // Start up DMA on all three
  DMASPI0.begin();
  DMASPI0.start();
  DMASPI1.begin();
  DMASPI1.start();
  DMASPI2.begin();
  DMASPI2.start();


  DmaSpi::Transfer trx(nullptr, 0, nullptr);
  DmaSpi::Transfer trx1(nullptr, 0, nullptr);
  DmaSpi::Transfer trx2(nullptr, 0, nullptr);

  Serial.println("--------------------------------------------------");
  Serial.println("Create CS objects");
  ActiveLowChipSelect cs(2, SPISettings(1000000, MSBFIRST, SPI_MODE0));
  ActiveLowChipSelect1 cs1(3, SPISettings(1000000, MSBFIRST, SPI_MODE0));
  ActiveLowChipSelect2 cs2(4, SPISettings(1000000, MSBFIRST, SPI_MODE0));

  Serial.println("Testing src -> dest, single transfer");
  Serial.println("--------------------------------------------------");
  Serial.println("SPI:");
  trx = DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);
  clrDest((uint8_t*)dest);
  DMASPI0.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);
  
  Serial.println("SPI1:");
  trx = DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs1);
  clrDest((uint8_t*)dest);
  DMASPI1.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);

  Serial.println("SPI2:");
  trx = DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs2);
  clrDest((uint8_t*)dest);
  DMASPI2.registerTransfer(trx);
  while(trx.busy())
  {
  }
  Serial.println("Finished DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);
  Serial.println("==================================================\n\n");

//==================================================================
// Try all three at same time
  Serial.println("Testing all three SRC to DEST");
  Serial.println("--------------------------------------------------");
  trx = DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);
  clrDest((uint8_t*)dest);
  trx1 = DmaSpi::Transfer(src, DMASIZE, dest1, 0, &cs1);
  clrDest((uint8_t*)dest1);
  trx2 = DmaSpi::Transfer(src, DMASIZE, dest2, 0, &cs2);
  clrDest((uint8_t*)dest2);
  DMASPI0.registerTransfer(trx);
  DMASPI1.registerTransfer(trx1);
  DMASPI2.registerTransfer(trx2);
  while(trx.busy() || trx1.busy() || trx2.busy())
  {
  }
  Serial.println("Finished all three dma DMA transfer");
  compareBuffers(src, (const uint8_t*)dest);
  compareBuffers(src, (const uint8_t*)dest1);
  compareBuffers(src, (const uint8_t*)dest2);
  Serial.println("==================================================\n\n");


// Close down all three...
//=========================================
  DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);

  if (DMASPI0.stopped())
  {
    Serial.println("DMA SPI stopped.");
  }
  else
  {
    Serial.println("DMA SPI is still running");
  }
  DMASPI0.stop();
  if (DMASPI0.stopped())
  {
    Serial.println("DMA SPI stopped.");
  }
  else
  {
    Serial.println("DMA SPI is still running");
  }
//=========================================
  DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);

  if (DMASPI1.stopped())
  {
    Serial.println("DMA SPI1 stopped.");
  }
  else
  {
    Serial.println("DMA SPI1 is still running");
  }
  DMASPI1.stop();
  if (DMASPI1.stopped())
  {
    Serial.println("DMA SPI1 stopped.");
  }
  else
  {
    Serial.println("DMA SPI1 is still running");
  }
//=========================================
  DmaSpi::Transfer(src, DMASIZE, dest, 0, &cs);

  if (DMASPI2.stopped())
  {
    Serial.println("DMA SPI2 stopped.");
  }
  else
  {
    Serial.println("DMA SPI2 is still running");
  }
  DMASPI2.stop();
  if (DMASPI2.stopped())
  {
    Serial.println("DMA SPI2 stopped.");
  }
  else
  {
    Serial.println("DMA SPI2 is still running");
  }
//===================================
  DMASPI0.end();
  DMASPI1.end();
  DMASPI2.end();
  SPI.end();
  SPI1.end();
  SPI2.end();
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  digitalWriteFast(LED_BUILTIN, true);
  delay(500);
  digitalWriteFast(LED_BUILTIN, false);
  delay(500);
}
Output when all three jumpers were set:
Code:
i!
Buffers are prepared
SPI: Time for non-DMA transfer: 2512us
src and dest match
SPI1: Time for non-DMA transfer: 2512us
src and dest match
SPI2: Time for non-DMA transfer: 2512us
src and dest match

Press a key to continue

--------------------------------------------------
Create CS objects
Testing src -> dest, single transfer
--------------------------------------------------
SPI:
Finished DMA transfer
src and dest match
SPI1:
Finished DMA transfer
src and dest match
SPI2:
Finished DMA transfer
src and dest match
==================================================


Testing all three SRC to DEST
--------------------------------------------------
Finished all three dma DMA transfer
src and dest match
src and dest match
src and dest match
==================================================


DMA SPI is still running
DMA SPI stopped.
DMA SPI1 is still running
DMA SPI1 stopped.
DMA SPI2 is still running
DMA SPI2 stopped.
Again this relies on uncommenting the code for DMA SPI2...
 
The audio board doesn't work when the K66 is overclocked at 216 or 240MHz.
I used my multimeter to measure the frequency on the three clock pins on the audio board.
Code:
freq MCLK(MHz)   BCLK(MHz) LRCLK(kHz)
192  11.29       1.41       44.1
216  11.29       2.82       88.2
240  11.29       unstable   unstable
At 192MHz the clocks are stable and audio output is correct. But at 216MHz the audio output is doubled in frequency as is evident in the BCLK and LRCLK values. At 240MHz the audio output warbles all over the place.
I'm currently looking at the source code and reading the K66 manual to see what causes this and if there's a simple fix for it.


Pete
 
@Frank B: was this reported earlier in the thread? If so, I somehow missed it. {+EDIT} found it - I had been looking for "audio" not "I2S"{/EDIT}
I've found a change which will stabilize the audio when at 240MHz but it produces double the audio rate like it does at 216MHz.
In teensy/avr/libraries/Audio/output_i2s.cpp add
Code:
#define MCLK_SRC 0
in the #elif F_CPU == 240000000 near line 282.

Pete
 
Last edited:
Status
Not open for further replies.
Back
Top