OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [net/] [soundmodem/] [smdma.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*****************************************************************************/
2
 
3
/*
4
 *      smdma.h  --  soundcard radio modem driver dma buffer routines.
5
 *
6
 *      Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
7
 *
8
 *      This program 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 2 of the License, or
11
 *      (at your option) any later version.
12
 *
13
 *      This program 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 this program; if not, write to the Free Software
20
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
22
 *  Please note that the GPL allows you to use the driver, NOT the radio.
23
 *  In order to use the radio, you need a license from the communications
24
 *  authority of your country.
25
 *
26
 */
27
 
28
#ifndef _SMDMA_H
29
#define _SMDMA_H
30
 
31
/* ---------------------------------------------------------------------- */
32
 
33
#include "sm.h"
34
 
35
/* ---------------------------------------------------------------------- */
36
 
37
#define DMA_MODE_AUTOINIT      0x10
38
#define NUM_FRAGMENTS          4
39
 
40
/*
41
 * NOTE: make sure that hdlcdrv_hdlcbuffer contains enough space
42
 * for the modulator to fill the whole DMA buffer without underrun
43
 * at the highest possible baud rate, otherwise the TX state machine will
44
 * not work correctly. That is (9k6 FSK): HDLCDRV_HDLCBUFFER > 6*NUM_FRAGMENTS
45
 */
46
 
47
/* --------------------------------------------------------------------- */
48
/*
49
 * ===================== DMA buffer management ===========================
50
 */
51
 
52
/*
53
 * returns the number of samples per fragment
54
 */
55
extern __inline__ unsigned int dma_setup(struct sm_state *sm, int send, unsigned int dmanr)
56
{
57
        if (send) {
58
                disable_dma(dmanr);
59
                clear_dma_ff(dmanr);
60
                set_dma_mode(dmanr, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
61
                set_dma_addr(dmanr, virt_to_bus(sm->dma.obuf));
62
                set_dma_count(dmanr, sm->dma.ofragsz * NUM_FRAGMENTS);
63
                enable_dma(dmanr);
64
                if (sm->dma.o16bit)
65
                        return sm->dma.ofragsz/2;
66
                return sm->dma.ofragsz;
67
        } else {
68
                disable_dma(dmanr);
69
                clear_dma_ff(dmanr);
70
                set_dma_mode(dmanr, DMA_MODE_READ | DMA_MODE_AUTOINIT);
71
                set_dma_addr(dmanr, virt_to_bus(sm->dma.ibuf));
72
                set_dma_count(dmanr, sm->dma.ifragsz * NUM_FRAGMENTS);
73
                enable_dma(dmanr);
74
                if (sm->dma.i16bit)
75
                        return sm->dma.ifragsz/2;
76
                return sm->dma.ifragsz;
77
        }
78
}
79
 
80
/* --------------------------------------------------------------------- */
81
 
82
extern __inline__ unsigned int dma_ptr(struct sm_state *sm, int send, unsigned int dmanr,
83
                                       unsigned int *curfrag)
84
{
85
        unsigned int dmaptr, sz, frg, offs;
86
 
87
        dmaptr = get_dma_residue(dmanr);
88
        if (send) {
89
                sz = sm->dma.ofragsz * NUM_FRAGMENTS;
90
                if (dmaptr == 0 || dmaptr > sz)
91
                        dmaptr = sz;
92
                dmaptr--;
93
                frg = dmaptr / sm->dma.ofragsz;
94
                offs = (dmaptr % sm->dma.ofragsz) + 1;
95
                *curfrag = NUM_FRAGMENTS - 1 - frg;
96
#ifdef SM_DEBUG
97
                if (!sm->debug_vals.dma_residue || offs < sm->debug_vals.dma_residue)
98
                        sm->debug_vals.dma_residue = offs;
99
#endif /* SM_DEBUG */
100
                if (sm->dma.o16bit)
101
                        return offs/2;
102
                return offs;
103
        } else {
104
                sz = sm->dma.ifragsz * NUM_FRAGMENTS;
105
                if (dmaptr == 0 || dmaptr > sz)
106
                        dmaptr = sz;
107
                dmaptr--;
108
                frg = dmaptr / sm->dma.ifragsz;
109
                offs = (dmaptr % sm->dma.ifragsz) + 1;
110
                *curfrag = NUM_FRAGMENTS - 1 - frg;
111
#ifdef SM_DEBUG
112
                if (!sm->debug_vals.dma_residue || offs < sm->debug_vals.dma_residue)
113
                        sm->debug_vals.dma_residue = offs;
114
#endif /* SM_DEBUG */
115
                if (sm->dma.i16bit)
116
                        return offs/2;
117
                return offs;
118
        }
119
}
120
 
121
/* --------------------------------------------------------------------- */
122
 
123
extern __inline__ int dma_end_transmit(struct sm_state *sm, unsigned int curfrag)
124
{
125
        unsigned int diff = (NUM_FRAGMENTS + curfrag - sm->dma.ofragptr) % NUM_FRAGMENTS;
126
 
127
        sm->dma.ofragptr = curfrag;
128
        if (sm->dma.ptt_cnt <= 0) {
129
                sm->dma.ptt_cnt = 0;
130
                return 0;
131
        }
132
        sm->dma.ptt_cnt -= diff;
133
        if (sm->dma.ptt_cnt <= 0) {
134
                sm->dma.ptt_cnt = 0;
135
                return -1;
136
        }
137
        return 0;
138
}
139
 
140
extern __inline__ void dma_transmit(struct sm_state *sm)
141
{
142
        void *p;
143
 
144
        while (sm->dma.ptt_cnt < NUM_FRAGMENTS && hdlcdrv_ptt(&sm->hdrv)) {
145
                p = (unsigned char *)sm->dma.obuf + sm->dma.ofragsz *
146
                        ((sm->dma.ofragptr + sm->dma.ptt_cnt) % NUM_FRAGMENTS);
147
                if (sm->dma.o16bit) {
148
                        time_exec(sm->debug_vals.mod_cyc,
149
                                  sm->mode_tx->modulator_s16(sm, p, sm->dma.ofragsz/2));
150
                } else {
151
                        time_exec(sm->debug_vals.mod_cyc,
152
                                  sm->mode_tx->modulator_u8(sm, p, sm->dma.ofragsz));
153
                }
154
                sm->dma.ptt_cnt++;
155
        }
156
}
157
 
158
extern __inline__ void dma_init_transmit(struct sm_state *sm)
159
{
160
        sm->dma.ofragptr = 0;
161
        sm->dma.ptt_cnt = 0;
162
}
163
 
164
extern __inline__ void dma_start_transmit(struct sm_state *sm)
165
{
166
        sm->dma.ofragptr = 0;
167
        if (sm->dma.o16bit) {
168
                time_exec(sm->debug_vals.mod_cyc,
169
                          sm->mode_tx->modulator_s16(sm, sm->dma.obuf, sm->dma.ofragsz/2));
170
        } else {
171
                time_exec(sm->debug_vals.mod_cyc,
172
                          sm->mode_tx->modulator_u8(sm, sm->dma.obuf, sm->dma.ofragsz));
173
        }
174
        sm->dma.ptt_cnt = 1;
175
}
176
 
177
extern __inline__ void dma_clear_transmit(struct sm_state *sm)
178
{
179
        sm->dma.ptt_cnt = 0;
180
        memset(sm->dma.obuf, (sm->dma.o16bit) ? 0 : 0x80, sm->dma.ofragsz * NUM_FRAGMENTS);
181
}
182
 
183
/* --------------------------------------------------------------------- */
184
 
185
extern __inline__ void dma_receive(struct sm_state *sm, unsigned int curfrag)
186
{
187
        void *p;
188
 
189
        while (sm->dma.ifragptr != curfrag) {
190
                if (sm->dma.ifragptr)
191
                        p = (unsigned char *)sm->dma.ibuf +
192
                                sm->dma.ifragsz * sm->dma.ifragptr;
193
                else {
194
                        p = (unsigned char *)sm->dma.ibuf + NUM_FRAGMENTS * sm->dma.ifragsz;
195
                        memcpy(p, sm->dma.ibuf, sm->dma.ifragsz);
196
                }
197
                if (sm->dma.o16bit) {
198
                        time_exec(sm->debug_vals.demod_cyc,
199
                                  sm->mode_rx->demodulator_s16(sm, p, sm->dma.ifragsz/2));
200
                } else {
201
                        time_exec(sm->debug_vals.demod_cyc,
202
                                  sm->mode_rx->demodulator_u8(sm, p, sm->dma.ifragsz));
203
                }
204
                sm->dma.ifragptr = (sm->dma.ifragptr + 1) % NUM_FRAGMENTS;
205
        }
206
}
207
 
208
extern __inline__ void dma_init_receive(struct sm_state *sm)
209
{
210
        sm->dma.ifragptr = 0;
211
}
212
 
213
/* --------------------------------------------------------------------- */
214
#endif /* _SMDMA_H */
215
 
216
 
217
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.