Author Topic: DAC - Sam D21 Bare Code Driver  (Read 6627 times)

0 Members and 1 Guest are viewing this topic.

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
DAC - Sam D21 Bare Code Driver
« on: October 09, 2016, 09:31:32 pm »
Hi friends!

I am starting to use the DAC of Sam D21 .

I would like to code it in Bare Metal.

Anyone has an example driver configuration to me study together DS? I have some doubts to coding it.

Best Regards
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #1 on: October 09, 2016, 10:33:28 pm »
What you've got so far and what does not work?
Alex
 

Online rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #3 on: October 09, 2016, 11:59:10 pm »
Why not start with the App Note?
The question is about bare-metal implementation and this AN can't be any further away from that.
Alex
 

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #4 on: October 10, 2016, 12:31:17 am »
Hi RSTOFER, yes I checked that file but all information is in ASF. I do not like ASF  :-\.

I searched a lot the driver configuration in Bare Code like that ASF file shows but no success for Bare Code.

Dear Alex, I cannot understand how I can do the syncronization for write data to DATA.reg.


Regards
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #5 on: October 10, 2016, 12:38:42 am »
Dear Alex, I cannot understand how I can do the syncronization for write data to DATA.reg.
Don't think about synchronization. It is not going to affect you in this case.
Alex
 

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #6 on: October 10, 2016, 12:48:39 am »
Alex, in page 934 of DS means:

'The following bits need synchronization when written:
• Software Reset bit in the Control A register (CTRLA.SWRST)
• Enable bit in the Control A register (CTRLA.ENABLE)
• All bits in the Data register (DATA)
• All bits in the Data Buffer register (DATABUF)

so, the STATUS.SYNCBUSY is not relevant?

Thanks friend!!!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #7 on: October 10, 2016, 12:53:22 am »
so, the STATUS.SYNCBUSY is not relevant?
Synchronization is needed if you are worried about interrupt latency (within a few clock cycles). If you do two writes in a row into the registers that need synchronization, then the second write will block the system bus until the first one completes. If you only write DATA register once in a while, then you have noting to worry about.

At the same time, it is not that hard to do the synchronization. Just do something like
Code: [Select]
  while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY);
before the write to the DATA register.
Alex
 
The following users thanked this post: Franc

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #8 on: October 10, 2016, 11:44:38 pm »
When I debug my code with the dac_carga_init() in main.C, my program blocks.
I have configured my DAC drive as below. I dont know what happens dear Alex.

Code: [Select]
#include "samd21.h"
#include "board_defs.h"


void dac_carga_init(void)
{
PM->APBCMASK.reg |= PM_APBCMASK_DAC; // Enable peripheral clock for DAC
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (DAC_GCLK_ID) | // DAC share same GCLK
GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (DAC_GCLK_SOURCE);
while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled

GPIO_dirOut(DAC_OUT); //PA02
GPIO_pmuxen(DAC_OUT, DAC_OUT_PMUX); //PMUX B for PA02 pin DAC

DAC->CTRLA.reg &= ~(DAC_CTRLA_ENABLE); //Disable DAC to permit change CTRLA B register.
DAC->CTRLB.reg |= DAC_CTRLB_EOEN | DAC_CTRLB_REFSEL_AVCC; //Enable the DAC output on Vout pin. Enable VDDANAL REF. 
DAC->CTRLA.reg |= DAC_CTRLA_ENABLE; //Enable DAC
}
.h file:
Code: [Select]
#ifndef DAC_CARGA_H_
#define DAC_CARGA_H_

void dac_carga_init(void);

inline uint16_t dac_carga_write(uint16_t carga);

uint16_t dac_carga_write(uint16_t carga)
{
// uint16_t received_data;
while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY); // Make sure clock synchronization
DAC->DATA.reg = (carga); // Write DAC value

}


#endif


Best Regards friends!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #9 on: October 11, 2016, 12:01:23 am »
Here is a full source code that works. If you want to test this as is, you can replace main.c here https://github.com/ataradov/mcu-starter-projects/tree/master/samd21 with this code.

You can go fancy with synchronization and stuff, but as I said, it is not necessary in most cases.

Code: [Select]
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "samd21.h"
#include "hal_gpio.h"

//-----------------------------------------------------------------------------
HAL_GPIO_PIN(DAC,      A, 2)

//-----------------------------------------------------------------------------
static void sys_init(void)
{
  // Switch to 8MHz clock (disable prescaler)
  SYSCTRL->OSC8M.bit.PRESC = 0;
}

