Mercurial > ecos-v2_0-branch
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 } |
