We're no longer updating This wiki!!

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
en:xu3_hardware_adc [2016/01/21 18:02]
john1117 [Register Map Summary]
en:xu3_hardware_adc [2016/12/19 16:03] (current)
charles.park [Using mmap]
Line 8: Line 8:
 | 23         | ADC_0.AIN3 ​  | XADC0AIN_3 ​        | | 23         | ADC_0.AIN3 ​  | XADC0AIN_3 ​        |
  
-==== Using sysfs ====+===== Using sysfs =====
  
 Read raw data.(ADC Channel 0) Read raw data.(ADC Channel 0)
Line 19: Line 19:
 **Input voltage range is 0~1.8Volt. Otherwise your ODROID will be damaged permanently.** **Input voltage range is 0~1.8Volt. Otherwise your ODROID will be damaged permanently.**
  
-==== Using mmap ====+===== Using mmap =====
  
-Example ​source code+Example ​source code to access the ADC.
 <file c mmap_adc.c>​ <file c mmap_adc.c>​
-#include <​stdio.h> ​                                                                            ​ +#include <​stdio.h>​ 
-#include <​fcntl.h> ​                                                                            ​ +#include <​fcntl.h>​ 
-#include <​sys/​mman.h> ​                                                                          +#include <​sys/​mman.h>​ 
-#include <​stdint.h> ​                                                                            +#include <​stdint.h>​ 
-                                                                                               ​ +  
-/* EXYNOS4412/​5250 ​ADC_V1 registers definitions */                                             ​ +/* EXYNOS ​ADC_V1 registers definitions */ 
-#define ADC_V1_DATAX ​           0x0C                                                           ​ +#define ADC_V1_DATAX 0x0C 
-                                                                                               ​ +  
-/* Future ADC_V2 registers definitions */                                                       +/* Future ADC_V2 registers definitions */ 
-#define ADC_V2_CON1 ​            ​0x00                                                           ​ +#define ADC_V2_CON1 0x00 
-#define ADC_V2_CON2 ​            ​0x04                                                           ​ +#define ADC_V2_CON2 0x04 
-#define ADC_V2_STAT ​            ​0x08                                                           ​ +#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) 
-/* 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_OSEL ​       (1u << 10)                                                     ​ +#define ADC_V2_CON2_HIGHF (1u << 8) 
-#define ADC_V2_CON2_ESEL ​       (1u << 9)                                                       +#define ADC_V2_CON2_C_TIME(x) (((x) & 7) << 4) 
-#define ADC_V2_CON2_HIGHF ​      ​(1u << 8)                                                       +#define ADC_V2_CON2_ACH_SEL(x) (((x) & 0xF) << 0) 
-#define ADC_V2_CON2_C_TIME(x) ​  ​(((x) & 7) << 4)                                               ​ +#define ADC_V2_CON2_ACH_MASK 0xF 
-#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) 
-/* Bit definitions common for ADC_V1 and ADC_V2 */                                             ​ +#define ADC_DATX_MASK ​          ​0xFFF 
-#define ADC_CON_EN_START ​       (1u << 0)                                                       + 
-#define ADC_DATX_MASK ​          ​0xFFF ​                                                          +static volatile uint32_t *adc; 
-                                                                                               ​ +static unsigned char channel; 
-static volatile uint32_t *adc;                                                                 ​ +static uint32_t con1, con2; 
-static uint32_t con1, con2;                                                                     +static int val0; 
-void exynos_read_raw(unsigned char channel); ​                                                   +static int val3; 
-void exynos_adc_isr(); ​                                                                         + 
-static int val;                                                                                ​ +void exynos_read_raw(unsigned char channel); 
-                                                                                               ​ + 
-int main(int argc, char **argv) ​                                                                +int main(int argc, char **argv) 
-                                                                                              +
-        int fd;                                                                                 + int fd; 
-                                                                                               ​ +  
-        if ((fd = open("/​dev/​mem",​ O_RDWR | O_SYNC)) < 0) {                                     + if ((fd = open("/​dev/​mem",​ O_RDWR | O_SYNC)) < 0) { 
-                printf("​Unable to open /​dev/​mem\n"​); ​                                          ​ + printf("​Unable to open /​dev/​mem\n"​);​ 
-                return -1;                                                                     ​ + return -1; 
-                                                                                              +
-                                                                                               ​ +  
-        adc = mmap(0, getpagesize(),​ PROT_READ | PROT_WRITE, ​                                  ​ + adc = mmap(0, getpagesize(),​ PROT_READ | PROT_WRITE,​ 
-                                        MAP_SHARED, fd, 0x12D10000); ​                          ​ + MAP_SHARED, fd, 0x12D10000);​ 
-        if (adc < 0) {                                                                         ​ + if (adc < 0) { 
-                printf("​mmap failed.\n"​); ​                                                      + printf("​mmap failed.\n"​);​ 
-                return -1;                                                                     ​ + return -1; 
-                                                                                              +
-                                                                                               ​ +  
-        // exynos_adc_hw_init ​                                                                  + // exynos_adc_hw_init 
-        con1 = ADC_V2_CON1_SOFT_RESET; ​                                                        ​ + con1 = ADC_V2_CON1_SOFT_RESET;​ 
-        *(adc + (ADC_V2_CON1 >> 2)) |= con1;                                                   ​ + *(adc + (ADC_V2_CON1 >> 2)) |= con1; 
-        con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL |                                           ​ + con2 = ADC_V2_CON2_OSEL | ADC_V2_CON2_ESEL | 
-                ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0); ​                                    ​ + ADC_V2_CON2_HIGHF | ADC_V2_CON2_C_TIME(0);​ 
-        *(adc + (ADC_V2_CON2 >> 2)) |= con2;                                                   ​ + *(adc + (ADC_V2_CON2 >> 2)) |= con2; 
-                                                                                               ​ +  
-        while (1)                                                                               + while (1) 
-                                                                                              +
-                if (*(adc + (ADC_V2_STAT >> 2)) && 4) {                                         + // End of A/D conversion 
-                        /* start channel 0 conversion ​*/                                       ​ + if (*(adc + (ADC_V2_STAT >> 2)) & 4) { 
-                        ​exynos_read_raw(0);                                                     + /* Read value */ 
-                        /* Read value */                                                        + if (channel == 0x0) { 
-                        ​val ​= *(adc + (ADC_V1_DATAX >> 2)) & ADC_DATX_MASK; ​                    + val0 = *(adc + (ADC_V1_DATAX >> 2)) & ADC_DATX_MASK;​ 
-                        printf("​ADC Channel ​: %d\n", ​val);                                   ​ + printf("​ADC Channel ​: %d\n", val0); 
-                                                                                              + } else if (channel == 0x3) { 
-                sleep(1); ​                                                                      + val3 ​= *(adc + (ADC_V1_DATAX >> 2)) & ADC_DATX_MASK;​ 
-                                                                                              + printf("​ADC Channel ​: %d\n", ​val3); 
-                                                                                               ​ +
-        return 0;                                                                               + 
-                                                                                              + if (channel == 0x0) { 
-                                                                                               ​ + /* start channel 0 conversion */ 
-void exynos_read_raw(unsigned char channel) ​                                                    + exynos_read_raw(3);​ 
-                                                                                              +
-        con2 = *(adc + (ADC_V2_CON2 >> 2));                                                     + else if (channel == 0x3) { 
-        con2 &= ~ADC_V2_CON2_ACH_MASK; ​                                                        ​ + // start channel 3 conversion 
-        con2 |= ADC_V2_CON2_ACH_SEL(channel); ​                                                  + exynos_read_raw(0);​ 
-        *(adc + (ADC_V2_CON2 >> 2)) |= con2;                                                   ​ +
-                                                                                               ​ +
-        con1 = *(adc + (ADC_V2_CON1 >> 2));                                                     + channel = con2 & ADC_V2_CON2_ACH_MASK;​ 
-        *(adc +(ADC_V2_CON1 >> 2)) = con1 | ADC_CON_EN_START; ​                                 + sleep(1); 
 +
 +  
 + return 0; 
 +
 +  
 +void exynos_read_raw(unsigned char channel) 
 +
 + con2 = *(adc + (ADC_V2_CON2 >> 2)); 
 + con2 &= ~ADC_V2_CON2_ACH_MASK;​ 
 + *(adc + (ADC_V2_CON2 >> 2)) &= con2; 
 + 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;​
 } }
 </​file>​ </​file>​
-===== Register Map Summary ====+==== Register Map Summary ====
-**Register Map Summary**+
  
   * Base Address : 0x12D1_0000   * Base Address : 0x12D1_0000
Line 136: Line 150:
  
 **ADC_CON2** **ADC_CON2**
 +
 +  * Base Address: 0x12D1_0000
 +  * Address = Base Address + 0x0004, Reset Value = 0x0000_0720
 +
 ^Name^Bit^Type^Description^Reset Value^ ^Name^Bit^Type^Description^Reset Value^
 |RSVD|[31:​11|R|Reserved(read as zero, do not modify)|0x0| |RSVD|[31:​11|R|Reserved(read as zero, do not modify)|0x0|
Line 149: Line 167:
 |RSVD|[7]|R|Reserved (read as zero, do not modify)|0x0| |RSVD|[7]|R|Reserved (read as zero, do not modify)|0x0|
 |C_TIME|[6:​4]|RW|Selection of the ADC conversion mode|0x2| |C_TIME|[6:​4]|RW|Selection of the ADC conversion mode|0x2|
-|:::​|:::​|:::​||:::​| +|:::​|:::​|:::​|0x0 = 1 times conversion to get the data|:::| 
-|:::​|:::​|:::​||:::​|+|:::​|:::​|:::​|0x1 = 2 times conversion|:::​| 
 +|:::​|:::​|:::​|0x2 = 4 times conversion|:::​| 
 +|:::​|:::​|:::​|0x3 = 8 times conversion|:::​| 
 +|:::​|:::​|:::​|0x4 = 16 times conversion|:::​| 
 +|:::​|:::​|:::​|0x5 = 32 times conversion|:::​| 
 +|:::​|:::​|:::​|0x6 = 64 times conversion|:::​| 
 +|:::​|:::​|:::​|NOTE:​ ADC_DAT register is updated on an average with a sum after 1, 2, 4, 8, 16, 32 or 64 times conversion.|:::​| 
 +|ACH_SEL|[3:​0]|RW|Analog input channel selection|0x0| 
 +|:::​|:::​|:::​|0x0 = Channel 0|:::| 
 +|:::​|:::​|:::​|0x1 = Channel 1|:::| 
 +|:::​|:::​|:::​|0x2 = Channel 2|:::| 
 +|:::​|:::​|:::​|0x3 = Channel 3|:::| 
 +|:::​|:::​|:::​|0x4 = Channel 4|:::| 
 +|:::​|:::​|:::​|0x5 = Channel 5|:::| 
 +|:::​|:::​|:::​|0x6 = Channel 6|:::| 
 +|:::​|:::​|:::​|0x7 = Channel 7|:::| 
 +|:::​|:::​|:::​|0x8 = Channel 8|:::| 
 +|:::​|:::​|:::​|0x9 = Channel 9|:::| 
 +|:::​|:::​|:::​|0xA to 0xF = Reserved|:::|
  
 **ADC_STATUS** **ADC_STATUS**
 +
 +  * Base Address: 0x12D1_0000
 +  * Address = Base Address + 0x00048, Reset Value = 0x0000_0000
 +
 ^Name^Bit^Type^Description^Reset Value^ ^Name^Bit^Type^Description^Reset Value^
 +|RSVD|[31:​3]|R|Reserved (read as zero, do not modify)|0x0|
 +|FLAG|[2]|R|End of conversion flag|-|
 +|:::​|:::​|:::​|0x0 = A/D conversion in process|:::​|
 +|:::​|:::​|:::​|0x1 = End of A/D conversion|:::​|
 +|RSVD|[1:​0]|R|Reserved (read as zero, do not modify)|0x0|
  
 **ADC_DAT** **ADC_DAT**
 +
 +  * Base Address: 0x12D1_0000
 +  * Address = Base Address + 0x000C, Reset Value = 0x0000_0000
 +
 ^Name^Bit^Type^Description^Reset Value^ ^Name^Bit^Type^Description^Reset Value^
 +|RSVD|[31:​12]|R|Reserved (read as zero, do not modify)|0x0|
 +|ADCDAT|[11:​0]|R|ADC conversion data value (0x000 to 0xFFF)|-|
  
 **ADC_INT_EN** **ADC_INT_EN**
 +
 +  * Base Address: 0x12D1_0000
 +  * Address = Base Address + 0x0010, Reset Value = 0x0000_0000
 +
 ^Name^Bit^Type^Description^Reset Value^ ^Name^Bit^Type^Description^Reset Value^
 +|RSVD|[31:​1]|R|Reserved (read as zero, do not modify)|0x0|
 +|INT_EN|[0]|RW|0x0 = Disables interrupt|0x0|
 +|:::​|:::​|:::​|0x1 = Enables interrupt|:::​|
  
 **ADC_INT_STATUS** **ADC_INT_STATUS**
 +
 +  * Base Address: 0x12D1_0000
 +  * Address = Base Address + 0x0014, Reset Value = 0x0000_0000
 +
 ^Name^Bit^Type^Description^Reset Value^ ^Name^Bit^Type^Description^Reset Value^
 +|RSVD|[31:​1]|R|Reserved (read as zero, do not modify)|0x0|
 +|INT_STATUS|[0]|RW|When Read|0x0|
 +|:::​|:::​|:::​|0x0 = Interrupt is not generated|:::​|
 +|:::​|:::​|:::​|0x1 = Interrupt is generated|:::​|
 +|:::​|:::​|:::​|When Write|:::|
 +|:::​|:::​|:::​|0x0 = No action|:::|
 +|:::​|:::​|:::​|0x1 = This bit is cleared|:::​|
 +
  
 **ADC_VERSION** **ADC_VERSION**
 +
 +  * Base Address: 0x12D1_0000
 +  * Address = Base Address + 0x0020, Reset Value = 0x8000_0008
 +
 ^Name^Bit^Type^Description^Reset Value^ ^Name^Bit^Type^Description^Reset Value^
 +|ADC_VERSION_INFO|[31:​0]|R|ADC Version Information|0x8000_0008|
en/xu3_hardware_adc.1453368766.txt.gz · Last modified: 2016/01/21 18:02 by john1117
CC Attribution-Share Alike 3.0 Unported
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0