AVR Basic Compiler Library Support


The library support is a new way for the basic statements implementation.
This is indeed an advanced feature, however that is a way that can be used by both the author and the users to extend the compiler language from the external library files.
The information is loaded from the external textual .lib files stored in the OshonSoft application data folder.
OshonSoft .lib files are documented enough with comments covering all the currently available features of the library support.
Library files can be edited by Notepad, or any other plain text editor.
 
 

oshonsoftavr-adc.lib file:
 
//the concept is that one library group contains the implementation of one new language element - statement
//library items contain different implementations of the same functionality for different groups of microcontrollers
//#lib_item_begin must be followed by #processor
//#statement_begin, #statement_type, #argument sequence must be fulfilled for proper library load
 
//#processor comma-separated list of processors, x can be used as a wild card character
//#processor can be used in multiple lines to quote all devices if needed
//#parameter is used to implement #define parameters needed for the statement implementation
//#parameter const, parameter_name, allowed_range, default_value
//#parameter symbol, parameter_name, type (pin, bit, byte, address of), system_bit or system_register
//'pin' type is used for the bits in the PORT registers
//'address of' type will implement a constant parameter
//#variable is used to declare global system variables
//#variable variable_name, type (byte, word, long, single, string)
//#statement_begin statement_name [argument1_name[, argument2_name[, ...]]]
//#statement_type type (procedure; inline; function, f_type (byte, word, long, single, string))
//#argument argument_name, type (byte, byte system xx, word, word system xx, long, long system xx, single, string), passing_type
//the default type of the system variables can not be changed with #argument
//passing_type (byval, byval allowed_constant_range, byref, byrefout) for statement_type procedure and inline
//passing_type (byval, byval allowed_constant_range) for statement_type function
 
//used to define parameters and statements that are not available or not applicable for the current item devices
//#parameter n/a, parameter_name
//#statement n/a, statement_name
 
//code section can contain both inline assembler and basic language lines of code
//symbol and const parameters can be used directly in the assembler lines of code
//calculate[] or calc[] macro is available
//calculate[] must be used to enter the parameter value in the basic code, will be replaced with the value of the parameter
//calculate[] can be used to perform one arithmetic operation, will be replaced with the value of the result
//calc[] arithmetic operators: +, -, *, /, % (modulus or remainder operator), \ (division returning integer result)
//calc[] macros can be nested
//reg_addr[] macro will be replaced with the register address; if not found, -1 is returned
//#if [], #endif macro is available
//#if comparison operators: ==,<>,<,>,<=,>=
//Clock_Freq in MHz is available as an argument
 
//be careful that basic statements like WaitUs also make use of the system registers and can alter those values
 
//special function registers are declared in basic code as byte variables; if needed, this byte variable type can be changed with #redim directive
//#redim register_name new_type (byte, word, long, single)
 
//list of available compiler system byte registers: R16, R17, R18, R19, R20, R21, R22, R23, R24, R25
//list of available compiler system byte registers: R26 (XL), R27 (XH), R28 (YL), R29 (YH), R30 (ZL), R31 (ZH)
//list of available compiler system byte registers: R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15
//list of available compiler system word registers: R1716, R1918, R2120, R2322, R2524
//list of available compiler system word registers: R2726 (XHL), R2928 (YHL), R3130 (ZHL)
//list of available compiler system word registers: R1R0, R3R2, R5R4, R7R6, R9R8, R1110, R1312, R1514
//list of available compiler system long registers: R19181716, R23222120, R27262524, R31302928
//the compiler holds zero value in R15 system register
//the compiler uses R16 system register as working register
//registers R16-R31 are much better covered by AVR instruction set
 
 
#lib_name OshonSoft ADC Module Library
 
 
#lib_group_begin //ADC_Read statement
 
#lib_item_begin
//ADMUX, i/o space 0-31,
//REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0 //v2
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor mega16
#processor mega16a
#processor mega32
#processor mega32a
#processor mega64
#processor mega64a
#processor mega128 //v2
#processor mega128a //v2
#processor mega8535
#processor tiny26 //v2
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-31
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x1f
        ori R31,calc[ADC_Ref * 64]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
//REFS1 REFS0 ADLAR MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor mega8
#processor mega8a
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-15
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x0f
        ori R31,calc[ADC_Ref * 64]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