//-----------------------------------------------------------------------------
static void dac_init(void)
{
  HAL_GPIO_DAC_out();
  HAL_GPIO_DAC_pmuxen(PORT_PMUX_PMUXE_B_Val);

  PM->APBCMASK.reg |= PM_APBCMASK_DAC;

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(DAC_GCLK_ID) |
    GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

  DAC->CTRLA.reg = DAC_CTRLA_SWRST;
  while (DAC->CTRLA.reg & DAC_CTRLA_SWRST);

  DAC->CTRLB.reg = DAC_CTRLB_EOEN | DAC_CTRLB_REFSEL_AVCC;
  DAC->CTRLA.reg = DAC_CTRLA_ENABLE;
}

//-----------------------------------------------------------------------------
static void dac_write(uint16_t value)
{
  DAC->DATA.reg = value;
}

//-----------------------------------------------------------------------------
int main(void)
{
  int dac_out = 0;

  sys_init();
  dac_init();

  while (1)
  {
    dac_write(dac_out++);
  }

  return 0;
}
Alex
 
The following users thanked this post: Franc

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #10 on: October 11, 2016, 12:21:03 am »
In page 33 of DS SAMD21 says that PA02 is the only pin for Vout of DAC. Is possible I use any other Analog pin for do it once all are MUX B?
(PA02 til PA07 and PB00 till PB09)

Thanks!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #11 on: October 11, 2016, 12:22:11 am »
Is possible I use any other Analog pin for do it once all are MUX B?
I don't understand the question.
Alex
 

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #12 on: October 11, 2016, 12:28:25 am »
Sorry,... Could I use  any other Analog Pin to DAC Vout? In DS, page 33, shows only PA02 as Vout, but I am using the PA02 with my OLED Xplained Pro in EXT03.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #13 on: October 11, 2016, 12:30:23 am »
No, the table "Table 6-1. PORT Function Multiplexing" lists all possible multiplexing options. If it is not in the table, it is impossible. In case of DAC, only PA2 is possible.
Alex
 
The following users thanked this post: Franc

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #14 on: October 11, 2016, 10:37:25 pm »
Still blocking my program when I call the dac_carga_init().
I am using the SERCOM5 SPI in same EXT03.

Also in my program I am using the TCC0 TC4 TC5, SERCOM0 SPI in EXT1.

My GCLK(0) is DFLL 48Mhz. Do you know if there is any incompatibility to use them together DAC?

Below my dac_carga_init():

Code: [Select]
void dac_carga_init(void)
{
GPIO_dirOut(DAC_OUT); //PA02
GPIO_pmuxen(DAC_OUT, DAC_OUT_PMUX); //PMUX B for PA02 pin DAC

PM->APBCMASK.reg |= PM_APBCMASK_DAC; // Enable peripheral clock for DAC
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID (DAC_GCLK_ID) | // DAC share same GCLK
GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN (0);
while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled

DAC->CTRLA.reg = DAC_CTRLA_SWRST;
while (DAC->CTRLA.reg & DAC_CTRLA_SWRST);

DAC->CTRLB.reg = DAC_CTRLB_EOEN | DAC_CTRLB_REFSEL_AVCC; //Enable the DAC output on Vout pin. Enable VDDANAL REF. 
DAC->CTRLA.reg = DAC_CTRLA_ENABLE; //Enable DAC
while (DAC->STATUS.reg & DAC_STATUS_SYNCBUSY);//Wait until clock ok.
}

Best Regards
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #15 on: October 11, 2016, 10:42:46 pm »
Code: [Select]
while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled
I'm pretty sure this is wrong. And the whole line is unnecessary.
Alex
 
The following users thanked this post: Franc

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #16 on: October 11, 2016, 11:02:31 pm »
 :palm: :phew: ..You are the guy..Alex! Worked perfect. Thanks.

By the way.... why this line is wrong? ' while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN); // Wait till enabled'
I have used it to all my TC and no issues.

Regards!
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11260
  • Country: us
    • Personal site
Re: DAC - Sam D21 Bare Code Driver
« Reply #17 on: October 11, 2016, 11:04:51 pm »
If you really want to wait until the clock is enabled, then it should be "while (0==(GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN));". Your TC is probably clocked from a slower clock, so it takes a few cycles for it to enable, so it was falling though on the first iteration.

In general, it probably is a good practice to wait, but in reality, even if clock is not enabled, your first access to the peripheral register will block until clock is enabled.
« Last Edit: October 11, 2016, 11:06:44 pm by ataradov »
Alex
 
The following users thanked this post: Franc

Offline FrancTopic starter

  • Regular Contributor
  • *
  • Posts: 64
  • Country: br
Re: DAC - Sam D21 Bare Code Driver
« Reply #18 on: October 11, 2016, 11:15:24 pm »
OK, nice clue!
*Now I will start in Analog Comparators of Sam D21.

Best Regards!  :-+
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf