📄 upd72001.c
字号:
/*
* TOPPERS/JSP Kernel
* Toyohashi Open Platform for Embedded Real-Time Systems/
* Just Standard Profile Kernel
*
* Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
* Toyohashi Univ. of Technology, JAPAN
*
* 忋婰挊嶌尃幰偼丆埲壓偺 (1)乣(4) 偺忦審偐丆Free Software Foundation
* 偵傛偭偰岞昞偝傟偰偄傞 GNU General Public License 偺 Version 2 偵婰
* 弎偝傟偰偄傞忦審傪枮偨偡応崌偵尷傝丆杮僜僼僩僂僃傾乮杮僜僼僩僂僃傾
* 傪夵曄偟偨傕偺傪娷傓丏埲壓摨偠乯傪巊梡丒暋惢丒夵曄丒嵞攝晍乮埲壓丆
* 棙梡偲屇傇乯偡傞偙偲傪柍彏偱嫋戻偡傞丏
* (1) 杮僜僼僩僂僃傾傪僜乕僗僐乕僪偺宍偱棙梡偡傞応崌偵偼丆忋婰偺挊嶌
* 尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕偑丆偦偺傑傑偺宍偱僜乕
* 僗僐乕僪拞偵娷傑傟偰偄傞偙偲丏
* (2) 杮僜僼僩僂僃傾傪丆儔僀僽儔儕宍幃側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒傞宍偱嵞攝晍偡傞応崌偵偼丆嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡
* 幰儅僯儏傾儖側偳乯偵丆忋婰偺挊嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰
* 偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (3) 杮僜僼僩僂僃傾傪丆婡婍偵慻傒崬傓側偳丆懠偺僜僼僩僂僃傾奐敪偵巊
* 梡偱偒側偄宍偱嵞攝晍偡傞応崌偵偼丆師偺偄偢傟偐偺忦審傪枮偨偡偙
* 偲丏
* (a) 嵞攝晍偵敽偆僪僉儏儊儞僩乮棙梡幰儅僯儏傾儖側偳乯偵丆忋婰偺挊
* 嶌尃昞帵丆偙偺棙梡忦審偍傛傃壓婰偺柍曐徹婯掕傪宖嵹偡傞偙偲丏
* (b) 嵞攝晍偺宍懺傪丆暿偵掕傔傞曽朄偵傛偭偰丆TOPPERS僾儘僕僃僋僩偵
* 曬崘偡傞偙偲丏
* (4) 杮僜僼僩僂僃傾偺棙梡偵傛傝捈愙揑傑偨偼娫愙揑偵惗偠傞偄偐側傞懝
* 奞偐傜傕丆忋婰挊嶌尃幰偍傛傃TOPPERS僾儘僕僃僋僩傪柶愑偡傞偙偲丏
*
* 杮僜僼僩僂僃傾偼丆柍曐徹偱採嫙偝傟偰偄傞傕偺偱偁傞丏忋婰挊嶌尃幰偍
* 傛傃TOPPERS僾儘僕僃僋僩偼丆杮僜僼僩僂僃傾偵娭偟偰丆偦偺揔梡壜擻惈傕
* 娷傔偰丆偄偐側傞曐徹傕峴傢側偄丏傑偨丆杮僜僼僩僂僃傾偺棙梡偵傛傝捈
* 愙揑傑偨偼娫愙揑偵惗偠偨偄偐側傞懝奞偵娭偟偰傕丆偦偺愑擟傪晧傢側偄丏
*
* @(#) $Id: upd72001.c,v 1.1 2003/06/04 05:41:58 hiro Exp $
*/
/*
* 兪PD72001梡 娙堈SIO僪儔僀僶
*/
#include <s_services.h>
#include "upd72001.h"
/*
* 僨僶僀僗儗僕僗僞偺傾僋僙僗娫妘帪娫乮nsec扨埵乯
*
* 200偲偄偆抣偵偁傑傝崻嫆偼側偄丏
*/
#define UPD72001_DELAY 200
/*
* 兪PD72001偺儗僕僗僞偺斣崋
*/
#define UPD72001_CR0 0x00u /* 僐儞僩儘乕儖儗僕僗僞 */
#define UPD72001_CR1 0x01u
#define UPD72001_CR2 0x02u
#define UPD72001_CR3 0x03u
#define UPD72001_CR4 0x04u
#define UPD72001_CR5 0x05u
#define UPD72001_CR10 0x0au
#define UPD72001_CR12 0x0cu
#define UPD72001_CR14 0x0eu
#define UPD72001_CR15 0x0fu
#define UPD72001_SR0 0x00u /* 僗僥乕僞僗儗僕僗僞 */
/*
* 僐儞僩儘乕儖儗僕僗僞偺愝掕抣
*/
#define CR_RESET 0x18u /* 億乕僩儕僙僢僩僐儅儞僪 */
#define CR0_EOI 0x38u /* EOI乮End of Interrupt乯*/
#define CR1_DOWN 0x00u /* 慡妱崬傒傪嬛巭 */
#define CR1_RECV 0x10u /* 庴怣妱崬傒嫋壜價僢僩 */
#define CR1_SEND 0x02u /* 憲怣妱崬傒嫋壜價僢僩 */
#define CR3_DEF 0xc1u /* 僨乕僞 8bit丆庴怣僀僱乕僽儖 */
#define CR4_DEF 0x44u /* 僗僩僢僾價僢僩 1bit丆僷儕僥傿側偟 */
#define CR5_DEF 0xeau /* 僨乕僞 8bit丆憲怣僀僱乕僽儖 */
#define BRG1_DEF 0x00u /* 9600bps乮忋埵乯*/
#define BRG2_DEF 0x1eu /* 9600bps乮壓埵乯*/
#define CR10_DEF 0x00u /* NRZ */
#define CR14_DEF 0x07u /* 儃乕儗乕僩僕僃僱儗乕僞僀僱乕僽儖 */
#define CR15_DEF 0x56u /* 儃乕儗乕僩僕僃僱儗乕僞巊梡 */
#define SR0_RECV 0x01u /* 庴怣捠抦價僢僩 */
#define SR0_SEND 0x04u /* 憲怣壜擻價僢僩 */
/*
* 僔儕傾儖I/O億乕僩弶婜壔僽儘僢僋偺掕媊
*/
typedef struct sio_port_initialization_block {
VP data; /* 僨乕僞儗僕僗僞偺斣抧 */
VP ctrl; /* 僐儞僩儘乕儖儗僕僗僞偺斣抧 */
UB cr3_def; /* CR3偺愝掕抣乮庴怣價僢僩悢乯*/
UB cr4_def; /* CR4偺愝掕抣乮僗僩僢僾價僢僩丆僷儕僥傿乯*/
UB cr5_def; /* CR5偺愝掕抣乮憲怣價僢僩悢乯*/
UB brg1_def; /* 儃乕儗乕僩忋埵偺愝掕抣 */
UB brg2_def; /* 儃乕儗乕僩壓埵偺愝掕抣 */
} SIOPINIB;
/*
* 僔儕傾儖I/O億乕僩娗棟僽儘僢僋偺掕媊
*/
struct sio_port_control_block {
const SIOPINIB *siopinib; /* 僔儕傾儖I/O億乕僩弶婜壔僽儘僢僋 */
VP_INT exinf; /* 奼挘忣曬 */
BOOL openflag; /* 僆乕僾儞嵪傒僼儔僌 */
UB cr1; /* CR1偺愝掕抣乮妱崬傒嫋壜乯*/
BOOL getready; /* 暥帤傪庴怣偟偨忬懺 */
BOOL putready; /* 暥帤傪憲怣偱偒傞忬懺 */
};
/*
* 僔儕傾儖I/O億乕僩弶婜壔僽儘僢僋
*
* ID = 1 傪億乕僩B丆ID = 2 傪億乕僩A偵懳墳偝偣偰偄傞丏
*/
const SIOPINIB siopinib_table[TNUM_SIOP] = {
{ (VP) TADR_UPD72001_DATAB, (VP) TADR_UPD72001_CTRLB,
CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF },
#if TNUM_SIOP >= 2
{ (VP) TADR_UPD72001_DATAA, (VP) TADR_UPD72001_CTRLA,
CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF },
#endif /* TNUM_SIOP >= 2 */
};
/*
* 僔儕傾儖I/O億乕僩娗棟僽儘僢僋偺僄儕傾
*/
SIOPCB siopcb_table[TNUM_SIOP];
/*
* 僔儕傾儖I/O億乕僩ID偐傜娗棟僽儘僢僋傪庢傝弌偡偨傔偺儅僋儘
*/
#define INDEX_SIOP(siopid) ((UINT)((siopid) - 1))
#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
/*
* 僨僶僀僗儗僕僗僞傊偺傾僋僙僗娭悢
*/
Inline UB
upd72001_read_reg(VP addr)
{
UB val;
val = (UB) upd72001_reb_reg(addr);
sil_dly_nse(UPD72001_DELAY);
return(val);
}
Inline void
upd72001_write_reg(VP addr, UB val)
{
upd72001_wrb_reg(addr, (VB) val);
sil_dly_nse(UPD72001_DELAY);
}
Inline UB
upd72001_read_ctrl(VP addr, UB reg)
{
upd72001_write_reg(addr, reg);
return(upd72001_read_reg(addr));
}
Inline void
upd72001_write_ctrl(VP addr, UB reg, UB val)
{
upd72001_write_reg(addr, reg);
upd72001_write_reg(addr, val);
}
Inline void
upd72001_write_brg(VP addr, UB reg, UB val, UB brg2, UB brg1)
{
upd72001_write_reg(addr, reg);
upd72001_write_reg(addr, val);
upd72001_write_reg(addr, brg2);
upd72001_write_reg(addr, brg1);
(void) upd72001_read_reg(addr); /* 僟儈乕儕乕僪 */
}
/*
* 忬懺偺撉弌偟乮SR0偺撉弌偟乯
*
* 兪PD72001偼丆忬懺乮SR0乯傪堦搙撉傓偲庴怣捠抦價僢僩偑棊偪偰偟傑偆偨
* 傔丆忬懺傪撉傒弌偡娭悢傪愝偗丆僔儕傾儖I/O億乕僩娗棟僽儘僢僋拞偺
* getready 偵庴怣捠抦忬懺丆putready 偵憲怣壜擻忬懺傪曐懚偟偰偄傞乮憲
* 怣壜擻忬懺偺曐懚偼晄梫偐傕偟傟側偄乯丏
* 忬懺儗僕僗僞傪撉傫偱傕庴怣捠抦價僢僩偑棊偪側偄僨僶僀僗乮偙偪傜偑晛
* 捠偲巚傢傟傞乯偱偼丆偙偺娭悢偼昁梫側偄丏
*/
static void
upd72001_get_stat(SIOPCB *siopcb)
{
UB sr0;
sr0 = upd72001_read_ctrl(siopcb->siopinib->ctrl, UPD72001_SR0);
if ((sr0 & SR0_RECV) != 0) {
siopcb->getready = TRUE;
}
if ((sr0 & SR0_SEND) != 0) {
siopcb->putready = TRUE;
}
}
/*
* 暥帤傪庴怣偱偒傞偐丠
*/
Inline BOOL
upd72001_getready(SIOPCB *siopcb)
{
upd72001_get_stat(siopcb);
return(siopcb->getready);
}
/*
* 暥帤傪憲怣偱偒傞偐丠
*/
Inline BOOL
upd72001_putready(SIOPCB *siopcb)
{
upd72001_get_stat(siopcb);
return(siopcb->putready);
}
/*
* 庴怣偟偨暥帤偺庢弌偟
*/
Inline char
upd72001_getchar(SIOPCB *siopcb)
{
siopcb->getready = FALSE;
return((char) upd72001_read_reg(siopcb->siopinib->data));
}
/*
* 憲怣偡傞暥帤偺彂崬傒
*/
Inline void
upd72001_putchar(SIOPCB *siopcb, char c)
{
siopcb->putready = FALSE;
upd72001_write_reg(siopcb->siopinib->data, (UB) c);
}
/*
* EOI乮End Of Interrupt乯敪峴
*/
Inline void
upd72001_eoi()
{
upd72001_write_ctrl((VP) TADR_UPD72001_CTRLA, UPD72001_CR0, CR0_EOI);
}
/*
* SIO僪儔僀僶偺弶婜壔儖乕僠儞
*/
void
upd72001_initialize()
{
SIOPCB *siopcb;
UINT i;
/*
* 僔儖傾儖I/O億乕僩娗棟僽儘僢僋偺弶婜壔
*/
for (siopcb = siopcb_table, i = 0; i < TNUM_SIOP; siopcb++, i++) {
siopcb->siopinib = &(siopinib_table[i]);
siopcb->openflag = FALSE;
}
}
/*
* 僆乕僾儞偟偰偄傞億乕僩偑偁傞偐丠
*/
BOOL
upd72001_openflag(void)
{
#if TNUM_SIOP < 2
return(siopcb_table[0].openflag);
#else /* TNUM_SIOP < 2 */
return(siopcb_table[0].openflag || siopcb_table[1].openflag);
#endif /* TNUM_SIOP < 2 */
}
/*
* 僔儕傾儖I/O億乕僩偺僆乕僾儞
*/
SIOPCB *
upd72001_opn_por(ID siopid, VP_INT exinf)
{
SIOPCB *siopcb;
const SIOPINIB *siopinib;
siopcb = get_siopcb(siopid);
siopinib = siopcb->siopinib;
upd72001_write_reg(siopinib->ctrl, CR_RESET);
if (!upd72001_openflag()) {
upd72001_write_ctrl((VP) TADR_UPD72001_CTRLA,
UPD72001_CR2, 0x18);
upd72001_write_ctrl((VP) TADR_UPD72001_CTRLB,
UPD72001_CR2, 0x00);
}
siopcb->cr1 = CR1_DOWN;
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR1, siopcb->cr1);
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR4, siopinib->cr4_def);
upd72001_write_brg(siopinib->ctrl, UPD72001_CR12,
0x01, siopinib->brg2_def, siopinib->brg1_def);
upd72001_write_brg(siopinib->ctrl, UPD72001_CR12,
0x02, siopinib->brg2_def, siopinib->brg1_def);
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR15, CR15_DEF);
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR14, CR14_DEF);
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR10, CR10_DEF);
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR3, siopinib->cr3_def);
upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR5, siopinib->cr5_def);
siopcb->exinf = exinf;
siopcb->getready = siopcb->putready = FALSE;
siopcb->openflag = TRUE;
return(siopcb);
}
/*
* 僔儕傾儖I/O億乕僩偺僋儘乕僘
*/
void
upd72001_cls_por(SIOPCB *siopcb)
{
upd72001_write_ctrl(siopcb->siopinib->ctrl, UPD72001_CR1, CR1_DOWN);
siopcb->openflag = FALSE;
}
/*
* 僔儕傾儖I/O億乕僩傊偺暥帤憲怣
*/
BOOL
upd72001_snd_chr(SIOPCB *siopcb, char c)
{
if (upd72001_putready(siopcb)) {
upd72001_putchar(siopcb, c);
return(TRUE);
}
return(FALSE);
}
/*
* 僔儕傾儖I/O億乕僩偐傜偺暥帤庴怣
*/
INT
upd72001_rcv_chr(SIOPCB *siopcb)
{
if (upd72001_getready(siopcb)) {
return((INT)(UB) upd72001_getchar(siopcb));
}
return(-1);
}
/*
* 僔儕傾儖I/O億乕僩偐傜偺僐乕儖僶僢僋偺嫋壜
*/
void
upd72001_ena_cbr(SIOPCB *siopcb, UINT cbrtn)
{
UB cr1_bit = 0;
switch (cbrtn) {
case SIO_ERDY_SND:
cr1_bit = CR1_SEND;
break;
case SIO_ERDY_RCV:
cr1_bit = CR1_RECV;
break;
}
siopcb->cr1 |= cr1_bit;
upd72001_write_ctrl(siopcb->siopinib->ctrl, UPD72001_CR1, siopcb->cr1);
}
/*
* 僔儕傾儖I/O億乕僩偐傜偺僐乕儖僶僢僋偺嬛巭
*/
void
upd72001_dis_cbr(SIOPCB *siopcb, UINT cbrtn)
{
UB cr1_bit = 0;
switch (cbrtn) {
case SIO_ERDY_SND:
cr1_bit = CR1_SEND;
break;
case SIO_ERDY_RCV:
cr1_bit = CR1_RECV;
break;
}
siopcb->cr1 &= ~cr1_bit;
upd72001_write_ctrl(siopcb->siopinib->ctrl, UPD72001_CR1, siopcb->cr1);
}
/*
* 僔儕傾儖I/O億乕僩偵懳偡傞妱崬傒張棟
*/
static void
upd72001_isr_siop(SIOPCB *siopcb)
{
if ((siopcb->cr1 & CR1_RECV) != 0 && upd72001_getready(siopcb)) {
/*
* 庴怣捠抦僐乕儖僶僢僋儖乕僠儞傪屇傃弌偡丏
*/
upd72001_ierdy_rcv(siopcb->exinf);
}
if ((siopcb->cr1 & CR1_SEND) != 0 && upd72001_putready(siopcb)) {
/*
* 憲怣壜擻僐乕儖僶僢僋儖乕僠儞傪屇傃弌偡丏
*/
upd72001_ierdy_snd(siopcb->exinf);
}
}
/*
* SIO偺妱崬傒僒乕價僗儖乕僠儞
*/
void
upd72001_isr()
{
if (siopcb_table[0].openflag) {
upd72001_isr_siop(&(siopcb_table[0]));
}
#if TNUM_SIOP >= 2
if (siopcb_table[1].openflag) {
upd72001_isr_siop(&(siopcb_table[1]));
}
#endif /* TNUM_SIOP >= 2 */
upd72001_eoi();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -