sh-lilo向けのシリアル通信コード

シリアル通信コードを書いてみた。前回7750シリーズのマニュアルって書いたような気がするけど、よく見たら7751シリーズって書いてあった。日記に書くときに間違えた?


それはともかく、マニュアルの15.1.1「特長」によると"調歩同期式モード"、"クロック同期式モード"の2種類通信方式があるっぽい。どっちなんだろう。。。クロック同期式の方が簡易な方式っぽいのでクロック同期式にしておけば動くだろうか。しかし、クロック同期式も15.3「動作説明」を読むと内部クロックと外部クロックの2方式があるっぽい。外部クロックはたぶん誰かからクロックをもらってないと動かないよね。ということは内部クロックが一番安全かなぁ。


15.3.4「クロック同期式モード時の動作」にレジスタ設定値を含んだシーケンスが載っているのでこれを参考にして組んでみる。


初期化コード

 /*
 * fixed setting:
 *  115200bps, 8bits, non parity, non stop bit
 */
static void
setup_sci (void)
{
	int i;

	SCI_SCSCR1_REG = 0x00; /* SCSCR1 TE:0 RE:0 CKE1:0 CKE0:0 */
	SCI_SCSSR1_REG = 0x00; /* SCSSR1 clear */
	SCI_SCSMR1_REG = 0x00; /* SCSMR1 C/A:0 CHR:0 PE:0 STOP:0 MP:0 CKS1:0 CKS0:0 */
	SCI_SCBRR1_REG = 0x00; /* SCBRR1 */
	for(i=0;i<2000;i++){ /* wait for at least one serial clock */
		asm volatile ("nop");
	}
	SCI_SCSCR1_REG = 0x30; /* SCSCR1 TIE:0 RIE:0 TE:1 RE:1 MPIE:0 TEIE:0 */
}

1文字送信コード

static void inline
put_string_1 (unsigned char *str, long len)
{
	long i, internal_timer;

	if(len < 0){
		return;
	}
	if(str == 0){
		return;
	}

	for(i=0;i 100*1024){
				return; /* too long! */
			}
		}
		SCI_SCTDR1_REG = *str++;
		bit_clear(SCI_SCSSR1_REG, SCI_TDRE); /* SCSSR1::TDRE clear */
	}
}


1文字受信コード

static int
serial_input (int timeout)
{
	int err, i, res;

	for(i=0;i


ヘッダかどこかに書く

#define SCI_SCSMR1_REG		(*(volatile unsigned char *volatile)0xFFE00000)
#define SCI_SCBRR1_REG		(*(volatile unsigned char *volatile)0xFFE00004)
#define SCI_SCSCR1_REG		(*(volatile unsigned char *volatile)0xFFE00008)
#define SCI_SCTDR1_REG		(*(volatile unsigned char *volatile)0xFFE0000C)
#define SCI_SCSSR1_REG		(*(volatile unsigned char *volatile)0xFFE00010)
#define SCI_SCRDR1_REG		(*(volatile unsigned char *volatile)0xFFE00014)
#define SCI_SCSPTR1_REG		(*(volatile unsigned char *volatile)0xFFE0001C)
#define SCI_TDRE			(0x80)
#define SCI_RDRF			(0x40)
#define SCI_ORER			(0x20)
#define SCI_FER				(0x10)
#define SCI_PER				(0x08)
#define bit_test(reg, mask)		( (reg)&(mask) )
#define bit_clear(reg, mask)	( (reg)=(reg)&~(mask) )


これであってるのか微妙かも。特にボーレートの設定があやしい。
何か簡単に確認する方法はないかな。
カーネルのシリアル設定部ソースを読むか、実機に何とかして載せるか、それともQEMUってので試しに動かしてみるか。う〜ん。

余力があればマニュアルを見直してみようかな。