I'm trying to make the ADC converter of the PortuxG20 work. I'm not one hundred percent sure that I've got my software correct yet, but when studying the documentation I found the following:
Maximum clock frequency for 8 bit conversion is 5MHz
Maximum clock frequency for 10 bit conversion is 1 MHz.
The Portux Master Clock (MCK) is at 132 MHz. The Prescaler (a 6 bit value, maximum value 63) is used to derive the ADC Clock from the MCK using the formula 132 / (PRESCALER x 2) MHz, i.e. at 132 / 126 MHz... which is > 1MHz. this would mean that I cannot use 10 bits ADC conversion anymore ?
Is there a way of reducing the clock speed of the PortuxG20 MCK?
Does anyone have a sample of software for driving the ADC controller of the PortuxG20?
Peter

Re: PortuxG20 Analog-Digital Converter
The only way to reduce the clock would be to reprogram the PMC in U-Boot (either U-Boot source or on the U-Boot CLI with the memory access functions), but I think it is still possible to use the ADC with the current MCK even if it is slightly over the specified maximum.
Here is a sample program reading all channels in 10 bit mode:
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #define MAP_SIZE 4096UL #define MAP_MASK (MAP_SIZE - 1) #define ADC_BASE 0xfffe0000 #define ADC_CR 0x00 #define ADC_MR 0x04 #define ADC_CHER 0x10 #define ADC_SR 0x1c #define ADC_CDR(x) (0x30+(x)*0x4) #define PMC_BASE 0xfffffc00 #define PMC_PCER 0x10 #define ADC_PID 5; void *adc_base; void *pmc_base; int main(int argc, char **argv) { int fd; if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { printf("couldn't open /dev/mem\n"); return 1; } /* map adc memory region */ adc_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ADC_BASE & ~MAP_MASK); if(adc_base == MAP_FAILED) { printf("mmap failed\n"); return 1; } /* map pmc memory region */ pmc_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PMC_BASE & ~MAP_MASK); if(pmc_base == MAP_FAILED) { printf("mmap failed\n"); return 1; } /* enable adc clock in pmc */ *((volatile unsigned long *) (pmc_base + ((PMC_BASE + PMC_PCER) & MAP_MASK))) = 1 << ADC_PID; /* software reset */ *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CR) & MAP_MASK))) = 0x00000001; /* enable adc channels 0-3 */ *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CHER) & MAP_MASK))) = 0x0000000f; /* maximum start and sample & hold time, maximum prescaler, normal and high resolution mode, no hardware trigger */ *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_MR) & MAP_MASK))) = 0x0f1f3f00; /* start conversion */ *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CR) & MAP_MASK))) = 0x00000002; /* wait for end of conversion of all channels */ while((*(volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_SR) & MAP_MASK)) & 0xf) != 0xf); /* read out adc values */ printf("%08x\n", *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CDR(0)) & MAP_MASK)))); printf("%08x\n", *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CDR(1)) & MAP_MASK)))); printf("%08x\n", *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CDR(2)) & MAP_MASK)))); printf("%08x\n", *((volatile unsigned long *) (adc_base + ((ADC_BASE + ADC_CDR(3)) & MAP_MASK)))); if(munmap(adc_base, MAP_SIZE) == -1) return 1; close(fd); return 0; }Re: PortuxG20 Analog-Digital Converter
Thanks, also for your sample code. I did not set the PMC and now my code also works (also at 10 bit). Onward with development!