/*
|
/*
|
* Copyright (c) 1998 Ralf Corsepius (corsepiu@faw.uni-ulm.de)
|
* Copyright (c) 1998 Ralf Corsepius (corsepiu@faw.uni-ulm.de)
|
*
|
*
|
* See the file COPYING for copyright notice.
|
* See the file COPYING for copyright notice.
|
*/
|
*/
|
|
|
#include <math.h>
|
#include <math.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
|
|
#include "sci.h"
|
#include "sci.h"
|
|
|
/*
|
/*
|
n .. baudrate generator source 0,1,2,3
|
n .. baudrate generator source 0,1,2,3
|
|
|
N .. BRR setting (0..255)
|
N .. BRR setting (0..255)
|
|
|
Phi .. processor baud rate
|
Phi .. processor baud rate
|
|
|
B .. bitrate
|
B .. bitrate
|
*/
|
*/
|
|
|
typedef struct sci_tab {
|
typedef struct sci_tab {
|
unsigned int B ;
|
unsigned int B ;
|
unsigned int n ;
|
unsigned int n ;
|
int N ;
|
int N ;
|
double err ;
|
double err ;
|
} sci_tab_t ;
|
} sci_tab_t ;
|
|
|
static unsigned int bitrate [] = {
|
static unsigned int bitrate [] = {
|
50,
|
50,
|
75,
|
75,
|
110,
|
110,
|
134,
|
134,
|
150,
|
150,
|
200,
|
200,
|
300,
|
300,
|
600,
|
600,
|
1200,
|
1200,
|
1800,
|
1800,
|
2400,
|
2400,
|
4800,
|
4800,
|
9600,
|
9600,
|
19200,
|
19200,
|
38400,
|
38400,
|
57600,
|
57600,
|
115200,
|
115200,
|
230400,
|
230400,
|
460800
|
460800
|
};
|
};
|
|
|
static sci_tab_t test_array[4] ;
|
static sci_tab_t test_array[4] ;
|
|
|
static void Compute(
|
static void Compute(
|
unsigned int n,
|
unsigned int n,
|
unsigned int B,
|
unsigned int B,
|
double Phi,
|
double Phi,
|
struct sci_tab *entry )
|
struct sci_tab *entry )
|
{
|
{
|
int a = ( 32 << ( 2 * n ) ) * B ;
|
int a = ( 32 << ( 2 * n ) ) * B ;
|
|
|
entry->n = n ;
|
entry->n = n ;
|
entry->B = B ;
|
entry->B = B ;
|
entry->N = rint( ( Phi / a ) - 1.0 ) ;
|
entry->N = rint( ( Phi / a ) - 1.0 ) ;
|
|
|
if ( ( entry->N > 0 ) && ( entry->N < 256 ) )
|
if ( ( entry->N > 0 ) && ( entry->N < 256 ) )
|
entry->err =
|
entry->err =
|
( ( Phi / ( (entry->N + 1) * a ) - 1.0 ) * 100.0 );
|
( ( Phi / ( (entry->N + 1) * a ) - 1.0 ) * 100.0 );
|
else
|
else
|
{
|
{
|
entry->err = 100.0 ;
|
entry->err = 100.0 ;
|
entry->n = 255 ;
|
entry->n = 255 ;
|
entry->N = 0 ;
|
entry->N = 0 ;
|
}
|
}
|
}
|
}
|
|
|
static sci_tab_t *SelectN(
|
static sci_tab_t *SelectN(
|
unsigned int B,
|
unsigned int B,
|
double Phi )
|
double Phi )
|
{
|
{
|
unsigned int i ;
|
unsigned int i ;
|
struct sci_tab* best = NULL ;
|
struct sci_tab* best = NULL ;
|
|
|
for ( i = 0 ; i < 4 ; i++ )
|
for ( i = 0 ; i < 4 ; i++ )
|
{
|
{
|
double err ;
|
double err ;
|
|
|
Compute( i, B, Phi, &test_array[i] );
|
Compute( i, B, Phi, &test_array[i] );
|
err = fabs( test_array[i].err );
|
err = fabs( test_array[i].err );
|
|
|
if ( best )
|
if ( best )
|
{
|
{
|
if ( err < fabs( best->err ) )
|
if ( err < fabs( best->err ) )
|
best = &test_array[i] ;
|
best = &test_array[i] ;
|
}
|
}
|
else
|
else
|
best = &test_array[i] ;
|
best = &test_array[i] ;
|
}
|
}
|
|
|
return best ;
|
return best ;
|
}
|
}
|
|
|
int shgen_gensci(
|
int shgen_gensci(
|
FILE *file,
|
FILE *file,
|
double Phi ) /* Processor frequency [Hz] */
|
double Phi ) /* Processor frequency [Hz] */
|
{
|
{
|
unsigned int i ;
|
unsigned int i ;
|
|
|
fprintf( file,
|
fprintf( file,
|
"/*\n * Bitrate table for the serial devices (sci) of the SH at %.3f MHz\n"
|
"/*\n * Bitrate table for the serial devices (sci) of the SH at %.3f MHz\n"
|
" */\n\n", Phi / 1000000.0 );
|
" */\n\n", Phi / 1000000.0 );
|
fprintf( file,
|
fprintf( file,
|
"/*\n"
|
"/*\n"
|
" * n .. SMR bits 0,1 : baud rate generator clock source\n"
|
" * n .. SMR bits 0,1 : baud rate generator clock source\n"
|
" * N .. BRR bits 0..7: setting for baud rate generator\n"
|
" * N .. BRR bits 0..7: setting for baud rate generator\n"
|
" * error .. percentual error to nominal bitrate\n"
|
" * error .. percentual error to nominal bitrate\n"
|
" * Hitachi's HW manual recommends bitrates with an error less than 1%%\n"
|
" * Hitachi's HW manual recommends bitrates with an error less than 1%%\n"
|
" * We experienced values less than 2%% to be stable\n"
|
" * We experienced values less than 2%% to be stable\n"
|
" */\n\n" );
|
" */\n\n" );
|
fprintf( file, "#include <termios.h>\n\n" );
|
fprintf( file, "#include <termios.h>\n\n" );
|
fprintf( file,
|
fprintf( file,
|
"static struct sci_bitrate_t {\n"
|
"static struct sci_bitrate_t {\n"
|
" unsigned char n ;\n"
|
" unsigned char n ;\n"
|
" unsigned char N ;\n"
|
" unsigned char N ;\n"
|
"} _sci_bitrates[] = {\n"
|
"} _sci_bitrates[] = {\n"
|
"/* n N error */\n" );
|
"/* n N error */\n" );
|
|
|
for ( i = 0 ; i < sizeof(bitrate)/sizeof(int) ; i++ )
|
for ( i = 0 ; i < sizeof(bitrate)/sizeof(int) ; i++ )
|
{
|
{
|
struct sci_tab* best = SelectN( bitrate[i], Phi );
|
struct sci_tab* best = SelectN( bitrate[i], Phi );
|
|
|
if ( i > 0 )
|
if ( i > 0 )
|
fprintf( file, ",\n" );
|
fprintf( file, ",\n" );
|
fprintf( file, " { %1d, %3d } /* %+7.2f%% ; B%d ",
|
fprintf( file, " { %1d, %3d } /* %+7.2f%% ; B%d ",
|
best->n,
|
best->n,
|
best->N,
|
best->N,
|
best->err,
|
best->err,
|
best->B );
|
best->B );
|
if ( best->n > 3 )
|
if ( best->n > 3 )
|
fprintf( file, "(unusable) " );
|
fprintf( file, "(unusable) " );
|
fprintf( file, "*/" );
|
fprintf( file, "*/" );
|
}
|
}
|
|
|
fprintf( file, "\n};\n\n" );
|
fprintf( file, "\n};\n\n" );
|
|
|
fprintf( file,
|
fprintf( file,
|
"int _sci_get_brparms( \n"
|
"int _sci_get_brparms( \n"
|
" tcflag_t cflag,\n"
|
" tcflag_t cflag,\n"
|
" unsigned char *smr,\n"
|
" unsigned char *smr,\n"
|
" unsigned char *brr )\n"
|
" unsigned char *brr )\n"
|
"{\n"
|
"{\n"
|
" unsigned int offset ;\n\n"
|
" unsigned int offset ;\n\n"
|
" offset = ( cflag & ( CBAUD & ~CBAUDEX ) )\n"
|
" offset = ( cflag & ( CBAUD & ~CBAUDEX ) )\n"
|
" + ( ( cflag & CBAUDEX ) ? B38400 : 0 );\n"
|
" + ( ( cflag & CBAUDEX ) ? B38400 : 0 );\n"
|
" if ( offset == 0 ) return -1 ;\n"
|
" if ( offset == 0 ) return -1 ;\n"
|
" offset-- ;\n\n"
|
" offset-- ;\n\n"
|
" if ( _sci_bitrates[offset].n > 3 ) return -1;\n\n"
|
" if ( _sci_bitrates[offset].n > 3 ) return -1;\n\n"
|
" *smr &= ~0x03;\n"
|
" *smr &= ~0x03;\n"
|
" *smr |= _sci_bitrates[offset].n;\n"
|
" *smr |= _sci_bitrates[offset].n;\n"
|
" *brr = _sci_bitrates[offset].N;\n\n"
|
" *brr = _sci_bitrates[offset].N;\n\n"
|
" return 0;\n"
|
" return 0;\n"
|
"}\n" );
|
"}\n" );
|
|
|
return 0 ;
|
return 0 ;
|
}
|
}
|
|
|