Hello,
I'm using a FRDM-K64F board, under Kinetis SDK v2.
I have configured the DAC to use the hardware trigger. The DAC is enable, the DAC buffer is enabled,
The DAC buffer work mode is set to Normal mode.
The problem I have, is that I never seen the read pointer changing. I always remains to the initial value of zero.
I have joined a test program to this email.
I run the associated program, and oscope the DAC0_OUT pin of the board.
=> If the line 155, in the file main.c is commented, a sinus curve is displayed.
But, the data are always written in the first entry of the Fifo.
=> If the line 155, in the fila main.c is un-commented, then a constant output appears.
// DACIndexBuffer = (DACIndexBuffer + 1) % DAC_USED_BUFFER_SIZE;
I have probably made a mistake in the DAC initialization or usage.
Thanks for your remarks.
Best Regards
Nadine
void PDB_IRQ_HANDLER(void){ uint32_t i;
GPIO_WritePinOutput(BOARD_DEBUG_GPIO1, BOARD_DEBUG_GPIO1_PIN, 0); for (i = 0; i < PDB_DAC_INDX_LOOP; i++) { DAC_BASEADDR->DAT[DACIndexBuffer].DATH = dath[sinusIndexTable]; /* High 4-bit. */ DAC_BASEADDR->DAT[DACIndexBuffer].DATL = datl[sinusIndexTable]; /* Low 8-bit. */
//DACIndexBuffer = (DACIndexBuffer + 1) % DAC_USED_BUFFER_SIZE; sinusIndexTable = (sinusIndexTable + 1) % INP_BUFFER_SIZE; }
#if 0 DACRegister[reg_index++] = DAC_BASEADDR->C2; if (reg_index == 20) { for (i = 0; i< 20; i++) PRINTF("i %d value = 0x%x\r\n", i , DACRegister[i]); reg_index = 0; }#endif
PDB_ClearStatusFlags(PDB_BASEADDR, kPDB_DelayEventFlag); GPIO_WritePinOutput(BOARD_DEBUG_GPIO1, BOARD_DEBUG_GPIO1_PIN, 1);}
Original Attachment has been moved to: DAC.zip
Hi, Nadine,
I see your application, you want to write 8 or 16 datas to DAC FIFO in ISR in order to save time of the core. In the case, i suggest you use DAC interrupt instead of PDB interrupt. If you use PDB interrupt, even if you use FIFO mode of DAC, every time the PDB trigger DAC, the PDB interrupt is triggered once, it can not save time of core and there is issue for your code, because you update all the FIFO of DAC in ISR of PDB.
You can enable the DAC buffer, and set the DACBTIEN, while you have to set the priority of the DAC and define the ISR of DAC, update vector table. In the ISR of DAC, you can update all the 16 FIFO. In the method, the DAC isr is executed once after DAC outputs 16 datas.
Hope it can help you.
BR
XiangJun Rong
Hi Xiangjun,
Thanks you very much your answer, it helps me a lot.
But, one problem remains : How to "set the priority of the DAC" ?
because, I need to manage, in a very accurate way (400 KHz or 1.2 MHz) the DAC FIFO
emtying.
Until now, I have only used the NVIC_EnableIRQ() function in my program.
I see there is a NVIC_SetPriority() function, I will read the associated documentation on this function.
I have no experience working with the Freescale board, so my questions
are probably obvious for you.
Best Regards
Nadine,
Hi, Nadine,
you can use the following line to set interrupt priority.
For example, the interrupt vector of DAC0 is 56, if you want to set DAC0 priority as 10, you can use the code:
NVIC_SetPriority(56,10); //
Note that the 0 is the highest priority level.
Pls refer to section 3.2.2 Nested Vectored Interrupt Controller (NVIC) Configuration in reference manual of K64.
BR
XiangJun Rong
Hi, Nadine,
Regarding the DAC, this is my opinion. If you use DAC buffer, you can save a sine table with 16 points to the DAC buffer, you can use PDB to trigger DAC buffer data one by one in normal mode, when the DAC pointer reaches to 15, it will wrap to zero in next triggering automatically, in the mode, you do not need update the DAC buffer in PDB ISR, it is okay to initialize the DAC buffer once. In other words, the PDB ISR is unnecessary.
If you want to use PDB interrupt to update the DAC value so that it can output sine table, you can DISABLE DAC buffer mode, in each PDB interrupt, you can update the data0 register, it is okay, in the mode only data0 register is outputted to DAC pin.
I refer to your code, it seems you enable buffer of DAC, while you update all DAC buffer in ISR, I do not think it is correct.
The DACBFEN bit in DACx_C1 determine if you use buffer mode or not, pls check if you clear or set it in debugger of KDS tools.
Hope it can help you.
BR
XiangJun Rong
Hi Xiangjun,
Sorry, but my first email was not clear.
The final application I'm working on, is a PowerLine Communications application (PLC).
I'm using a daughter board, plugged on the FRDM-K64F board to send data on the power line or read data
from the power line.
The data transmission speeds are 400 KHz or 1.2 MHz. These are standards.
The data to be sent, in the final application, will not be a sinus table of 16 points but a large data table
(thousands of points).
I need to to program an hardware interrupt at the period of 400 KHz (or 1.2 MHz).
For now, I have configured the PIT timer, the PDB and the DAC to do so, but my program is not optmize because
I need to write the data in the DAC FIFO one by one.
To save time, I would have like to program the PBD to use the "DAC interval trigger output" mechanism as it is described
in the section 39.4.3 of the K64 Sub-Family Reference Manual.
As the FIFO DAC size is 16, I have tried unsuccessfully to program the MOD register value of the PDB to 8,
and the DAC Trigger interval to 1 to generate a PDB interrupt only after 8 DAC hardware triggers and to fill half
of the FIFO during this PDB interrupt.
That is why I have enabled the buffer read pointer of the DAC (DACBFEN). I thought, that the buffer read pointer
of the DAC would have been updated during the hardware trigger.
But, it looks like that the buffer read pointer of the DAC FIFO always remains to the first word of the FIFO.
This is what I have tried to illustrate in the test program I have send in my previous email.
Thanks again for your help on this topic.
Best Regards
Nadine