Chameleon-Mini
Codec.h
1 /*
2  * CODEC.h
3  *
4  * Created on: 18.02.2013
5  * Author: skuser
6  */
7 
8 #ifndef CODEC_H_
9 #define CODEC_H_
10 
11 /* Peripheral definitions */
12 #define CODEC_DEMOD_POWER_PORT PORTB
13 #define CODEC_DEMOD_POWER_MASK PIN0_bm
14 #define CODEC_DEMOD_IN_PORT PORTB
15 #define CODEC_DEMOD_IN_MASK (CODEC_DEMOD_IN_MASK0 | CODEC_DEMOD_IN_MASK1)
16 #define CODEC_DEMOD_IN_MASK0 PIN1_bm
17 #define CODEC_DEMOD_IN_MASK1 PIN2_bm
18 #define CODEC_DEMOD_IN_PINCTRL0 PIN1CTRL
19 #define CODEC_DEMOD_IN_PINCTRL1 PIN2CTRL
20 #define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN1_gc
21 #define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN2_gc
22 #define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect
23 #define CODEC_DEMOD_IN_INT1_VECT PORTB_INT1_vect
24 #define CODEC_LOADMOD_PORT PORTC
25 #define CODEC_LOADMOD_MASK PIN6_bm
26 #define CODEC_CARRIER_IN_PORT PORTC
27 #define CODEC_CARRIER_IN_MASK PIN2_bm
28 #define CODEC_CARRIER_IN_PINCTRL PIN2CTRL
29 #define CODEC_CARRIER_IN_EVMUX EVSYS_CHMUX_PORTC_PIN2_gc
30 #define CODEC_CARRIER_IN_DIV 2 /* external clock division factor */
31 #define CODEC_SUBCARRIER_PORT PORTC
32 #define CODEC_SUBCARRIER_MASK_PSK PIN4_bm
33 #define CODEC_SUBCARRIER_MASK_OOK PIN5_bm
34 #define CODEC_SUBCARRIER_MASK (CODEC_SUBCARRIER_MASK_PSK | CODEC_SUBCARRIER_MASK_OOK)
35 #define CODEC_SUBCARRIER_TIMER TCC1
36 #define CODEC_SUBCARRIER_CC_PSK CCA
37 #define CODEC_SUBCARRIER_CC_OOK CCB
38 #define CODEC_SUBCARRIER_CCEN_PSK TC1_CCAEN_bm
39 #define CODEC_SUBCARRIER_CCEN_OOK TC1_CCBEN_bm
40 #define CODEC_TIMER_SAMPLING TCD0
41 #define CODEC_TIMER_SAMPLING_OVF_VECT TCD0_OVF_vect
42 #define CODEC_TIMER_SAMPLING_CCA_VECT TCD0_CCA_vect
43 #define CODEC_TIMER_SAMPLING_CCB_VECT TCD0_CCB_vect
44 #define CODEC_TIMER_SAMPLING_CCC_VECT TCD0_CCC_vect
45 #define CODEC_TIMER_SAMPLING_CCD_VECT TCD0_CCD_vect
46 #define CODEC_TIMER_LOADMOD TCE0
47 #define CODEC_TIMER_LOADMOD_OVF_VECT TCE0_OVF_vect
48 #define CODEC_TIMER_LOADMOD_CCA_VECT TCE0_CCA_vect
49 #define CODEC_TIMER_LOADMOD_CCB_VECT TCE0_CCB_vect
50 #define CODEC_TIMER_LOADMOD_CCC_VECT TCE0_CCC_vect
51 #define CODEC_TIMER_MODSTART_EVSEL TC_EVSEL_CH0_gc
52 #define CODEC_TIMER_MODEND_EVSEL TC_EVSEL_CH1_gc
53 #define CODEC_TIMER_CARRIER_CLKSEL TC_CLKSEL_EVCH6_gc
54 #define CODEC_READER_TIMER TCC0
55 #define CODEC_READER_PORT PORTC
56 #define CODEC_READER_MASK_LEFT PIN0_bm
57 #define CODEC_READER_MASK_RIGHT PIN1_bm
58 #define CODEC_READER_MASK (CODEC_READER_MASK_LEFT | CODEC_READER_MASK_RIGHT)
59 #define CODEC_READER_PINCTRL_LEFT PIN0CTRL
60 #define CODEC_READER_PINCTRL_RIGHT PIN1CTRL
61 #define CODEC_AC_DEMOD_SETTINGS AC_HSMODE_bm | AC_HYSMODE_NO_gc
62 #define CODEC_MAXIMUM_THRESHOLD 0xFFF // the maximum voltage can be calculated with ch0data * Vref / 0xFFF
63 #define CODEC_THRESHOLD_CALIBRATE_MIN 128
64 #define CODEC_THRESHOLD_CALIBRATE_MID 768
65 #define CODEC_THRESHOLD_CALIBRATE_MAX 2048
66 #define CODEC_THRESHOLD_CALIBRATE_STEPS 16
67 #define CODEC_TIMER_TIMESTAMPS TCD1
68 #define CODEC_TIMER_TIMESTAMPS_OVF_VECT TCD1_OVF_vect
69 #define CODEC_TIMER_TIMESTAMPS_CCA_VECT TCD1_CCA_vect
70 #define CODEC_TIMER_TIMESTAMPS_CCB_VECT TCD1_CCB_vect
71 
72 #ifndef __ASSEMBLER__
73 
74 #include <avr/io.h>
75 #include <stdint.h>
76 #include <stdbool.h>
77 #include "../Common.h"
78 #include "../Configuration.h"
79 #include "../Settings.h"
80 
81 #include "ISO14443-2A.h"
82 #include "Reader14443-2A.h"
83 #include "SniffISO14443-2A.h"
84 #include "ISO15693.h"
85 #include "SniffISO15693.h"
86 
87 /* Timing definitions for ISO14443A */
88 #define ISO14443A_SUBCARRIER_DIVIDER 16
89 #define ISO14443A_BIT_GRID_CYCLES 128
90 #define ISO14443A_BIT_RATE_CYCLES 128
91 #define ISO14443A_FRAME_DELAY_PREV1 1236
92 #define ISO14443A_FRAME_DELAY_PREV0 1172
93 #define ISO14443A_RX_PENDING_TIMEOUT 4 // ms
94 
95 #define CODEC_BUFFER_SIZE 256
96 
97 #define CODEC_CARRIER_FREQ 13560000
98 
99 #define Codec8Reg0 GPIOR0
100 #define Codec8Reg1 GPIOR1
101 #define Codec8Reg2 GPIOR2
102 #define Codec8Reg3 GPIOR3
103 #define CodecCount16Register1 (*((volatile uint16_t*) &GPIOR4)) /* GPIOR4 & GPIOR5 */
104 #define CodecCount16Register2 (*((volatile uint16_t*) &GPIOR6)) /* GPIOR6 & GPIOR7 */
105 #define CodecPtrRegister1 (*((volatile uint8_t**) &GPIOR8))
106 #define CodecPtrRegister2 (*((volatile uint8_t**) &GPIORA))
107 #define CodecPtrRegister3 (*((volatile uint8_t**) &GPIORC))
108 
109 
110 extern uint16_t Reader_FWT;
111 
112 #define FWI2FWT(x) ((uint32_t)(256 * 16 * ((uint32_t)1 << (x))) / (CODEC_CARRIER_FREQ / 1000) + 1)
113 
114 typedef enum {
115  CODEC_SUBCARRIERMOD_OFF,
116  CODEC_SUBCARRIERMOD_OOK
117 } SubcarrierModType;
118 
119 extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
120 extern uint8_t CodecBuffer2[CODEC_BUFFER_SIZE];
121 
122 extern enum RCTraffic {TRAFFIC_READER, TRAFFIC_CARD} SniffTrafficSource;
123 
124 /* Shared ISR pointers and handlers */
125 extern void (* volatile isr_func_TCD0_CCC_vect)(void);
126 void isr_Reader14443_2A_TCD0_CCC_vect(void);
127 void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void);
128 extern void (* volatile isr_func_CODEC_DEMOD_IN_INT0_VECT)(void);
129 void isr_ISO14443_2A_TCD0_CCC_vect(void);
130 void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void);
131 extern void (* volatile isr_func_CODEC_TIMER_LOADMOD_OVF_VECT)(void);
132 void isr_ISO14443_2A_CODEC_TIMER_LOADMOD_OVF_VECT(void);
133 void isr_SNIFF_ISO15693_CODEC_TIMER_LOADMOD_OVF_VECT(void);
134 extern void (* volatile isr_func_CODEC_TIMER_LOADMOD_CCA_VECT)(void);
135 void isr_Reader14443_2A_CODEC_TIMER_LOADMOD_CCA_VECT(void);
136 void isr_SNIFF_ISO15693_CODEC_TIMER_LOADMOD_CCA_VECT(void);
137 extern void (* volatile isr_func_CODEC_TIMER_LOADMOD_CCB_VECT)(void);
138 void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void);
139 void isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT(void);
140 void isr_SNIFF_ISO15693_CODEC_TIMER_LOADMOD_CCA_VECT(void);
141 extern void (* volatile isr_func_CODEC_TIMER_TIMESTAMPS_CCA_VECT)(void);
142 void isr_Reader14443_2A_CODEC_TIMER_TIMESTAMPS_CCA_VECT(void);
143 void isr_SNIFF_ISO15693_CODEC_TIMER_TIMESTAMPS_CCA_VECT(void);
144 extern void (* volatile isr_func_ACA_AC0_vect)(void);
145 void isr_SniffISO14443_2A_ACA_AC0_VECT(void);
146 void isr_SNIFF_ISO15693_ACA_AC0_VECT(void);
147 
148 INLINE void CodecInit(void) {
149  ActiveConfiguration.CodecInitFunc();
150 }
151 
152 INLINE void CodecDeInit(void) {
153  ActiveConfiguration.CodecDeInitFunc();
154 }
155 
156 INLINE void CodecTask(void) {
157  ActiveConfiguration.CodecTaskFunc();
158 }
159 
160 /* Helper Functions for Codec implementations */
161 INLINE void CodecInitCommon(void) {
162  /* Configure CARRIER input pin and route it to EVSYS.
163  * Multiply by 2 again by using both edges when externally
164  * dividing by 2 */
165 #if CODEC_CARRIER_IN_DIV == 2
166  CODEC_CARRIER_IN_PORT.CODEC_CARRIER_IN_PINCTRL = PORT_ISC_BOTHEDGES_gc;
167 #else
168 #error Option not supported
169 #endif
170  CODEC_CARRIER_IN_PORT.DIRCLR = CODEC_CARRIER_IN_MASK;
171  EVSYS.CH6MUX = CODEC_CARRIER_IN_EVMUX;
172 
173  /* Configure two DEMOD pins for input.
174  * Configure event channel 0 for rising edge (begin of modulation pause)
175  * Configure event channel 1 for falling edge (end of modulation pause) */
176  CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK;
177  CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK;
178  CODEC_DEMOD_IN_PORT.DIRCLR = CODEC_DEMOD_IN_MASK;
179  CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc;
180  CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc;
181  CODEC_DEMOD_IN_PORT.INT0MASK = 0;
182  CODEC_DEMOD_IN_PORT.INT1MASK = 0;
183  CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc | PORT_INT1LVL_HI_gc;
184  EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0;
185  EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1;
186 
187  /* Configure loadmod pin configuration and use a virtual port configuration
188  * for single instruction cycle access */
189  CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK;
190  CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
191  PORTCFG.VPCTRLA &= ~PORTCFG_VP0MAP_gm;
192  PORTCFG.VPCTRLA |= PORTCFG_VP02MAP_PORTC_gc;
193 
194  /* Configure subcarrier pins for output */
195  CODEC_SUBCARRIER_PORT.DIRSET = CODEC_SUBCARRIER_MASK;
196  CODEC_SUBCARRIER_PORT.OUTCLR = CODEC_SUBCARRIER_MASK;
197 
198  /* Configure pins for reader field with the LEFT output being inverted
199  * and all bridge outputs static high */
200  CODEC_READER_PORT.CODEC_READER_PINCTRL_LEFT = PORT_INVEN_bm;
201  CODEC_READER_PORT.OUTCLR = CODEC_READER_MASK_LEFT;
202  CODEC_READER_PORT.OUTSET = CODEC_READER_MASK_RIGHT;
203  CODEC_READER_PORT.DIRSET = CODEC_READER_MASK;
204 
205  /* Configure timer for generating reader field and configure AWEX for outputting pattern
206  * with disabled outputs. */
207  CODEC_READER_TIMER.CTRLB = TC0_CCAEN_bm | TC_WGMODE_SINGLESLOPE_gc;
208  CODEC_READER_TIMER.PER = F_CPU / CODEC_CARRIER_FREQ - 1;
209  CODEC_READER_TIMER.CCA = F_CPU / CODEC_CARRIER_FREQ / 2 ;
210 
211  AWEXC.OUTOVEN = 0x00;
212  AWEXC.CTRL = AWEX_CWCM_bm | AWEX_DTICCAEN_bm | AWEX_DTICCBEN_bm;
213 
214  /* Configure DAC for the reference voltage */
215  DACB.EVCTRL = 0;
216  DACB.CTRLB = DAC_CHSEL_SINGLE_gc;
217  DACB.CTRLC = DAC_REFSEL_AVCC_gc;
218  DACB.CTRLA = DAC_IDOEN_bm | DAC_ENABLE_bm;
219  DACB.CH0DATA = GlobalSettings.ActiveSettingPtr->ReaderThreshold; // real threshold voltage can be calculated with ch0data * Vref / 0xFFF
220 
221  /* Configure Analog Comparator 0 to detect changes in demodulated reader field */
222  ACA.AC0MUXCTRL = AC_MUXPOS_DAC_gc | AC_MUXNEG_PIN7_gc;
223  ACA.AC0CTRL = CODEC_AC_DEMOD_SETTINGS;
224 
225  /* Configure Analog Comparator 1 to detect SOC */
226  ACA.AC1MUXCTRL = AC_MUXPOS_DAC_gc | AC_MUXNEG_PIN7_gc;
227  ACA.AC1CTRL = CODEC_AC_DEMOD_SETTINGS;
228 }
229 
230 INLINE void CodecSetSubcarrier(SubcarrierModType ModType, uint16_t Divider) {
231  if (ModType == CODEC_SUBCARRIERMOD_OFF) {
232  CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_OFF_gc;
233  CODEC_SUBCARRIER_TIMER.CTRLB = 0;
234  } else if (ModType == CODEC_SUBCARRIERMOD_OOK) {
235  /* Configure subcarrier generation with 50% DC output using OOK */
236  CODEC_SUBCARRIER_TIMER.CNT = 0;
237  CODEC_SUBCARRIER_TIMER.PER = Divider - 1;
238  CODEC_SUBCARRIER_TIMER.CODEC_SUBCARRIER_CC_OOK = Divider / 2;
239  CODEC_SUBCARRIER_TIMER.CTRLB = CODEC_SUBCARRIER_CCEN_OOK | TC_WGMODE_SINGLESLOPE_gc;
240  }
241 }
242 
243 INLINE void CodecChangeDivider(uint16_t Divider) {
244  CODEC_SUBCARRIER_TIMER.PER = Divider - 1;
245 }
246 
247 INLINE void CodecStartSubcarrier(void) {
248  CODEC_SUBCARRIER_TIMER.CTRLA = CODEC_TIMER_CARRIER_CLKSEL;
249 }
250 
251 INLINE void CodecSetDemodPower(bool bOnOff) {
252  if (bOnOff) {
253  CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK;
254  } else {
255  CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK;
256  }
257 }
258 
259 INLINE bool CodecGetLoadmodState(void) {
260  if (ACA.STATUS & AC_AC0STATE_bm) {
261  return true;
262  } else {
263  return false;
264  }
265 }
266 
267 INLINE void CodecSetLoadmodState(bool bOnOff) {
268  if (bOnOff) {
269  VPORT0.OUT |= CODEC_LOADMOD_MASK;
270  } else {
271  VPORT0.OUT &= ~CODEC_LOADMOD_MASK;
272  }
273 }
274 
275 // Turn on and off the codec Reader field
276 INLINE void CodecSetReaderField(bool bOnOff) { // this is the function for turning on/off the reader field dumbly; before using this function, please consider to use CodecReaderField{Start,Stop}
277 
278  if (bOnOff) {
279  /* Start timer for field generation and unmask outputs */
280  CODEC_READER_TIMER.CTRLA = TC_CLKSEL_DIV1_gc;
281  AWEXC.OUTOVEN = CODEC_READER_MASK;
282  } else {
283  /* Disable outputs of AWEX and stop field generation */
284  AWEXC.OUTOVEN = 0x00;
285  CODEC_READER_TIMER.CTRLA = TC_CLKSEL_OFF_gc;
286  }
287 }
288 
289 // Get the status of the reader field
290 INLINE bool CodecGetReaderField(void) {
291  return (CODEC_READER_TIMER.CTRLA == TC_CLKSEL_DIV1_gc) && (AWEXC.OUTOVEN == CODEC_READER_MASK);
292 }
293 
294 void CodecReaderFieldStart(void);
295 void CodecReaderFieldStop(void);
296 bool CodecIsReaderFieldReady(void);
297 
298 void CodecReaderFieldRestart(uint16_t delay);
299 #define FIELD_RESTART() CodecReaderFieldRestart(100)
300 bool CodecIsReaderToBeRestarted(void);
301 
302 void CodecThresholdSet(uint16_t th);
303 uint16_t CodecThresholdIncrement(void);
304 void CodecThresholdReset(void);
305 
306 #endif /* __ASSEMBLER__ */
307 
308 #endif /* CODEC_H_ */
void(* CodecInitFunc)(void)
Definition: Configuration.h:96
void(* CodecTaskFunc)(void)
Definition: Configuration.h:102
void(* CodecDeInitFunc)(void)
Definition: Configuration.h:98