]> sigrok.org Git - sigrok-firmware-fx2lafw.git/blob - fx2lib/lib/serial.c
Import fx2lib into fx2lafw directly.
[sigrok-firmware-fx2lafw.git] / fx2lib / lib / serial.c
1 /**
2  * Copyright (C) 2009 Ubixum, Inc. 
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  **/
18
19
20 #include <fx2regs.h>
21 #include <fx2macros.h>
22 #include <serial.h>
23
24
25 /**
26  * using the comp port implies that timer 2 will be used as
27  * a baud rate generator.  (Don't use timer 2)
28  **/
29 void sio0_init( WORD baud_rate ) __critical { // baud_rate max should be 57600 since int=2 bytes
30         
31     WORD hl; // hl value for reload     
32         BYTE mult; // multiplier for clock speed
33     DWORD tmp; // scratch for mult/divide
34
35     // 0 = 12mhz, 1=24mhz, 2=48mhz    
36         mult = CPUFREQ == CLK_12M ? 1 :
37            CPUFREQ == CLK_24M ? 2 : 4; // since only 3 clock speeds, fast switch instead of doing 2^clock speed pow(2,clkspd)
38
39         // set the clock rate
40         // use clock 2
41         RCLK=1;TCLK=1;
42
43 //    RCAP2H:L = 0xFFFF - CLKOUT / 32 x baud_rate
44
45     // in order to round to nearest value..
46     // tmp * 2 // double
47     // tmp / rate // do the divide
48     // tmp + 1 // add one (which is like adding 1/2)
49     // tmp / 2 // back to original rounded 
50     tmp = mult * 375000L * 2 ;
51     tmp /= baud_rate;
52     tmp += 1;
53     tmp /= 2;
54
55     hl = 0xFFFF - (WORD)tmp;
56
57         RCAP2H= MSB(hl);
58         // seems that the 24/48mhz calculations are always one less than suggested values    
59     // trm table 14-16
60         RCAP2L= LSB(hl) + (mult>0?1:0);
61         TR2=1; // start the timer
62         
63         // set up the serial port       
64         SM0 = 0; SM1=1;// serial mode 1 (asyncronous)   
65         SM2 = 0 ; // has to do with receiving
66         REN = 1 ; // to enable receiving
67     PCON |= 0x80; // SET SMOD0, baud rate doubler
68     TI = 1; // we send initial byte
69
70 }
71
72 char getchar() {
73   char c;
74   while (!RI)
75     ;  
76   c=SBUF0;
77   RI=0;
78   return c;
79 }
80
81 void _transchar(char c) {
82  while ( !TI ); // wait for TI=1 
83  TI=0;
84  SBUF0=c;
85 }
86
87 void putchar (char c) {
88   if (c=='\n') _transchar('\r'); // transmit \r\n
89   _transchar(c);  
90   if (c == '\r' ) _transchar('\n'); // transmit \r\n
91 }
92