~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/simavr/sim/avr_adc.h

  • Committer: arcachofo
  • Date: 2021-01-01 14:23:42 UTC
  • Revision ID: arcachofo@simulide.com-20210101142342-ozfljnll44g5lbl3
Initial Commit 0.5.15-RC3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
        avr_adc.h
 
3
 
 
4
        Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
 
5
 
 
6
        This file is part of simavr.
 
7
 
 
8
        simavr is free software: you can redistribute it and/or modify
 
9
        it under the terms of the GNU General Public License as published by
 
10
        the Free Software Foundation, either version 3 of the License, or
 
11
        (at your option) any later version.
 
12
 
 
13
        simavr is distributed in the hope that it will be useful,
 
14
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
        GNU General Public License for more details.
 
17
 
 
18
        You should have received a copy of the GNU General Public License
 
19
        along with simavr.  If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#ifndef __AVR_ADC_H___
 
23
#define __AVR_ADC_H___
 
24
 
 
25
#ifdef __cplusplus
 
26
extern "C" {
 
27
#endif
 
28
 
 
29
#include "sim_avr.h"
 
30
 
 
31
/*
 
32
 * simavr ADC allows external code to feed real voltages to the
 
33
 * simulator, and the simulator uses it's 'real' reference voltage
 
34
 * to do the right thing and return the 'proper' 10 bits ADC value
 
35
 * to the AVR firmware.
 
36
 *
 
37
 * To send values to the ADC, register your code to wait for the
 
38
 * ADC_IRQ_OUT_TRIGGER irq, and at that point send any of the
 
39
 * ADC_IRQ_ADC* with Millivolts as value.
 
40
 *
 
41
 * External trigger is not done yet.
 
42
 */
 
43
 
 
44
enum {
 
45
        // input IRQ values. Values are /always/ volts * 1000 (millivolts)
 
46
        ADC_IRQ_ADC0 = 0, ADC_IRQ_ADC1, ADC_IRQ_ADC2, ADC_IRQ_ADC3,
 
47
        ADC_IRQ_ADC4, ADC_IRQ_ADC5, ADC_IRQ_ADC6, ADC_IRQ_ADC7,
 
48
        ADC_IRQ_ADC8, ADC_IRQ_ADC9, ADC_IRQ_ADC10, ADC_IRQ_ADC11,
 
49
        ADC_IRQ_ADC12, ADC_IRQ_ADC13, ADC_IRQ_ADC14, ADC_IRQ_ADC15,
 
50
        ADC_IRQ_TEMP,                   // see the datasheet
 
51
        ADC_IRQ_IN_TRIGGER,
 
52
        ADC_IRQ_OUT_TRIGGER,    // sends a avr_adc_mux_t
 
53
        ADC_IRQ_COUNT
 
54
};
 
55
 
 
56
// Get the internal IRQ corresponding to the INT
 
57
#define AVR_IOCTL_ADC_GETIRQ AVR_IOCTL_DEF('a','d','c',' ')
 
58
 
 
59
/*
 
60
 * Definition of a ADC mux mode.
 
61
 */
 
62
enum {
 
63
        ADC_MUX_NONE = 0,               // Nothing. return 0
 
64
        ADC_MUX_NOISE,                  // Nothing. return something random
 
65
        ADC_MUX_SINGLE,                 // Normal ADC pin reading
 
66
        ADC_MUX_DIFF,                   // differential channels (src-diff)
 
67
        ADC_MUX_TEMP,                   // internal temp sensor
 
68
        ADC_MUX_REF,                    // reference voltage (in src * 100)
 
69
        ADC_MUX_VCC4,                   // VCC/4
 
70
};
 
71
typedef struct avr_adc_mux_t {
 
72
        unsigned long kind : 3, gain : 8, diff : 8, src : 13;
 
73
} avr_adc_mux_t;
 
74
 
 
75
enum {
 
76
        ADC_VREF_AREF   = 0,    // default mode
 
77
        ADC_VREF_VCC,
 
78
        ADC_VREF_AVCC,
 
79
        ADC_VREF_V110   = 1100,
 
80
        ADC_VREF_V256   = 2560,
 
81
};
 
82
 
 
83
// ADC trigger sources
 
84
typedef enum {
 
85
        avr_adts_none = 0,
 
86
        avr_adts_free_running,
 
87
        avr_adts_analog_comparator_0,
 
88
        avr_adts_analog_comparator_1,
 
89
        avr_adts_analog_comparator_2,
 
90
        avr_adts_analog_comparator_3,
 
91
        avr_adts_external_interrupt_0,
 
92
        avr_adts_timer_0_compare_match_a,
 
93
        avr_adts_timer_0_compare_match_b,
 
94
        avr_adts_timer_0_overflow,
 
95
        avr_adts_timer_1_compare_match_b,
 
96
        avr_adts_timer_1_overflow,
 
97
        avr_adts_timer_1_capture_event,
 
98
        avr_adts_pin_change_interrupt,
 
99
        avr_adts_psc_module_0_sync_signal,
 
100
        avr_adts_psc_module_1_sync_signal,
 
101
        avr_adts_psc_module_2_sync_signal,
 
102
} avr_adts_type;
 
103
 
 
104
typedef struct avr_adc_t {
 
105
        avr_io_t                io;
 
106
 
 
107
    uint8_t       r_admux;
 
108
 
 
109
    avr_regbit_t  mux[6]; // if the last bit exists in the mux, we are an extended ADC
 
110
    avr_regbit_t  ref[3];               // reference voltages bits
 
111
    uint16_t      ref_values[7]; // ADC_VREF_*
 
112
 
 
113
    avr_regbit_t  adlar;                // left/right adjustment bit
 
114
 
 
115
    uint8_t               r_adcsra;     // ADC Control and Status Register A
 
116
    avr_regbit_t  aden;         // ADC Enabled
 
117
    avr_regbit_t  adsc;         // ADC Start Conversion
 
118
    avr_regbit_t  adate;                // ADC Auto Trigger Enable
 
119
 
 
120
    avr_regbit_t  adps[3];      // Prescaler bits. Note that it's a frequency bit shift
 
121
 
 
122
    uint8_t               r_adcl, r_adch;       // Data Registers
 
123
 
 
124
    uint8_t               r_adcsrb;     // ADC Control and Status Register B
 
125
    avr_regbit_t  adts[4];      // Timing Source
 
126
    avr_adts_type adts_op[16];    // ADTS type
 
127
    uint8_t               adts_mode;      // the extracted ADTS mode
 
128
    avr_regbit_t  bin;          // Bipolar Input Mode (tinyx5 have it)
 
129
    avr_regbit_t  ipr;          // Input Polarity Reversal (tinyx5 have it)
 
130
 
 
131
    avr_int_vector_t adc; // use ADIF and ADIE bits
 
132
 
 
133
        /*
 
134
         * runtime bits
 
135
         */
 
136
        avr_adc_mux_t   muxmode[64];// maximum 6 bits of mux modes
 
137
    uint16_t            adc_values[16]; // current values on the ADCs
 
138
        uint16_t                temp;           // temp sensor reading
 
139
        uint8_t                 first;
 
140
        uint8_t                 read_status;    // marked one when adcl is read
 
141
} avr_adc_t;
 
142
 
 
143
void avr_adc_init(avr_t * avr, avr_adc_t * port);
 
144
 
 
145
 
 
146
/*
 
147
 * Helper macros for the Cores definition of muxes
 
148
 */
 
149
#define AVR_ADC_SINGLE(_chan) { \
 
150
                .kind = ADC_MUX_SINGLE, \
 
151
                .src = (_chan), \
 
152
        }
 
153
#define AVR_ADC_DIFF(_a,_b,_g) { \
 
154
                .kind = ADC_MUX_DIFF, \
 
155
                .src = (_a), \
 
156
                .diff = (_b), \
 
157
                .gain = (_g), \
 
158
        }
 
159
#define AVR_ADC_REF(_t) { \
 
160
                .kind = ADC_MUX_REF, \
 
161
                .src = (_t), \
 
162
        }
 
163
#define AVR_ADC_TEMP() { \
 
164
                .kind = ADC_MUX_TEMP, \
 
165
        }
 
166
 
 
167
#define AVR_ADC_VCC4() { \
 
168
                .kind = ADC_MUX_VCC4, \
 
169
        }
 
170
 
 
171
#ifdef __cplusplus
 
172
};
 
173
#endif
 
174
 
 
175
#endif /* __AVR_ADC_H___ */