📄 h8s_sci.c
字号:
}
//=============================================================================
// READ BUFFER OF CHARACTERS
///
/// Read a number of chars from serial channel.
/// Reads __len number of charaters from serail channel and stores them into
/// the buffer __buf.
///
/// \param __ch_data Pointer to channel configuration data
/// \param __buf Receive buffer
/// \param __len Number of chars to be received.
//=============================================================================
void hal_sci_read(void *__ch_data,
cyg_uint8 *__buf,
cyg_uint32 __len)
{
CYGARC_HAL_SAVE_GP();
//
// Read a number of chars from SCI until __len ist counted down
// to zero
//
while(__len-- > 0)
{
*__buf++ = hal_sci_getc(__ch_data);
}
CYGARC_HAL_RESTORE_GP();
}
//=============================================================================
// READ CHARACTER WITH TIMEOUT
///
/// Reads a character from serial channel with timeout.
///
/// \param __ch_data Pointer to channel configuration data
/// \param ch Stores received character
///
/// \retval TRUE if character was received successfully
//=============================================================================
cyg_bool hal_sci_getc_timeout(void *__ch_data, cyg_uint8 *ch)
{
channel_data_t *chan = (channel_data_t*)__ch_data;
int delay_count;
cyg_bool res;
CYGARC_HAL_SAVE_GP();
delay_count = chan->msec_timeout * 20; // delay in .1 ms steps
//
// Loop until we received a char or until time is over
//
while (1)
{
res = hal_sci_getc_nonblock(__ch_data, ch);
if (res || (0 == delay_count--))
{
break;
}
CYGACC_CALL_IF_DELAY_US(50);
}
CYGARC_HAL_RESTORE_GP();
return res;
}
//=============================================================================
// CONTROL SCI DEVICE
///
/// IOCTL-like function for controlling serial device.
/// Its possible to enable, disable interrupts here, change the baudrate
/// set the timeout value and query the interrup vector
///
/// \param __ch_data Points to channel configuratin data. The following
/// symbolic constants should be used
/// - __COMMCTL_IRQ_ENABLE
/// - __COMMCTL_IRQ_DISABLE
/// - __COMMCTL_DBG_ISR_VECTOR
/// - __COMMCTL_SET_TIMEOUT
/// - __COMMCTL_SETBAUD
/// - __COMMCTL_GETBAUD
/// \param __func I/O control code
///
/// \return Control code dependent value
//=============================================================================
int hal_sci_control(void *__ch_data, __comm_control_cmd_t __func, ...)
{
channel_data_t *chan = (channel_data_t*)__ch_data;
cyg_uint8 scr;
int ret = 0;
CYGARC_HAL_SAVE_GP();
//
// decide what we have to do according to the control command
//
switch (__func)
{
//
// Enable receive interrupts
//
case __COMMCTL_IRQ_ENABLE:
HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
scr |= CYGARC_REG_SCSCR_RIE;
HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
break;
//
// disable receive interrupts
//
case __COMMCTL_IRQ_DISABLE:
HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
scr &= ~CYGARC_REG_SCSCR_RIE;
HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
break;
//
// query isr vector of channel
//
case __COMMCTL_DBG_ISR_VECTOR:
ret = chan->isr_vector;
break;
//
// set new timeout and return the old one
//
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);
}
break;
//
// set new baudrate for comm channel
//
case __COMMCTL_SETBAUD:
{
cyg_uint32 baud_rate;
cyg_uint8 tmp;
va_list ap;
//
// get baud rate from variable argument list
//
va_start(ap, __func);
baud_rate = va_arg(ap, cyg_uint32);
va_end(ap);
//
// disable sci interrupts while changing the hardware
//
HAL_READ_UINT8(chan->base + _REG_SCSCR, scr);
tmp = scr;
tmp = scr & ~(CYGARC_REG_SCSCR_TIE
| CYGARC_REG_SCSCR_RIE
| CYGARC_REG_SCSCR_MPIE
| CYGARC_REG_SCSCR_TEIE);
HAL_WRITE_UINT8(chan->base + _REG_SCSCR, tmp);
//
// Now set new baud rate - we have to set BRR and CKS in SCSMR
//
HAL_READ_UINT8(chan->base + _REG_SCSMR, tmp);
tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
tmp |= CYGARC_SCBRR_CKSx(baud_rate);
HAL_WRITE_UINT8(chan->base + _REG_SCSMR, tmp);
HAL_WRITE_UINT8(chan->base + _REG_SCBRR, CYGARC_SCBRR_N(baud_rate));
//
// now restore old scr register settings before disabling interrupts
//
HAL_WRITE_UINT8(chan->base + _REG_SCSCR, scr);
}
break; // End of case __COMMCTL_SETBAUD:
//
// Query baud rate
//
case __COMMCTL_GETBAUD:
break;
//
//
//
default:
; // do nothing
} // End of switch (__func)
CYGARC_HAL_RESTORE_GP();
return ret;
}
//=============================================================================
// INTERRUPT HANDLER
///
/// Interrupt service routine for serial channel.
/// This interrupt handler, called from the spurious interrupt vector,
/// is specifically for dealing with Ctrl-C interrupts from GDB. When called
/// this function does the following:
/// -# Check for an incoming character. The code here is very similar
/// to that in cyg_hal_plf_sci_getc_nonblock().
/// -# Read the character and call cyg_hal_is_break().
/// -# if result is true, set *__ctrlc to 1.
/// -# Return CYG_ISR_HANDLED.
///
/// \param __ch_data Points to channel configuration data
/// \param __ctrlc Stores CTRL C information
/// \param __vector Interrupt vector number of interrupt wich called this ISR
/// \param __data Interrupt data passed to ISR from kernel
///
/// \retval CYG_ISR_HANDLED
//=============================================================================
int hal_sci_isr(void *__ch_data,
int *__ctrlc,
CYG_ADDRWORD __vector,
CYG_ADDRWORD __data)
{
cyg_uint8 c;
cyg_uint8 sr;
cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
int res = 0;
CYGARC_HAL_SAVE_GP();
*__ctrlc = 0;
HAL_READ_UINT8(base + _REG_SCSSR, sr);
if (sr & CYGARC_REG_SCSSR_ORER)
{
//
// Serial RX overrun. Clear error and hope protocol recovers.
//
HAL_WRITE_UINT8(base+_REG_SCSSR,
CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_ORER);
res = CYG_ISR_HANDLED;
}
else if (sr & CYGARC_REG_SCSSR_RDRF)
{
HAL_READ_UINT8(base+_REG_SCRDR, c); // Received character
HAL_WRITE_UINT8(base+_REG_SCSSR, // Clear buffer full flag.
CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
if(cyg_hal_is_break(&c, 1 ))
{
*__ctrlc = 1;
}
res = CYG_ISR_HANDLED;
}
CYGARC_HAL_RESTORE_GP();
return res;
}
#endif // End of #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
//-----------------------------------------------------------------------------
// end of sci.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -