?? smdk2410_serial.c
字號:
//UART modem control register
HAL_WRITE_UINT32(base+OFS_UMCON, 0);
}
_lcr = select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |
select_stop_bits[new_config->stop] |
select_parity[new_config->parity];
HAL_WRITE_UINT32(base+OFS_ULCON, _lcr);
//UART control register, Enable Rx Timeout Int
HAL_WRITE_UINT32(base+OFS_UCON, 0x085);
if (new_config != &chan->config) {
chan->config = *new_config;
}
return true;
}
// Function to initialize the device. Called at bootstrap time.
static bool
smdk2410_serial_init(struct cyg_devtab_entry *tab)
{
serial_channel *chan = (serial_channel *)tab->priv;
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv; cyg_uint32 _intsubm;
#ifdef CYGDBG_IO_INIT
diag_printf("SMDK2410 SERIAL init - dev: 0x%08x.%d\n",
smdk2410_chan->base, smdk2410_chan->int_num);
#endif
(chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
if (chan->out_cbuf.len != 0) {
cyg_drv_interrupt_create(smdk2410_chan->int_num,
1, // Priority - unused
(cyg_addrword_t)chan, // Data item passed to interrupt handler
smdk2410_serial_ISR,
smdk2410_serial_DSR,
&smdk2410_chan->serial_interrupt_handle,
&smdk2410_chan->serial_interrupt);
cyg_drv_interrupt_attach(smdk2410_chan->serial_interrupt_handle);
cyg_drv_interrupt_unmask(smdk2410_chan->int_num);
HAL_READ_UINT32(INTSUBMSK, _intsubm);
_intsubm &= ~(smdk2410_chan->bit_sub_rxd<<0); // BIT_SUB_RXD
HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
}
smdk2410_serial_config_port(chan, &chan->config, true);
return true;
}
// This routine is called when the device is "looked" up (i.e. attached)
static Cyg_ErrNo
smdk2410_serial_lookup(struct cyg_devtab_entry **tab,
struct cyg_devtab_entry *sub_tab,
const char *name)
{
serial_channel *chan = (serial_channel *)(*tab)->priv;
(chan->callbacks->serial_init)(chan); // Really only required for interrupt driven devices
return ENOERR;
}
// Send a character to the device output buffer.
// Return 'true' if character is sent to device
static bool
smdk2410_serial_putc(serial_channel *chan, unsigned char c)
{
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
CYG_ADDRWORD base = smdk2410_chan->base;
cyg_uint32 _status;
HAL_READ_UINT32(base+OFS_UFSTAT, _status);
if (_status & 0x200) {
// No space
return false;
} else {
// Transmit buffer is not full
HAL_WRITE_UINT8(base+OFS_UTXH, (cyg_uint32)c);
return true;
}
}
// Fetch a character from the device input buffer, waiting if necessary
static unsigned char
smdk2410_serial_getc(serial_channel *chan)
{
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
CYG_ADDRWORD base = smdk2410_chan->base;
cyg_uint32 _status;
cyg_uint8 _c;
do {
HAL_READ_UINT32(base+OFS_UFSTAT, _status);
} while ((_status & 0xf) == 0);
HAL_READ_UINT8(base+OFS_URXH, _c);
return (unsigned char)_c;
}
// Set up the device characteristics; baud rate, etc.
static Cyg_ErrNo
smdk2410_serial_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len)
{
switch (key) {
case CYG_IO_SET_CONFIG_SERIAL_INFO:
{
cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
if ( *len < sizeof(cyg_serial_info_t) ) {
return -EINVAL;
}
*len = sizeof(cyg_serial_info_t);
if ( true != smdk2410_serial_config_port(chan, config, false) )
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return ENOERR;
}
// Enable the transmitter on the device
static void
smdk2410_serial_start_xmit(serial_channel *chan)
{
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
cyg_uint32 _intsubm;
HAL_READ_UINT32(INTSUBMSK, _intsubm);
_intsubm &= ~(smdk2410_chan->bit_sub_rxd<<1); // BIT_SUB_TXD
HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
}
// Disable the transmitter on the device
static void
smdk2410_serial_stop_xmit(serial_channel *chan)
{
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
cyg_uint32 _intsubm;
HAL_READ_UINT32(INTSUBMSK, _intsubm);
_intsubm |= (smdk2410_chan->bit_sub_rxd<<1); // BIT_SUB_TXD
HAL_WRITE_UINT32(INTSUBMSK, _intsubm);
}
// Serial I/O - low level interrupt handler (ISR)
static cyg_uint32
smdk2410_serial_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
cyg_drv_interrupt_mask(smdk2410_chan->int_num);
cyg_drv_interrupt_acknowledge(smdk2410_chan->int_num);
return CYG_ISR_CALL_DSR; // Cause DSR to be run
}
// Serial I/O - high level interrupt handler (DSR)
static void
smdk2410_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
smdk2410_serial_info *smdk2410_chan = (smdk2410_serial_info *)chan->dev_priv;
CYG_ADDRWORD base = smdk2410_chan->base;
cyg_uint32 _intsubpnd, _status, _c;
cyg_uint32 _rxd_bit = (smdk2410_chan->bit_sub_rxd<<0), _txd_bit=(smdk2410_chan->bit_sub_rxd<<1);
HAL_READ_UINT32(SUBSRCPND, _intsubpnd);
// Empty Rx FIFO
if (_intsubpnd & _rxd_bit) {
HAL_READ_UINT32(base+OFS_UFSTAT, _status);
while((_status & 0x0f) != 0) {
HAL_READ_UINT8(base+OFS_URXH, _c);
(chan->callbacks->rcv_char)(chan, (unsigned char)_c);
HAL_READ_UINT32(base+OFS_UFSTAT, _status);
}
HAL_WRITE_UINT32(SUBSRCPND, _rxd_bit);
}
// Fill into Tx FIFO. xmt_char will mask the interrupt when it
// runs out of chars, so doing this in a loop is OK.
if (_intsubpnd & _txd_bit) {
(chan->callbacks->xmt_char)(chan);
HAL_WRITE_UINT32(SUBSRCPND, _txd_bit);
}
cyg_drv_interrupt_unmask(smdk2410_chan->int_num);
}
#endif // CYGPKG_IO_SERIAL_ARM_SMDK2410
// EOF smdk2410_serial.c
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -