/* * シリアルI/Oポートからの文字受信 */ INT sfruart_rcv_chr(SIOPCB *siopcb) { if(sil_reb_mem((VP)(siopcb->siopinib->cntrl_addr+TADR_SFR_UC1_OFFSET)) & TBIT_UiC1_RI){ return((INT)sil_reb_mem((VP)(siopcb->siopinib->cntrl_addr+TADR_SFR_URB_OFFSET))); } return(-1); }
/* * 受信した文字の取出し */ Inline bool_t scif_getchar(SIOPCB *p_siopcb, char *rxdata) { uint16_t fsrval; uint16_t lsrval; uint8_t read_data; fsrval = sil_reh_mem((uint16_t *)((uint8_t *)p_siopcb->p_siopinib->port + REG_SCFSR)); lsrval = sil_reh_mem((uint16_t *)((uint8_t *)p_siopcb->p_siopinib->port + REG_SCLSR)); if (fsrval & (SCFSR_ER | SCFSR_BRK)) { fsrval = fsrval & ~(SCFSR_ER | SCFSR_BRK); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopcb->p_siopinib->port + REG_SCFSR), fsrval); } if (lsrval & SCLSR_ORER) { lsrval = lsrval & ~SCLSR_ORER; sil_wrh_mem((uint16_t *)((uint8_t *)p_siopcb->p_siopinib->port + REG_SCLSR), lsrval); } if (fsrval & SCFSR_RDF) { read_data = sil_reb_mem((uint8_t *)p_siopcb->p_siopinib->port + REG_SCFRDR); fsrval = fsrval & ~SCFSR_RDF; sil_wrh_mem((uint16_t *)((uint8_t *)p_siopcb->p_siopinib->port + REG_SCFSR), fsrval); *rxdata = (char)read_data; return true; } return false; }
/* * ハードウェアの初期化処理 */ static int scif_init_siopinib(const SIOPINIB *p_siopinib) { uint16_t fsrval; uint8_t brrval; fsrval = UART_CLK / (32 * p_siopinib->bps_setting) - 1; if (fsrval > 255) return 1; brrval = (uint8_t)fsrval; sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCSCR), 0); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFCR), SCFCR_TFRST | SCFCR_RFRST); (void)sil_reh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFSR)); (void)sil_reh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCLSR)); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFSR), 0); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCLSR), 0); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCSCR), SCSCR_INTCLK); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCSMR), SCSMR_CKS1); /* 8N1, P1clock/1 */ sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCEMR), 0); sil_wrb_mem((uint8_t *)p_siopinib->port + REG_SCBRR, brrval); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFCR), SCFCR_RSTRG_15 | SCFCR_RTRG_1 | SCFCR_TTRG_8); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCSCR), SCSCR_TE | SCSCR_RE | SCSCR_INTCLK); while (sil_reh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFSR)) & SCFSR_RDF) { (void)sil_reb_mem((uint8_t *)p_siopinib->port + REG_SCFRDR); sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFSR), ~SCFSR_RDF); } sil_wrh_mem((uint16_t *)((uint8_t *)p_siopinib->port + REG_SCFSR), 0); return 0; }
/* * シリアルI/Oポートからのコールバックの禁止 */ void sh2scif_dis_cbr (SIOPCB * siopcb, UINT cbrtn) { switch (cbrtn) { case SIO_ERDY_SND: /* 送信割り込み要求を禁止 */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR), sil_reb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR)) & ~SCSCR_TIE); break; case SIO_ERDY_RCV: /* 受信割り込み要求を禁止 */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR), sil_reb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR)) & ~SCSCR_RIE); break; } }
void sys_initialize(void) { VB * p; volatile char ps0, pd6; /* * ポートの設定 */ /* ポートP63を TxD0, ポートP62を RxD0 に */ ps0 = sil_reb_mem((VP)TADR_SFR_PS0); ps0 |= 0x08; ps0 &= ~0x04; sil_wrb_mem((VP)TADR_SFR_PS0, ps0); pd6 = sil_reb_mem((VP)TADR_SFR_PD6); pd6 &= ~0x04; pd6 |= 0x08; sil_wrb_mem((VP)TADR_SFR_PD6, pd6); p = (VB*)TADR_SFR_UART0_BASE; /* * UART関連レジスタの設定 */ /* 送受信禁止 */ sil_wrb_mem((VP)(p+TADR_SFR_UC1_OFFSET), 0x00); /* 送受信モードレジスタの初期化 */ sil_wrb_mem((VP)(p+TADR_SFR_UMR_OFFSET), 0x05); /* 送受信モ−ドレジスタ 内部クロック,*/ /* 非同期、8ビット、パリティなし、*/ /* スリープなし */ /* 送信制御レジスタの初期化 */ sil_wrb_mem((VP)(p+TADR_SFR_UC0_OFFSET), 0x10); /* 送受信制御レジスタ0 クロックf8選択 */ /* 転送速度レジスタの初期化 */ sil_wrb_mem((VP)(p+TADR_SFR_UBRG_OFFSET), 48); /* 転送速度レジスタ(38400bps) */ /* 送受信制御レジスタの初期化 */ sil_wrb_mem((VP)(p+TADR_SFR_UC1_OFFSET), (TBIT_UiC1_TE | TBIT_UiC1_RE)); /* 送受信制御レジスタ1 送受信許可 */ /* * LED の初期化 */ sil_wrb_mem((VP)TADR_SFR_P0, 0xff); /* ポート0データ初期化 */ sil_wrb_mem((VP)TADR_SFR_PD0, 0xff); /* ポート0出力設定 */ }
/* * シリアルI/Oポートへの文字送信 */ BOOL sfruart_snd_chr(SIOPCB *siopcb, char c) { if(sil_reb_mem((VP)(siopcb->siopinib->cntrl_addr+TADR_SFR_UC1_OFFSET)) & TBIT_UiC1_TI){ sil_wrb_mem((VP)(siopcb->siopinib->cntrl_addr+TADR_SFR_UTB_OFFSET), c); return(TRUE); } return(FALSE); }
/** * \ingroup SIOSUPPORT * \brief シリアルポート・ペリフェラル読み込み関数 * \param addr UARTペリフェラルのベースアドレス。通常はTHRのアドレスである。 * \param offset ベースアドレスに対する、オフセット値。単位はバイト。 * \return レジスタから読み込んだ値。 * \details * ベースアドレスとオフセットを整数で受け取り、ペリフェラルレジスタに * アクセスする。 */ Inline uint8_t uart_read(uint32_t addr, uint32_t offset) { #ifdef TOPPERS_CHIP_LPC17XX return(sil_reb_mem((void *)(addr + offset))); #else #error "You must define access method for your architecture" #endif }
/* * ターゲットシステム依存の初期化 */ void sys_initialize() { volatile int i; /* LED ポート設定 */ sil_wrb_mem((VP)PMCCT, sil_reb_mem((VP)PMCCT) & (UB)~LED_BIT); sil_wrb_mem((VP)PMCT, sil_reb_mem((VP)PMCT) & (UB)~LED_BIT); sil_wrb_mem((VP)PCT, sil_reb_mem((VP)PCT) | (UB)LED_BIT); /* LED off */ #if 0 /* USBでシリアル通信をするときに、 */ /* TOPPERSロゴを表示するためにwaitを入れる */ for(i=0; i<0x1000000; i++) ; led(1); #endif }
Inline UB uart_read(UW addr, UW offset) { #ifdef UART_IOP_ACCESS return(sil_reb_iop((VP)(addr + offset))); #else return(sil_reb_mem((VP)(addr + offset))); #endif }
/* * uart1からの送信割込み */ void serial_out_handler2(void) { SIOPCB *siopcb = &siopcb_table[1]; if(siopcb->tic > 0 && (sil_reb_mem((VP)(siopcb->siopinib->cntrl+TADR_SFR_UC1_OFFSET)) & TBIT_UiC1_TI)){ /* * 送信可能コールバックルーチンを呼び出す. */ sfruart_ierdy_snd(siopcb->exinf); } }
inline BOOL hw_port_getready(SIOPCB *p) { switch(SIO_TYP(p->flags)) { case SIO_TYP_M32RUART: return (sil_reb_mem((void *)(SIOSTS(p->port)+3)) & 0x4) != 0 ? TRUE : FALSE; } return FALSE; }
/* * シリアルI/Oポートからの文字受信 */ INT sio_rcv_chr(SIOPCB * siopcb) { switch(SIO_TYP(siopcb->flags)) { case SIO_TYP_M32RUART: return sil_reb_mem((void *)(SIORXB(siopcb->port)+3)); } return -1; }
/* * シリアルI/Oポートのオープン */ SIOPCB * sfruart_opn_por(ID siopid, VP_INT exinf) { SIOPCB *siopcb; const SIOPINIB *siopinib; int i; siopcb = get_siopcb(siopid); siopinib = siopcb->siopinib; /* 送受信禁止 */ sil_wrb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_UC1_OFFSET), sil_reb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_UC1_OFFSET))&~(TBIT_UiC1_TE | TBIT_UiC1_RE)); /* ポート設定(動作モード、通信速度) */ sil_wrb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_UMR_OFFSET), siopinib->mr_def); sil_wrb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_UC0_OFFSET), siopinib->c0_def); sil_wrb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_UBRG_OFFSET), siopinib->brg_def); /* * シリアル割込みの設定 */ sil_wrb_mem((VP)(siopinib->tic_addr), TB_LEVEL); sil_wrb_mem((VP)(siopinib->ric_addr), RB_LEVEL); /* オープン時はコールバック禁止 */ sil_wrb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_UC1_OFFSET), siopcb->uc1); /* * ダミーデータ受信 */ sil_reb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_URB_OFFSET)); sil_reb_mem((VP)(siopinib->cntrl_addr+TADR_SFR_URB_OFFSET)); for(i = 0 ; i < SFRUART_COUNT ; i++){ /* オープン時送信READYまで待ち */ if(sil_reb_mem((VP)(siopcb->siopinib->cntrl_addr+TADR_SFR_UC1_OFFSET)) & TBIT_UiC1_TI) break; } siopcb->exinf = exinf; return(siopcb); }
/* * SIO受信エラー割込みサービスルーチン * * SH1内蔵のSCIでは割込み番号がチャネル別に分かれているので、 * SCI0の受信エラー割込み以外でこのルーチンが呼ばれることはない * * エラー処理自体はエラーフラグのクリアのみにとどめている。 * ・オーバーランエラー * ・フレーミングエラー * ・パリティエラー */ void sh1sci2_isr_error(void) { VB ssr1; if (siopcb_table[1].openflag) { ssr1 = sil_reb_mem(SCI_SSR1); /* 1度読み出して */ ssr1 &= ~(SSR_RDRF | SSR_ORER | SSR_FER | SSR_PER); sil_wrb_mem(SCI_SSR1, ssr1); /* エラーフラグクリア */ } }
/* * SIO受信エラー割込みサービスルーチン * * SH1内蔵のSCIでは割込み番号がチャネル別に分かれているので、 * SCI0の受信エラー割込み以外でこのルーチンが呼ばれることはない * * エラー処理自体はエラーフラグのクリアのみにとどめている。 * ・オーバーランエラー * ・フレーミングエラー * ・パリティエラー */ void sh1sci_isr_error(void) { VB ssr0; if (siopcb_table[0].openflag) { ssr0 = sil_reb_mem(SCI_SSR0); /* 1度読み出して */ ssr0 &= ~(SSR_RDRF | SSR_ORER | SSR_FER | SSR_PER); sil_wrb_mem(SCI_SSR0, ssr0); /* エラーフラグクリア */ } }
/* * 受信した文字の取出し */ Inline char sh1sci_getchar(SIOPCB *siopcb) { char data; data = sil_reb_mem(siopcb->inib->base + RDR); /* レシーブデータレジスタフル・フラグのクリア */ sh1_anb_reg(siopcb->inib->base + SSR, (VB)~SSR_RDRF); return data; }
/* * シリアルI/Oポートに対する受信割込み処理 */ Inline void sh2scif_isr_siop_in (SIOPCB * siopcb) { VB scr0 = sil_reb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR)); if ((scr0 & SCSCR_RIE) != 0 && sh2scif_getready (siopcb)) { /* * 受信通知コールバックルーチンを呼び出す. */ sh2scif_ierdy_rcv (siopcb->exinf); } }
/* * 受信した文字の取出し */ Inline char sh2scif_getchar (SIOPCB * siopcb) { VB data; data = sil_reb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCFRDR)); /* レシーブデータレジスタフル・フラグのクリア */ sil_wrh_mem ((VH *) (siopcb->siopinib->reg_base + SCIF_SC1SSR), sil_reh_mem ((VH *) (siopcb->siopinib->reg_base + SCIF_SC1SSR)) & ~SC1SSR_RDRF); return data; }
/* * シリアルI/Oポートに対する受信割込み処理 */ Inline void sh1sci_isr_siop_in(SIOPCB *siopcb) { VB scr = sil_reb_mem(siopcb->inib->base + SCR); if ((scr & SCR_RIE) != 0 && sh1sci_getready(siopcb)) { /* * 受信通知コールバックルーチンを呼び出す. */ sh1sci_ierdy_rcv(siopcb->exinf); } }
/* * シリアルI/Oポートに対する送信割込み処理 */ Inline void sh1sci_isr_siop_out(SIOPCB *siopcb) { VB scr = sil_reb_mem(siopcb->inib->base + SCR); if ((scr & SCR_TIE) != 0 && sh1sci_putready(siopcb)) { /* * 送信通知コールバックルーチンを呼び出す. */ sh1sci_ierdy_snd(siopcb->exinf); } }
/* * シリアルI/Oポートのオープン */ SIOPCB * sh2scif_opn_por (ID siopid, VP_INT exinf) { SIOPCB *siopcb; siopcb = get_siopcb (siopid); /* 送受信停止 */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR), sil_reb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR)) & ~(SCSCR_TE | SCSCR_RE)); /* SCIデータ入出力ポートの設定 */ /* ピンアサイン */ /* sys_initializeで設定 */ /* FIFOの初期化 */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCFCR), (VB) (SCFCR_TFRST | SCFCR_RFRST)); /* 送受信フォーマット */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSMR), 0x00); /* 調歩同期式 */ /* 8ビット、パリティなし */ /* ストップビットレングス:1 */ /* クロックセレクト */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCBRR), (VB) siopcb->siopinib->brr); /* ボーレート設定 */ /* * ボーレートの設定後、1カウント分待たなければならない。 */ sil_dly_nse (sh2scif_DELAY); /* 値はsh1と同じ */ /* FIFOの設定 */ sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCFCR), 0x00); /* エラーフラグをクリア */ sil_wrh_mem ((VH *) (siopcb->siopinib->reg_base + SCIF_SC1SSR), sil_reh_mem ((VH *) (siopcb->siopinib->reg_base + SCIF_SC1SSR)) & ~SC1SSR_ER); sil_wrb_mem ((VB *) (siopcb->siopinib->reg_base + SCIF_SCSCR), (VB) (SCSCR_RIE | SCSCR_TE | SCSCR_RE)); siopcb->exinf = exinf; siopcb->openflag = TRUE; return (siopcb); }
/* * シリアルI/Oポートのオープン */ SIOPCB * sfruart_opn_por(ID siopid, VP_INT exinf) { SIOPCB *siopcb; const SIOPINIB *siopinib; int i; siopcb = get_siopcb(siopid); siopinib = siopcb->siopinib; sil_wrb_mem((VP)(siopinib->cntrl+TADR_SFR_UMR_OFFSET), siopinib->mr_def); sil_wrb_mem((VP)(siopinib->cntrl+TADR_SFR_UC0_OFFSET), siopinib->c0_def); sil_wrb_mem((VP)(siopinib->cntrl+TADR_SFR_UBRG_OFFSET), siopinib->brg_def); /* * シリアル割込みの設定 */ set_ic_ilvl((VP)(siopinib->hint+TADR_SFR_S0TIC_OFFSET), siopcb->tic); set_ic_ilvl((VP)(siopinib->hint+TADR_SFR_S0RIC_OFFSET), RB_LEVEL); siopcb->cr1 = TBIT_UiC1_TE; sil_wrb_mem((VP)(siopinib->cntrl+TADR_SFR_UC1_OFFSET), siopcb->cr1); /* * ダミーデータ受信 */ sil_reb_mem((VP)(siopinib->cntrl+TADR_SFR_URB_OFFSET)); sil_reb_mem((VP)(siopinib->cntrl+TADR_SFR_URB_OFFSET)); for(i = 0 ; i < SFRUART_COUNT ; i++){ /* オープン時送信READYまで待ち */ if(sil_reb_mem((VP)(siopcb->siopinib->cntrl+TADR_SFR_UC1_OFFSET)) & TBIT_UiC1_TI) break; } siopcb->exinf = exinf; return(siopcb); }
/* * 文字を送信できるか? */ Inline BOOL sh1sci_putready(SIOPCB *siopcb) { VB ssr = sil_reb_mem(siopcb->inib->base + SSR); return(ssr & SSR_TDRE); }