/* * Copyright (c) 1998 Ralf Corsepius (corsepiu@faw.uni-ulm.de) * * See the file COPYING for copyright notice. */ #include #include #include #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, 57600, 115200, 230400, 460800 }; 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 ; } 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 \n\n" ); fprintf( file, "static struct sci_bitrate_t {\n" " unsigned char n ;\n" " unsigned char N ;\n" "} _sci_bitrates[] = {\n" "/* n N 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 } /* %+7.2f%% ; B%d */", best->n, best->N, best->err, best->B ); } fprintf( file, "\n};\n\n" ); fprintf( file, "int _sci_get_brparms( \n" " tcflag_t cflag,\n" " unsigned char *smr,\n" " unsigned char *brr )\n" "{\n" " unsigned int offset ;\n\n" " offset = ( cflag & ( CBAUD & ~CBAUDEX ) )\n" " + ( ( cflag & CBAUDEX ) ? B38400 : 0 );\n" " if ( offset == 0 ) return -1 ;\n" " offset-- ;\n\n" " *smr &= ~0x03;\n" " *smr |= _sci_bitrates[offset].n;\n" " *brr = _sci_bitrates[offset].N;\n\n" " return 0;\n" "}\n" ); return 0 ; }