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

Reply via email to