Dale Roberts

K66 Doc error for DAC Top/Bottom flag bits

Discussion created by Dale Roberts on Mar 1, 2017
Latest reply on Mar 10, 2017 by Dale Roberts

Hello, I think I have found a documentation error in the K66 Reference Manual. I am using a MK66FX1M0VMD18 on an Arduino Teensy 3.6. It looks like Top and Bottom pointer flags in the 12-bit DAC DACx_SR register (0x02-DACBFRPTF and 0x01-DACBFRPBF) and in DACx_C0 (0x02-DACBTIEN and 0x01-DACBBIEN) are documented backwards. I noticed this when trying to connect DMA to the DAC.

 

I verified this with a small Arduino program to step the DAC buffer pointer with a software trigger, and show the SR flags at each step (then clear the SR flags after each step). It shows the 0x01 bit going high at the TOP of the buffer (this is documented as the Bottom bit), and the 0x02 bit going high at the BOTTOM of the buffer (this is documented as the Top bit). The 0x04 water mark flag goes high correctly 4 words from the upper limit (which I have set to 8 here).

 

Program Output:

Initial: DAC0_SR:2  DAC0_C0:A0  DAC0_C1:19  DAC0_C2:08

 

 0   DACBufPtr: 0   SR: 2  
 1   DACBufPtr: 1   SR: 0  
 2   DACBufPtr: 2   SR: 0  
 3   DACBufPtr: 3   SR: 0  
 4   DACBufPtr: 4   SR: 4     (Water Mark flag, correct)
 5   DACBufPtr: 5   SR: 0  
 6   DACBufPtr: 6   SR: 0  
 7   DACBufPtr: 7   SR: 0  
 8   DACBufPtr: 8   SR: 1    (the "BOTTOM" bit triggers at the top of the buffer)
 9   DACBufPtr: 0   SR: 2    (the "TOP bit triggers at the bottom of the buffer)
10   DACBufPtr: 1   SR: 0  
11   DACBufPtr: 2   SR: 0  
12   DACBufPtr: 3   SR: 0  
13   DACBufPtr: 4   SR: 4  
14   DACBufPtr: 5   SR: 0  
15   DACBufPtr: 6   SR: 0  
16   DACBufPtr: 7   SR: 0  
17   DACBufPtr: 8   SR: 1  
18   DACBufPtr: 0   SR: 2  
19   DACBufPtr: 1   SR: 0

 

Complete working Arduino code:

void dprintf(const char *Format, ...);

//
// Initialize DAC0, set pointer to 0, and increment the pointer 20 times.
// After each increment, print out the Status Register to see which
// interrupts have been fired, then reset the SR interrupt flags.
//
void TestDacIRQ()
{
  SIM_SCGC2 |= SIM_SCGC2_DAC0;    // enable DAC clock

  DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACTRGSEL;
  DAC0_C1 = DAC_C1_DACBFWM(3) | DAC_C1_DACBFEN;
  DAC0_C2 = 0x08;                 // Read pointer=0, max=8.

  // Show initial state.
  dprintf("Initial: DAC0_SR:%d  DAC0_C0:%02X  DAC0_C1:%02X  DAC0_C2:%02X \n\n",
        DAC0_SR, DAC0_C0, DAC0_C1, DAC0_C2);

  for(int i=0; i < 20; ++i) {
    // Show current DAC buffer pointer, and the Status Register.
    dprintf("%2d   DACBufPtr:%2d   SR:%2d  \n",
            i, DAC0_C2>>4, DAC0_SR);

    DAC0_SR = 0;                  // Clear Status Register bits.
    DAC0_C0 |= DAC_C0_DACSWTRG;   // Software Trigger to step Buffer Pointer.
  }
}

void setup() {
  Serial.begin(9600);
  for(int i=0; !Serial && (i < 50); ++i)
    delay(20);
  TestDacIRQ();
}

void loop() { }

char spbuf[300];
void dprintf(const char *Format, ...)
{
  va_list ap;
  va_start(ap, Format);
  vsnprintf(spbuf, sizeof(spbuf), Format, ap);
  va_end(ap);
  Serial.print(spbuf);
}

Outcomes