It is not hard at all to use the device on a register level, and that's what I personally do. I have a number of simple starter project that you can use here https://github.com/ataradov/mcu-starter-projects
I'll go look into your starter project. Probably just what I need to get beyond the chip setup phase of development.
HAL_GPIO_PIN(ADC, A, 2)
//-----------------------------------------------------------------------------
void adc_init(void)
{
HAL_GPIO_ADC_in();
HAL_GPIO_ADC_pmuxen(HAL_GPIO_PMUX_B);
MCLK->APBCMASK.reg |= MCLK_APBCMASK_ADC0;
GCLK->PCHCTRL[ADC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
while (0 == (GCLK->PCHCTRL[ADC0_GCLK_ID].reg & GCLK_PCHCTRL_CHEN));
ADC0->CTRLA.reg = ADC_CTRLA_SWRST;
while (ADC0->CTRLA.reg & ADC_CTRLA_SWRST);
ADC0->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC2 | ADC_REFCTRL_REFCOMP;
ADC0->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV32;
ADC0->CTRLC.reg = ADC_CTRLC_RESSEL_16BIT;
ADC0->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_128;
ADC0->INPUTCTRL.reg = ADC_INPUTCTRL_MUXPOS_AIN0 | ADC_INPUTCTRL_MUXNEG(0x18/*GND*/);
// ADC0->CALIB.reg = ADC_CALIB_BIAS_CAL(NVM_READ_CAL(ADC_BIASCAL)) |
// ADC_CALIB_LINEARITY_CAL(NVM_READ_CAL(ADC_LINEARITY));
ADC0->INTENSET.reg = ADC_INTENSET_RESRDY;
NVIC_EnableIRQ(ADC0_IRQn);
ADC0->CTRLA.reg = ADC_CTRLA_ENABLE;
}
//-----------------------------------------------------------------------------
int adc_read(void)
{
ADC0->SWTRIG.reg = ADC_SWTRIG_START;
}
//-----------------------------------------------------------------------------
void irq_handler_adc0(void)
{
int data = ADC0->RESULT.reg;
// TODO: use data
}
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "samc21.h"
#include "hal_gpio.h"
#define _nop() asm("nop")
#define F_CPU 24000000
HAL_GPIO_PIN(LED, A, 15)
HAL_GPIO_PIN(BUTTON, A, 28)
HAL_GPIO_PIN(UART_TX, A, 22)
HAL_GPIO_PIN(UART_RX, A, 23)
HAL_GPIO_PIN(ADC, A, 2)
//-----------------------------------------------------------------------------
void adc_init(void)
{
HAL_GPIO_ADC_in();
HAL_GPIO_ADC_pmuxen(HAL_GPIO_PMUX_B);
MCLK->APBCMASK.reg |= MCLK_APBCMASK_ADC0;
GCLK->PCHCTRL[ADC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN(0) | GCLK_PCHCTRL_CHEN;
while (0 == (GCLK->PCHCTRL[ADC0_GCLK_ID].reg & GCLK_PCHCTRL_CHEN));
ADC0->CTRLA.reg = ADC_CTRLA_SWRST;
while (ADC0->CTRLA.reg & ADC_CTRLA_SWRST);
ADC0->REFCTRL.reg = ADC_REFCTRL_REFSEL_INTVCC2 | ADC_REFCTRL_REFCOMP;
ADC0->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV32;
ADC0->CTRLC.reg = ADC_CTRLC_RESSEL_16BIT;
ADC0->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_128;
ADC0->INPUTCTRL.reg = ADC_INPUTCTRL_MUXPOS_AIN0 | ADC_INPUTCTRL_MUXNEG(0x18/*GND*/);
// ADC0->CALIB.reg = ADC_CALIB_BIAS_CAL(NVM_READ_CAL(ADC_BIASCAL)) |
// ADC_CALIB_LINEARITY_CAL(NVM_READ_CAL(ADC_LINEARITY));
ADC0->INTENSET.reg = ADC_INTENSET_RESRDY;
NVIC_EnableIRQ(ADC0_IRQn);
ADC0->CTRLA.reg = ADC_CTRLA_ENABLE;
}
//-----------------------------------------------------------------------------
void adc_read(void)
{
ADC0->SWTRIG.reg = ADC_SWTRIG_START;
}
//-----------------------------------------------------------------------------
void irq_handler_adc0(void)
{
data = ADC0->RESULT.reg;
// TODO: use data
}
//----------------------------------------------------------------------------
static void sys_int(void)
{
// Set flash wait states to maximum for 24 MHz operation
NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_RWS(1) | NVMCTRL_CTRLB_MANW;
// Switch to 48MHz clock and divide by 2
OSCCTRL->OSC48MDIV.reg = OSCCTRL_OSC48MDIV_DIV(1);
}
//----------------------------------------------------------------------------
int main(void)
{
sys_int();
adc_init();
adc_read();
while(1)
{
}
}
I see your first name is Alex and that you live in the silicon valley area, you should be working for Atmel in offering help to their customers.
May I be bold and ask just what you do at Atmel?
How should I start a new project in Atmel Studio without Atmel adding in their startup code?
Or should I start there and clear out their stuff, then add your framework? How to handle your library file, etc.