h8s_sci.c File Reference


Detailed Description

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.

Definition in file h8s_sci.c.

Go to the source code of this file.

Functions

void hal_sci_init_channel (void *chan)
 Initializes one SCI channel.

cyg_bool hal_sci_getc_nonblock (void *__ch_data, cyg_uint8 *ch)
 Checks if character is available for reception.

cyg_uint8 hal_sci_getc (void *__ch_data)
 Polls the device until reception of a character.

void hal_sci_putc (void *__ch_data, cyg_uint8 c)
 Send a character to the sci device.

void hal_sci_write (void *__ch_data, const cyg_uint8 *__buf, cyg_uint32 __len)
 Send content of buffer through serial channel.

void hal_sci_read (void *__ch_data, cyg_uint8 *__buf, cyg_uint32 __len)
 Read a number of chars from serial channel.

cyg_bool hal_sci_getc_timeout (void *__ch_data, cyg_uint8 *ch)
 Reads a character from serial channel with timeout.

int hal_sci_control (void *__ch_data, __comm_control_cmd_t __func,...)
 IOCTL-like function for controlling serial device.

int hal_sci_isr (void *__ch_data, int *__ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
 Interrupt service routine for serial channel.


Function Documentation

int hal_sci_control void *  __ch_data,
__comm_control_cmd_t  __func,
... 
 

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

Parameters:
__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
__func I/O control code
Returns:
Control code dependent value

Definition at line 356 of file h8s_sci.c.

References channel_data_t::base, channel_data_t::isr_vector, and channel_data_t::msec_timeout.

Referenced by hal_console_comm_init().

00357 {
00358     channel_data_t *chan      = (channel_data_t*)__ch_data;
00359     cyg_uint8       scr;
00360     int             ret       = 0;
00361     
00362     
00363     CYGARC_HAL_SAVE_GP();
00364     //
00365     // decide what we have to do according to the control command
00366     //
00367     switch (__func) 
00368     {
00369         //
00370         // Enable receive interrupts
00371         //
00372         case __COMMCTL_IRQ_ENABLE:
00373              HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
00374              scr |= CYGARC_REG_SCSCR_RIE;
00375              HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
00376              break;
00377         //
00378         // disable receive interrupts
00379         //
00380         case __COMMCTL_IRQ_DISABLE:
00381              HAL_READ_UINT8(chan->base+_REG_SCSCR, scr);
00382              scr &= ~CYGARC_REG_SCSCR_RIE;
00383              HAL_WRITE_UINT8(chan->base+_REG_SCSCR, scr);
00384              break;
00385         //
00386         // query isr vector of channel
00387         //
00388         case __COMMCTL_DBG_ISR_VECTOR:
00389              ret = chan->isr_vector;
00390              break;
00391         //
00392         // set new timeout and return the old one
00393         //
00394         case __COMMCTL_SET_TIMEOUT:
00395              {
00396                  va_list ap;
00397 
00398                  va_start(ap, __func);
00399 
00400                  ret = chan->msec_timeout;
00401                  chan->msec_timeout = va_arg(ap, cyg_uint32);
00402 
00403                  va_end(ap);
00404              } 
00405              break;
00406         //
00407         // set new baudrate for comm channel
00408         // 
00409         case __COMMCTL_SETBAUD:
00410              {
00411                 cyg_uint32 baud_rate;
00412                 cyg_uint8  tmp;
00413                 va_list    ap;
00414                 //
00415                 // get baud rate from variable argument list
00416                 //
00417                 va_start(ap, __func);
00418                 baud_rate = va_arg(ap, cyg_uint32);
00419                 va_end(ap);
00420                 //
00421                 // disable sci interrupts while changing the hardware
00422                 //
00423                 HAL_READ_UINT8(chan->base + _REG_SCSCR, scr);
00424                 tmp = scr;
00425                 tmp = scr & ~(CYGARC_REG_SCSCR_TIE 
00426                             | CYGARC_REG_SCSCR_RIE
00427                             | CYGARC_REG_SCSCR_MPIE
00428                             | CYGARC_REG_SCSCR_TEIE);
00429                 HAL_WRITE_UINT8(chan->base + _REG_SCSCR, tmp);
00430                 //
00431                 // Now set new baud rate - we have to set BRR and CKS in SCSMR
00432                 //
00433                 HAL_READ_UINT8(chan->base + _REG_SCSMR, tmp);                          
00434                 tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
00435                 tmp |= CYGARC_SCBRR_CKSx(baud_rate);
00436                 HAL_WRITE_UINT8(chan->base + _REG_SCSMR, tmp);
00437                 HAL_WRITE_UINT8(chan->base + _REG_SCBRR, CYGARC_SCBRR_N(baud_rate));
00438                 //
00439                 // now restore old scr register settings before disabling interrupts
00440                 //
00441                 HAL_WRITE_UINT8(chan->base + _REG_SCSCR, scr);
00442              } 
00443              break; // End of case __COMMCTL_SETBAUD: 
00444         //
00445         // Query baud rate
00446         //
00447         case __COMMCTL_GETBAUD:
00448              break; 
00449         //
00450         //
00451         //  
00452         default:
00453              ; // do nothing
00454     } // End of switch (__func) 
00455 
00456     CYGARC_HAL_RESTORE_GP();
00457     return ret;
00458 }

cyg_uint8 hal_sci_getc void *  __ch_data  ) 
 

