comparison packages/io/serial/current/src/mn10300/mn10300_serial.c @ 30:641b639be825 ecos-sw-1999-08-16

Merge from eCos master repository on 1999-08-16-22:01:37-BST
author jlarmour
date Mon, 16 Aug 1999 22:10:49 +0000
parents d3fbcdfa1b2f
children 5af43b635655
comparison
equal deleted inserted replaced
29:093762bd6ba9 30:641b639be825
108 #define LCR_WL6 0x00 // not supported - use 7bit 108 #define LCR_WL6 0x00 // not supported - use 7bit
109 #define LCR_WL7 0x00 // 7 bit chars 109 #define LCR_WL7 0x00 // 7 bit chars
110 #define LCR_WL8 0x80 // 8 bit chars 110 #define LCR_WL8 0x80 // 8 bit chars
111 #define LCR_RXE 0x4000 // receive enable 111 #define LCR_RXE 0x4000 // receive enable
112 #define LCR_TXE 0x8000 // transmit enable 112 #define LCR_TXE 0x8000 // transmit enable
113 #define LCR_TWE 0x0100 // interrupt enable (only on serial2) 113
114 #if defined(CYG_HAL_MN10300_AM31)
115 #define LCR_TWE 0x0100 // interrupt enable (only on serial2/AM31)
116 #else
117 #define LCR_TWE 0x0000 // Bit does not exist in other variants
118 #endif
114 119
115 //------------------------------------------------------------------------- 120 //-------------------------------------------------------------------------
116 // MN10300 timer registers: 121 // MN10300 timer registers:
117 122
118 #undef TIMER_BR 123 #undef TIMER_BR
119 #undef TIMER_MD 124 #undef TIMER_MD
120 #define TIMER_MD 0x00 125 #define TIMER_MD 0x00
121 #define TIMER_BR 0x10 126 #define TIMER_BR 0x10
122 127
123 //------------------------------------------------------------------------- 128 //-------------------------------------------------------------------------
124 // IO Port: 129 // Serial and timer base registers:
125 130
126 #define PORT3_MD 0x36008025 131 #if defined(CYG_HAL_MN10300_AM31)
132
133 #define SERIAL0_BASE 0x34000800
134 #define SERIAL1_BASE 0x34000810
135 #define SERIAL2_BASE 0x34000820
136
137 #define TIMER0_BASE 0x34001000
138 #define TIMER1_BASE 0x34001001
139 #define TIMER2_BASE 0x34001002
140
141 #define SERIAL0_TIMER_SELECT 0x0004 // timer 0
142 #define SERIAL1_TIMER_SELECT 0x0004 // timer 1
143 #define SERIAL2_TIMER_SELECT 0x0001 // timer 2
144
145 #ifdef CYG_HAL_MN10300_AM31_STDEVAL1
146 // The use of PORT3 to provide CTS/CTR is specific to
147 // the STDEVAL1 board only.
148 #define PORT3_MD 0x36008025
149 #endif
150
151 #define ENABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
152 CYG_MACRO_START \
153 if( mn10300_chan->is_serial2 ) \
154 cr |= LCR_TWE; \
155 else \
156 cr |= LCR_TXE; \
157 CYG_MACRO_END
158
159 #define DISABLE_TRANSMIT_INTERRUPT(mn10300_chan) \
160 CYG_MACRO_START \
161 if( mn10300_chan->is_serial2 ) \
162 cr &= ~LCR_TWE; \
163 else \
164 cr &= ~LCR_TXE; \
165 CYG_MACRO_END
166
167 #else
168
169 #error Unsupported MN10300 variant
170
171 #endif
127 172
128 //------------------------------------------------------------------------- 173 //-------------------------------------------------------------------------
129 // Tables to map input values to hardware settings 174 // Tables to map input values to hardware settings
130 175
131 static unsigned char select_word_length[] = { 176 static unsigned char select_word_length[] = {
147 LCR_PE, // Even parity 192 LCR_PE, // Even parity
148 LCR_PO, // Odd parity 193 LCR_PO, // Odd parity
149 LCR_PM, // Mark parity 194 LCR_PM, // Mark parity
150 LCR_PS, // Space parity 195 LCR_PS, // Space parity
151 }; 196 };
197
198 #if defined(CYG_HAL_MN10300_AM31)
152 199
153 static unsigned short select_baud_01[] = { 200 static unsigned short select_baud_01[] = {
154 0, // Unused 201 0, // Unused
155 0, // 50 202 0, // 50
156 0, // 75 203 0, // 75
206 { 88, 2 }, // 57600 253 { 88, 2 }, // 57600
207 { 64, 1 }, // 115200 254 { 64, 1 }, // 115200
208 { 62, 0 }, // 230400 255 { 62, 0 }, // 230400
209 }; 256 };
210 257
258 #else
259
260 #error Unsupported MN10300 variant
261
262 #endif
211 263
212 //------------------------------------------------------------------------- 264 //-------------------------------------------------------------------------
213 // Info for each serial device controlled 265 // Info for each serial device controlled
214 266
215 typedef struct mn10300_serial_info { 267 typedef struct mn10300_serial_info {
216 CYG_ADDRWORD base; 268 CYG_ADDRWORD base;
217 CYG_ADDRWORD timer_base; 269 CYG_ADDRWORD timer_base;
270 CYG_WORD timer_select;
218 CYG_WORD rx_int; 271 CYG_WORD rx_int;
219 CYG_WORD tx_int; 272 CYG_WORD tx_int;
220 cyg_bool is_serial2; 273 cyg_bool is_serial2;
221 cyg_interrupt rx_interrupt; 274 cyg_interrupt rx_interrupt;
222 cyg_interrupt tx_interrupt; 275 cyg_interrupt tx_interrupt;
239 // Hardware info for each serial line 292 // Hardware info for each serial line
240 293
241 #ifndef CYG_HAL_MN10300_STDEVAL1 294 #ifndef CYG_HAL_MN10300_STDEVAL1
242 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0 295 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0
243 static mn10300_serial_info mn10300_serial_info0 = { 296 static mn10300_serial_info mn10300_serial_info0 = {
244 0x34000800, 297 SERIAL0_BASE,
245 0x34001000, 298 TIMER0_BASE,
299 SERIAL0_TIMER_SELECT,
246 CYGNUM_HAL_INTERRUPT_SERIAL_0_RX, 300 CYGNUM_HAL_INTERRUPT_SERIAL_0_RX,
247 CYGNUM_HAL_INTERRUPT_SERIAL_0_TX, 301 CYGNUM_HAL_INTERRUPT_SERIAL_0_TX,
248 false 302 false
249 }; 303 };
250 #if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0 304 #if CYGNUM_IO_SERIAL_MN10300_SERIAL0_BUFSIZE > 0
254 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0 308 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0
255 #endif 309 #endif
256 310
257 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1 311 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1
258 static mn10300_serial_info mn10300_serial_info1 = { 312 static mn10300_serial_info mn10300_serial_info1 = {
259 0x34000810, 313 SERIAL1_BASE,
260 0x34001001, 314 TIMER1_BASE,
315 SERIAL1_TIMER_SELECT,
261 CYGNUM_HAL_INTERRUPT_SERIAL_1_RX, 316 CYGNUM_HAL_INTERRUPT_SERIAL_1_RX,
262 CYGNUM_HAL_INTERRUPT_SERIAL_1_TX, 317 CYGNUM_HAL_INTERRUPT_SERIAL_1_TX,
263 false 318 false
264 }; 319 };
265 #if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0 320 #if CYGNUM_IO_SERIAL_MN10300_SERIAL1_BUFSIZE > 0
268 #endif 323 #endif
269 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1 324 #endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1
270 325
271 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2 326 #ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2
272 static mn10300_serial_info mn10300_serial_info2 = { 327 static mn10300_serial_info mn10300_serial_info2 = {
273 0x34000820, 328 SERIAL2_BASE,
274 0x34001002, 329 TIMER2_BASE,
330 SERIAL2_TIMER_SELECT,
275 CYGNUM_HAL_INTERRUPT_SERIAL_2_RX, 331 CYGNUM_HAL_INTERRUPT_SERIAL_2_RX,
276 CYGNUM_HAL_INTERRUPT_SERIAL_2_TX, 332 CYGNUM_HAL_INTERRUPT_SERIAL_2_TX,
277 true 333 true
278 }; 334 };
279 #if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0 335 #if CYGNUM_IO_SERIAL_MN10300_SERIAL2_BUFSIZE > 0
448 mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init) 504 mn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init)
449 { 505 {
450 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; 506 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
451 cyg_uint16 cr = 0; 507 cyg_uint16 cr = 0;
452 cyg_uint16 sr; 508 cyg_uint16 sr;
453 509
454 // wait for the device to become acquiescent. This could take some time 510 // wait for the device to become quiescent. This could take some time
455 // if the device had been transmitting at a low baud rate. 511 // if the device had been transmitting at a low baud rate.
456 do { 512 do {
457 sr = mn10300_read_sr(mn10300_chan); 513 sr = mn10300_read_sr(mn10300_chan);
458 } while (sr & (SR_RXF|SR_TXF)); 514 } while (sr & (SR_RXF|SR_TXF));
459 515
468 { 524 {
469 // Serial 2 is a bit different from 0 and 1 in the way that the 525 // Serial 2 is a bit different from 0 and 1 in the way that the
470 // baud rate is controlled. 526 // baud rate is controlled.
471 527
472 cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val; 528 cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val;
473 529
474 if (baud_divisor == 0) 530 if (baud_divisor == 0)
475 return false; // Invalid baud rate selected 531 return false; // Invalid baud rate selected
476 532
477 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); 533 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);
478 534
480 536
481 baud_divisor = select_baud_2[new_config->baud].serial2_val; 537 baud_divisor = select_baud_2[new_config->baud].serial2_val;
482 538
483 HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor); 539 HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor);
484 540
485 cr |= 0x0001; // Source clock from timer 2 541 cr |= mn10300_chan->timer_select;
486 } 542 }
487 else 543 else
488 { 544 {
489 cyg_uint8 baud_divisor = select_baud_01[new_config->baud]; 545 cyg_uint16 baud_divisor = select_baud_01[new_config->baud];
490 546 cyg_uint8 timer_mode = 0x80;
547
491 if (baud_divisor == 0) 548 if (baud_divisor == 0)
492 return false; // Invalid baud rate selected 549 return false; // Invalid baud rate selected
493 550
551
494 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor); 552 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);
495 553
496 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 ); 554 HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, timer_mode );
497 555
498 cr |= 0x0004; // Source clock from timer 0 or 1 556 cr |= mn10300_chan->timer_select;
499 } 557 }
500 558
559 #ifdef PORT3_MD
501 HAL_WRITE_UINT8( PORT3_MD, 0x01 ); 560 HAL_WRITE_UINT8( PORT3_MD, 0x01 );
561 #endif
502 562
503 // set up other config values: 563 // set up other config values:
504 564
505 cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5]; 565 cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];
506 cr |= select_stop_bits[new_config->stop]; 566 cr |= select_stop_bits[new_config->stop];
507 cr |= select_parity[new_config->parity]; 567 cr |= select_parity[new_config->parity];
508 568
509 #ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE 569 cr |= LCR_RXE | LCR_TXE; // enable Rx and Tx
510 // enable RX and TX 570
511 cr |= LCR_RXE | LCR_TXE; 571 #ifdef CYG_HAL_MN10300_AM31
512 #else 572 if( mn10300_chan->is_serial2 )
513 if( mn10300_chan->is_serial2 ) { 573 {
514 cr |= LCR_RXE | LCR_TXE; // enable Rx and TX 574 // AM31 has an extra TX interrupt enable bit for serial 2.
515 cr &= ~LCR_TWE; // disable transmit interrupts 575 DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);
516 } else { 576 }
517 // Enable RX only 577 #endif
518 cr |= LCR_RXE; 578
519 }
520 #endif
521
522 // Write CR into hardware 579 // Write CR into hardware
523 HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr); 580 HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr);
524 581
525 mn10300_read_sr(mn10300_chan); 582 sr = mn10300_read_sr(mn10300_chan);
583
526 if (new_config != &chan->config) { 584 if (new_config != &chan->config) {
527 chan->config = *new_config; 585 chan->config = *new_config;
528 } 586 }
529 return true; 587 return true;
530 } 588 }
642 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; 700 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
643 cyg_uint16 cr; 701 cyg_uint16 cr;
644 702
645 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); 703 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
646 704
647 if( mn10300_chan->is_serial2 ) 705 ENABLE_TRANSMIT_INTERRUPT(mn10300_chan);
648 cr |= LCR_TWE; // enable transmit interrupts
649 else
650 cr |= LCR_TXE; // enable TX
651 706
652 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); 707 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
653 708
654 cyg_drv_interrupt_unmask(mn10300_chan->tx_int); 709 cyg_drv_interrupt_unmask(mn10300_chan->tx_int);
655 710
676 731
677 } while( sr & SR_TXF ); 732 } while( sr & SR_TXF );
678 733
679 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); 734 HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
680 735
681 if( mn10300_chan->is_serial2 ) 736 DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);
682 cr &= ~LCR_TWE; // disable transmit interrupts 737
683 else
684 cr &= ~LCR_TXE; // disable transmission
685
686 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr ); 738 HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );
687 739
688 cyg_drv_interrupt_mask(mn10300_chan->tx_int); 740 cyg_drv_interrupt_mask(mn10300_chan->tx_int);
689 741
690 #endif 742 #endif
698 static cyg_uint32 750 static cyg_uint32
699 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data) 751 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data)
700 { 752 {
701 serial_channel *chan = (serial_channel *)data; 753 serial_channel *chan = (serial_channel *)data;
702 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv; 754 mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;
703 755
704 cyg_drv_interrupt_mask(mn10300_chan->rx_int); 756 cyg_drv_interrupt_mask(mn10300_chan->rx_int);
705 cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int); 757 cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);
706 758
707 return CYG_ISR_CALL_DSR; // Cause DSR to be run 759 return CYG_ISR_CALL_DSR; // Cause DSR to be run
708 } 760 }