We're no longer updating This wiki!!

This is an old revision of the document!


Using the ADC ports on 30pin header

There are two ADC inputs on the 30pin header provides 12-bit analog-to-digital converter.

CON10 - 2×15 pins

Pin Number Net Name GPIO & Export No
3 ADC_0.AIN0 XADC0AIN_0
23 ADC_0.AIN3 XADC0AIN_3

Using sysfs

Read raw data.(ADC Channel 0)

cat /sys/devices/12d10000.adc/iio:device0/in_voltage0_raw

Read raw data.(ADC Channel 3)

cat /sys/devices/12d10000.adc/iio:device0/in_voltage3_raw

Input voltage range is 0~1.8Volt. Otherwise your ODROID will be damaged permanently.

Using mmap

Example c source code

mmap_adc.c
#include <stdio.h>                                                                             
#include <fcntl.h>                                                                             
#include <sys/mman.h>                                                                          
#include <stdint.h>                                                                            
 
/* EXYNOS4412/5250 ADC_V1 registers definitions */                                             
#define ADC_V1_DATAX            0x0C                                                           
 
/* Future ADC_V2 registers definitions */                                                      
#define ADC_V2_CON1             0x00                                                           
#define ADC_V2_CON2             0x04                                                           
#define ADC_V2_STAT             0x08                                                           
#define ADC_V2_INT_EN           0x10                                                           
#define ADC_V2_INT_ST           0x14                                                           
 
/* Bit definitions for ADC_V2 */                                                               
#define ADC_V2_CON1_SOFT_RESET  (1u << 2)                                                      
 
#define ADC_V2_CON2_OSEL        (1u << 10)                                                     
#define ADC_V2_CON2_ESEL        (1u << 9)                                                      
#define ADC_V2_CON2_HIGHF       (1u << 8)                                                      
#define ADC_V2_CON2_C_TIME(x)   (((x) & 7) << 4)                                               
#define ADC_V2_CON2_ACH_SEL(x)  (((x) & 0xF) << 0)                                             
#define ADC_V2_CON2_ACH_MASK    0xF                                                            
 
/* Bit definitions common for ADC_V1 and ADC_V2 */                                             
#define ADC_CON_EN_START        (1u << 0)                                                      
#define ADC_DATX_MASK           0xFFF                                                          
 
static volatile uint32_t *adc;                                                                 
static uint32_t con1, con2;                                                                    
void exynos_read_raw(unsigned char channel);                                                   
void exynos_adc_isr();                                                                         
static int val;                                                                                
 
int main(int argc, char **argv)                                                                
{                                                                                              
        int fd;                                                                                
 
        if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) {                                    
                printf("Unable to open /dev/mem\n");                                           
                return -1;                                                                     
        }                                                                                      
 
        adc = mmap(0, getpagesize(), PROT_READ | PROT_WRITE,                                   
                                        MAP_SHARED, fd, 0x12D10000);                           
        if (adc < 0) {                                                                         
                printf("mmap failed.\n");                                                      
                return -1;                                                                     
        }                                                                                      
 
        // exynos_adc_hw_init                                                                  
        con1 = ADC_V2_CON1_SOFT_RESET;                                                         
        *(adc + (ADC_V2_CON1 >> 2)) |= con1;                                                   
        con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |                                           
                ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);                                     
        *(adc + (ADC_V2_CON2 >> 2)) |= con2;                                                   
 
        while (1)                                                                              
        {                                                                                      
                if (*(adc + (ADC_V2_STAT >> 2)) && 4) {                                        
                        /* start channel 0 conversion */                                       
                        exynos_read_raw(0);                                                    
                        /* Read value */                                                       
                        val = *(adc + (ADC_V1_DATAX >> 2)) & ADC_DATX_MASK;                    
                        printf("ADC Channel 0 : %d\n", val);                                   
                }                                                                              
                sleep(1);                                                                      
        }                                                                                      
 
        return 0;                                                                              
}                                                                                              
 
void exynos_read_raw(unsigned char channel)                                                    
{                                                                                              
        con2 = *(adc + (ADC_V2_CON2 >> 2));                                                    
        con2 &= ~ADC_V2_CON2_ACH_MASK;                                                         
        con2 |= ADC_V2_CON2_ACH_SEL(channel);                                                  
        *(adc + (ADC_V2_CON2 >> 2)) |= con2;                                                   
 
        con1 = *(adc + (ADC_V2_CON1 >> 2));                                                    
        *(adc +(ADC_V2_CON1 >> 2)) = con1 | ADC_CON_EN_START;                                  
}

Register Map Summary

NameOffsetDescriptionReset Value
ADC_CON10x0000ADC Control register0x0000_0002
ADC_CON20x0004ADC Configuration register0x0000_0720
ADC_STATUS0x0008ADC Status register0x0000_0000
ADC_DAT0x000CADC Data register0x0000_0000
ADC_INT_EN0x0010ADC Interrupt Enable register0x0000_0000
ADC_INT_STATUS0x0014ADC Interrupt Status register0x0000_0000
ADC_VERSION0x0020ADC Version information register0x8000_0008

ADC_CON1

NameBitTypeDescriptionReset Value
en/xu3_hardware_adc.1453368049.txt.gz · Last modified: 2016/01/21 17:50 by john1117
CC Attribution-Share Alike 3.0 Unported
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0