1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: #include <sys/machine.h>
15: #ifdef CPU_RZA2M
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:
32: const LOCAL UW ba[DEV_SER_UNITNM] =
33: { SCI0_BASE, SCI1_BASE, SCI2_BASE, SCI3_BASE, SCI4_BASE};
34:
35: 36: 37:
38: const LOCAL UINT inotbl[DEV_SER_UNITNM] =
39: { INTNO_SCI0_ERI, INTNO_SCI1_ERI, INTNO_SCI2_ERI, INTNO_SCI3_ERI, INTNO_SCI4_ERI};
40: #define INTNO_BRI(n) (inotbl[n])
41: #define INTNO_ERI(n) (inotbl[n])
42: #define INTNO_RXI(n) (inotbl[n]+1)
43: #define INTNO_TXI(n) (inotbl[n]+2)
44: #define INTNO_TEI(n) (inotbl[n]+3)
45: #define INTNO_DRI(n) (inotbl[n]+3)
46:
47: 48: 49:
50: typedef struct {
51: UW mode;
52: UW speed;
53: } T_DEV_SER_LLDEVCB;
54:
55: LOCAL T_DEV_SER_LLDEVCB ll_devcb[DEV_SER_UNITNM];
56:
57: 58: 59:
60:
61: 62: 63:
64: void sci_txi_inthdr( UINT intno)
65: {
66: UW unit, data;
67: UH reg;
68: UINT inttxi = INTNO_SCI0_TXI;
69:
70: ClearInt(intno);
71:
72: for(unit = 0; unit < DEV_SER_UNITNM; unit++, inttxi+=6) {
73: if(intno == inttxi) break;
74: }
75:
76: if(unit < DEV_SER_UNITNM ) {
77: if( dev_ser_get_snddat(unit, &data)) {
78: out_b(ba[unit] + SCI_FTDR, (UB)data);
79: } else {
80: reg = in_h(ba[unit] + SCI_SCR);
81: out_h(ba[unit] + SCI_SCR, reg & ~SCI_SCR_TIE);
82: }
83: }
84:
85: EndOfInt(intno);
86: }
87:
88: 89: 90:
91: void sci_rxi_inthdr( UINT intno)
92: {
93: UW unit, data;
94: UH reg;
95: UINT intrxi = INTNO_SCI0_RXI;
96:
97: ClearInt(intno);
98:
99: for(unit = 0; unit < DEV_SER_UNITNM; unit++, intrxi+=6) {
100: if(intno == intrxi) break;
101: }
102:
103: if(unit < DEV_SER_UNITNM ) {
104: data = in_b(ba[unit] + SCI_FRDR);
105:
106:
107: reg = in_h(ba[unit] + SCI_FSR);
108: out_h(ba[unit] + SCI_FSR, reg & ~(SCI_FSR_DR|SCI_FSR_RDF));
109:
110: dev_ser_notify_rcv(unit, data);
111: }
112:
113: EndOfInt(intno);
114: }
115:
116: 117: 118:
119: void sci_eri_inthdr( UINT intno)
120: {
121: UW unit, err;
122: UH reg;
123: UINT interi = INTNO_SCI0_ERI;
124:
125: ClearInt(intno);
126:
127: for(unit = 0; unit < DEV_SER_UNITNM; unit++, interi+=6) {
128: if(intno == interi) break;
129: }
130:
131: if(unit < DEV_SER_UNITNM ) {
132: reg = in_h(ba[unit] + SCI_FSR);
133: out_h(ba[unit] + SCI_FSR, reg & ~SCI_FSR_ER);
134: err = (UW)(reg & (DEV_SER_ERR_PE | DEV_SER_ERR_FE));
135:
136: reg = in_h(ba[unit] + SCI_LSR);
137: out_h(ba[unit] + SCI_FSR, reg & ~SCI_LSR_ORER);
138: err |= (UW)(reg & DEV_SER_ERR_OE);
139:
140: dev_ser_notify_err(unit, err);
141: }
142:
143: EndOfInt(intno);
144: }
145:
146:
147: 148: 149:
150: LOCAL void start_com(UW unit, UW mode, UW speed)
151: {
152: UH reg;
153:
154:
155: out_h( ba[unit] + SCI_SMR, (UH)((mode & 0x00000078)|(speed>>8 & 0x00000003)));
156:
157: reg = in_h( ba[unit] + SCI_SEMR);
158: out_h( ba[unit] + SCI_SEMR, (UH)((reg & ~SCI_SEMR_ABCS)|(speed & SCI_SEMR_ABCS)));
159:
160: out_b( ba[unit] + SCI_BRR, (UB)(speed >>16));
161:
162:
163: reg = in_h(ba[unit] + SCI_FSR);
164: out_h(ba[unit] + SCI_FSR, reg & ~(SCI_FSR_DR|SCI_FSR_RDF));
165:
166:
167: out_h( ba[unit] + SCI_SCR,
168: (SCI_SCR_RE | SCI_SCR_TE | SCI_SCR_RIE | SCI_SCR_REIE));
169: }
170:
171: 172: 173:
174: LOCAL void stop_com(UW unit)
175: {
176: if(unit != DEVCNF_SER_DBGUN) {
177: out_h(ba[unit] + SCI_SCR, SCI_SCR_INI);
178: } else {
179: out_h(ba[unit] + SCI_SCR, SCI_SCR_DEBUG);
180: }
181: }
182:
183: 184: 185:
186: typedef struct {
187: UW baud;
188: UW val;
189: } T_BPS_VAL;
190:
191: LOCAL const T_BPS_VAL bps_tbl[] = {
192:
193:
194: { 500000, ( 3<<16) + (0<<8) + 0 },
195: { 230400, ( 8<<16) + (0<<8) + 0 },
196: { 115200, ( 17<<16) + (0<<8) + 0 },
197: { 38400, ( 53<<16) + (0<<8) + 0 },
198: { 31250, ( 65<<16) + (0<<8) + 0 },
199: { 28800, ( 71<<16) + (0<<8) + 0 },
200: { 19200, (106<<16) + (0<<8) + 0 },
201: { 14400, (142<<16) + (0<<8) + 0 },
202: { 9600, (214<<16) + (0<<8) + 0 },
203: { 4800, (106<<16) + (1<<8) + 0 },
204: { 2400, (214<<16) + (1<<8) + 0 },
205: { 1200, (106<<16) + (2<<8) + 0 },
206: { 600, (214<<16) + (2<<8) + 0 },
207: { 300, (106<<16) + (3<<8) + 0 },
208: { 150, (214<<16) + (3<<8) + 0 },
209: { 0, 0 }
210: };
211:
212: LOCAL UW calc_brr(UW baud)
213: {
214: const T_BPS_VAL *p_tbl;
215:
216: for(p_tbl = bps_tbl; p_tbl->baud != 0; p_tbl++) {
217: if(p_tbl->baud == baud) break;
218: }
219:
220: return (p_tbl->baud != 0)? p_tbl->val: 0;
221: }
222:
223: 224: 225:
226: EXPORT ER dev_ser_llctl( UW unit, INT cmd, UW parm)
227: {
228: UW data;
229: UH reg;
230: ER err = E_OK;
231:
232: switch(cmd) {
233: case LLD_SER_MODE:
234: ll_devcb[unit].mode = parm;
235: break;
236:
237: case LLD_SER_SPEED:
238: data = calc_brr(parm);
239: if(data != 0) {
240: ll_devcb[unit].speed = data;
241: } else {
242: err = E_PAR;
243: }
244: break;
245:
246: case LLD_SER_START:
247:
248: out_h(ba[unit] + SCI_FCR, SCI_FCR_RFRST | SCI_FCR_TFRST);
249: out_h(ba[unit] + SCI_FCR, SCI_FCR_INI);
250: out_h(ba[unit] + SCI_FTCR, SCI_FTCR_INI);
251:
252:
253: reg = in_h(ba[unit] + SCI_FSR);
254: out_h(ba[unit] + SCI_FSR, 0);
255: reg = in_h(ba[unit] + SCI_LSR);
256: out_h(ba[unit] + SCI_LSR, 0);
257:
258:
259: ClearInt( INTNO_ERI(unit));
260: ClearInt( INTNO_RXI(unit));
261: ClearInt( INTNO_TXI(unit));
262:
263:
264: EnableInt( INTNO_ERI(unit), DEVCNF_SER_INTPRI);
265: EnableInt( INTNO_RXI(unit), DEVCNF_SER_INTPRI);
266: EnableInt( INTNO_TXI(unit), DEVCNF_SER_INTPRI);
267:
268:
269: start_com( unit, ll_devcb[unit].mode, ll_devcb[unit].speed);
270: break;
271:
272: case LLD_SER_STOP:
273:
274: DisableInt( INTNO_ERI(unit));
275: DisableInt( INTNO_RXI(unit));
276: DisableInt( INTNO_TXI(unit));
277: stop_com(unit);
278: break;
279:
280: case LLD_SER_SEND:
281: reg = in_h( ba[unit] + SCI_FDR);
282: if((reg>>8) < 0x0010) {
283: out_b(ba[unit] + SCI_FTDR, (UB)parm);
284: reg = in_h(ba[unit] + SCI_SCR);
285: out_h(ba[unit] + SCI_SCR, reg | SCI_SCR_TIE);
286: err = E_OK;
287: } else {
288: err = E_BUSY;
289: }
290: break;
291:
292: case LLD_SER_BREAK:
293: err = E_NOSPT;
294: break;
295: }
296:
297: return err;
298: }
299:
300: 301: 302:
303: EXPORT ER dev_ser_llinit( T_SER_DCB *p_dcb)
304: {
305: T_DINT dint;
306: UW unit;
307: ER err;
308:
309: unit = p_dcb->unit;
310:
311: #if DEVCONF_SER_INIT_MSTP
312: UB stbc;
313:
314: stbc = in_b(CPG_STBCR1);
315: out_b(CPG_STBCR1, stbc & ~(1<<(7-unit)));
316: stbc = in_b(CPG_STBCR1);
317:
318: #endif
319:
320: stop_com(unit);
321: out_h(ba[unit] + SCI_SPTR, SCI_SPTR_INI);
322: out_h( ba[unit] + SCI_SEMR, 0);
323:
324:
325:
326: p_dcb->intno_rcv = INTNO_RXI(unit);
327: p_dcb->intno_snd = INTNO_TXI(unit);
328:
329:
330: dint.intatr = TA_HLNG;
331: dint.inthdr = sci_eri_inthdr;
332: err = tk_def_int(INTNO_ERI(unit), &dint);
333: dint.inthdr = sci_rxi_inthdr;
334: err = tk_def_int(INTNO_RXI(unit), &dint);
335: dint.inthdr = sci_txi_inthdr;
336: err = tk_def_int(INTNO_TXI(unit), &dint);
337:
338: return err;
339: }
340:
341: #endif
342: #endif