hsk_libs-dev  163:b63ae088cc97
High Speed Karlsruhe XC878 library collection
 All Data Structures Files Functions Variables Typedefs Macros Groups Pages
hsk_ssc.h
Go to the documentation of this file.
1 /** \file
2  * HSK Synchronous Serial Interface headers
3  *
4  * General purpose serial communication, setup in the following order:
5  * - hsk_ssc_init()
6  * - hsk_ssc_ports()
7  * - hsk_ssc_enable()
8  *
9  * Communication is established by the hsk_ssc_talk() function.
10  * Use hsk_ssc_busy() to detect whether a buffer was completely read and
11  * written.
12  *
13  * @author kami
14  *
15  * \section half_dublex Half Duplex Operation
16  *
17  * For half duplex operation TX and RX pins need to be short circuited.
18  *
19  * The TX pin is set up in open drain mode, i.e. an external pull-up
20  * resistor is required.
21  *
22  * The TX pin needs to be manually configured before calling hsk_ssc_talk()
23  * in order to speak or listen on the bus. To listen the TX pin needs to
24  * be configured as an input pin, to speak on the bus as an output pin.
25  * For efficiency reasons this is not handled by this library (it would
26  * result in lots of runtime logic for what should be a single instruction).
27  *
28  * Instead it is recommended to define macros in a central header. E.g. for
29  * the port configuration \ref SSC_MRST_P05 in slave mode the following
30  * code would work:
31  * \code
32  * #define SSC_TX() (P0_DIR |= 1 << 5)
33  * #define SSC_RX() (P0_DIR &= ~(1 << 5))
34  * \endcode
35  *
36  * Syntactically it can be used like a regular function:
37  * \code
38  * SSC_TX();
39  * hsk_ssc_talk(buffer, sizeof(buffer) - 1);
40  * \endcode
41  */
42 
43 #ifndef _HSK_SSC_H_
44 #define _HSK_SSC_H_
45 
46 /*
47  * ISR prototypes for SDCC.
48  */
49 #ifdef SDCC
50 #include "hsk_ssc.isr"
51 #endif /* SDCC */
52 
53 /**
54  * \defgroup SSC_PORTS SSC I/O Ports
55  *
56  * Used to create an I/O Port configuration, by unifying one of the
57  * SSC_MRST_P* with a SSC_MTSR_P* and a SSC_SCLK_P* ports.
58  * E.g.:
59  * \verbatim
60  * SSC_MRST_P05 | SSC_MTSR_P4 | SSC_SCLK_P03.
61  * \endverbatim
62  *
63  * The ports have the following functions:
64  * | Type | Master Mode | Slave Mode
65  * |------|-------------|------------
66  * | MRST | RX port | TX port
67  * | MTSR | TX port | RX port
68  * | SCLK | TX clock | RX clock
69  *
70  * @{
71  */
72 
73 /**
74  * Master mode RX, slave mode TX port P0.5.
75  */
76 #define SSC_MRST_P05 1
77 
78 /**
79  * Master mode RX, slave mode TX port P1.4.
80  */
81 #define SSC_MRST_P14 0
82 
83 /**
84  * Master mode RX, slave mode TX port P1.5.
85  */
86 #define SSC_MRST_P15 2
87 
88 /**
89  * Master mode TX, slave mode RX port P0.4.
90  */
91 #define SSC_MTSR_P04 (1 << 2)
92 
93 /**
94  * Master mode TX, slave mode RX port P1.3.
95  */
96 #define SSC_MTSR_P13 (0 << 2)
97 
98 /**
99  * Master mode TX, slave mode RX port P1.4.
100  */
101 #define SSC_MTSR_P14 (2 << 2)
102 
103 /**
104  * Synchronous clock port P0.3.
105  */
106 #define SSC_SCLK_P03 (1 << 4)
107 
108 /**
109  * Synchronous clock port P1.2.
110  */
111 #define SSC_SCLK_P12 (0 << 4)
112 
113 /**
114  * Synchronous clock port P1.3.
115  */
116 #define SSC_SCLK_P13 (2 << 4)
117 
118 /**
119  * @}
120  */
121 
122 /**
123  * Master mode, output shift clock on SCLK.
124  */
125 #define SSC_MASTER 1
126 
127 /**
128  * Slave mode, receive shift clock on SCLK.
129  */
130 #define SSC_SLAVE 0
131 
132 /**
133  * Converts a baud rate value in bits/s into a baud rate value for the
134  * hsk_ssc_init() function.
135  *
136  * The distance between adjustable baud rates grows exponentially.
137  * Available baud rates in kBit progress like this:
138  *
139  * \f[\{12000, 6000, 4000, 3000, 2400, 2000, ...\}\f]
140  *
141  * Use the following formula to determine the baud rate that results from
142  * a desired value:
143  * \f[{realBps}(bps) = \frac{12000000}{\lfloor\frac{12000000}{bps}\rfloor}\f]
144  *
145  * @note
146  * The maximum speed is 12 Mbit/s in master mode and 6 Mbit/s in slave
147  * mode.
148  * @param bps
149  * The desired number in bits/s
150  * @return
151  * A timer reload value
152  */
153 #define SSC_BAUD(bps) (uword)(12000000ul / (bps) - 1)
154 
155 /**
156  * Generates an SSC configuration byte.
157  *
158  * For details check the XC878 user manual section 12.3.5.1.
159  *
160  * @param width
161  * The data with in bits, the available range is \f$[2;8]\f$
162  * @param heading
163  * Use 0 for transmitting/receiving LSB first, 1 for MSB first
164  * @param phase
165  * Use 0 to shift on leading and latch on trailing edge, use 1 to
166  * shift on trailing and latch on leading edge
167  * @param polarity
168  * Use 0 for low idle clock, and 1 for high idle clock
169  * @param duplex
170  * Use 0 for full duplex mode and 1 for half duplex
171  */
172 #define SSC_CONF(width, heading, phase, polarity, duplex) \
173  (((width) - 1) | ((heading) << 4) | ((phase) << 5) | ((polarity) << 6) | ((duplex) << 7))
174 
175 /**
176  * The maximum baud rate in master mode is 12000000 bits/s, and 6000000
177  * bits/s in slave mode.
178  *
179  * Calling this function turns the SSC off until hsk_ssc_enable() is called.
180  *
181  * @param baud
182  * The timer reload value for the baud rate generator, use \ref SSC_BAUD
183  * to generate this value
184  * @param config
185  * The SSC configuration byte, use \ref SSC_CONF to generate it
186  * @param mode
187  * Select master or slave operation
188  */
189 void hsk_ssc_init(const uword baud, const ubyte config, const bool mode);
190 
191 /**
192  * Configure the I/O ports of the SSC unit.
193  *
194  * @warning
195  * Do not use when the SSC is enabled.
196  * @param ports
197  * Selects an \ref SSC_PORTS I/O port configuration
198  */
199 void hsk_ssc_ports(const ubyte ports);
200 
201 /**
202  * Send and receive data.
203  *
204  * The buffer with the given length should contain the data to transceive
205  * and will be filled with the received data upon completion.
206  *
207  * The provided buffer needs to reside in xdata memory, e.g. to create and
208  * use a string buffer the following should work:
209  * \code
210  * char xdata buffer[] = "20 character buffer.";
211  * …
212  * hsk_ssc_talk(buffer, sizeof(buffer) - 1);
213  * \endcode
214  *
215  * Note that char must not be const and that \f$sizeof(buffer) - 1\f$ is
216  * used to prevent sending and overwriting the terminal 0 character.
217  * There may be cases where a terminal 0 character is desired.
218  *
219  * @param buffer
220  * The rx/tx transmission buffer
221  * @param len
222  * The length of the buffer
223  */
224 void hsk_ssc_talk(char xdata * buffer, ubyte len);
225 
226 /**
227  * Returns whether the SSC is currently busy with data transmission.
228  */
229 #define hsk_ssc_busy() ESSC
230 
231 /**
232  * Turn the SSC module on.
233  */
234 void hsk_ssc_enable();
235 
236 /**
237  * Turn the SSC module off.
238  */
239 void hsk_ssc_disable();
240 
241 #endif /* _HSK_SSC_H_ */