ser_asb.c
来自「eCos操作系统源码」· C语言 代码 · 共 507 行 · 第 1/2 页
C
507 行
}static voidcyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len){ cyg_uint8* base = ((channel_data_t*)__ch_data)->base; CYGARC_HAL_SAVE_GP(); FLOWCTL_SET(DTR); while(__len-- > 0) cyg_hal_plf_serial_putc_aux(__ch_data, *__buf++); FLOWCTL_CLEAR(DTR); CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len){ CYGARC_HAL_SAVE_GP(); while(__len-- > 0) *__buf++ = cyg_hal_plf_serial_getc(__ch_data); CYGARC_HAL_RESTORE_GP();}#define TM0MD 0xD4003000#define TM0BR 0xD4003010#define TM0BC 0xD4003020cyg_boolcyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch){#if 1 int delay_count; channel_data_t* chan = (channel_data_t*)__ch_data; cyg_uint8* base = chan->base; cyg_uint8 last, val; cyg_bool res; CYGARC_HAL_SAVE_GP(); /* see if there's any cached data in the FIFO */ res = cyg_hal_plf_serial_getc_nonblock(__ch_data,ch); if (!res) { /* there isn't - open the flood gates */ delay_count = chan->msec_timeout * 125; // want delay in 8uS steps HAL_WRITE_UINT8(TM0BR,200); // IOCLK is 25MHz, we want 125KHz HAL_WRITE_UINT8(TM0MD,0x40); // stop and load HAL_WRITE_UINT8(TM0MD,0x80); // set source to be IOCLK and go HAL_READ_UINT8(TM0BC,last); while (delay_count>0 && !FLOWCTL_QUERY(DSR)) { HAL_READ_UINT8(TM0BC,val); if (val==last) continue; if (val>last) delay_count--; // count the underflows last = val; } if (delay_count==0) goto timeout; FLOWCTL_SET(RTS); while (delay_count>0 && !LSR_QUERY(DR)) { HAL_READ_UINT8(TM0BC,val); if (val==last) continue; if (val>last) delay_count--; // count the underflows last = val; } FLOWCTL_CLEAR(RTS); if (LSR_QUERY(DR)) { HAL_READ_UINT8(base+CYG_DEV_RBR, *ch); res = true; } timeout: HAL_WRITE_UINT8(TM0MD,0x00); // stop h/w timer } CYGARC_HAL_RESTORE_GP(); return res;#else int delay_count; channel_data_t* chan = (channel_data_t*)__ch_data; cyg_uint8* base = chan->base; cyg_bool res; CYGARC_HAL_SAVE_GP(); /* see if there's some cached data in the FIFO */ res = cyg_hal_plf_serial_getc_nonblock(__ch_data,ch); if (!res) { /* there isn't - open the flood gates */ delay_count = chan->msec_timeout * 1000; // want delay in uS steps for (; delay_count>0 && !FLOWCTL_QUERY(DSR); delay_count--) CYGACC_CALL_IF_DELAY_US(1); if (delay_count==0) goto timeout; FLOWCTL_SET(RTS); for (; delay_count>0 && !LSR_QUERY(DR); delay_count--) CYGACC_CALL_IF_DELAY_US(1); FLOWCTL_CLEAR(RTS); if (LSR_QUERY(DR)) { HAL_READ_UINT8(base+CYG_DEV_RBR, *ch); res = true; } }timeout: CYGARC_HAL_RESTORE_GP(); return res;#endif}static intcyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...){ static int irq_state = 0; channel_data_t* chan = (channel_data_t*)__ch_data; int ret = 0; CYGARC_HAL_SAVE_GP(); switch (__func) { case __COMMCTL_IRQ_ENABLE: irq_state = 1; HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, SIO_IER_RCV); HAL_WRITE_UINT8(chan->base+CYG_DEV_MCR, SIO_MCR_INT|SIO_MCR_DTR|SIO_MCR_RTS); HAL_INTERRUPT_UNMASK(chan->isr_vector); break; case __COMMCTL_IRQ_DISABLE: ret = irq_state; irq_state = 0; HAL_WRITE_UINT8(chan->base+CYG_DEV_IER, 0); HAL_INTERRUPT_MASK(chan->isr_vector); break; case __COMMCTL_DBG_ISR_VECTOR: ret = chan->isr_vector; break; case __COMMCTL_SET_TIMEOUT: { va_list ap; va_start(ap, __func); ret = chan->msec_timeout; chan->msec_timeout = va_arg(ap, cyg_uint32); va_end(ap); } default: break; } CYGARC_HAL_RESTORE_GP(); return ret;}static intcyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data){ int res = 0; channel_data_t* chan = (channel_data_t*)__ch_data; char c; cyg_uint8 lsr; CYGARC_HAL_SAVE_GP(); cyg_drv_interrupt_acknowledge(chan->isr_vector); *__ctrlc = 0; HAL_READ_UINT8(chan->base+CYG_DEV_LSR, lsr); if ( (lsr & SIO_LSR_DR) != 0 ) { HAL_READ_UINT8(chan->base+CYG_DEV_RBR, c); if( cyg_hal_is_break( &c , 1 ) ) *__ctrlc = 1; res = CYG_ISR_HANDLED; } CYGARC_HAL_RESTORE_GP(); return res;}static voidcyg_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); // Disable interrupts. HAL_INTERRUPT_MASK(asb2305_serial_channels[0].isr_vector); // Init channels cyg_hal_plf_serial_init_channel(&asb2305_serial_channels[0]); // Setup procs in the vector table // Set channel 0 CYGACC_CALL_IF_SET_CONSOLE_COMM(0); comm = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CH_DATA_SET(*comm, &asb2305_serial_channels[0]); 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);}voidcyg_hal_plf_comms_init(void){ static int initialized = 0; if (initialized) return; initialized = 1; cyg_hal_plf_serial_init();#if defined(CYGNUM_HAL_AM33_SERIAL_CHANNELS) && CYGNUM_HAL_AM33_SERIAL_CHANNELS > 0 cyg_hal_am33_serial_init(1);#endif}#endif // defined(CYGNUM_HAL_AM33_PLF_SERIAL_CHANNELS) && CYGNUM_HAL_AM33_PLF_SERIAL_CHANNELS > 0/*---------------------------------------------------------------------------*//* End of ser_asb.c */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?