summaryrefslogblamecommitdiffstats
path: root/tools/cpu/sh/sci.c
blob: 2b68612f2c9ba8893a4a813fa436773aeef6778e (plain) (tree)












































                                                              


        
        
        

         

         





































































                                                                                
                                        




                                              
                           
                             
                                          






                                                       
                                                             

              
              










                                     
                             


                              








                                                                               








                                                          
/*
 * Copyright (c) 1998 Ralf Corsepius (corsepiu@faw.uni-ulm.de)
 *
 * See the file COPYING for copyright notice.
 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "sci.h"

/*
   n .. baudrate generator source 0,1,2,3

   N .. BRR setting (0..255)

   Phi .. processor baud rate

   B .. bitrate
 */

typedef struct sci_tab {
  unsigned int  B ;
  unsigned int  n ;
  int 		N ;
  double        err ;
  } sci_tab_t ;

static unsigned int bitrate [] = {
  50,
  75,
  110,
  134,
  150,
  200,
  300,
  600,
  1200,
  1800,
  2400,
  4800,
  9600,
  19200,
  38400,
  7200,
  14400,
  28800,
  57600,
  76800,
  115200,
  230400,
  460800,
  921600
};

static sci_tab_t test_array[4] ;

static void Compute(
  unsigned int n,
  unsigned int B,
  double   Phi,
  struct sci_tab *entry )
{
  int    a = ( 32 << ( 2 * n ) ) * B ;

  entry->n = n ;
  entry->B = B ;
  entry->N = rint( ( Phi / a ) - 1.0 ) ;

  if ( ( entry->N > 0 ) && ( entry->N < 256 ) )
    entry->err =
      ( ( Phi / ( (entry->N + 1) * a ) - 1.0 ) * 100.0 );
  else
  {
    entry->err = 100.0 ;
    entry->n = 255 ;
    entry->N = 0 ;
  }
}

static sci_tab_t *SelectN(
  unsigned int 	B,
  double 	Phi )
{
  unsigned int i ;
  struct sci_tab* best = NULL ;

  for ( i = 0 ; i < 4 ; i++ )
  {
    double err ;

    Compute( i, B, Phi, &test_array[i] );
    err = fabs( test_array[i].err );

    if ( best )
    {
      if ( err < fabs( best->err ) )
        best = &test_array[i] ;
    }
    else
      best = &test_array[i] ;
  }

  return best ;
}

int shgen_gensci(
  FILE		*file,
  double	Phi ) /* Processor frequency [Hz] */
{
  unsigned int i ;

  fprintf( file,
    "/*\n * Bitrate table for the serial devices (sci) of the SH at %.3f MHz\n"
    " */\n\n", Phi / 1000000.0 );
  fprintf( file,
    "/*\n"
    " * n     .. SMR bits 0,1 : baud rate generator clock source\n"
    " * N     .. BRR bits 0..7: setting for baud rate generator\n"
    " * error .. percentual error to nominal bitrate\n"
    " *   Hitachi's HW manual recommends bitrates with an error less than 1%%\n"
    " *   We experienced values less than 2%% to be stable\n"
    " */\n\n" );
  fprintf( file, "#include <bsp.h>\n" );
  fprintf( file, "#include <termios.h>\n\n" );
  fprintf( file,
    "static struct sci_bitrate_t {\n"
    "  unsigned char n ;\n"
    "  unsigned char N ;\n"
    "  speed_t       B ;\n"
    "} _sci_bitrates[] = {\n"
    "/*  n    N      B      error */\n" );

  for ( i = 0 ; i < sizeof(bitrate)/sizeof(int) ; i++ )
  {
    struct sci_tab* best = SelectN( bitrate[i], Phi );

    if ( i > 0 )
      fprintf( file, ",\n" );
      fprintf( file, "  { %1d, %3d, %d } /* %+7.2f%% ; B%d ",
      best->n,
      best->N,
      best->B,
      best->err,
      best->B );
    if ( best->n > 3 )
      fprintf( file, "(unusable) " );
    fprintf( file, "*/" );
  }

  fprintf( file, "\n};\n\n" );

  fprintf( file,
    "int _sci_get_brparms( \n"
    "  speed_t        spd,\n"
    "  unsigned char *smr,\n"
    "  unsigned char *brr )\n"
    "{\n"
    "  int offset = -1;\n"
    "  int i;\n\n"
    "  for(i = 0; i < sizeof(_sci_bitrates)/sizeof(_sci_bitrates[0]); i++) {\n"
    "    if( _sci_bitrates[i].B == spd ) {\n"
    "      offset = i;\n"
    "      break;\n"
    "    }\n"
    "  }\n"
    "  if ( offset == -1 ) return -1 ;\n"
    "  if ( _sci_bitrates[offset].n > 3 )  return -1;\n\n"
    "  *smr &= ~0x03;\n"
    "  *smr |= _sci_bitrates[offset].n;\n"
    "  *brr =  _sci_bitrates[offset].N;\n\n"
    "  return 0;\n"
    "}\n" );

  return 0 ;
}