Polls the device until reception of a character.

Parameters:
__ch_data Pointer to channel configuration buffer
Returns:
Received character

Definition at line 176 of file h8s_sci.c.

References hal_sci_getc_nonblock().

Referenced by hal_console_comm_init(), hal_diag_read_char(), and hal_sci_read().

00177 {
00178     cyg_uint8 ch;
00179     CYGARC_HAL_SAVE_GP();
00180 
00181     while(!hal_sci_getc_nonblock(__ch_data, &ch))
00182     {
00183         // do nothing
00184     }
00185 
00186     CYGARC_HAL_RESTORE_GP();
00187     return ch;
00188 }

Here is the call graph for this function:

cyg_bool hal_sci_getc_nonblock void *  __ch_data,
cyg_uint8 *  ch
[static]
 

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

Parameters:
__ch_data Points to buffer with configuration data
ch Stores received character
Return values:
TRUE if a character received sucessfully

Definition at line 133 of file h8s_sci.c.

Referenced by hal_sci_getc(), and hal_sci_getc_timeout().

00134 {
00135     cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
00136     cyg_uint8  sr;
00137 
00138     HAL_READ_UINT8(base+ _REG_SCSSR, sr);
00139     //
00140     // check if we have an RX overrun
00141     //
00142     if (sr & CYGARC_REG_SCSSR_ORER) 
00143     {
00144         //
00145         // Serial RX overrun. Clear error and let caller try again.
00146         //
00147         HAL_WRITE_UINT8(base + _REG_SCSSR, 
00148                         CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_ORER);
00149         return false;
00150     }
00151     //
00152     // if no char arrived leave immediatelly with false
00153     //
00154     if ((sr & CYGARC_REG_SCSSR_RDRF) == 0)
00155     {
00156         return false;
00157     }
00158     //
00159     // read the received char and clear buffer full flag
00160     //
00161     HAL_READ_UINT8(base+_REG_SCRDR, *ch);
00162     HAL_WRITE_UINT8(base+_REG_SCSSR, sr & ~CYGARC_REG_SCSSR_RDRF);     // Clear buffer full flag
00163 
00164     return true;
00165 }

cyg_bool hal_sci_getc_timeout void *  __ch_data,
cyg_uint8 *  ch
 

Reads a character from serial channel with timeout.

Parameters:
__ch_data Pointer to channel configuration data
ch Stores received character
Return values:
TRUE if character was received successfully

