Hello Simon and others, On Thursday 05 of August 2021 14:02:31 Simon Filgis wrote: > Dear all, Pavel, thanks for following up! > > Regarding: > *CAN*: Until now everything works out of the box for me. Thanks for the > hint with Rev A/B ... I will keep this in mind.
the baudare or some other stuff has been incorrect without header file and driver updates. At least for CAN FD the result has been significantly broken/non functional. Check that you have B rev and changes by Milos Pokorny https://gitlab.com/elektroline-predator/nuttx/-/commit/1306a0e739cc8a97e4b3c28e7fa35731343830e5 https://gitlab.com/elektroline-predator/nuttx/-/commit/5aec4cedb641ebe504dabf08e3bd48a83486454d > *ADC/AFEC*: I found the existing headers and I'm trying to implement a very > basic interrupsdriven implementation. > Work is still in progress: https://github.com/SimonFilgis/incubator-nuttx > Please excuse the mess, I'm learning about the buildsystem and nuttx > in general with that example. > If you could ask your colleagues for their AEFC implementation I > would appreciate it. I am attaching "user space" code develop by Milos Pokorny which is already used in the simple applications. AFE headers https://gitlab.com/elektroline-predator/nuttx/-/commit/3fa4e624a28c9a6836895119e7dd41afec7eae88 https://gitlab.com/elektroline-predator/nuttx/-/commit/617015e84910a95ed2faf9b198b34059e6a947d7 Best wishes, Pavel
int adc_init(void); void adc_measure(uint32_t *current, uint32_t *voltage, uint32_t *temperature);
#include <stdio.h> #include <hardware/sam_afec.h> #include <hardware/sam_pio.h> #include <common/arm_arch.h> #include <same70_periphclks.h> #include <nuttx/arch.h> #include "adc.h" #define CONF_ADC_PRESCALER 2 #define ADC_CONFIG (AFEC_MR_PRESCAL(CONF_ADC_PRESCALER) | AFEC_MR_STARTUP_64 | AFEC_MR_ONE) #define CHANNELS0 (AFEC_CH10 | AFEC_CH1) #define CHANNELS1 (AFEC_CH0) static uint32_t current = 0; static uint32_t voltage = 0; static uint32_t temperature = 0; static uint32_t count0 = 0; static sem_t sem0; static sem_t sem1; #ifdef ADC_DEBUG static void adc_debug(uint32_t base); #endif static int sam_adc_interrupt0(int base, void* irq, void *context) { uint32_t isr = getreg32(SAM_AFEC0_ISR); if(isr & AFEC_CH10) { putreg32(AFEC_CSELR_CSEL(10), SAM_AFEC0_CSELR); current = getreg32(SAM_AFEC0_CDR); count0++; } if(isr & AFEC_CH1) { putreg32(AFEC_CSELR_CSEL(1), SAM_AFEC0_CSELR); temperature = getreg32(SAM_AFEC0_CDR); count0++; } if(count0 >= 2) { sem_post( &sem0 ); } return OK; } static int sam_adc_interrupt1(int base, void* irq, void *context) { uint32_t isr = getreg32(SAM_AFEC1_ISR); if(isr & AFEC_CH0) { putreg32(AFEC_CSELR_CSEL(0), SAM_AFEC1_CSELR); voltage = getreg32(SAM_AFEC1_CDR); sem_post( &sem1 ); } return OK; } int adc_init(void) { uint32_t i; /* clock init */ sam_afec0_enableclk(); sam_afec1_enableclk(); /* reset */ putreg32(AFEC_CR_SWRST, SAM_AFEC0_CR); putreg32(AFEC_CR_SWRST, SAM_AFEC1_CR); /* MR configuration*/ putreg32(ADC_CONFIG, SAM_AFEC0_MR); putreg32(ADC_CONFIG, SAM_AFEC1_MR); /* Disable PULL UP */ putreg32(0x50494F00, SAM_PIOA_WPMR); putreg32(1 << 21, SAM_PIOA_PUDR); putreg32(0x50494F01, SAM_PIOA_WPMR); putreg32(0x50494F00, SAM_PIOB_WPMR); putreg32(0x3, SAM_PIOB_PUDR); putreg32(0x50494F01, SAM_PIOB_WPMR); /* EMR configuration*/ putreg32(AFEC_EMR_TAG | AFEC_EMR_RES_OSR256 | AFEC_EMR_STM, SAM_AFEC0_EMR); putreg32(AFEC_EMR_TAG | AFEC_EMR_RES_OSR256 | AFEC_EMR_STM, SAM_AFEC1_EMR); /* Offset Compensation set to 512 on all channels */ for (i = 0; i < 12; i++) { putreg32(i, SAM_AFEC0_CSELR); putreg32(512, SAM_AFEC0_COCR); putreg32(i, SAM_AFEC1_CSELR); putreg32(512, SAM_AFEC1_COCR); } /* Enable gain */ putreg32(AFEC_ACR_IBCTL(2) | AFEC_ACR_PGA0EN | AFEC_ACR_PGA1EN, SAM_AFEC0_ACR); putreg32(AFEC_ACR_IBCTL(2) | AFEC_ACR_PGA0EN | AFEC_ACR_PGA1EN, SAM_AFEC1_ACR); /* attach irq call */ i = irq_attach(SAM_IRQ_AFEC0, sam_adc_interrupt0, NULL); if (i != OK) { printf("ERROR: Attach irq AFEC0\n"); return -1; } up_enable_irq(SAM_IRQ_AFEC0); i = irq_attach(SAM_IRQ_AFEC1, sam_adc_interrupt1, NULL); if (i != OK) { printf("ERROR: Attach irq AFEC1\n"); return -1; } up_enable_irq(SAM_IRQ_AFEC1); /* enable interrupts */ putreg32(CHANNELS0, SAM_AFEC0_IER); putreg32(CHANNELS1, SAM_AFEC1_IER); return 0; } void adc_measure(uint32_t *c, uint32_t *v, uint32_t *t) { /* disable all channels */ putreg32(AFEC_INT_EOCALL, SAM_AFEC0_CHDR); putreg32(AFEC_INT_EOCALL, SAM_AFEC1_CHDR); count0 = 0; sem_init(&sem0, 0, 0); sem_init(&sem1, 0, 0); putreg32(CHANNELS0, SAM_AFEC0_CHER); putreg32(CHANNELS1, SAM_AFEC1_CHER); putreg32(AFEC_CR_START, SAM_AFEC0_CR); putreg32(AFEC_CR_START, SAM_AFEC1_CR); sem_wait(&sem0); sem_wait(&sem1); *c = current; *v = voltage; *t = temperature; } #ifdef ADC_DEBUG static void adc_debug(uint32_t base) { printf(" Base : %08lx\n", base); printf(" MR: %08lx EMR: %08lx\n", getreg32(base + SAM_AFEC_MR_OFFSET), getreg32(base + SAM_AFEC_EMR_OFFSET)); printf(" SEQ1R: %08lx SEQ2R: %08lx\n", getreg32(base + SAM_AFEC_SEQ1R_OFFSET), getreg32(base + SAM_AFEC_SEQ2R_OFFSET)); printf(" CHSR: %08lx LCDR: %08lx\n", getreg32(base + SAM_AFEC_CHSR_OFFSET), getreg32(base + SAM_AFEC_LCDR_OFFSET)); printf(" IMR: %08lx ISR: %08lx\n", getreg32(base + SAM_AFEC_IMR_OFFSET), getreg32(base + SAM_AFEC_ISR_OFFSET)); printf(" OVER: %08lx CWR: %08lx CGR: %08lx CDOR: %08lx\n", getreg32(base + SAM_AFEC_OVER_OFFSET), getreg32(base + SAM_AFEC_CWR_OFFSET), getreg32(base + SAM_AFEC_CGR_OFFSET), getreg32(base + SAM_AFEC_CDOR_OFFSET)); printf(" DIFFER: %08lx CSELR: %08lx CDR: %08lx COCR: %08lx\n", getreg32(base + SAM_AFEC_DIFFR_OFFSET), getreg32(base + SAM_AFEC_CSELR_OFFSET), getreg32(base + SAM_AFEC_CDR_OFFSET), getreg32(base + SAM_AFEC_COCR_OFFSET)); printf("TEMPPMR: %08lx TEMPCWR: %08lx ACR: %08lx SHMR: %08lx\n", getreg32(base + SAM_AFEC_TEMPMR_OFFSET), getreg32(base + SAM_AFEC_TEMPCWR_OFFSET), getreg32(base + SAM_AFEC_ACR_OFFSET), getreg32(base + SAM_AFEC_SHMR_OFFSET)); printf(" COSR: %08lx CVR: %08lx CECR: %08lx\n", getreg32(base + SAM_AFEC_COSR_OFFSET), getreg32(base + SAM_AFEC_CVR_OFFSET), getreg32(base + SAM_AFEC_CECR_OFFSET)); printf(" WPMR: %08lx WPSR: %08lx\n\n", getreg32(base + SAM_AFEC_WPMR_OFFSET), getreg32(base + SAM_AFEC_WPSR_OFFSET)); } #endif