/** * \brief ターゲットのシリアル初期化 * \param siopid SIOのポートID * \details * siopidで指定されるターゲットのSIOペリフェラルを初期化する。初期化するのは、ストップビットやビット数といった * プロトコルのほか、ボーレートも含む。この館数は、target_initialize() 関数からも呼び出され、バナー出力用の * ポート初期化に使用される。 * * ボーレートの設定にはUARTへ供給されるクロック周波数の設定が必要であるが、これは全UARTで共通であると * 仮定して決めうちしている。周波数はSIO_UART_CLOCKで指定する。単位はHzである。また、ボーレートは * * SIO_BAUD_RATE_DEFAULTに設定されるが、上書きしたければSIOx_BAUD_RATEを宣言する。単位はBAUDである。 */ void target_uart_init(ID siopid) { uint32_t reg = sioreg_table[SIOPID2INDEX(siopid)]; /* 使用するUARTのベースアドレスを取得 */ /* UARTの無効化 */ uart_write( reg, UART_LCR, 0 ); /* DLAB モードをいったんクリアする */ uart_write( reg, UART_FCR, 0 ); /* FIFO クリア*/ uart_write( reg, UART_IER, 0 ); /* 割り込みをディセーブルにする */ /* ボーレートの設定 */ uart_write( reg, UART_LCR, LCR_DLAB ); /* ディバイザ設定モードに移行 */ switch (siopid) { case 1: #if defined(SIO_BAUD_RATE_PORT1) uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT1/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT1/16)) ); #else uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); #endif break; case 2: #if defined(SIO_BAUD_RATE_PORT2) uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT2/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT2/16)) ); #else uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); #endif break; case 3: #if defined(SIO_BAUD_RATE_PORT3) uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT3/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT3/16)) ); #else uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); #endif break; case 4: #if defined(SIO_BAUD_RATE_PORT4) uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT4/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_PORT4/16)) ); #else uart_write( reg, UART_DLL, DLL((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); uart_write( reg, UART_DLM, DLM((SIO_UART_CLOCK/SIO_BAUD_RATE_DEFAULT/16)) ); #endif break; } /* デバイザ設定モードから、通常モードに戻す */ uart_write( reg, UART_LCR, 0 ); /* 通常モードに移行 */ /* プロトコルを設定。8bit, 1stop bit, parityなし */ uart_write( reg, UART_LCR, LCR_NP_8_1 ); /* 通常モードに移行 */ }
static void uart_init_line(int port, unsigned long baud) { int i, baudconst; switch (baud) { case 115200: baudconst = 1; break; case 57600: baudconst = 2; break; case 38400: baudconst = 3; break; case 19200: baudconst = 6; break; case 9600: default: baudconst = 12; break; } outb(0x87, LCR(port)); outb(0x00, DLM(port)); outb(baudconst, DLL(port)); outb(0x07, LCR(port)); outb(0x0f, MCR(port)); for (i = 10; i > 0; i--) { if (inb(LSR(port)) == (unsigned int) 0) break; inb(RBR(port)); } }
static void fpga_reset(int iobase) { outb(0, IER(iobase)); outb(LCR_DLAB | LCR_BIT5, LCR(iobase)); outb(1, DLL(iobase)); outb(0, DLM(iobase)); outb(LCR_BIT5, LCR(iobase)); inb(LSR(iobase)); inb(MSR(iobase)); /* turn off FPGA supply voltage */ outb(MCR_OUT1 | MCR_OUT2, MCR(iobase)); delay(100); /* turn on FPGA supply voltage again */ outb(MCR_DTR | MCR_RTS | MCR_OUT1 | MCR_OUT2, MCR(iobase)); delay(100); }
static inline void ser12_set_divisor(struct net_device *dev, unsigned char divisor) { outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */ outb(divisor, DLL(dev->base_addr)); outb(0, DLM(dev->base_addr)); outb(0x01, LCR(dev->base_addr)); /* word length = 6 */ /* * make sure the next interrupt is generated; * 0 must be used to power the modem; the modem draws its * power from the TxD line */ outb(0x00, THR(dev->base_addr)); /* * it is important not to set the divider while transmitting; * this reportedly makes some UARTs generating interrupts * in the hundredthousands per second region * Reported by: [email protected] (Ignacio Arenaza Nuno) */ }
static void yam_set_uart(struct net_device *dev) { struct yam_port *yp = netdev_priv(dev); int divisor = 115200 / yp->baudrate; outb(0, IER(dev->base_addr)); outb(LCR_DLAB | LCR_BIT8, LCR(dev->base_addr)); outb(divisor, DLL(dev->base_addr)); outb(0, DLM(dev->base_addr)); outb(LCR_BIT8, LCR(dev->base_addr)); outb(PTT_OFF, MCR(dev->base_addr)); outb(0x00, FCR(dev->base_addr)); /* Flush pending irq */ inb(RBR(dev->base_addr)); inb(MSR(dev->base_addr)); /* Enable rx irq */ outb(ENABLE_RTXINT, IER(dev->base_addr)); }
#error "If you don't use UART, please remove this file from your make file" #endif #if TNUM_SIOP_UART > 3 #error "Only TNUM_SIOP_UART < 4 is supported" #endif /* TNUM_SIOP_UART >= 2 */ /* ディバイザ計算マクロ */ #define DLM(divisor) (divisor/256) #define DLL(divisor) (divisor%256) SIOPINIB siopinib_table[TNUM_SIOP_UART] = { /*----------------------------------------------------------------- * PDICが管理する最初のUARTの初期化パラメータ */ {UART0_ADDRESS, DLM(UART0_DIVISOR), DLL(UART0_DIVISOR), #ifdef UART0_BLACKFIN_UCEN 1 /* マクロUART0_BLACKFIN_UCENが定義されていたら、GCTLのUCENを1にしてクロックを動かす */ #else 0 #endif } /*----------------------------------------------------------------- * PDICが管理する2番目のUARTの初期化パラメータ */ #if TNUM_SIOP_UART > 1 ,{UART1_ADDRESS, DLM(UART1_DIVISOR), DLL(UART1_DIVISOR), #ifdef UART1_BLACKFIN_UCEN 1 /* マクロUART1_BLACKFIN_UCENが定義されていたら、GCTLのUCENを1にしてクロックを動かす */