Definition at line 308 of file h8s_sci.c.

References hal_sci_getc_nonblock(), and channel_data_t::msec_timeout.

Referenced by hal_console_comm_init().

00309 {
00310     channel_data_t *chan = (channel_data_t*)__ch_data;
00311     int            delay_count;
00312     cyg_bool       res;
00313 
00314 
00315     CYGARC_HAL_SAVE_GP();
00316 
00317     delay_count = chan->msec_timeout * 20; // delay in .1 ms steps 
00318     //
00319     // Loop until we received a char or until time is over
00320     //
00321     while (1)
00322     {
00323         res = hal_sci_getc_nonblock(__ch_data, ch);
00324         if (res || (0 == delay_count--))
00325         {
00326             break;
00327         }
00328         
00329         CYGACC_CALL_IF_DELAY_US(50);
00330     }
00331 
00332     CYGARC_HAL_RESTORE_GP();
00333     return res;
00334 }

Here is the call graph for this function:

void hal_sci_init_channel void *  chan  ) 
 

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.

Parameters:
chan Pointer to a channel_data_t type

Definition at line 101 of file h8s_sci.c.

Referenced by hal_console_comm_init(), and hal_diag_init().

00102 {
00103     cyg_uint8  tmp;
00104     cyg_uint8 *base = ((channel_data_t *)chan)->base;
00105 
00106     //
00107     // Disable Tx/Rx interrupts, but enable Tx/Rx. Set 8-1-no parity an
00108     // Set speed to value stored in chan->baud_rate
00109     //
00110     HAL_WRITE_UINT8(base + _REG_SCSCR, CYGARC_REG_SCSCR_TE | CYGARC_REG_SCSCR_RE);
00111     HAL_WRITE_UINT8(base + _REG_SCSMR, 0);                           // 8-1-no parity.
00112     HAL_READ_UINT8(base + _REG_SCSMR, tmp);                          // now set baud rate
00113     tmp &= ~CYGARC_REG_SCSMR_CKSx_MASK;
00114     tmp |= CYGARC_SCBRR_CKSx(((channel_data_t *)chan)->baud_rate);
00115     HAL_WRITE_UINT8(base + _REG_SCSMR, tmp);
00116     HAL_WRITE_UINT8(base + _REG_SCBRR, CYGARC_SCBRR_N(((channel_data_t *)chan)->baud_rate));   
00117 }

int hal_sci_isr void *  __ch_data,
int *  __ctrlc,
CYG_ADDRWORD  __vector,
CYG_ADDRWORD  __data
 

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:

  1. Check for an incoming character. The code here is very similar to that in cyg_hal_plf_sci_getc_nonblock().
  2. Read the character and call cyg_hal_is_break().
  3. if result is true, set *__ctrlc to 1.
  4. Return CYG_ISR_HANDLED.

Parameters:
__ch_data Points to channel configuration data
__ctrlc Stores CTRL C information
__vector Interrupt vector number of interrupt wich called this ISR
__data Interrupt data passed to ISR from kernel
Return values:
CYG_ISR_HANDLED 

Definition at line 481 of file h8s_sci.c.

References CYG_ISR_HANDLED.

Referenced by hal_console_comm_init().

00485 {
00486     cyg_uint8  c; 
00487     cyg_uint8  sr;
00488     cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
00489     int        res  = 0;
00490 
00491 
00492     CYGARC_HAL_SAVE_GP();
00493 
00494     *__ctrlc = 0;
00495     HAL_READ_UINT8(base + _REG_SCSSR, sr);
00496     if (sr & CYGARC_REG_SCSSR_ORER) 
00497     {
00498         //
00499         // Serial RX overrun. Clear error and hope protocol recovers.
00500         //
00501         HAL_WRITE_UINT8(base+_REG_SCSSR, 
00502                         CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_ORER);
00503         res = CYG_ISR_HANDLED;
00504     } 
00505     else if (sr & CYGARC_REG_SCSSR_RDRF) 
00506     {
00507         
00508         HAL_READ_UINT8(base+_REG_SCRDR, c);     // Received character
00509         HAL_WRITE_UINT8(base+_REG_SCSSR,        // Clear buffer full flag.
00510                         CYGARC_REG_SCSSR_CLEARMASK & ~CYGARC_REG_SCSSR_RDRF);
00511 
00512         if(cyg_hal_is_break(&c, 1 ))
00513         {
00514             *__ctrlc = 1;
00515         }
00516 
00517         res = CYG_ISR_HANDLED;
00518     }
00519 
00520     CYGARC_HAL_RESTORE_GP();
00521     return res;
00522 }

