[Uclinux-h8-devel] シリアル通信について

Back to archive index

Akira Katsumata a_katsu****@altek*****
2005年 9月 26日 (月) 18:47:07 JST


ひとつのポートを設定によってコンソールとして使ったりデータ送受信したり、
また、pppdによって、無線通信モジュールを38400bpsで通信するため、
sh-sci.cを安定化しました。ttySC1とttySC2はこのメーリングリストを参考に

既存のデバイスドライバの割り込みを、request_irqによる割り込みから、
間接ベクタ(?)を書き換える方法により、若干、性能が上がりました。

static void sci_rx_int1( void ) __attribute__ ((interrupt_handler));
static void sci_rx_int1()
{
 struct sci_port *port = &sci_ports[1];

 if (port->gs.flags & GS_ACTIVE)
  if (!(port->gs.flags & SCI_RX_THROTTLE)) {
   sci_receive_chars(port, NULL);
   return;
  }
 sci_disable_rx_interrupts(port);
}

ttySC0は、38400bpsで通信したいため、DMAによってシリアルデータを取り込み
タイマーによって、DMAのアドレスレジスタを監視し、データを取り込むようにしました。
static unsigned long sci_readp;

static char f_rts = 0;
static void t8_interrupt( void ) __attribute__ ((interrupt_handler));
static void t8_interrupt(/*int irq, void *ptr, struct pt_regs *regs*/)
{
 struct tty_struct *tty;

 outb( inb(_8TCSR0)&~0xe0, _8TCSR0 );
 if( sci_readp != inl( MAR0AR )) {
  outb( inb(_8TCR0)&~0x40, _8TCR0 );
//  while( sci_readp != inl( MAR0AR )) {
   tty = sci_ports[0].gs.tty;
   if( tty ) {
    while( sci_readp != inl( MAR0AR )) {
     if (tty->flip.count < TTY_FLIPBUF_SIZE) {
      *tty->flip.char_buf_ptr++ = *(char *)sci_readp;
      *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
      tty->flip.count++;
      sci_ports[0].icount.rx++;
     } else {
      printk("Check! %06X,%6X,%d\n", inl(MAR0AR),
           sci_readp, tty->flip.count);
     }
     if( tty->flip.count > TTY_FLIPBUF_SIZE-16 ) {
      if( tty->termios->c_cflag & CRTSCTS ) {
       ctrl_outb(ctrl_inb(PADR) | 0x1, PADR);
       f_rts = 1;
      }
     }
     if( ++sci_readp > READ_BUFFER+254 ) {
      sci_readp = READ_BUFFER;
     }
    }
    tty_flip_buffer_push(tty);
   }
  }
  outb( inb(_8TCR0)|0x40, _8TCR0 );
// }
 if( f_rts ) {
  tty = sci_ports[0].gs.tty;
  if( tty ) {
   if( f_rts  && tty->flip.count < TTY_FLIPBUF_SIZE-32 ) {
    ctrl_outb(ctrl_inb(PADR) & ~0x1, PADR);
    f_rts = 0;
   }
  }
 }
}

static void set_dmareg(void)
{
 char c;
 unsigned long *vectadr;

 outl( READ_BUFFER, MAR0AR );
 outb( (unsigned char)RDR0, IOAR0A );
 outb( 0xff, ETCR0AH );
 outb( 0xff, ETCR0AL );
 c = inb(DTCR0A);
 c = inb(DTCR0A);
 outb( 0x95, DTCR0A);
 sci_readp = READ_BUFFER;
#if 0
 if( request_irq( 36,t8_interrupt,SA_INTERRUPT,"t8",NULL )) {
  printk(KERN_ERR "t8: Cannot allocate irq.\n");
 }
#else
 vectadr = (unsigned long *)
  (*(unsigned long *)(36*4) & 0x00ffffff);
 *vectadr = 0x5a000000 | ((unsigned long)t8_interrupt & 0x00ffffff);
#endif
 outb( CONFIG_CLK_FREQ/8192, TCORA0 );
 outb( 0x00, _8TCSR0 );
 outb( 0x40|0x08|0x03, _8TCR0 );

// memset( (char*)READ_BUFFER, 0x55, 0x100 );
}

ttySC1、ttySC2はたいしたことないですけど、ttySC0の高速化は
使えると思いますが・・・
sh-sci.cのバージョンが違ってるので添付します。
ALT3069が定義してあるので、そのあたりです。

ご参考までに・・・(^^ゞ
おかしなところがあったら、教えてください。

P.S. 先日の私のスタックオーバーフロー云々のメールは、この修正でバグってました・・(^^ゞ
お騒がせしました。


Uclinux-h8-devel メーリングリストの案内
Back to archive index