// ADCBG MUX2 MUX1 MUX0
// MUX2 MUX1 MUX0 //v2
//ADCSR, i/o space 0-31,
//ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor 90s4433
#processor 90s8535 //v2
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter n/a, ADC_Ref
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-7
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x07
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSR,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSR,ADSC
        sbis ADCSR,ADIF
        rjmp PC-1
        sbi ADCSR,ADIF
        cbi ADCSR,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
//REFS1 REFS0 MUX5 MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space 0-31,
//BIN ACME ADLAR ADTS2 ADTS1 ADTS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor tiny24, tiny44, tiny84
#processor tiny24a, tiny44a, tiny84a
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-63
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        cbi ADCSRB,ADLAR
        andi R31,0x3f
        ori R31,calc[ADC_Ref * 64]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
//REFS1 REFS0 ADLAR REFS2 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor tiny25, tiny45, tiny85
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-7, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-15
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x0f
        ori R31,calc[calc[calc[ADC_Ref % 4] * 64] + calc[calc[ADC_Ref \ 4] * 16]]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
// REFS0 ADLAR MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor tiny13
#processor tiny13a
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-1, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-3
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x03
        ori R31,calc[ADC_Ref * 64]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
//REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space 0-31,
//BIN GSEL - REFS2 MUX5 ADTS2 ADTS1 ADTS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor tiny261, tiny461, tiny861
#processor tiny261a, tiny461a, tiny861a
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-7, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-63
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        in R30,ADCSRB
        bst R31,5
        bld R30,3
        #if [ADC_Ref > 3] sbr R30,0x10
        #if [ADC_Ref <= 3] cbr R30,0x10
        out ADCSRB,R30
        andi R31,0x1f
        ori R31,calc[calc[ADC_Ref % 4] * 64]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUXA, i/o space 0-31,
