1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: #include <sys/machine.h>
15: #ifdef CPU_RX231
16:
17: #include <tk/tkernel.h>
18: #include <tm/tmonitor.h>
19: #include "../../ser.h"
20: #include "../../../include/dev_def.h"
21: #if DEV_SER_ENABLE
22: 23: 24: 25: 26:
27:
28: 29: 30:
31: const LOCAL UW ba[DEV_SER_UNITNM] = {
32: SCI0_BASE, SCI1_BASE, SCI5_BASE, SCI6_BASE,
33: SCI8_BASE, SCI9_BASE, SCI12_BASE
34: };
35:
36: 37: 38:
39: const LOCAL UINT inotbl[DEV_SER_UNITNM] = {
40: INTNO_SCI0_ERI, INTNO_SCI1_ERI, INTNO_SCI5_ERI, INTNO_SCI6_ERI,
41: INTNO_SCI8_ERI,INTNO_SCI9_ERI, INTNO_SCI12_ERI
42: };
43: #define INTNO_ERI(n) (inotbl[n])
44: #define INTNO_RXI(n) (inotbl[n]+1)
45: #define INTNO_TXI(n) (inotbl[n]+2)
46: #define INTNO_TXE(n) (inotbl[n]+3)
47:
48: 49: 50:
51: typedef struct {
52: UW mode;
53: UW speed;
54: } T_DEV_SER_LLDEVCB;
55:
56: LOCAL T_DEV_SER_LLDEVCB ll_devcb[DEV_SER_UNITNM];
57:
58: 59: 60:
61:
62: 63: 64:
65: void sci_txi_inthdr( UINT intno)
66: {
67: UW unit, data;
68:
69: unit = (intno - INTNO_SCI0_TXI) >>2 ;
70: if(unit >= DEV_SER_UNITNM ) return;
71:
72: if( dev_ser_get_snddat(unit, &data)) {
73: out_b(ba[unit] + SCI_TDR, (UB)data);
74: }
75: }
76:
77: 78: 79:
80: void sci_rxi_inthdr( UINT intno)
81: {
82: UW unit, data;
83:
84: unit = (intno - INTNO_SCI0_RXI) >>2 ;
85: if(unit >= DEV_SER_UNITNM ) return;
86:
87: data = in_b(ba[unit] + SCI_RDR);
88: dev_ser_notify_rcv(unit, data);
89:
90: }
91:
92: 93: 94:
95: void sci_eri_inthdr( UINT intno)
96: {
97: UW unit, ssr;
98:
99: unit = (intno - INTNO_SCI0_ERI) >>2 ;
100: if(unit >= DEV_SER_UNITNM ) return;
101:
102: ssr = in_b(ba[unit] + SCI_SSR);
103: out_b(ba[unit] + SCI_SSR, 0);
104:
105: ssr &= (SCI_SSR_ORER | SCI_SSR_PER | SCI_SSR_FER);
106: dev_ser_notify_err(unit, ssr);
107: }
108:
109:
110: 111: 112:
113: LOCAL void start_com(UW unit, UW mode, UW speed)
114: {
115: UB data;
116:
117:
118: out_b( ba[unit] + SCI_SMR, (UB)((mode & 0x00000078)|(speed>>8 & 0x00000003)));
119: out_b( ba[unit] + SCI_SCMR, 0xF2);
120: data = in_b( ba[unit] + SCI_SEMR);
121: out_b( ba[unit] + SCI_SEMR, (data & ~SCI_SEMR_ABCS) | (speed & SCI_SEMR_ABCS));
122: out_b( ba[unit] + SCI_BRR, speed >>16);
123:
124:
125: out_b( ba[unit] + SCI_SCR,
126: (SCI_SCR_RE | SCI_SCR_TE | SCI_SCR_RIE | SCI_SCR_TIE | SCI_SCR_INI));
127: }
128:
129: 130: 131:
132: LOCAL void stop_com(UW unit)
133: {
134: if(unit != DEVCNF_SER_DBGUN) {
135: out_b(ba[unit] + SCI_SCR, SCI_SCR_INI);
136: } else {
137: out_b(ba[unit] + SCI_SCR, SCI_SCR_DEBUG);
138: }
139: }
140:
141: 142: 143:
144: LOCAL UW calc_brr(UW baud)
145: {
146: UW abcs, brr, cks;
147: W work;
148:
149: work = SYSCLK_PCLKB / (baud * 256);
150: if(work < 16) {
151: abcs = SCI_SEMR_ABCS;
152: cks = 0;
153: brr = SYSCLK_PCLKB / (baud * 16) - 1;
154: } else if(work < 32) {
155: abcs = 0;
156: cks = 0;
157: brr = SYSCLK_PCLKB / (baud * 32) - 1;
158: } else if(work < 64) {
159: abcs = SCI_SEMR_ABCS;
160: cks = 1;
161: brr = SYSCLK_PCLKB / (baud * 64) - 1;
162: } else if(work < 128) {
163: abcs = 0;
164: cks = 1;
165: brr = SYSCLK_PCLKB / (baud * 128) - 1;
166: } else if(work < 256) {
167: abcs = SCI_SEMR_ABCS;
168: cks = 2;
169: brr = SYSCLK_PCLKB / (baud * 256) - 1;
170: } else if(work < 512) {
171: abcs = 0;
172: cks = 2;
173: brr = SYSCLK_PCLKB / (baud * 512) - 1;
174: } else if(work < 1024) {
175: abcs = SCI_SEMR_ABCS;
176: cks = 3;
177: brr = SYSCLK_PCLKB / (baud * 1024) - 1;
178: } else if(work < 2048) {
179: abcs = 0;
180: cks = 3;
181: brr = SYSCLK_PCLKB / (baud * 2048) - 1;
182: } else {
183: return 0;
184: }
185:
186: return (brr<<16 | cks << 8 | abcs);
187: }
188:
189: 190: 191:
192: EXPORT ER dev_ser_llctl( UW unit, INT cmd, UW parm)
193: {
194: UW data;
195: ER err = E_OK;
196:
197: switch(cmd) {
198: case LLD_SER_MODE:
199: ll_devcb[unit].mode = parm;
200: break;
201:
202: case LLD_SER_SPEED:
203: data = calc_brr(parm);
204: if(data != 0) {
205: ll_devcb[unit].speed = data;
206: } else {
207: err = E_PAR;
208: }
209: break;
210:
211: case LLD_SER_START:
212:
213: in_b(ba[unit] + SCI_SSR);
214: out_b(ba[unit] + SCI_SSR, 0xC0);
215:
216: EnableInt( INTNO_ERI(unit), DEVCNF_SER_INTPRI);
217: EnableInt( INTNO_RXI(unit), DEVCNF_SER_INTPRI);
218: EnableInt( INTNO_TXI(unit), DEVCNF_SER_INTPRI);
219:
220: start_com( unit, ll_devcb[unit].mode, ll_devcb[unit].speed);
221: break;
222:
223: case LLD_SER_STOP:
224:
225: DisableInt( INTNO_ERI(unit));
226: DisableInt( INTNO_RXI(unit));
227: DisableInt( INTNO_TXI(unit));
228: stop_com(unit);
229: break;
230:
231: case LLD_SER_SEND:
232: if((in_b( ba[unit] + SCI_SSR) & SCI_SSR_TDRF) != 0) {
233: out_b(ba[unit] + SCI_TDR, (UB)parm);
234: err = E_OK;
235: } else {
236: err = E_BUSY;
237: }
238: break;
239:
240: case LLD_SER_BREAK:
241: err = E_NOSPT;
242: break;
243: }
244:
245: return err;
246: }
247:
248: 249: 250:
251: EXPORT ER dev_ser_llinit( T_SER_DCB *p_dcb)
252: {
253: T_DINT dint;
254: UW unit;
255: ER err;
256:
257: unit = p_dcb->unit;
258:
259: #if DEVCONF_SER_INIT_MSTP
260: const UINT mstp_bit[] = { 31, 30, 26, 25, 27, 26, 4};
261: UINT sts;
262: UW *mstp;
263:
264: if(unit == 4 || unit == 5) {
265: mstp = (UB*)MSTPCRC;
266: } else {
267: mstp = (UB*)MSTPCRB;
268: }
269:
270: if(in_w(mstp) & (1<<mstp_bit[unit])) {
271: DI(sts);
272: out_h(SYSTEM_PRCR, 0xA502);
273: *mstp &= ~(1<<mstp_bit[unit]);
274: out_h(SYSTEM_PRCR, 0xA500);
275: EI(sts);
276: }
277: #endif
278:
279: stop_com(unit);
280: out_b(ba[unit] + SCI_SPMR, SCI_SPMR_INI);
281:
282:
283: p_dcb->intno_rcv = INTNO_SCI0_RXI + (unit<<2);
284: p_dcb->intno_snd = INTNO_SCI0_TXI + (unit<<2);
285:
286:
287: dint.intatr = TA_HLNG;
288: dint.inthdr = sci_eri_inthdr;
289: err = tk_def_int(INTNO_ERI(unit), &dint);
290: dint.inthdr = sci_rxi_inthdr;
291: err = tk_def_int(INTNO_RXI(unit), &dint);
292: dint.inthdr = sci_txi_inthdr;
293: err = tk_def_int(INTNO_TXI(unit), &dint);
294:
295: return err;
296: }
297:
298: #endif
299: #endif