Add description to all example projects.
[bertos.git] / boards / at91sam7s-ek / hw / hw_afsk.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
30  * All Rights Reserved.
31  * -->
32  *
33  * \brief AFSK modem hardware-specific definitions.
34  *
35  * \version $Id$
36  *
37  * \author Francesco Sacchi <batt@develer.com>
38  */
39
40
41 #include <net/afsk.h>
42 #include <drv/pwm.h>
43
44 #include <io/arm.h>
45 #include <cfg/compiler.h>
46 #include <cfg/macros.h>
47 #include <cfg/module.h>
48
49
50 #define CONFIG_ADC_CLOCK        4800000UL
51 #define CONFIG_ADC_STARTUP_TIME 20
52 #define CONFIG_ADC_SHTIME       834
53
54 #define ADC_COMPUTED_PRESCALER    ((CPU_FREQ/(2 * CONFIG_ADC_CLOCK)) - 1)
55 #define ADC_COMPUTED_STARTUPTIME  (((CONFIG_ADC_STARTUP_TIME * CONFIG_ADC_CLOCK)/ 8000000UL) - 1)
56 #define ADC_COMPUTED_SHTIME       (((CONFIG_ADC_SHTIME * CONFIG_ADC_CLOCK)/1000000000UL) - 1)
57
58 static Afsk *afsk_ctx;
59 bool hw_afsk_dac_isr;
60
61
62 static void __attribute__((interrupt)) hw_afsk_adc_isr(void)
63 {
64         afsk_adc_isr(afsk_ctx, ADC_LCDR - 128);
65
66         /* Enable block writing */
67         PIOA_OWER = DAC_PIN_MASK;
68
69         if (hw_afsk_dac_isr)
70                 PIOA_ODSR = (afsk_dac_isr(afsk_ctx) << 15) & DAC_PIN_MASK;
71         else
72                 /* Vdac/2 = 128 */
73                 PIOA_ODSR = 0x4000000;
74
75         PIOA_OWDR = DAC_PIN_MASK;
76
77         AIC_EOICR = 0;
78 }
79
80 void hw_afsk_adc_init(int ch, struct Afsk * ctx)
81 {
82         afsk_ctx = ctx;
83         afsk_ctx->adc_ch = ch;
84         ADC_MR = 0;
85         ADC_MR |= BV(ADC_LOWRES);
86
87         //Apply computed prescaler value
88         ADC_MR &= ~ADC_PRESCALER_MASK;
89         ADC_MR |= ((ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK);
90
91         //Apply computed start up time
92         ADC_MR &= ~ADC_STARTUP_MASK;
93         ADC_MR |= ((ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK);
94
95         //Apply computed sample and hold time
96         ADC_MR &= ~ADC_SHTIME_MASK;
97         ADC_MR |= ((ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK);
98
99         // Disable all interrupt
100         ADC_IDR = 0xFFFFFFFF;
101
102         //Register interrupt vector
103         AIC_SVR(ADC_ID) = hw_afsk_adc_isr;
104         AIC_SMR(ADC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED;
105         AIC_IECR = BV(ADC_ID);
106
107         //Enable data ready irq
108         ADC_IER = BV(ADC_DRDY);
109
110         ///////
111         PMC_PCER = BV(TC0_ID);
112         TC_BMR = TC_NONEXC0;
113         TC0_CCR = BV(TC_SWTRG) | BV(TC_CLKEN);
114
115         TC0_CMR = BV(TC_WAVE);
116         TC0_CMR |= (TC_WAVSEL_UP_RC_TRG | TC_ACPC_CLEAR_OUTPUT | TC_ACPA_SET_OUTPUT);
117         TC0_RC = (CPU_FREQ / 2) / 9600;
118         TC0_RA = TC0_RC / 2;
119         ///////
120
121         // Auto trigger enabled on TIOA channel 0
122         ADC_MR |= BV(ADC_TRGEN);
123
124         //Disable all channels
125         ADC_CHDR = ADC_CH_MASK;
126         //Enable channel
127         ADC_CHER = BV(ch);
128 }