// MUX5 MUX4 MUX3 MUX2 MUX1 MUX0
//ADMUXB, i/o space 0-31,
//REFS2 REFS1 REFS0 GSEL1 GSEL0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space 0-31,
// ADLAR ADTS2 ADTS1 ADTS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor tiny441, tiny841
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-7, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-63
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        cbi ADCSRB,ADLAR
        andi R31,0x3f
        out ADMUXA,R31
        in R30,ADMUXB
        andi R30,0x1f
        ori R30,calc[ADC_Ref * 32]
        out ADMUXB,R30
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space 0-31,
//REFS1 REFS0 REFEN ADC0EN MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space 0-31,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space 0-31,
//VDEN VDPD ADLAR ADTS2 ADTS1 ADTS0
//ADCL, i/o space 0-31,
//ADCH, i/o space 0-31,
#processor tiny1634
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-15
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        cbi ADCSRB,ADLAR
        andi R31,0x0f
        ori R31,calc[ADC_Ref * 64]
        out ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        out ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        sbi ADCSRA,ADSC
        sbis ADCSRA,ADIF
        rjmp PC-1
        sbi ADCSRA,ADIF
        cbi ADCSRA,ADEN
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space ext,
//REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space ext,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCL, i/o space ext,
//ADCH, i/o space ext,
#processor mega164p, mega324p, mega644p
#processor mega164a, mega164pa, mega324a, mega324pa, mega644a, mega644pa, mega1284, mega1284p
#processor mega165
#processor mega165p
#processor mega165a, mega165pa, mega325a, mega325pa, mega3250a, mega3250pa, mega645a, mega645p, mega6450a, mega6450p
#processor mega169
#processor mega169p
#processor mega169a, mega169pa, mega329a, mega329pa, mega649a, mega649p, mega3290a, mega3290pa, mega6490a, mega6490p
#processor mega325, mega3250, mega645, mega6450
#processor mega325p, mega3250p
#processor mega644
#processor mega329, mega3290, mega649, mega6490
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-31
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x1f
        ori R31,calc[ADC_Ref * 64]
        sts ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        sts ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        lds R30,ADCSRA
        sbr R30,0x40 //ADSC
        sts ADCSRA,R30
        l1:
        lds R30,ADCSRA
        sbrs R30,ADIF
        rjmp l1
        ldi R30,calc[calc[ADC_Clk] + 16] //16-ADIF
        sts ADCSRA,R30
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space ext,
//REFS1 REFS0 ADLAR MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space ext,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCL, i/o space ext,
//ADCH, i/o space ext,
#processor mega48, mega88, mega168
#processor mega48a, mega48pa, mega88a, mega88pa, mega168a, mega168pa, mega328, mega328p
#processor mega48p, mega88p, mega168p
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-15
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        andi R31,0x0f
        ori R31,calc[ADC_Ref * 64]
        sts ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        sts ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        lds R30,ADCSRA
        sbr R30,0x40 //ADSC
        sts ADCSRA,R30
        l1:
        lds R30,ADCSRA
        sbrs R30,ADIF
        rjmp l1
        ldi R30,calc[calc[ADC_Clk] + 16] //16-ADIF
        sts ADCSRA,R30
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space ext,
//REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space ext,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space ext,
// ACME MUX5 ADTS2 ADTS1 ADTS0
//ADCL, i/o space ext,
//ADCH, i/o space ext,
#processor mega640, mega1280, mega1281, mega2560, mega2561
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 6
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-63
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        bst R31,5
        lds R30,ADCSRB
        bld R30,3
        sts ADCSRB,R30
        andi R31,0x1f
        ori R31,calc[ADC_Ref * 64]
        sts ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        sts ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        lds R30,ADCSRA
        sbr R30,0x40 //ADSC
        sts ADCSRA,R30
        l1:
        lds R30,ADCSRA
        sbrs R30,ADIF
        rjmp l1
        ldi R30,calc[calc[ADC_Clk] + 16] //16-ADIF
        sts ADCSRA,R30
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space ext,
//REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space ext,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space ext,
//ADHSM ISRCEN AREFEN - ADTS3 ADTS2 ADTS1 ADTS0
//ADCL, i/o space ext,
//ADCH, i/o space ext,
#processor mega16m1, mega32m1, mega64m1
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-31
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        ADCSRB = 0xa0 //ADC High Speed Mode, Analog Reference pin Enable
        andi R31,0x1f
        ori R31,calc[ADC_Ref * 64]
        sts ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        sts ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        lds R30,ADCSRA
        sbr R30,0x40 //ADSC
        sts ADCSRA,R30
        l1:
        lds R30,ADCSRA
        sbrs R30,ADIF
        rjmp l1
        ldi R30,calc[calc[ADC_Clk] + 16] //16-ADIF
        sts ADCSRA,R30
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
//ADMUX, i/o space ext,
//REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
//ADCSRA, i/o space ext,
//ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
//ADCSRB, i/o space ext,
//ADHSM ACME MUX5 ADTS3 ADTS2 ADTS1 ADTS0
//ADCL, i/o space ext,
//ADCH, i/o space ext,
#processor mega16u4, mega32u4
#parameter const, ADC_Sample_uS, 0-255, 20
#parameter const, ADC_Clk, 0-7, 3
#parameter const, ADC_Ref, 0-3, 0
        #statement_begin ADC_Read adc_channel, adc_result
        #statement_type procedure
        #argument adc_channel, byte system R31, byval 0-63
        #argument adc_result, word system ADCL, byrefout
        #code_begin
        //
        #redim ADCL word
        ADCSRB = 0xa0 //ADC High Speed Mode
        bst R31,5
        lds R30,ADCSRB
        bld R30,5
        sts ADCSRB,R30
        andi R31,0x1f
        ori R31,calc[ADC_Ref * 64]
        sts ADMUX,R31
        ldi R30,calc[calc[ADC_Clk + 128] + 16] //16-ADIF, 128-ADEN
        sts ADCSRA,R30
        //
        WaitUs calculate[ADC_Sample_uS]
        //
        lds R30,ADCSRA
        sbr R30,0x40 //ADSC
        sts ADCSRA,R30
        l1:
        lds R30,ADCSRA
        sbrs R30,ADIF
        rjmp l1
        ldi R30,calc[calc[ADC_Clk] + 16] //16-ADIF
        sts ADCSRA,R30
        //
        #code_end
        #statement_end
#lib_item_end
 
#lib_item_begin
#processor mega8515
#processor mega162
#processor mega8u2, mega16u2, mega32u2
#processor 90s2313
#processor 90s2323, 90s2343
#processor 90s8515
#processor tiny2313
#processor tiny2313a, tiny4313
#parameter n/a, ADC_Sample_uS
#parameter n/a, ADC_Clk
#parameter n/a, ADC_Ref
#statement n/a, ADC_Read
#lib_item_end
#lib_group_end