Subversion Repositories shark

Rev

Rev 771 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
714 giacomo 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
736 giacomo 9
 *   Michele Cirinei
10
 *   Giacomo Guidi       <giacomo@gandalf.sssup.it>
714 giacomo 11
 *   (see the web pages for full authors list)
12
 *
13
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
14
 *
15
 * http://www.sssup.it
16
 * http://retis.sssup.it
17
 * http://shark.sssup.it
18
 */
19
 
20
/*
21
 * Copyright (C) 2000 Michele Cirinei
22
 *
23
 * This program is free software; you can redistribute it and/or modify
24
 * it under the terms of the GNU General Public License as published by
25
 * the Free Software Foundation; either version 2 of the License, or
26
 * (at your option) any later version.
27
 *
28
 * This program is distributed in the hope that it will be useful,
29
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31
 * GNU General Public License for more details.
32
 *
33
 * You should have received a copy of the GNU General Public License
34
 * along with this program; if not, write to the Free Software
35
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
36
 */
37
 
38
#include <kernel/kern.h>
39
#include <drivers/scomirq.h>
40
 
41
/****************************
42
 Variables
43
****************************/
44
static unsigned com_irq[] = {COM1_IRQ, COM2_IRQ, COM3_IRQ, COM4_IRQ};
45
 
771 giacomo 46
struct SCom_Access_Type SCom_Access[4];
714 giacomo 47
 
729 giacomo 48
unsigned SCom_Error[4];
714 giacomo 49
 
50
struct TX_data_t{
51
    int ptr;
52
    int len;
53
    BYTE buf[100];
54
};
55
 
729 giacomo 56
static struct TX_data_t SCom_TX_data[4];
714 giacomo 57
 
58
/*****************************
59
* Functions
60
*****************************/
61
 
62
void RBRF_handler(unsigned port);
63
 
64
void THRE_handler(unsigned port);
65
 
66
void LSR_handler(unsigned port);
67
 
68
void com_send_msg(unsigned port, BYTE len, BYTE *m);
69
 
70
void com_irq_sel(int no)
71
{
735 giacomo 72
    BYTE b, v;
714 giacomo 73
    unsigned i;
735 giacomo 74
 
714 giacomo 75
    for(i=0;i<4;i++)
76
      if (com_irq[i] == no) break;
77
 
735 giacomo 78
    while(PENDIRQ(v = com_read(i, IIR))) {
714 giacomo 79
 
735 giacomo 80
      b = DECODE(v);
81
 
82
      switch (b)
83
      {
714 giacomo 84
        case LS_CHANGED:
85
            LSR_handler(i);
86
        break;
87
 
88
        case RX_FULL:
89
            RBRF_handler(i);
90
        break;
91
 
92
        case TX_EMPTY:
93
            THRE_handler(i);
94
        break;
735 giacomo 95
      }
96
 
714 giacomo 97
    }
735 giacomo 98
 
714 giacomo 99
}      
100
 
101
void com_irq_enable(unsigned port, unsigned irq)
102
{
103
    SYS_FLAGS f;
721 giacomo 104
 
714 giacomo 105
    f = kern_fsave();
106
 
107
    com_read(port, LSR);
108
    com_read(port, IIR);
109
    com_write(port, IER, com_read(port, IER) | irq); /* Enable  irq */
110
 
111
    kern_frestore(f);
112
 
113
}
114
 
115
void com_irq_disable(unsigned port, unsigned irq)
116
{
117
 
118
    SYS_FLAGS f;
119
 
120
    f = kern_fsave();
121
 
122
    com_read(port, LSR);
123
    com_read(port, IIR);
124
    com_write(port, IER, com_read(port, IER) & ~irq); /* Disable irq */
125
 
126
    kern_frestore(f);
127
 
128
}
129
 
716 giacomo 130
void com_close_irq(unsigned port)
714 giacomo 131
{
132
    SYS_FLAGS f;
133
 
134
    f = kern_fsave();
135
 
136
    com_write(port, IER, 0);
137
    com_read(port, LSR);
138
    com_read(port, IIR);
139
 
716 giacomo 140
    handler_remove(com_irq[port]);
141
 
714 giacomo 142
    kern_frestore(f);
143
 
144
}
145
 
716 giacomo 146
void com_init_irq(unsigned port)
714 giacomo 147
{
148
    SYS_FLAGS f;
149
 
150
    f = kern_fsave();
151
 
729 giacomo 152
    SCom_Error[port] = 0;
1007 mauro 153
    handler_set(com_irq[port], com_irq_sel, TRUE, NIL, NULL);
714 giacomo 154
    com_irq_disable(port, ALL_IRQ);     /* Disable interrupts */
155
 
156
    kern_frestore(f);
157
 
158
}
159
 
771 giacomo 160
void com_set_functions(unsigned port, void (*confirm)(unsigned port, BYTE msg_status),void (*indication)(unsigned port, BYTE data))
714 giacomo 161
{
162
    SYS_FLAGS f;
163
 
164
    f = kern_fsave();
165
 
771 giacomo 166
    SCom_Access[port].confirm    = confirm;
167
    SCom_Access[port].request    = com_send_msg;
168
    SCom_Access[port].indication = indication;
714 giacomo 169
 
170
    kern_frestore(f);
171
 
172
}
173
 
174
void com_send_msg(unsigned port, BYTE len, BYTE *m)
175
{
176
    SYS_FLAGS f;
177
 
178
    f = kern_fsave();
179
 
180
    /* Transmit first byte of message  */
729 giacomo 181
    SCom_TX_data[port].ptr = 0;
182
    SCom_TX_data[port].len = len;
714 giacomo 183
    if (len < 100) {
729 giacomo 184
      memcpy(SCom_TX_data[port].buf, m, len);
185
      com_write(port, THR, SCom_TX_data[port].buf[SCom_TX_data[port].ptr++]);
714 giacomo 186
    }
187
 
188
    kern_frestore(f);
189
 
190
}
191
 
716 giacomo 192
__inline__ void com_irq_send(unsigned port, BYTE len, BYTE *m) {
193
 
194
  com_send_msg(port, len, m);
195
 
196
}
197
 
714 giacomo 198
void THRE_handler (unsigned port) /* Transmit Data Register Ready for next byte */
730 giacomo 199
{
736 giacomo 200
    if (SCom_TX_data[port].ptr < SCom_TX_data[port].len)
201
        com_write(port, THR, SCom_TX_data[port].buf[SCom_TX_data[port].ptr++]);
771 giacomo 202
    else SCom_Access[port].confirm(port, COM_OK);
714 giacomo 203
}
204
 
205
void RBRF_handler (unsigned port) /* Receive Data Register Full */
206
{
771 giacomo 207
    SCom_Access[port].indication(port, com_read(port, RBR));
714 giacomo 208
}
209
 
210
void LSR_handler (unsigned port)    /* break = 8, frame = 4, parity = 2, RBR overrun = 1*/
211
{
729 giacomo 212
    SCom_Error[port] = (com_read(port, LSR) & (bit4|bit3|bit2|bit1) ) >> 1;
771 giacomo 213
    SCom_Access[port].confirm(port, COM_ERROR);
714 giacomo 214
}
215