filename | src/sh4/scif.c |
changeset | 975:007bf7eb944f |
prev | 929:fd8cb0c82f5f |
next | 1077:136fc24d17ef |
author | nkeynes |
date | Sun Apr 19 05:14:19 2009 +0000 (15 years ago) |
branch | xlat-refactor |
permissions | -rw-r--r-- |
last change | Remove branch instructions and replace with direct modification of PC + EXIT Add MIN/MAX instructions (for bound checks) Implement x86_target_is_legal Correct a few sh4 instructions |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 * SCIF (Serial Communication Interface with FIFO) implementation - part of the
4 * SH4 standard on-chip peripheral set. The SCIF is hooked up to the DCs
5 * external serial port
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #include <glib.h>
21 #include "dream.h"
22 #include "mem.h"
23 #include "sh4/sh4core.h"
24 #include "sh4/sh4mmio.h"
25 #include "sh4/intc.h"
26 #include "sh4/dmac.h"
27 #include "clock.h"
28 #include "serial.h"
30 void SCIF_set_break(void);
32 /************************* External serial interface ************************/
34 /**
35 * Note: serial_* operations are called from outside the SH4, and as such are
36 * named relative to the external serial device. SCIF_* operations are only
37 * called internally to the SH4 and so are named relative to the CPU.
38 */
40 /**
41 * Storage space for inbound/outbound data blocks. It's a little more
42 * convenient for serial consumers to be able to deal with block-sized pieces
43 * rather than a byte at a time, even if it makes all this look rather
44 * complicated.
45 *
46 * Currently there's no limit on the number of blocks that can be queued up.
47 */
48 typedef struct serial_data_block {
49 uint32_t length;
50 uint32_t offset;
51 struct serial_data_block *next;
52 char data[];
53 } *serial_data_block_t;
55 serial_data_block_t serial_recvq_head = NULL, serial_recvq_tail = NULL;
56 serial_device_t serial_device = NULL;
58 void serial_attach_device( serial_device_t dev )
59 {
60 if( serial_device != NULL )
61 serial_detach_device();
62 serial_device = dev;
63 }
66 void serial_detach_device( void )
67 {
68 serial_device = NULL;
69 }
71 /**
72 * Add a block of data to the serial receive queue. The data will be received
73 * by the CPU at the appropriate baud rate.
74 */
75 void serial_transmit_data( char *data, int length ) {
76 if( length == 0 )
77 return;
78 serial_data_block_t block =
79 g_malloc( sizeof( struct serial_data_block ) + length );
80 block->length = length;
81 block->offset = 0;
82 block->next = NULL;
83 memcpy( block->data, data, length );
85 if( serial_recvq_head == NULL ) {
86 serial_recvq_head = serial_recvq_tail = block;
87 } else {
88 serial_recvq_tail->next = block;
89 serial_recvq_tail = block;
90 }
91 }
93 /**
94 * Dequeue a byte from the serial input queue
95 */
96 static int serial_transmit_dequeue( ) {
97 if( serial_recvq_head != NULL ) {
98 uint8_t val = serial_recvq_head->data[serial_recvq_head->offset++];
99 if( serial_recvq_head->offset >= serial_recvq_head->length ) {
100 serial_data_block_t next = serial_recvq_head->next;
101 g_free( serial_recvq_head );
102 serial_recvq_head = next;
103 if( next == NULL )
104 serial_recvq_tail = NULL;
105 }
106 return (int)(unsigned int)val;
107 }
108 return -1;
110 }
112 void serial_transmit_break() {
113 SCIF_set_break();
114 }
116 /********************************* SCIF *************************************/
118 #define FIFO_LENGTH 16
119 #define FIFO_ARR_LENGTH (FIFO_LENGTH+1)
121 /* Serial control register flags */
122 #define SCSCR2_TIE 0x80
123 #define SCSCR2_RIE 0x40
124 #define SCSCR2_TE 0x20
125 #define SCSCR2_RE 0x10
126 #define SCSCR2_REIE 0x08
127 #define SCSCR2_CKE 0x02
129 #define IS_TRANSMIT_IRQ_ENABLED() (MMIO_READ(SCIF,SCSCR2) & SCSCR2_TIE)
130 #define IS_RECEIVE_IRQ_ENABLED() (MMIO_READ(SCIF,SCSCR2) & SCSCR2_RIE)
131 #define IS_RECEIVE_ERROR_IRQ_ENABLED() (MMIO_READ(SCIF,SCSCR2) & (SCSCR2_RIE|SCSCR2_REIE))
132 /* Receive is enabled if the RE bit is set in SCSCR2, and the ORER bit is cleared in SCLSR2 */
133 #define IS_RECEIVE_ENABLED() ( (MMIO_READ(SCIF,SCSCR2) & SCSCR2_RE) && ((MMIO_READ(SCIF,SCLSR2) & SCLSR2_ORER) == 0) )
134 /* Transmit is enabled if the TE bit is set in SCSCR2 */
135 #define IS_TRANSMIT_ENABLED() (MMIO_READ(SCIF,SCSCR2) & SCSCR2_TE)
136 #define IS_LOOPBACK_ENABLED() (MMIO_READ(SCIF,SCFCR2) & SCFCR2_LOOP)
138 /* Serial status register flags */
139 #define SCFSR2_ER 0x80
140 #define SCFSR2_TEND 0x40
141 #define SCFSR2_TDFE 0x20
142 #define SCFSR2_BRK 0x10
143 #define SCFSR2_RDF 0x02
144 #define SCFSR2_DR 0x01
146 /* FIFO control register flags */
147 #define SCFCR2_MCE 0x08
148 #define SCFCR2_TFRST 0x04
149 #define SCFCR2_RFRST 0x02
150 #define SCFCR2_LOOP 0x01
152 /* Line Status Register */
153 #define SCLSR2_ORER 0x01
155 struct SCIF_fifo {
156 int head;
157 int tail;
158 int trigger;
159 uint8_t data[FIFO_ARR_LENGTH];
160 };
162 int SCIF_recvq_triggers[4] = {1, 4, 8, 14};
163 struct SCIF_fifo SCIF_recvq = {0,0,1};
165 int SCIF_sendq_triggers[4] = {8, 4, 2, 1};
166 struct SCIF_fifo SCIF_sendq = {0,0,8};
168 /**
169 * Flag to indicate if data was received (ie added to the receive queue)
170 * during the last SCIF clock tick. Used to determine when to set the DR
171 * flag.
172 */
173 gboolean SCIF_rcvd_last_tick = FALSE;
175 uint32_t SCIF_tick_period = 0;
176 uint32_t SCIF_tick_remainder = 0;
178 void SCIF_save_state( FILE *f )
179 {
180 fwrite( &SCIF_recvq, sizeof(SCIF_recvq), 1, f );
181 fwrite( &SCIF_sendq, sizeof(SCIF_sendq), 1, f );
182 fwrite( &SCIF_rcvd_last_tick, sizeof(gboolean), 1, f );
184 }
186 int SCIF_load_state( FILE *f )
187 {
188 fread( &SCIF_recvq, sizeof(SCIF_recvq), 1, f );
189 fread( &SCIF_sendq, sizeof(SCIF_sendq), 1, f );
190 fread( &SCIF_rcvd_last_tick, sizeof(gboolean), 1, f );
191 return 0;
192 }
194 static inline uint8_t SCIF_recvq_size( )
195 {
196 int val = SCIF_recvq.tail - SCIF_recvq.head;
197 if( val < 0 ) {
198 val = FIFO_ARR_LENGTH - SCIF_recvq.head + SCIF_recvq.tail;
199 }
200 return val;
201 }
203 int SCIF_recvq_dequeue( gboolean clearFlags )
204 {
205 uint8_t result;
206 uint32_t tmp, length;
207 if( SCIF_recvq.head == SCIF_recvq.tail )
208 return -1; /* No data */
209 result = SCIF_recvq.data[SCIF_recvq.head++];
210 if( SCIF_recvq.head > FIFO_LENGTH )
211 SCIF_recvq.head = 0;
213 /* Update data count register */
214 tmp = MMIO_READ( SCIF, SCFDR2 ) & 0xF0;
215 length = SCIF_recvq_size();
216 MMIO_WRITE( SCIF, SCFDR2, tmp | length );
218 /* Clear flags (if requested ) */
219 if( clearFlags && length < SCIF_recvq.trigger ) {
220 tmp = SCFSR2_RDF;
221 if( length == 0 )
222 tmp |= SCFSR2_DR;
223 tmp = MMIO_READ( SCIF, SCFSR2 ) & (~tmp);
224 MMIO_WRITE( SCIF, SCFSR2, tmp );
225 /* If both flags are cleared, clear the interrupt as well */
226 if( (tmp & (SCFSR2_DR|SCFSR2_RDF)) == 0 && IS_RECEIVE_IRQ_ENABLED() )
227 intc_clear_interrupt( INT_SCIF_RXI );
228 }
230 return (int)(unsigned int)result;
231 }
233 gboolean SCIF_recvq_enqueue( uint8_t value )
234 {
235 uint32_t tmp, length;
236 int newpos = SCIF_recvq.tail + 1;
237 if( newpos > FIFO_LENGTH )
238 newpos = 0;
239 if( newpos == SCIF_recvq.head ) {
240 /* FIFO full - set ORER and discard the value */
241 MMIO_WRITE( SCIF, SCLSR2, SCLSR2_ORER );
242 if( IS_RECEIVE_ERROR_IRQ_ENABLED() )
243 intc_raise_interrupt( INT_SCIF_ERI );
244 return FALSE;
245 }
246 SCIF_recvq.data[SCIF_recvq.tail] = value;
248 /* Update data count register */
249 tmp = MMIO_READ( SCIF, SCFDR2 ) & 0xF0;
250 length = SCIF_recvq_size();
251 MMIO_WRITE( SCIF, SCFDR2, tmp | length );
253 /* Update status register */
254 tmp = MMIO_READ( SCIF, SCFSR2 );
255 if( length >= SCIF_recvq.trigger ) {
256 tmp |= SCFSR2_RDF;
257 if( IS_RECEIVE_IRQ_ENABLED() )
258 intc_raise_interrupt( INT_SCIF_RXI );
259 DMAC_trigger( DMAC_SCIF_RDF );
260 }
261 MMIO_WRITE( SCIF, SCFSR2, tmp );
262 return TRUE;
263 }
266 /**
267 * Reset the receive FIFO to its initial state. Manual is unclear as to
268 * whether this also clears flags/interrupts, but we're assuming here that
269 * it does until proven otherwise.
270 */
271 void SCIF_recvq_clear( void )
272 {
273 SCIF_recvq.head = SCIF_recvq.tail = 0;
274 MMIO_WRITE( SCIF, SCFDR2, MMIO_READ( SCIF, SCFDR2 ) & 0xF0 );
275 MMIO_WRITE( SCIF, SCFSR2, MMIO_READ( SCIF, SCFSR2 ) & ~(SCFSR2_DR|SCFSR2_RDF) );
276 if( IS_RECEIVE_IRQ_ENABLED() )
277 intc_clear_interrupt( INT_SCIF_RXI );
278 }
280 static inline uint8_t SCIF_sendq_size( )
281 {
282 int val = SCIF_sendq.tail - SCIF_sendq.head;
283 if( val < 0 ) {
284 val = FIFO_ARR_LENGTH - SCIF_sendq.head + SCIF_sendq.tail;
285 }
286 return val;
287 }
289 /**
290 * Dequeue one byte from the SCIF transmit queue (ie transmit the byte),
291 * updating all status flags as required.
292 * @return The byte dequeued, or -1 if the queue is empty.
293 */
294 int SCIF_sendq_dequeue( )
295 {
296 uint8_t result;
297 uint32_t tmp, length;
298 if( SCIF_sendq.head == SCIF_sendq.tail )
299 return -1; /* No data */
301 /* Update queue head pointer */
302 result = SCIF_sendq.data[SCIF_sendq.head++];
303 if( SCIF_sendq.head > FIFO_LENGTH )
304 SCIF_sendq.head = 0;
306 /* Update data count register */
307 tmp = MMIO_READ( SCIF, SCFDR2 ) & 0x0F;
308 length = SCIF_sendq_size();
309 MMIO_WRITE( SCIF, SCFDR2, tmp | (length << 8) );
311 /* Update status register */
312 if( length <= SCIF_sendq.trigger ) {
313 tmp = MMIO_READ( SCIF, SCFSR2 ) | SCFSR2_TDFE;
314 if( length == 0 )
315 tmp |= SCFSR2_TEND; /* Transmission ended - no data waiting */
316 if( IS_TRANSMIT_IRQ_ENABLED() )
317 intc_raise_interrupt( INT_SCIF_TXI );
318 DMAC_trigger( DMAC_SCIF_TDE );
319 MMIO_WRITE( SCIF, SCFSR2, tmp );
320 }
321 return (int)(unsigned int)result;
322 }
324 /**
325 * Enqueue a single byte in the SCIF transmit queue. If the queue is full,
326 * the value will be discarded.
327 * @param value to be queued.
328 * @param clearFlags TRUE if the TEND/TDFE flags should be cleared
329 * if the queue exceeds the trigger level. (According to the manual,
330 * DMAC writes will clear the flag, whereas regular SH4 writes do NOT
331 * automatically clear it. Go figure).
332 * @return gboolean TRUE if the value was queued, FALSE if the queue was
333 * full.
334 */
335 gboolean SCIF_sendq_enqueue( uint8_t value, gboolean clearFlags )
336 {
337 uint32_t tmp, length;
338 int newpos = SCIF_sendq.tail + 1;
339 if( newpos > FIFO_LENGTH )
340 newpos = 0;
341 if( newpos == SCIF_sendq.head ) {
342 /* FIFO full - discard */
343 return FALSE;
344 }
345 SCIF_sendq.data[SCIF_sendq.tail] = value;
346 SCIF_sendq.tail = newpos;
348 /* Update data count register */
349 tmp = MMIO_READ( SCIF, SCFDR2 ) & 0x0F;
350 length = SCIF_sendq_size();
351 MMIO_WRITE( SCIF, SCFDR2, tmp | (length << 8) );
353 /* Update flags if requested */
354 if( clearFlags ) {
355 tmp = SCFSR2_TEND;
356 if( length > SCIF_sendq.trigger ) {
357 tmp |= SCFSR2_TDFE;
358 if( IS_TRANSMIT_IRQ_ENABLED() )
359 intc_clear_interrupt( INT_SCIF_TXI );
360 }
361 tmp = MMIO_READ( SCIF, SCFSR2 ) & (~tmp);
362 MMIO_WRITE( SCIF, SCFSR2, tmp );
363 }
364 return TRUE;
365 }
367 void SCIF_sendq_clear( void )
368 {
369 SCIF_sendq.head = SCIF_sendq.tail = 0;
370 MMIO_WRITE( SCIF, SCFDR2, MMIO_READ( SCIF, SCFDR2 ) & 0x0F );
371 MMIO_WRITE( SCIF, SCFSR2, MMIO_READ( SCIF, SCFSR2 ) | SCFSR2_TEND | SCFSR2_TDFE );
372 if( IS_TRANSMIT_IRQ_ENABLED() ) {
373 intc_raise_interrupt( INT_SCIF_TXI );
374 DMAC_trigger( DMAC_SCIF_TDE );
375 }
376 }
378 /**
379 * Update the SCFSR2 status register with the given mask (ie clear any values
380 * that are set to 0 in the mask. According to a strict reading of the doco
381 * though, the bits will only actually clear if the flag state is no longer
382 * true, so we need to recheck everything...
383 */
384 void SCIF_update_status( uint32_t mask )
385 {
386 uint32_t value = MMIO_READ( SCIF, SCFSR2 );
387 uint32_t result = value & mask;
388 uint32_t sendq_size = SCIF_sendq_size();
389 uint32_t recvq_size = SCIF_recvq_size();
391 if( sendq_size != 0 )
392 result |= SCFSR2_TEND;
394 if( sendq_size <= SCIF_sendq.trigger )
395 result |= SCFSR2_TDFE;
396 else if( (result & SCFSR2_TDFE) == 0 && IS_TRANSMIT_IRQ_ENABLED() )
397 intc_clear_interrupt( INT_SCIF_TXI );
399 if( recvq_size >= SCIF_recvq.trigger )
400 result |= SCFSR2_RDF;
401 if( (value & SCFSR2_DR) != 0 && (result & SCFSR2_DR) == 0 &&
402 recvq_size != 0 )
403 result |= SCFSR2_DR;
404 if( (result & (SCFSR2_DR|SCFSR2_RDF)) == 0 && IS_RECEIVE_IRQ_ENABLED() )
405 intc_clear_interrupt( INT_SCIF_RXI );
407 if( IS_RECEIVE_ERROR_IRQ_ENABLED() ) {
408 if( (result & SCFSR2_BRK) == 0 )
409 intc_clear_interrupt( INT_SCIF_BRI );
410 if( (result & SCFSR2_ER) == 0 &&
411 (MMIO_READ( SCIF, SCLSR2 ) & SCLSR2_ORER) == 0 )
412 intc_clear_interrupt( INT_SCIF_ERI );
413 }
414 }
416 /**
417 * Set the break detected flag
418 */
419 void SCIF_set_break( void )
420 {
421 MMIO_WRITE( SCIF, SCFSR2, MMIO_READ( SCIF, SCFSR2 ) | SCFSR2_BRK );
422 if( IS_RECEIVE_ERROR_IRQ_ENABLED() )
423 intc_raise_interrupt( INT_SCIF_BRI );
424 }
426 const static int SCIF_CLOCK_MULTIPLIER[4] = {1, 4, 16, 64};
428 /**
429 * Calculate the current line speed.
430 */
431 void SCIF_update_line_speed( void )
432 {
433 /* If CKE1 is set, use the external clock as a base */
434 if( MMIO_READ( SCIF, SCSCR2 ) & SCSCR2_CKE ) {
437 } else {
439 /* Otherwise, SH4 peripheral clock divided by n */
440 int mult = SCIF_CLOCK_MULTIPLIER[MMIO_READ( SCIF, SCSMR2 ) & 0x03];
442 /* Then process the bitrate register */
443 int bbr = MMIO_READ( SCIF, SCBRR2 ) & 0xFF;
445 int baudrate = sh4_peripheral_freq / (32 * mult * (bbr+1) );
447 if( serial_device != NULL && serial_device->set_line_speed != NULL )
448 serial_device->set_line_speed( baudrate );
450 SCIF_tick_period = sh4_peripheral_period * (32 * mult * (bbr+1));
452 /*
453 clock_set_tick_rate( CLOCK_SCIF, baudrate / 10 );
454 */
455 }
456 }
458 MMIO_REGION_READ_FN( SCIF, reg )
459 {
460 reg &= 0xFFF;
461 switch( reg ) {
462 case SCFRDR2: /* Receive data */
463 return SCIF_recvq_dequeue(FALSE);
464 default:
465 return MMIO_READ( SCIF, reg );
466 }
467 }
468 MMIO_REGION_READ_DEFSUBFNS(SCIF)
471 MMIO_REGION_WRITE_FN( SCIF, reg, val )
472 {
473 uint32_t tmp;
474 reg &= 0xFFF;
475 switch( reg ) {
476 case SCSMR2: /* Serial mode register */
477 /* Bit 6 => 0 = 8-bit, 1 = 7-bit
478 * Bit 5 => 0 = Parity disabled, 1 = parity enabled
479 * Bit 4 => 0 = Even parity, 1 = Odd parity
480 * Bit 3 => 0 = 1 stop bit, 1 = 2 stop bits
481 * Bits 0-1 => Clock select 00 = P, 01 = P/4, 10 = P/16, 11 = P/64
482 */
483 val &= 0x007B;
484 if( serial_device != NULL ) {
485 serial_device->set_line_params( val );
486 }
487 tmp = MMIO_READ( SCIF, SCSMR2 );
488 if( (tmp & 0x03) != (val & 0x03) ) {
489 /* Clock change */
490 SCIF_update_line_speed( );
491 }
492 /* Save for later read-back */
493 MMIO_WRITE( SCIF, SCSMR2, val );
494 break;
495 case SCBRR2: /* Bit rate register */
496 MMIO_WRITE( SCIF, SCBRR2, val );
497 SCIF_update_line_speed( );
498 break;
499 case SCSCR2: /* Serial control register */
500 /* Bit 7 => Transmit-FIFO-data-empty interrupt enabled
501 * Bit 6 => Receive-data-full interrupt enabled
502 * Bit 5 => Transmit enable
503 * Bit 4 => Receive enable
504 * Bit 3 => Receive-error/break interrupt enabled
505 * Bit 1 => Clock enable
506 */
507 val &= 0x00FA;
508 /* Clear any interrupts that just became disabled */
509 if( (val & SCSCR2_TIE) == 0 )
510 intc_clear_interrupt( INT_SCIF_TXI );
511 if( (val & SCSCR2_RIE) == 0 )
512 intc_clear_interrupt( INT_SCIF_RXI );
513 if( (val & (SCSCR2_RIE|SCSCR2_REIE)) == 0 ) {
514 intc_clear_interrupt( INT_SCIF_ERI );
515 intc_clear_interrupt( INT_SCIF_BRI );
516 }
518 MMIO_WRITE( SCIF, reg, val );
519 break;
520 case SCFTDR2: /* Transmit FIFO data register */
521 SCIF_sendq_enqueue( val, FALSE );
522 break;
523 case SCFSR2: /* Serial status register */
524 /* Bits 12-15 Parity error count
525 * Bits 8-11 Framing erro count
526 * Bit 7 - Receive error
527 * Bit 6 - Transmit end
528 * Bit 5 - Transmit FIFO data empty
529 * Bit 4 - Break detect
530 * Bit 3 - Framing error
531 * Bit 2 - Parity error
532 * Bit 1 - Receive FIFO data full
533 * Bit 0 - Receive data ready
534 */
535 /* Clear off any flags/interrupts that are being set to 0 */
536 SCIF_update_status( val );
537 break;
538 case SCFCR2: /* FIFO control register */
539 val &= 0x0F;
540 SCIF_recvq.trigger = SCIF_recvq_triggers[val >> 6];
541 SCIF_sendq.trigger = SCIF_sendq_triggers[(val >> 4) & 0x03];
542 if( val & SCFCR2_TFRST ) {
543 SCIF_sendq_clear();
544 }
545 if( val & SCFCR2_RFRST ) {
546 SCIF_recvq_clear();
547 }
549 MMIO_WRITE( SCIF, reg, val );
550 break;
551 case SCSPTR2: /* Serial Port Register */
552 MMIO_WRITE( SCIF, reg, val );
553 /* NOT IMPLEMENTED - 'direct' serial I/O */
554 if( val != 0 ) {
555 WARN( "SCSPTR2 not implemented: Write %08X", val );
556 }
557 break;
558 case SCLSR2:
559 val = val & SCLSR2_ORER;
560 if( val == 0 ) {
561 MMIO_WRITE( SCIF, SCLSR2, val );
562 if( (MMIO_READ( SCIF, SCFSR2 ) & SCFSR2_ER) == 0 &&
563 IS_RECEIVE_ERROR_IRQ_ENABLED() )
564 intc_clear_interrupt( INT_SCIF_ERI );
565 }
567 break;
568 }
569 }
571 /**
572 * Actions for a single tick of the serial clock, defined as the transmission
573 * time of a single frame.
574 *
575 * If transmit queue is non-empty:
576 * Transmit one byte and remove from queue
577 * If input receive source is non-empty:
578 * Transfer one byte to the receive queue (if queue is full, byte is lost)
579 * If recvq is non-empty, less than the trigger level, and no data has been
580 * received in the last 2 ticks (including this one), set the DR flag and
581 * IRQ if appropriate.
582 */
583 void SCIF_clock_tick( void )
584 {
585 gboolean rcvd = FALSE;
587 if( IS_LOOPBACK_ENABLED() ) {
588 if( IS_TRANSMIT_ENABLED() ) {
589 int val = SCIF_sendq_dequeue();
590 if( val != -1 && IS_RECEIVE_ENABLED() ) {
591 SCIF_recvq_enqueue( val );
592 rcvd = TRUE;
593 }
594 }
595 } else {
596 if( IS_TRANSMIT_ENABLED() ) {
597 int val = SCIF_sendq_dequeue();
598 if( val != -1 && serial_device != NULL &&
599 serial_device->receive_data != NULL ) {
600 serial_device->receive_data( val );
601 }
602 }
604 if( IS_RECEIVE_ENABLED() ) {
605 int val = serial_transmit_dequeue();
606 if( val != -1 ) {
607 SCIF_recvq_enqueue( val );
608 rcvd = TRUE;
609 }
610 }
611 }
613 /* Check if we need to set the DR flag */
614 if( !rcvd && !SCIF_rcvd_last_tick &&
615 SCIF_recvq.head != SCIF_recvq.tail &&
616 SCIF_recvq_size() < SCIF_recvq.trigger ) {
617 uint32_t tmp = MMIO_READ( SCIF, SCFSR2 );
618 if( (tmp & SCFSR2_DR) == 0 ) {
619 MMIO_WRITE( SCIF, SCFSR2, tmp | SCFSR2_DR );
620 if( IS_RECEIVE_IRQ_ENABLED() )
621 intc_raise_interrupt( INT_SCIF_RXI );
622 DMAC_trigger( DMAC_SCIF_RDF );
623 }
624 }
625 SCIF_rcvd_last_tick = rcvd;
626 }
628 void SCIF_reset( void )
629 {
630 SCIF_recvq_clear();
631 SCIF_sendq_clear();
632 SCIF_update_line_speed();
633 }
635 void SCIF_run_slice( uint32_t nanosecs )
636 {
637 SCIF_tick_remainder += nanosecs;
638 while( SCIF_tick_remainder >= SCIF_tick_period ) {
639 SCIF_tick_remainder -= SCIF_tick_period;
640 SCIF_clock_tick();
641 }
642 }
.