void hal_sci_putc void *  __ch_data,
cyg_uint8  c
 

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

Parameters:
__ch_data Points to buffer holding channel configuration data
c Character to be send

Definition at line 203 of file h8s_sci.c.

Referenced by hal_console_comm_init(), hal_diag_write_char(), and hal_sci_write().

00204 {
00205     cyg_uint8 *base = ((channel_data_t*)__ch_data)->base;
00206     cyg_uint8  sr;
00207 
00208 
00209     CYGARC_HAL_SAVE_GP();
00210     //
00211     // wait until send register is empty
00212     //
00213     do 
00214     {
00215         HAL_READ_UINT8(base + _REG_SCSSR, sr);
00216     } 
00217     while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
00218     //
00219     // Write char into send register and clear the empty flag
00220     //
00221     HAL_WRITE_UINT8(base + _REG_SCTDR, c);
00222     HAL_WRITE_UINT8(base + _REG_SCSSR, sr & ~CYGARC_REG_SCSSR_TDRE); // Clear empty flag.
00223     //
00224     // Hang around until the character has been safely sent.
00225     //
00226     do 
00227     {
00228         HAL_READ_UINT8(base + _REG_SCSSR, sr);
00229     } 
00230     while ((sr & CYGARC_REG_SCSSR_TDRE) == 0);
00231 
00232     CYGARC_HAL_RESTORE_GP();
00233 }

void hal_sci_read void *  __ch_data,
cyg_uint8 *  __buf,
cyg_uint32  __len
 

Read a number of chars from serial channel.

Reads __len number of charaters from serail channel and stores them into the buffer __buf.

Parameters:
__ch_data Pointer to channel configuration data
__buf Receive buffer
__len Number of chars to be received.

Definition at line 280 of file h8s_sci.c.

References hal_sci_getc().

Referenced by hal_console_comm_init().

00283 {
00284     CYGARC_HAL_SAVE_GP();
00285     //
00286     // Read a number of chars from SCI until __len ist counted down
00287     // to zero
00288     //
00289     while(__len-- > 0)
00290     {
00291         *__buf++ = hal_sci_getc(__ch_data);
00292     }
00293 
00294     CYGARC_HAL_RESTORE_GP();
00295 }

Here is the call graph for this function:

void hal_sci_write void *  __ch_data,
const cyg_uint8 *  __buf,
cyg_uint32  __len
 

Send content of buffer through serial channel.

Sends __len characters to device taken from buffer __buf.

Parameters:
__ch_data Pointer to a channel_data_t
__buf Buffer containing the data to be sent
__len Length of data to be send

Definition at line 251 of file h8s_sci.c.

References hal_sci_putc().

Referenced by hal_console_comm_init().

00254 {
00255     CYGARC_HAL_SAVE_GP();
00256     //
00257     // Send buffer until detection of terminating zero
00258     //
00259     while(__len-- > 0)
00260     {
00261         hal_sci_putc(__ch_data, *__buf++);
00262     }
00263 
00264     CYGARC_HAL_RESTORE_GP();
00265 }

Here is the call graph for this function:


Generated on Tue Feb 17 09:06:13 2004 for eCos EDOSK-2674 HAL by doxygen 1.3.5