📄 h8s_sci.c
字号:
//=============================================================================
//
// h8s_sci.c
//
// Simple driver for the H8S Serial Communication Interface (SCI)
// for diagnostic serial communication.
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): ysato
// Contributors:ysato, Uwe Kindler
// Date: 2003-12-06
// Description: Simple driver for the H8S Serial Communication Interface. The
// SCI is the same for all H8S variants so we define this here in
// architecture hal
//
//####DESCRIPTIONEND####
//
//=============================================================================
//=============================================================================
// DOXYGEN FILE HEADER
/// \file h8s_sci.c
/// \brief Simple driver for the H8S Serial Communication Interface.
/// \author Yoshinori Sato, Uwe Kindler
/// \date 2003-12-06
///
/// The SCI is the same for all H8S variants so we place it into
/// architecture hal.
//=============================================================================
//=============================================================================
// INCLUDES
//=============================================================================
#include <pkgconf/hal.h>
#include <cyg/hal/hal_io.h> // IO macros
#include <cyg/hal/hal_misc.h> // Helper functions
#include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP
#include <cyg/hal/hal_if.h> // Calling-if API
#include <cyg/hal/mod_regs_sci.h> // serial register definitions
#include <cyg/hal/h8s_sci.h> // our header
//
// if the kernel is present then also the kernel API have to be present
// in order to use driver api
//
#if !defined(CYGPKG_KERNEL) || defined(CYGFUN_KERNEL_API_C)
#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
#endif
//=============================================================================
// INITIALIZE SCI CHANNEL
///
/// Initializes one SCI channel.
/// The parameter is actually a pointer to a channel_data_t and should be
/// cast back to this type before use. This function should use the CDL
/// definition for the baud rate for the channel it is initializing.
///
/// \param chan Pointer to a channel_data_t type
//=============================================================================
void hal_sci_init_channel(void* chan)
{
cyg_uint8 tmp;
cyg_uint8 *base = ((channel_data_t *)chan)->base;
//
// Disable Tx/Rx interrupts, but enable Tx/Rx. Set 8-1-no parity an
// Set speed to value stored in chan->baud_rate
//
HAL_WRITE_UINT8(base + _REG_SCSCR, CYGARC_REG_SCSCR_TE | CYGARC_REG_SCSCR_RE);
HAL_WRITE_UINT8(base + _REG_SCSMR, 0); // 8-1-no parity.
HAL_READ_UINT8(base + _REG_SCSMR, tmp); // now set baud rate
tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
tmp |= CYGARC_SCBRR_CKSx(((channel_data_t *)chan)->baud_rate);
HAL_WRITE_UINT8(base + _REG_SCSMR, tmp);
HAL_WRITE_UINT8(base + _REG_SCBRR, CYGARC_SCBRR_N(((channel_data_t *)chan)->baud_rate));
}
//=============================================================================
// READ CHARACTER NONBLOCKED
//
/// Checks if character is available for reception.
/// This function tests the device and if a character is available, places
/// it in *ch and returns TRUE. If no character is available, then the
/// function returns FALSE immediately
///
/// \param __ch_data Points to buffer with configuration data
/// \param ch Stores received character
///
/// \retval TRUE if a character received sucessfully
//=============================================================================
static cyg_bool hal_sci_getc_nonblock(void* __ch_data, cyg_uint8* ch)
{
cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
cyg_uint8 sr;
HAL_READ_UINT8(base+ _REG_SCSSR, sr);
//
// check if we have an RX overrun
//
if (sr & CYGARC_REG_SCSSR_ORER)
{
//
// Serial RX overrun. Clear error and let caller try again.
//
HAL_WRITE_UINT8(base + _REG_SCSSR,
CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_ORER);
return false;
}
//
// if no char arrived leave immediatelly with false
//
if ((sr & CYGARC_REG_SCSSR_RDRF) == 0)
{
return false;
}
//
// read the received char and clear buffer full flag
//
HAL_READ_UINT8(base+_REG_SCRDR, *ch);
HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_RDRF); // Clear buffer full flag
return true;
}
//=============================================================================
// POLL FOR CHARACTER
///
/// Polls the device until reception of a character
///
/// \param __ch_data Pointer to channel configuration buffer
/// \return Received character
//=============================================================================
cyg_uint8 hal_sci_getc(void *__ch_data)
{
cyg_uint8 ch;
CYGARC_HAL_SAVE_GP();
while(!hal_sci_getc_nonblock(__ch_data, &ch))
{
// do nothing
}
CYGARC_HAL_RESTORE_GP();
return ch;
}
//=============================================================================
// WRITE CHARACTER
///
/// Send a character to the sci device.
/// This function polls for the device being ready to send and then writes
/// the character. Since this is intended to be a diagnostic/debug channel,
/// it is polled for end of transmission too. This ensures that as much data
/// gets out of the system as possible
///
/// \param __ch_data Points to buffer holding channel configuration data
/// \param c Character to be send
//=============================================================================
void hal_sci_putc(void *__ch_data, cyg_uint8 c)
{
cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
cyg_uint8 sr;
CYGARC_HAL_SAVE_GP();
//
// wait until send register is empty
//
do
{
HAL_READ_UINT8(base + _REG_SCSSR, sr);
}
while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
//
// Write char into send register and clear the empty flag
//
HAL_WRITE_UINT8(base + _REG_SCTDR, c);
HAL_WRITE_UINT8(base + _REG_SCSSR, sr & ~CYGARC_REG_SCSSR_TDRE); // Clear empty flag.
//
// Hang around until the character has been safely sent.
//
do
{
HAL_READ_UINT8(base + _REG_SCSSR, sr);
}
while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
CYGARC_HAL_RESTORE_GP();
}
//
// If we use virtual vector table then we have to define some additional
// functions for the COMM tables within the virtual vector table
//
#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
//=============================================================================
// WRITE BUFFER OF CHARACTERS
///
/// Send content of buffer through serial channel.
/// Sends __len characters to device taken from buffer __buf.
///
/// \param __ch_data Pointer to a channel_data_t
/// \param __buf Buffer containing the data to be sent
/// \param __len Length of data to be send
//=============================================================================
void hal_sci_write(void *__ch_data,
const cyg_uint8 *__buf,
cyg_uint32 __len)
{
CYGARC_HAL_SAVE_GP();
//
// Send buffer until detection of terminating zero
//
while(__len-- > 0)
{
hal_sci_putc(__ch_data, *__buf++);
}
CYGARC_HAL_RESTORE_GP();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -