comparison packages/hal/sh/arch/current/src/sh3_sci.c @ 105:5a0cc6c243a9 ecos-sw-2000-06-30

Merge from eCos master repository on 2000-06-30-08:18:49-BST
author jlarmour
date Fri, 30 Jun 2000 16:27:35 +0000
parents
children 7f461c3a372c
comparison
equal deleted inserted replaced
104:ad66e26a9e7c 105:5a0cc6c243a9
1 //=============================================================================
2 //
3 // sh3_sci.c
4 //
5 // Simple driver for the SH Serial Communication Interface (SCI)
6 //
7 //=============================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Red Hat eCos Public License
12 // Version 1.1 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://www.redhat.com/
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Configurable Operating System,
22 // released September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Red Hat.
25 // Portions created by Red Hat are
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
27 // All Rights Reserved.
28 // -------------------------------------------
29 //
30 //####COPYRIGHTEND####
31 //=============================================================================
32 //#####DESCRIPTIONBEGIN####
33 //
34 // Author(s): jskov
35 // Contributors:jskov
36 // Date: 1999-05-17
37 // Description: Simple driver for the SH Serial Communication Interface
38 // Clients of this file can configure the behavior with:
39 // CYGNUM_SCI_PORTS: number of SCI ports
40 //
41 //####DESCRIPTIONEND####
42 //
43 //=============================================================================
44
45 #include <pkgconf/hal.h>
46
47 #ifdef CYGNUM_HAL_SH_SH3_SCI_PORTS
48
49 #include <cyg/hal/hal_io.h> // IO macros
50 #include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
51 #include <cyg/hal/hal_misc.h> // Helper functions
52 #include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
53 #include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP
54 #include <cyg/hal/hal_if.h> // Calling-if API
55 #include <cyg/hal/sh_regs.h> // serial register definitions
56
57 #include <cyg/hal/sh3_sci.h> // our header
58
59 //--------------------------------------------------------------------------
60
61 void
62 cyg_hal_plf_sci_init_channel(const channel_data_t* chan)
63 {
64 cyg_uint8 tmp;
65 cyg_uint8* base = chan->base;
66
67 // Disable Tx/Rx interrupts, but enable Tx/Rx
68 HAL_WRITE_UINT8(base+_REG_SCSCR,
69 CYGARC_REG_SCSCR_TE|CYGARC_REG_SCSCR_RE);
70
71 // 8-1-no parity.
72 HAL_WRITE_UINT8(base+_REG_SCSMR, 0);
73
74 // Set speed to 38400
75 HAL_READ_UINT8(base+_REG_SCSMR, tmp);
76 tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
77 tmp |= CYGARC_SCBRR_CKSx(38400);
78 HAL_WRITE_UINT8(base+_REG_SCSMR, tmp);
79 HAL_WRITE_UINT8(base+_REG_SCBRR, CYGARC_SCBRR_N(38400));
80 }
81
82 static cyg_bool
83 cyg_hal_plf_sci_getc_nonblock(void* __ch_data, cyg_uint8* ch)
84 {
85 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
86 cyg_uint8 sr;
87
88 HAL_READ_UINT8(base+_REG_SCSSR, sr);
89 if ((sr & CYGARC_REG_SCSSR_RDRF) == 0)
90 return false;
91
92 HAL_READ_UINT8(base+_REG_SCRDR, *ch);
93
94 // Clear buffer full flag.
95 HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_RDRF);
96
97 return true;
98 }
99
100 cyg_uint8
101 cyg_hal_plf_sci_getc(void* __ch_data)
102 {
103 cyg_uint8 ch;
104 CYGARC_HAL_SAVE_GP();
105
106 while(!cyg_hal_plf_sci_getc_nonblock(__ch_data, &ch));
107
108 CYGARC_HAL_RESTORE_GP();
109 return ch;
110 }
111
112 void
113 cyg_hal_plf_sci_putc(void* __ch_data, cyg_uint8 c)
114 {
115 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
116 cyg_uint8 sr;
117 CYGARC_HAL_SAVE_GP();
118
119 do {
120 HAL_READ_UINT8(base+_REG_SCSSR, sr);
121 } while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
122
123 HAL_WRITE_UINT8(base+_REG_SCTDR, c);
124
125 // Clear empty flag.
126 HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_TDRE);
127
128 // Hang around until the character has been safely sent.
129 do {
130 HAL_READ_UINT8(base+_REG_SCSSR, sr);
131 } while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
132
133 CYGARC_HAL_RESTORE_GP();
134 }
135
136 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
137 || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
138
139 static channel_data_t channels[CYGNUM_HAL_SH_SH3_SCI_PORTS];
140
141 static void
142 cyg_hal_plf_sci_write(void* __ch_data, const cyg_uint8* __buf,
143 cyg_uint32 __len)
144 {
145 CYGARC_HAL_SAVE_GP();
146
147 while(__len-- > 0)
148 cyg_hal_plf_sci_putc(__ch_data, *__buf++);
149
150 CYGARC_HAL_RESTORE_GP();
151 }
152
153 static void
154 cyg_hal_plf_sci_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
155 {
156 CYGARC_HAL_SAVE_GP();
157
158 while(__len-- > 0)
159 *__buf++ = cyg_hal_plf_sci_getc(__ch_data);
160
161 CYGARC_HAL_RESTORE_GP();
162 }
163
164 cyg_bool
165 cyg_hal_plf_sci_getc_timeout(void* __ch_data, cyg_uint8* ch)
166 {
167 channel_data_t* chan = (channel_data_t*)__ch_data;
168 int delay_count;
169 cyg_bool res;
170 CYGARC_HAL_SAVE_GP();
171
172 delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
173
174 for(;;) {
175 res = cyg_hal_plf_sci_getc_nonblock(__ch_data, ch);
176 if (res || 0 == delay_count--)
177 break;
178
179 CYGACC_CALL_IF_DELAY_US()(100);
180 }
181
182 CYGARC_HAL_RESTORE_GP();
183 return res;
184 }
185
186 static int
187 cyg_hal_plf_sci_control(void *__ch_data, __comm_control_cmd_t __func, ...)
188 {
189 static int irq_state = 0;
190 channel_data_t* chan = (channel_data_t*)__ch_data;
191 cyg_uint8 scr;
192 int ret = 0;
193 CYGARC_HAL_SAVE_GP();
194
195 switch (__func) {
196 case __COMMCTL_IRQ_ENABLE:
197 irq_state = 1;
198 HAL_INTERRUPT_UNMASK(chan->isr_vector);
199 HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
200 scr |= CYGARC_REG_SCSCR_RIE;
201 HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
202 break;
203 case __COMMCTL_IRQ_DISABLE:
204 ret = irq_state;
205 irq_state = 0;
206 HAL_INTERRUPT_UNMASK(chan->isr_vector);
207 HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
208 scr &= ~CYGARC_REG_SCSCR_RIE;
209 HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
210 break;
211 case __COMMCTL_DBG_ISR_VECTOR:
212 ret = chan->isr_vector;
213 break;
214 case __COMMCTL_SET_TIMEOUT:
215 {
216 va_list ap;
217
218 va_start(ap, __func);
219
220 ret = chan->msec_timeout;
221 chan->msec_timeout = va_arg(ap, cyg_uint32);
222
223 va_end(ap);
224 }
225 default:
226 break;
227 }
228 CYGARC_HAL_RESTORE_GP();
229 return ret;
230 }
231
232 static int
233 cyg_hal_plf_sci_isr(void *__ch_data, int* __ctrlc,
234 CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
235 {
236 cyg_uint8 c, sr;
237 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
238 int res = 0;
239 CYGARC_HAL_SAVE_GP();
240
241 *__ctrlc = 0;
242 HAL_READ_UINT8(base+_REG_SCSSR, sr);
243 if (sr & CYGARC_REG_SCSSR_RDRF) {
244 HAL_READ_UINT8(base+_REG_SCRDR, c);
245
246 // Clear buffer full flag.
247 HAL_WRITE_UINT8(base+_REG_SCSSR,
248 CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
249
250 if( cyg_hal_is_break( &c , 1 ) )
251 *__ctrlc = 1;
252
253 res = CYG_ISR_HANDLED;
254 }
255
256 CYGARC_HAL_RESTORE_GP();
257 return res;
258 }
259
260 void
261 cyg_hal_plf_sci_init(int sci_index, int comm_index,
262 int rcv_vect, cyg_uint8* base)
263 {
264 channel_data_t* chan = &channels[sci_index];
265 hal_virtual_comm_table_t* comm;
266 int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
267
268 // Initialize channel table
269 chan->base = base;
270 chan->isr_vector = rcv_vect;
271 chan->msec_timeout = 1000;
272
273 // Disable interrupts.
274 HAL_INTERRUPT_MASK(chan->isr_vector);
275
276 // Init channel
277
278 cyg_hal_plf_sci_init_channel(chan);
279
280 // Setup procs in the vector table
281
282 // Initialize channel procs
283 CYGACC_CALL_IF_SET_CONSOLE_COMM()(comm_index);
284 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
285 CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
286 CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_sci_write);
287 CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_sci_read);
288 CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_sci_putc);
289 CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_sci_getc);
290 CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_sci_control);
291 CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_sci_isr);
292 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_sci_getc_timeout);
293
294 // Restore original console
295 CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur);
296 }
297
298 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
299
300 #endif // CYGNUM_HAL_SH_SH3_SCI_PORTS
301
302 //-----------------------------------------------------------------------------
303 // end of sh_sci.c