Mercurial > ecos
diff packages/hal/powerpc/quicc/current/src/quicc_smc1.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 | 95f3e12a6327 |
| children | 7f461c3a372c |
line wrap: on
line diff
--- a/packages/hal/powerpc/quicc/current/src/quicc_smc1.c +++ b/packages/hal/powerpc/quicc/current/src/quicc_smc1.c @@ -60,14 +60,11 @@ #include <cyg/hal/quicc/quicc_smc1.h> -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) #include <cyg/hal/hal_stub.h> // target_register_t #include <cyg/hal/hal_intr.h> // HAL_INTERRUPT_UNMASK(...) #include <cyg/hal/hal_if.h> // Calling interface definitions #include <cyg/hal/hal_misc.h> // Helper functions #include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED -#endif #define UART_BIT_RATE(n) (((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000)/16)/n) #define UART_BAUD_RATE CYGNUM_HAL_QUICC_DIAG_BAUD @@ -92,8 +89,8 @@ * The basic initialization steps are from Section 16.15.8 * of that manual. */ -static void -init_smc1_uart(void) +void +cyg_hal_plf_serial_init_channel(void) { EPPC *eppc; volatile struct smc_uart_pram *uart_pram; @@ -286,22 +283,22 @@ cyg_hal_plf_serial_putc(void* __ch_data, CYGARC_HAL_RESTORE_GP(); } -cyg_uint8 -cyg_hal_plf_serial_getc(void* __ch_data) + +static cyg_bool +cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch) { volatile struct cp_bufdesc *bd; - char ch; EPPC *eppc = (EPPC*) __ch_data; volatile struct smc_uart_pram *uart_pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u; int cache_state; - CYGARC_HAL_SAVE_GP(); /* rx buffer descriptor */ bd = (struct cp_bufdesc *)((char *)eppc + uart_pram->rbptr); - while (bd->ctrl & QUICC_BD_CTL_Ready) ; + if (bd->ctrl & QUICC_BD_CTL_Ready) + return false; - ch = bd->buffer[0]; + *ch = bd->buffer[0]; bd->length = 0; bd->buffer[0] = '\0'; @@ -312,10 +309,26 @@ cyg_hal_plf_serial_getc(void* __ch_data) HAL_DCACHE_INVALIDATE(bd->buffer, uart_pram->mrblr); // Make sure no stale data } + return true; +} + +cyg_uint8 +cyg_hal_plf_serial_getc(void* __ch_data) +{ + cyg_uint8 ch; + CYGARC_HAL_SAVE_GP(); + + while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch)); + CYGARC_HAL_RESTORE_GP(); return ch; } + + +#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ + || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) + static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len) @@ -339,11 +352,101 @@ cyg_hal_plf_serial_read(void* __ch_data, CYGARC_HAL_RESTORE_GP(); } +cyg_int32 msec_timeout = 1000; + +cyg_bool +cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch) +{ + int delay_count = msec_timeout * 10; // delay in .1 ms steps + cyg_bool res; + CYGARC_HAL_SAVE_GP(); + + for(;;) { + res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch); + if (res || 0 == delay_count--) + break; + + CYGACC_CALL_IF_DELAY_US()(100); + } + + CYGARC_HAL_RESTORE_GP(); + return res; +} + static int cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...) { - // Do nothing (yet). - return 0; + static int irq_state = 0; + int ret = 0; + CYGARC_HAL_SAVE_GP(); + + switch (__func) { + case __COMMCTL_IRQ_ENABLE: + HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1); + irq_state = 1; + break; + case __COMMCTL_IRQ_DISABLE: + ret = irq_state; + irq_state = 0; + HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1); + break; + case __COMMCTL_DBG_ISR_VECTOR: + ret = CYGNUM_HAL_INTERRUPT_CPM_SMC1; + break; + case __COMMCTL_SET_TIMEOUT: + { + va_list ap; + + va_start(ap, __func); + + ret = msec_timeout; + msec_timeout = va_arg(ap, cyg_uint32); + + va_end(ap); + } + default: + break; + } + CYGARC_HAL_RESTORE_GP(); + return ret; +} + +static int +cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, + CYG_ADDRWORD __vector, CYG_ADDRWORD __data) +{ + EPPC *eppc = (EPPC*) __ch_data; + struct cp_bufdesc *bd; + char ch; + int res = 0; + CYGARC_HAL_SAVE_GP(); + + *__ctrlc = 0; + if (eppc->smc_regs[0].smc_smce & QUICC_SMCE_RX) { + + eppc->smc_regs[0].smc_smce = QUICC_SMCE_RX; + + /* rx buffer descriptors */ + bd = (struct cp_bufdesc *)((char *)eppc + Rxbd); + + if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) { + + // then there be a character waiting + ch = bd->buffer[0]; + bd->length = 1; + bd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int; + + if( cyg_hal_is_break( &ch , 1 ) ) + *__ctrlc = 1; + } + + // Interrupt handled. Acknowledge it. + eppc->cpmi_cisr = 0x10; + res = CYG_ISR_HANDLED; + } + + CYGARC_HAL_RESTORE_GP(); + return res; } /* @@ -354,6 +457,8 @@ cyg_hal_plf_serial_control(void *__ch_da void cyg_hal_plf_serial_init(void) { + hal_virtual_comm_table_t* comm; + int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); volatile EPPC *eppc = eppc_base(); int i; @@ -367,126 +472,27 @@ cyg_hal_plf_serial_init(void) eppc->cp_cr = QUICC_CPM_CR_RESET | QUICC_CPM_CR_BUSY; for (i = 0; i < 100000; i++); - init_smc1_uart(); + cyg_hal_plf_serial_init_channel(); -#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \ - || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES) - { - // Setup procs in the vector table - hal_virtual_comm_table_t* comm; - int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM()(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); + // Setup procs in the vector table - // Set channel 0 - CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);// Should be configurable! - comm = CYGACC_CALL_IF_CONSOLE_PROCS(); - CYGACC_COMM_IF_CH_DATA_SET(*comm, eppc_base()); - CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); - CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); - CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); - CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); - CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); + // Set channel 0 + CYGACC_CALL_IF_SET_CONSOLE_COMM()(0);// Should be configurable! + comm = CYGACC_CALL_IF_CONSOLE_PROCS(); + CYGACC_COMM_IF_CH_DATA_SET(*comm, eppc_base()); + CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); + CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); + CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); + CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); + CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); + CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr); + CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); - // Restore original console - CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); - } -#endif + // Restore original console + CYGACC_CALL_IF_SET_CONSOLE_COMM()(cur); } -#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT // the below should be removed - - -#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT -// This ISR is called from the interrupt handler. This should only -// happen when there is no real serial driver, so the code shouldn't -// mess anything up. -int cyg_hal_gdb_isr( target_register_t pc ) -{ - EPPC *eppc = eppc_base(); - struct cp_bufdesc *bd; - char ch; - - eppc->smc_regs[0].smc_smce = 0xff; - - /* rx buffer descriptors */ - bd = (struct cp_bufdesc *)((char *)eppc_base() + Rxbd); - - if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) { - // then there be a character waiting - ch = bd->buffer[0]; - bd->length = 1; - bd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int; - - if ( 3 == ch ) { - // Ctrl-C: set a breakpoint at PC so GDB will display the - // correct program context when stopping rather than the - // interrupt handler. - cyg_hal_gdb_interrupt( pc ); - - // Interrupt handled. Don't call ISR proper. At return - // from the VSR, execution will stop at the breakpoint - // just set. - - eppc->cpmi_cisr = 0x10; - return 0; - } - } - eppc->cpmi_cisr = 0x10; // acknowledge the Rx event anyway - // in case it was left over from polled reception - // Not caused by GDB. Call ISR proper. - return 1; -} -#endif // CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT - - -#else // the below stays - -#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \ - || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT) - -struct Hal_SavedRegisters *hal_saved_interrupt_state; - -void -hal_ctrlc_isr_init(void) -{ - HAL_INTERRUPT_UNMASK(CYGHWR_HAL_GDB_PORT_VECTOR); -} - - -cyg_uint32 -hal_ctrlc_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data) -{ - EPPC *eppc = eppc_base(); - struct cp_bufdesc *bd; - char ch; - - if (eppc->smc_regs[0].smc_smce & QUICC_SMCE_RX) { - - eppc->smc_regs[0].smc_smce = QUICC_SMCE_RX; - - /* rx buffer descriptors */ - bd = (struct cp_bufdesc *)((char *)eppc_base() + Rxbd); - - if ((bd->ctrl & QUICC_BD_CTL_Ready) == 0) { - - // then there be a character waiting - ch = bd->buffer[0]; - bd->length = 1; - bd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Wrap | QUICC_BD_CTL_Int; - - if( cyg_hal_is_break( &ch , 1 ) ) - cyg_hal_user_break( (CYG_ADDRWORD *)hal_saved_interrupt_state ); - } - - // Interrupt handled. Acknowledge it. - eppc->cpmi_cisr = 0x10; - return CYG_ISR_HANDLED; - } - - // Not a serial interrupt. - return 0; -} -#endif -#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT +#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES #endif // CYGPKG_HAL_POWERPC_MPC860 // EOF quicc_smc1.c
