uartsa1110.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. #include "../port/netif.h"
  9. /* this isn't strictly an sa1110 driver. The rts/cts stuff is h3650 specific */
  10. static void sa1110_uartpower(Uart *, int);
  11. enum
  12. {
  13. /* ctl[0] bits */
  14. Parity= 1<<0,
  15. Even= 1<<1,
  16. Stop2= 1<<2,
  17. Bits8= 1<<3,
  18. SCE= 1<<4, /* synchronous clock enable */
  19. RCE= 1<<5, /* rx on falling edge of clock */
  20. TCE= 1<<6, /* tx on falling edge of clock */
  21. /* ctl[3] bits */
  22. Rena= 1<<0, /* receiver enable */
  23. Tena= 1<<1, /* transmitter enable */
  24. Break= 1<<2, /* force TXD3 low */
  25. Rintena= 1<<3, /* enable receive interrupt */
  26. Tintena= 1<<4, /* enable transmitter interrupt */
  27. Loopback= 1<<5, /* loop back data */
  28. /* data bits */
  29. DEparity= 1<<8, /* parity error */
  30. DEframe= 1<<9, /* framing error */
  31. DEoverrun= 1<<10, /* overrun error */
  32. /* status[0] bits */
  33. Tint= 1<<0, /* transmit fifo half full interrupt */
  34. Rint0= 1<<1, /* receiver fifo 1/3-2/3 full */
  35. Rint1= 1<<2, /* receiver fifo not empty and receiver idle */
  36. Breakstart= 1<<3,
  37. Breakend= 1<<4,
  38. Fifoerror= 1<<5, /* fifo error */
  39. /* status[1] bits */
  40. Tbusy= 1<<0, /* transmitting */
  41. Rnotempty= 1<<1, /* receive fifo not empty */
  42. Tnotfull= 1<<2, /* transmit fifo not full */
  43. ParityError= 1<<3,
  44. FrameError= 1<<4,
  45. Overrun= 1<<5,
  46. };
  47. extern PhysUart sa1110physuart;
  48. //static
  49. Uart sa1110uart[2] = {
  50. { .regs = (void*)UART3REGS,
  51. .name = "serialport3",
  52. .freq = ClockFreq,
  53. .bits = 8,
  54. .stop = 1,
  55. .parity = 'n',
  56. .baud = 115200,
  57. .phys = &sa1110physuart,
  58. .special = 0,
  59. .next = &sa1110uart[1], },
  60. { .regs = (void*)UART1REGS,
  61. .name = "serialport1",
  62. .freq = ClockFreq,
  63. .bits = 8,
  64. .stop = 1,
  65. .parity = 'n',
  66. .baud = 115200,
  67. .phys = &sa1110physuart,
  68. .putc = µcputc,
  69. .special = 0,
  70. .next = nil, },
  71. };
  72. static Uart* µcuart;
  73. #define R(p) ((Uartregs*)((p)->regs))
  74. #define SR(p) ((Uartregs*)((p)->saveregs))
  75. /*
  76. * enable a port's interrupts. set DTR and RTS
  77. */
  78. static void
  79. sa1110_uartenable(Uart *p, int intena)
  80. {
  81. ulong s;
  82. s = R(p)->ctl[3] & ~(Rintena|Tintena|Rena|Tena);
  83. if(intena)
  84. R(p)->ctl[3] = s |Rintena|Tintena|Rena|Tena;
  85. else
  86. R(p)->ctl[3] = s | Rena|Tena;
  87. }
  88. /*
  89. * disable interrupts. clear DTR, and RTS
  90. */
  91. static void
  92. sa1110_uartdisable(Uart *p)
  93. {
  94. R(p)->ctl[3] &= ~(Rintena|Tintena|Rena|Tena);
  95. }
  96. static long
  97. sa1110_uartstatus(Uart *p, void *buf, long n, long offset)
  98. {
  99. char str[256];
  100. ulong ctl0;
  101. ctl0 = R(p)->ctl[0];
  102. snprint(str, sizeof(str),
  103. "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
  104. "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n",
  105. p->baud,
  106. p->hup_dcd,
  107. 0,
  108. p->hup_dsr,
  109. (ctl0 & Bits8) ? 8 : 7,
  110. 0,
  111. (ctl0 & Parity) ? ((ctl0 & Even) ? 'e' : 'o') : 'n',
  112. 0,
  113. (ctl0 & Stop2) ? 2 : 1,
  114. 1,
  115. p->dev,
  116. p->type,
  117. p->ferr,
  118. p->oerr,
  119. "",
  120. "",
  121. "",
  122. "" );
  123. return readstr(offset, buf, n, str);
  124. }
  125. /*
  126. * set the buad rate
  127. */
  128. static int
  129. sa1110_uartbaud(Uart *p, int rate)
  130. {
  131. ulong brconst;
  132. ulong ctl3;
  133. if(rate <= 0)
  134. return -1;
  135. /* disable */
  136. ctl3 = R(p)->ctl[3];
  137. R(p)->ctl[3] = 0;
  138. brconst = p->freq/(16*rate) - 1;
  139. R(p)->ctl[1] = (brconst>>8) & 0xf;
  140. R(p)->ctl[2] = brconst & 0xff;
  141. /* reenable */
  142. R(p)->ctl[3] = ctl3;
  143. p->baud = rate;
  144. return 0;
  145. }
  146. /*
  147. * send a break
  148. */
  149. static void
  150. sa1110_uartbreak(Uart *p, int ms)
  151. {
  152. if(ms == 0)
  153. ms = 200;
  154. R(p)->ctl[3] |= Break;
  155. tsleep(&up->sleep, return0, 0, ms);
  156. R(p)->ctl[3] &= ~Break;
  157. }
  158. /*
  159. * set bits/char
  160. */
  161. static int
  162. sa1110_uartbits(Uart *p, int n)
  163. {
  164. ulong ctl0, ctl3;
  165. ctl0 = R(p)->ctl[0];
  166. switch(n){
  167. case 7:
  168. ctl0 &= ~Bits8;
  169. break;
  170. case 8:
  171. ctl0 |= Bits8;
  172. break;
  173. default:
  174. return -1;
  175. }
  176. /* disable */
  177. ctl3 = R(p)->ctl[3];
  178. R(p)->ctl[3] = 0;
  179. R(p)->ctl[0] = ctl0;
  180. /* reenable */
  181. R(p)->ctl[3] = ctl3;
  182. p->bits = n;
  183. return 0;
  184. }
  185. /*
  186. * set stop bits
  187. */
  188. static int
  189. sa1110_uartstop(Uart *p, int n)
  190. {
  191. ulong ctl0, ctl3;
  192. ctl0 = R(p)->ctl[0];
  193. switch(n){
  194. case 1:
  195. ctl0 &= ~Stop2;
  196. break;
  197. case 2:
  198. ctl0 |= Stop2;
  199. break;
  200. default:
  201. return -1;
  202. }
  203. /* disable */
  204. ctl3 = R(p)->ctl[3];
  205. R(p)->ctl[3] = 0;
  206. R(p)->ctl[0] = ctl0;
  207. /* reenable */
  208. R(p)->ctl[3] = ctl3;
  209. p->stop = n;
  210. return 0;
  211. }
  212. /*
  213. * turn on/off rts
  214. */
  215. static void
  216. sa1110_uartrts(Uart*, int)
  217. {
  218. }
  219. /*
  220. * turn on/off dtr
  221. */
  222. static void
  223. sa1110_uartdtr(Uart*, int)
  224. {
  225. }
  226. /*
  227. * turn on/off modem flow control on/off (rts/cts)
  228. */
  229. static void
  230. sa1110_uartmodemctl(Uart *p, int on)
  231. {
  232. if(on) {
  233. } else {
  234. p->cts = 1;
  235. }
  236. }
  237. /*
  238. * set parity
  239. */
  240. static int
  241. sa1110_uartparity(Uart *p, int type)
  242. {
  243. ulong ctl0, ctl3;
  244. ctl0 = R(p)->ctl[0];
  245. switch(type){
  246. case 'e':
  247. ctl0 |= Parity|Even;
  248. break;
  249. case 'o':
  250. ctl0 |= Parity;
  251. break;
  252. default:
  253. ctl0 &= ~(Parity|Even);
  254. break;
  255. }
  256. /* disable */
  257. ctl3 = R(p)->ctl[3];
  258. R(p)->ctl[3] = 0;
  259. R(p)->ctl[0] = ctl0;
  260. /* reenable */
  261. R(p)->ctl[3] = ctl3;
  262. return 0;
  263. }
  264. /*
  265. * restart output if not blocked and OK to send
  266. */
  267. static void
  268. sa1110_uartkick(Uart *p)
  269. {
  270. int i;
  271. R(p)->ctl[3] &= ~Tintena;
  272. if(p->cts == 0 || p->blocked)
  273. return;
  274. for(i = 0; i < 1024; i++){
  275. if(!(R(p)->status[1] & Tnotfull)){
  276. R(p)->ctl[3] |= Tintena;
  277. break;
  278. }
  279. if(p->op >= p->oe && uartstageoutput(p) == 0)
  280. break;
  281. R(p)->data = *p->op++;
  282. }
  283. }
  284. /*
  285. * take an interrupt
  286. */
  287. static void
  288. sa1110_uartintr(Ureg*, void *x)
  289. {
  290. Uart *p;
  291. ulong s;
  292. Uartregs *regs;
  293. p = x;
  294. regs = p->regs;
  295. /* receiver interrupt, snarf bytes */
  296. while(regs->status[1] & Rnotempty)
  297. uartrecv(p, regs->data);
  298. /* remember and reset interrupt causes */
  299. s = regs->status[0];
  300. regs->status[0] |= s;
  301. if(s & Tint){
  302. /* transmitter interrupt, restart */
  303. uartkick(p);
  304. }
  305. if(s & (ParityError|FrameError|Overrun)){
  306. if(s & ParityError)
  307. p->parity++;
  308. if(s & FrameError)
  309. p->ferr++;
  310. if(s & Overrun)
  311. p->oerr++;
  312. }
  313. /* receiver interrupt, snarf bytes */
  314. while(regs->status[1] & Rnotempty)
  315. uartrecv(p, regs->data);
  316. }
  317. static Uart*
  318. sa1110_pnp(void)
  319. {
  320. return sa1110uart;
  321. }
  322. static int
  323. sa1110_getc(Uart *uart)
  324. {
  325. Uartregs *ur;
  326. ur = uart->regs;
  327. while((ur->status[1] & Rnotempty) == 0)
  328. ;
  329. return ur->data;
  330. }
  331. static void
  332. sa1110_putc(Uart *uart, int c)
  333. {
  334. Uartregs *ur;
  335. ur = uart->regs;
  336. /* wait for output ready */
  337. while((ur->status[1] & Tnotfull) == 0)
  338. ;
  339. ur->data = c;
  340. while((ur->status[1] & Tbusy))
  341. ;
  342. }
  343. PhysUart sa1110physuart = {
  344. .name= "sa1110",
  345. .pnp= sa1110_pnp,
  346. .enable= sa1110_uartenable,
  347. .disable= sa1110_uartdisable,
  348. .bits= sa1110_uartbits,
  349. .kick= sa1110_uartkick,
  350. .modemctl= sa1110_uartmodemctl,
  351. .baud= sa1110_uartbaud,
  352. .stop= sa1110_uartstop,
  353. .parity= sa1110_uartparity,
  354. .dobreak= sa1110_uartbreak,
  355. .rts= sa1110_uartrts,
  356. .dtr= sa1110_uartdtr,
  357. .status= sa1110_uartstatus,
  358. .power= sa1110_uartpower,
  359. .getc= sa1110_getc,
  360. .putc= sa1110_putc,
  361. };
  362. /*
  363. * for iprint, just write it
  364. */
  365. void
  366. serialµcputs(uchar *str, int n)
  367. {
  368. Uartregs *ur;
  369. if(µcuart == nil)
  370. return;
  371. ur = µcuart->regs;
  372. while(n-- > 0){
  373. /* wait for output ready */
  374. while((ur->status[1] & Tnotfull) == 0)
  375. ;
  376. ur->data = *str++;
  377. }
  378. while((ur->status[1] & Tbusy))
  379. ;
  380. }
  381. enum
  382. {
  383. /* gpclk register 0 */
  384. Gpclk_sus= 1<<0, /* set uart mode */
  385. };
  386. Gpclkregs *gpclkregs;
  387. /*
  388. * setup all uarts (called early by main() to allow debugging output to
  389. * a serial port)
  390. */
  391. void
  392. sa1110_uartsetup(int console)
  393. {
  394. Uart *p;
  395. /* external serial port (eia0) */
  396. p = &sa1110uart[0];
  397. p->regs = mapspecial(UART3REGS, sizeof(Uartregs));
  398. p->saveregs = xalloc(sizeof(Uartregs));
  399. /* set eia0 up as a console */
  400. if(console){
  401. uartctl(p, "b115200 l8 pn s1");
  402. (*p->phys->enable)(p, 0);
  403. p->console = 1;
  404. consuart = p;
  405. }
  406. intrenable(IRQ, IRQuart3, sa1110_uartintr, p, p->name);
  407. /* port for talking to microcontroller (eia1) */
  408. gpclkregs = mapspecial(GPCLKREGS, sizeof(Gpclkregs));
  409. gpclkregs->r0 = Gpclk_sus; /* set uart mode */
  410. p = &sa1110uart[1];
  411. p->regs = mapspecial(UART1REGS, sizeof(Uartregs));
  412. p->saveregs = xalloc(sizeof(Uartregs));
  413. uartctl(p, "b115200 l8 pn s1");
  414. µcuart = p;
  415. p->special = 1;
  416. (*p->phys->enable)(p, 0);
  417. intrenable(IRQ, IRQuart1b, sa1110_uartintr, p, p->name);
  418. }
  419. static void
  420. uartcpy(Uartregs *to, Uartregs *from)
  421. {
  422. to->ctl[0] = from->ctl[0];
  423. // to->ctl[1] = from->ctl[1];
  424. // to->ctl[2] = from->ctl[2];
  425. to->ctl[3] = from->ctl[3];
  426. }
  427. static void
  428. sa1110_uartpower(Uart *p, int powerup)
  429. {
  430. if (powerup) {
  431. /* power up, restore the registers */
  432. uartcpy(R(p), SR(p));
  433. R(p)->status[0] = R(p)->status[0];
  434. } else {
  435. /* power down, save the registers */
  436. uartcpy(SR(p), R(p));
  437. }
  438. }