#include "ADC_READ.h"
#include "adc.h"
#include "dma.h"

#define READ_CH 1
// definisci il vettore per i risultati delle misure


void ADC_calibrate(){
  // calibrazione
  // ADC3->CR 	|= ADC_CR_ADCALDIF; // SOLO per misure differenziali (defualt=0)
  // esegui anche calibrazione linearità (oltre che offest)
  ADC3->CR	|= ADC_CR_ADCALLIN;
  // inizia la calibrazione
  ADC3->CR	|= ADC_CR_ADCAL;
}

void DMA_init(){
  // DMA per USART (DMA1 stream3)
  DMA1_Stream3->M0AR 	=  (uint32_t) &results;
  DMA1_Stream3->PAR	=  (uint32_t) &(USART3->TDR);
  DMA1_Stream3->NDTR	= (uint16_t) (N_MEAS+1)*2;	// send signle bytes

  DMA1->LIFCR	= 0xffffffff;
  DMA1->HIFCR	= 0xffffffff;
  DMA1_Stream3->CR	|= DMA_SxCR_TCIE;

  // DMA per ADC (DMA2 stream0)
  DMA2_Stream0->M0AR 	=  (uint32_t) &results;
  DMA2_Stream0->PAR	=  (uint32_t) &(ADC3->DR);
  DMA2_Stream0->NDTR	= (uint16_t) N_MEAS;

  DMA2->LIFCR	= 0xffffffff;
  DMA2->HIFCR	= 0xffffffff;
  DMA2_Stream0->CR	|= DMA_SxCR_TCIE;
}

void ADC_READ_init(){

  // TIM6 conf.
  TIM6 -> PSC = 6000;	// set single timer ticks to 0.25us (240MHz/30 = 4MHz) - 240MHz is APB1 clock freq.
  TIM6 -> CNT = 0;
  TIM6 -> ARR = 4;	// 1/4 us

  // configura canali da leggere in modalità sequenziale
  ADC3->SQR1 	= 0;
  ADC3->SQR1 	|= (READ_CH << ADC_SQR1_SQ1_Pos);
  // imposta una sola misura (lui misura L+1 canali dove L è il valore impostato in questo reg.)
  ADC3->SQR1 	|= (0 << ADC_SQR1_L_Pos);
  // abilita i canali da utilizzare nel multiplexer
  ADC3->PCSEL 	|= ADC_PCSEL_PCSEL_1;
  // imposta il tempo di lettura (bigger, better)
  ADC3->SMPR1	|= (0 << ADC_SMPR1_SMP1_Pos);
  // abilita interrupt per fine misura [e messa in funzione (ADRDY abilitato)]
  ADC3->IER 	|= ADC_IER_EOSIE;
  // cont. mode
  //ADC3->CFGR	|= ADC_CFGR_CONT;
  // abilita DMA sull'ADC
  ADC3->CFGR 	|= ADC_CFGR_DMNGT;

  // ignora overrun
  //ADC3->CFGR 	|= ADC_CFGR_OVRMOD;

  // abilita ADC vera e propria
  ADC3->ISR 	|= ADC_ISR_ADRDY;
  ADC3->CR 	|= ADC_CR_ADEN;

  DMA2_Stream0->CR 	|= DMA_SxCR_EN;
}


