I am using the PortentaH7 ADC to sample a signal however the results I get are way too different from what I should get with the RES and Ref Voltage that I use (for exemple the value I should get for 0V should be around 0000 0000 0000 0000 on a 16 bit RES yet I get values around 0000 0001 1111 0100). I wonder why I do get these values beacause aside from not giving me coherent values the signal form is perfectly fine... . Here a pic for a 12 bit Res with a 1V offset on the signal and 1V amplitude for 2.5V ref:
I wonder if anyone has faced this issue up till now and if not could someone test my code on his own portentaH7 to check wether the issue comes from my code or my board. The code :
//////////////////////////////////////CORE_CM7////////////////////////////////////
#ifdef CORE_CM7
#define HSEM_ID_INIT 0
#define HSEM_PROCESS_INIT 0
#define HSEM_ID_DATA 1
#define HSEM_PROCESS_DATA 1
#define HSEM_ID_RDY 2
#define HSEM_PROCESS_RDY 2
#define HSEM_ID_RST 3
#define HSEM_PROCESS_RST 3
#define HSEM_ID_FRQ 4
#define HSEM_PROCESS_FRQ 4
#define HSEM_ID_RDYM 5
#define HSEM_PROCESS_RDYM 5
/*************************Variable*************************/
int readyP = 0;
int initt = 0;
int freq = 0;
int readyM4 = 0;
String chaineF;
/**************************Shared struct********************/
struct shared_data
{
uint8_t datReady1;
uint8_t datInit;
uint32_t datFreq;
uint8_t datReset;
uint8_t datReady;
//uint32_t val;//status : 1=transfer complete 0=waiting
uint32_t data_M4toM7[3];
uint8_t sts_transfer;//status : 1=transfer complete 0=waiting
uint8_t sts_buff1_or2; // status : 1=M7toM4_1, 0=M7toM4_2
uint8_t sts_4to7; // status: 0 = no fluo, 1 = fluo, 2 = waiting for fluo
//uint8_t sts_7to4; // status: 0 = empty, 1 = has data, 2 = locked (CM7-CM4)
uint16_t M7toM4_1[10]; // bytes from CM7 to CM4 DMA1
uint16_t M7toM4_2[10]; // bytes from CM7 to CM4 DMA2
};
volatile struct shared_data * const buff = (struct shared_data *)0x38001000;
/*************************function headers*********************/
void setupLabviewM7();
/**************************setup*******************************/
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
LL_RCC_ForceCM4Boot();
setupLabviewM7();
}
/****************************loop******************************/
void loop() {
// put your main code here, to run repeatedly:
/*******************Poll for Reset order*******************/
if (Serial.available() > 0) {
char incomingByte = Serial.read();
if (incomingByte == 'z') {
while (HAL_HSEM_Take(HSEM_ID_RST, HSEM_PROCESS_RST) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
buff->datReset = 1;
SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_RST, HSEM_PROCESS_RST);
Serial.println("reseting");
setupLabviewM7();
}
}
/*****************Serial print values************************/
while (HAL_HSEM_Take(HSEM_ID_DATA, HSEM_PROCESS_DATA) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
chaineF = (String)buff->data_M4toM7[0] + "|" + (String)buff->data_M4toM7[1] + "|" + (String)buff->data_M4toM7[2];
SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_DATA, HSEM_PROCESS_DATA);
Serial.println(chaineF);
}
/*****************SETUP FUNCTION CM7***********************/
void setupLabviewM7(void) {
readyM4 = 0;
readyP = 0;
initt = 0;
freq = 0;
/***************LABVIEW COM**************/
while (initt != 1) { //Check message from Labview before starting!
if (Serial.available() > 0) {
char incomingByte = Serial.read();
if (incomingByte == 'i') {
initt = 1;
while (HAL_HSEM_Take(HSEM_ID_INIT, HSEM_PROCESS_INIT) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
buff->datInit = 1;
SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_INIT, HSEM_PROCESS_INIT);
}
}
}
while (freq != 1) {
while (HAL_HSEM_Take(HSEM_ID_FRQ, HSEM_PROCESS_FRQ) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
if (Serial.available() > 0) {
char incomingByte = Serial.read();
switch (incomingByte) {
case 'a':
buff->datFreq = 100;
break;
case 'b':
buff->datFreq = 200;
break;
case 'c':
buff->datFreq = 300;
break;
case 'd':
buff->datFreq = 400;
break;
case 'e':
buff->datFreq = 500;
break;
case 'f':
buff->datFreq = 600;
break;
case 'g':
buff->datFreq = 700;
break;
case 'h':
buff->datFreq = 800;
break;
case 'i':
buff->datFreq = 900;
break;
} SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_FRQ, HSEM_PROCESS_FRQ);
freq = 1;
}
}
/***********SETUP******************/
//No setup on M7
/***********SETUP DONE*************/
while (readyM4 != 1) {
while (HAL_HSEM_Take(HSEM_ID_RDYM, HSEM_PROCESS_RDYM) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
if (buff->datReady1 == 1) {
readyM4 = 1;
} SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_RDYM, HSEM_PROCESS_RDYM);
}
while (readyP != 1) {
Serial.println("ready");
if (Serial.available() > 0) {
char incomingByte = Serial.read();
if (incomingByte == 'r') {
readyP = 1;
while (HAL_HSEM_Take(HSEM_ID_RDY, HSEM_PROCESS_RDY) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
buff->datReady = 1;
SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_RDY, HSEM_PROCESS_RDY);
}
}
}
while (HAL_HSEM_Take(HSEM_ID_RST, HSEM_PROCESS_RST) != HAL_OK) {};
SCB_CleanInvalidateDCache_by_Addr(buff, sizeof(*buff));
buff->datInit = 0;
buff->datReset = 0;
buff->datReady = 0;
buff->datReady1 = 0;
SCB_CleanDCache_by_Addr(buff, sizeof(*buff));
HAL_HSEM_Release(HSEM_ID_RST, HSEM_PROCESS_RST);
}
#endif
//////////////////////////////////////END CORE_CM7////////////////////////////////////
///////////////////////////////////////CORE_CM4////////////////////////////////////
#ifdef CORE_CM4
#define HSEM_ID_INIT 0
#define HSEM_PROCESS_INIT 0
#define HSEM_ID_DATA 1
#define HSEM_PROCESS_DATA 1
#define HSEM_ID_RDY 2
#define HSEM_PROCESS_RDY 2
#define HSEM_ID_RST 3
#define HSEM_PROCESS_RST 3
#define HSEM_ID_FRQ 4
#define HSEM_PROCESS_FRQ 4
#define HSEM_ID_RDYM 5
#define HSEM_PROCESS_RDYM 5
/*****************************function headers**********************/
void setupLabviewM4();
//void setupTresholdManual();
void ADC_Init();
void ADC_Stop();
void DMA_Stop();
void DMA_Start();
void ADC_Start();
void DMA_Config();
void VREFBUF_Init();
void AC_TIMER1_Init();
void AC_TIMER1_Stop();
void AC_TIMER1_ChangeFreq(int);
void TrigDAC(uint16_t,int);
void DAC_Config();
void GPIOH_Init();
void GPIOH_Port15_Toggle();
/***************************variables*******************************/
bool SetupComplete = false;
int myValEch = 200;
int readyP = 0;
int initt = 0;
int freq = 0;
int myLED;
int updateEV = 0;
int DMABuffered = 0;
int DMABufferedi = 0;
int Eosmp = 0;
int Eocie = 0;
int Eos = 0;
int DMAError = 0;
int valADC = 0;
bool TCpair = true;
int Mat1 =1;
/**************************shared struct*****************************/
struct shared_data
{
uint8_t datReady1;
uint8_t datInit;
uint32_t datFreq;
uint8_t datReset;
uint8_t datReady;
//uint32_t val;//status : 1=transfer complete 0=waiting
uint32_t data_M4toM7[3];
uint8_t sts_transfer;//status : 1=transfer complete 0=waiting
uint8_t sts_buff1_or2; // status : 1=M7toM4_1, 0=M7toM4_2
uint8_t sts_4to7; // status: 0 = no fluo, 1 = fluo, 2 = waiting for fluo
//uint8_t sts_7to4; // status: 0 = empty, 1 = has data, 2 = locked (CM7-CM4)
uint16_t M7toM4_1[10]; // bytes from CM7 to CM4 DMA1
uint16_t M7toM4_2[10]; // bytes from CM7 to CM4 DMA2
};
volatile struct shared_data * const buff = (struct shared_data *)0x38001000;
/******************************setup*********************************/
void setup() {
// put your setup code here, to run once:
setupLabviewM4();
}
/******************************loop**********************************/
void loop() {
// put your main code here, to run repeatedly:
/*********************Poll for Reset**********************/
while (HAL_HSEM_Take(HSEM_ID_RST, HSEM_PROCESS_RST) != HAL_OK) {};
if (buff->datReset == 1) {
HAL_HSEM_Release(HSEM_ID_RST, HSEM_PROCESS_RST);
setupLabviewM4();
} else {
HAL_HSEM_Release(HSEM_ID_RST, HSEM_PROCESS_RST);
}
/*********************Algorithms**************************/
//TEST ALGO
while (HAL_HSEM_Take(HSEM_ID_DATA, HSEM_PROCESS_DATA) != HAL_OK) {};
while(!(DMABuffered>DMABufferedi)){
digitalWrite(LEDB,LOW);
}
digitalWrite(LEDB,HIGH);
if(Mat1==1){
buff->data_M4toM7[0] = myValEch;
buff->data_M4toM7[1] = buff->M7toM4_1[4];
buff->data_M4toM7[2] = buff->M7toM4_1[9];
DMABufferedi=DMABuffered;
}else if(Mat1==0){
buff->data_M4toM7[0] = myValEch;
buff->data_M4toM7[1] = buff->M7toM4_2[4];
buff->data_M4toM7[2] = buff->M7toM4_2[9];
DMABufferedi=DMABuffered;
}
HAL_HSEM_Release(HSEM_ID_DATA, HSEM_PROCESS_DATA);
}
/************************Setup functions********************/
void setupLabviewM4(void) {
readyP = 0;
initt = 0;
freq = 0;
/***************LABVIEW COM**************/
while (initt != 1) { //Check message from Labview before starting!
while (HAL_HSEM_Take(HSEM_ID_INIT, HSEM_PROCESS_INIT) != HAL_OK) {};
if (buff->datInit == 1) {
initt = 1;
} HAL_HSEM_Release(HSEM_ID_INIT, HSEM_PROCESS_INIT);
}
while (freq != 1) {
while (HAL_HSEM_Take(HSEM_ID_FRQ, HSEM_PROCESS_FRQ) != HAL_OK) {};
myValEch = buff->datFreq;
HAL_HSEM_Release(HSEM_ID_FRQ, HSEM_PROCESS_FRQ);
freq = 1;
}
/***********SETUP******************/
if (SetupComplete) {
digitalWrite(LEDG,LOW);
ADC_Stop();
AC_TIMER1_Stop();
DMA_Stop();
DMABufferedi= 0;
DMABuffered= 0;
DMA_Start();
AC_TIMER1_ChangeFreq(myValEch);
} else {
GPIOH_Init();
//analogReference();
VREFBUF_Init();
DAC_Config();
DMA_Config();
AC_TIMER1_Init();
ADC_Init();
SetupComplete = true;
}
//ALGO TEST
//randomSeed(analogRead(0));//To replace with M4 Init code
/***********SETUP DONE*************/
while (HAL_HSEM_Take(HSEM_ID_RDYM, HSEM_PROCESS_RDYM) != HAL_OK) {};
buff->datReady1 = 1;
HAL_HSEM_Release(HSEM_ID_RDYM, HSEM_PROCESS_RDYM);
while (readyP != 1) {
while (HAL_HSEM_Take(HSEM_ID_RDY, HSEM_PROCESS_RDY) != HAL_OK) {};
if (buff->datReady == 1) {
readyP = 1;
} HAL_HSEM_Release(HSEM_ID_RDY, HSEM_PROCESS_RDY);
}
ADC_Start();
}
/***********************Peripherals functions********************/
void VREFBUF_Init(void) {
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_VREFEN_Msk);
delay(1000);
SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR_Msk);
CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_HIZ_Msk);
while (VREFBUF_CSR_VRR & VREFBUF_CSR_VRR_Msk != 1) {}
}
void DMA_Config(void) {
/************DMA CLock Enable******************/
SET_BIT(RCC_C2->AHB1ENR, RCC_AHB1ENR_DMA1EN_Msk);
delay(1000);
/***************P2M****************************/
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_DIR_0 | DMA_SxCR_DIR_1);
/******************Disable FIFO*************************/
//LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);
//LL_DMA_SetMemoryBurstxfer(DMA1, LL_DMA_STREAM_1, LL_DMA_MBURST_SINGLE);
/******************Memory size**************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_MSIZE_0);
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_MSIZE_1);
/******************MEM Increment**********************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_MINC_Msk);
/******************MEM Address to buffer**************/
DMA1_Stream1->M0AR = (uint32_t)&buff->M7toM4_1; //0x30000000;
DMA1_Stream1->M1AR = (uint32_t)&buff->M7toM4_2; //0x30000000;
/*******************Number of data transfer***********/
SET_BIT(DMA1_Stream1->NDTR, DMA_SxNDT_3 | DMA_SxNDT_1);
/***********************DMA Mode**********************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_CIRC_Msk);//circular
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_DBM_Msk);//Double Buffer Mode
/*******************Flow controller*******************/
//SET_BIT(DMA1_Stream1->CR, DMA_SxCR_PFCTRL_Msk);//ADC in control
/******************Periph size************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_PSIZE_0);
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_PSIZE_1);
/******************Peripheral no Increment*************/
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_PINCOS_Msk);
/******************Periph request**********************/
SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_DMAREQ_ID_1 | DMAMUX_CxCR_DMAREQ_ID_3);//adc2_dma
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SYNC_ID_0 | DMAMUX_CxCR_SYNC_ID_1 | DMAMUX_CxCR_SYNC_ID_2);//TIM12_TRGO
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SPOL_0);//rising edge
// DMAMUX1_Channel1->CCR = 0; //Number of requests after synchro (add 1 to the reg value)
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_EGE_Msk);//Event Generation end of synchro req
// SET_BIT(DMAMUX1_Channel1->CCR, DMAMUX_CxCR_SE_Msk);//Synchro Enable
/******************Periph address***********************/
DMA1_Stream1->PAR = (uint32_t)&ADC2->DR;
/******************TC IT********************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_TCIE_Msk | DMA_SxCR_TEIE_Msk); //TC IT
DMA1->LIFCR = DMA_LIFCR_CTCIF1;//Clear IT in LISR Register
NVIC_SetVector(DMA1_Stream1_IRQn, (uint32_t)&DMA1_Stream1_IRQHandler);
NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/*******************Enable DMA****************************/
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_EN_Msk);
}
void DMA1_Stream1_IRQHandler(void) {
if (DMA1->LISR & DMA_LISR_TCIF1 ) {
//TCpair = !TCpair;
//buff->sts_buff1_or2 = DMABuffered % 2;
//valADC=BufferADC[0];
DMABuffered = DMABuffered + 1;
Mat1=(Mat1+1)%2;
//buff->sts_transfer = 1;
DMA1->LIFCR = DMA_LIFCR_CTCIF1;
}
if (DMA1->LISR & DMA_LISR_TEIF1 ) {
DMAError = DMAError + 1;
DMA1->LIFCR = DMA_LIFCR_CTEIF1;
}
}
void ADC_Init(void) {
/*******************Horloges**************************/
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_SYSCFGEN_Msk); //SYSCFG clock
delay(1000);
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_RTCAPBEN_Msk); //RTCAPB clock
delay(1000);
SET_BIT(RCC_C2->AHB1ENR, RCC_AHB1ENR_ADC12EN_Msk); //ADC12 clocks
delay(1000);
//SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOAEN_Msk); //GPIOA clock
//delay(1000);
SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOCEN_Msk); //GPIOA clock
delay(1000);
/********************Port config************************/
// SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_0);
// SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_1);
// CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_0);
// CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_1);
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE4_0);
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE4_1);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD4_0);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD4_1);
//SET_BIT(SYSCFG->PMCR, SYSCFG_PMCR_PA0SO_Msk);
delay(1000);//PA0_C in analog mode
/********************ADC voltage regulator***************/
CLEAR_BIT(ADC2->CR, ADC_CR_DEEPPWD_Msk); //END DEEPPWD
SET_BIT(ADC2->CR, ADC_CR_ADVREGEN_Msk); //ENABLE ADC VOLTAGE REG
delay(1000);//WAIT VOLTAGE REG
/********************ADC calibration*********************/
CLEAR_BIT(ADC2->CR, ADC_CR_ADCALDIF_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADCALLIN_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADCAL_Msk);
while (ADC_CR_ADCAL & ADC_CR_ADCAL_Msk != 0) {}
/******************ADC clock*****************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1);
/*******************ADC Prescaler************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 );
/*******************Input Mode***************************/
CLEAR_BIT(ADC2->DIFSEL, ADC_DIFSEL_DIFSEL_0); //Single Ended
/*******************ADC Enable***************************/
SET_BIT(ADC2->ISR, ADC_ISR_ADRDY_Msk);
SET_BIT(ADC2->CR, ADC_CR_ADEN_Msk);
while (ADC_ISR_ADRDY & ADC_ISR_ADRDY_Msk != 1) {}
SET_BIT(ADC2->ISR, ADC_ISR_ADRDY_Msk);
/********************ADC RES*****************************/
//SET_BIT(ADC2->CFGR, ADC_CFGR_RES_2 | ADC_CFGR_RES_1);
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_RES_0 | ADC_CFGR_RES_1 | ADC_CFGR_RES_2);
/********************ADC Data Management*****************/
SET_BIT(ADC2->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1);//DMA Circular mode
/********************OVRMODE*****************************/
SET_BIT(ADC2->CFGR, ADC_CFGR_OVRMOD_Msk); //Erase old data
/********************CONT/Single/Discont*****************/
SET_BIT(ADC2->CFGR, ADC_CFGR_DISCEN_Msk); // discontinuous mode
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_CONT_Msk); // | ADC_CFGR_DISCEN_Msk
/********************Trigger Detection*******************/
SET_BIT(ADC2->CFGR, ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3);//Trig rising edge TRGO2
CLEAR_BIT(ADC2->CFGR, ADC_CFGR_EXTEN_1 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_4);
/********************INput Preselection******************/
SET_BIT(ADC2->PCSEL, ADC_PCSEL_PCSEL_0);//Chan 0
/********************Sample Time reg*********************/
SET_BIT(ADC2->SMPR1, ADC_SMPR1_SMP0_0); //2.5 CLCK Cycles
/********************ADC IT******************************/
SET_BIT(ADC2->IER, ADC_IER_EOCIE_Msk | ADC_IER_EOSMPIE_Msk );//| ADC_IER_EOSIE_Msk | ADC_IER_OVRIE_Msk
NVIC_EnableIRQ(ADC_IRQn);
NVIC_SetVector(ADC_IRQn, (uint32_t)&ADC_IRQHandler);
}
void ADC_IRQHandler(void) {
if (ADC2->ISR & 0x02) {
Eosmp += 1;
SET_BIT(ADC2->ISR, ADC_IER_EOSMPIE_Msk);
}
if (ADC2->ISR & 0x04) {
Eocie += 1;
SET_BIT(ADC2->ISR, ADC_IER_EOCIE_Msk);
}
// if (ADC2->ISR & 0x08) {
// Eos += 1;
// SET_BIT(ADC2->ISR, ADC_IER_EOSIE_Msk);
// }
}
void ADC_Start(void) {
SET_BIT(ADC2->CR, ADC_CR_ADSTART_Msk); //Start
}
void AC_TIMER1_Init(void) {
//------------------------------Horloge Timer1----------------------------------------//
SET_BIT(RCC_C2->APB2ENR, RCC_APB2ENR_TIM1EN_Msk);
//------------------------------Select TRGO source-----------------------------------//
TIM1->PSC = 19; //PSC=1
//----------------------------------------------------------TIM2 autoreload register--------------------------------------------//
TIM1->ARR = 47;//200kHz
//---------selectupdatevent-----------------//
SET_BIT(TIM1->CR2, TIM_CR2_MMS2_1);
//-----------IT-----------------------//
// SET_BIT(TIM1->DIER,TIM_DIER_UIE_Msk);
// NVIC_SetPriority(TIM1_UP_IRQn,0);
// NVIC_SetVector(TIM1_UP_IRQn, (uint32_t)&TIM1_UP_IRQHandler);
// NVIC_EnableIRQ(TIM1_UP_IRQn);
SET_BIT(TIM1->CR1, TIM_CR1_CEN_Msk);//CEN=1
}
void GPIOH_Init(void) {
SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOHEN_Msk);
delay(1000);
SET_BIT(GPIOH->MODER, GPIO_MODER_MODE15_0);
CLEAR_BIT(GPIOH->MODER, GPIO_MODER_MODE15_1);
CLEAR_BIT(GPIOH->OTYPER, GPIO_OTYPER_OT15);
}
void GPIOH_Port15_Toggle(void) {
SET_BIT(GPIOH->BSRR, GPIO_BSRR_BS15);
CLEAR_BIT(GPIOH->BSRR, GPIO_BSRR_BS15);
SET_BIT(GPIOH->BSRR, GPIO_BSRR_BR15);
CLEAR_BIT(GPIOH->BSRR, GPIO_BSRR_BR15);
}
void AC_TIMER1_ChangeFreq(int myValEch) {
TIM1->PSC = 19; //PSC=1
TIM1->ARR = myValEch;//Change this value to get correct frequency
SET_BIT(TIM1->CR1, TIM_CR1_CEN_Msk);//RESTART
}
void ADC_Stop(void) {
//STOP ADC CONV
SET_BIT(ADC2->CR, ADC_CR_ADSTP_Msk);
//Poll ADC STOPPED
while (!(ADC2->CR & ADC_CR_ADSTART)) {}
}
void AC_TIMER1_Stop(void) {
CLEAR_BIT(TIM1->CR1, TIM_CR1_CEN_Msk);//STOP
}
void DMA_Stop(void) {
CLEAR_BIT(DMA1_Stream1->CR, DMA_SxCR_EN_Msk);
}
void DMA_Start(void) {
SET_BIT(DMA1_Stream1->CR, DMA_SxCR_EN_Msk);
}
void DAC_Config(void) {
/**************************Configure GPIO pins************/
SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN_Msk); //GPIOA clock
delay(1000);
SET_BIT(GPIOA->MODER, GPIO_MODER_MODE4_0);
SET_BIT(GPIOA->MODER, GPIO_MODER_MODE4_1);
CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD4_0);
CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD4_1);
/*******************EN_DAC_CLCK*************************/
SET_BIT(RCC->APB1LENR,RCC_APB1LENR_DAC12EN_Msk);
delay(1000);
/*******************DAC_MODE*****************************/
SET_BIT(DAC1->MCR, DAC_MCR_MODE2_1); //disable buffer DAC chan 2
//Chan 1 000 buffer enabled
/********************CR**********************************/
}
void TrigDAC(uint16_t value,int timepulse) {
//int timTrig=100000;
DAC1->DHR12R1=value;
SET_BIT(DAC1->CR, DAC_CR_EN1_Msk ); //Enable DAC
// while (timTrig > 1) {
//
// timTrig--;
//}
delay(timepulse);
CLEAR_BIT(DAC1->CR, DAC_CR_EN1_Msk ); //Enable DAC
}
#endif
/////////////////////////////////END CORE_CM4//////////////////////////////////////
This code is supposed to work with a Labview interface but you can just go in your serial monitor and write:
'i'
when it says ready write :
'r'
You will get :
'data1|data2|data3'
The data corresponding to the ADC is data2 and data3.
For the montage since I use VrefBuf from the board (with a 2.5 V value) you must do the following circuit on Vref pin:
With of course all the grounds linked (source, portenta,...).