]> git.sur5r.net Git - freertos/blob - Demo/Common/drivers/Atmel/at91lib/peripherals/ssc/ssc.c
Atmel provided hardware specifics.
[freertos] / Demo / Common / drivers / Atmel / at91lib / peripherals / ssc / ssc.c
1 /* ----------------------------------------------------------------------------\r
2  *         ATMEL Microcontroller Software Support \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2008, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 //------------------------------------------------------------------------------\r
31 //         Headers\r
32 //------------------------------------------------------------------------------\r
33 \r
34 #include "ssc.h"\r
35 #include <utility/trace.h>\r
36 \r
37 //------------------------------------------------------------------------------\r
38 //         Exported functions\r
39 //------------------------------------------------------------------------------\r
40 //------------------------------------------------------------------------------\r
41 /// Configures a SSC peripheral. If the divided clock is not used, the master\r
42 /// clock frequency can be set to 0.\r
43 /// \note The emitter and transmitter are disabled by this function.\r
44 /// \param ssc  Pointer to an AT91S_SSC instance.\r
45 /// \param id  Peripheral ID of the SSC.\r
46 //------------------------------------------------------------------------------\r
47 void SSC_Configure(AT91S_SSC *ssc,\r
48                           unsigned int id,\r
49                           unsigned int bitRate,\r
50                           unsigned int masterClock)\r
51 {\r
52     // Enable SSC peripheral clock\r
53     AT91C_BASE_PMC->PMC_PCER = 1 << id;\r
54 \r
55     // Reset, disable receiver & transmitter\r
56     ssc->SSC_CR = AT91C_SSC_RXDIS | AT91C_SSC_TXDIS | AT91C_SSC_SWRST;\r
57     ssc->SSC_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;\r
58 \r
59     // Configure clock frequency\r
60     if (bitRate != 0) {\r
61     \r
62         ssc->SSC_CMR = masterClock / (2 * bitRate);\r
63     }\r
64     else {\r
65 \r
66         ssc->SSC_CMR = 0;\r
67     }\r
68 }\r
69 \r
70 //------------------------------------------------------------------------------\r
71 /// Configures the transmitter of a SSC peripheral. Several macros can be used\r
72 /// to compute the values of the Transmit Clock Mode Register (TCMR) and the\r
73 /// Transmit Frame Mode Register (TFMR) (see "SSC configuration macros").\r
74 /// \param ssc  Pointer to a AT91S_SSC instance.\r
75 /// \param tcmr  Transmit Clock Mode Register value.\r
76 /// \param tfmr  Transmit Frame Mode Register value.\r
77 //------------------------------------------------------------------------------\r
78 void SSC_ConfigureTransmitter(AT91S_SSC *ssc,\r
79                                      unsigned int tcmr,\r
80                                      unsigned int tfmr)\r
81 {\r
82     ssc->SSC_TCMR = tcmr;\r
83     ssc->SSC_TFMR = tfmr;\r
84 }\r
85 \r
86 //------------------------------------------------------------------------------\r
87 /// Configures the receiver of a SSC peripheral. Several macros can be used\r
88 /// to compute the values of the Receive Clock Mode Register (TCMR) and the\r
89 /// Receive Frame Mode Register (TFMR) (see "SSC configuration macros").\r
90 /// \param ssc  Pointer to a AT91S_SSC instance.\r
91 /// \param rcmr  Receive Clock Mode Register value.\r
92 /// \param rfmr  Receive Frame Mode Register value.\r
93 //------------------------------------------------------------------------------\r
94 void SSC_ConfigureReceiver(AT91S_SSC *ssc,\r
95                                   unsigned int rcmr,\r
96                                   unsigned int rfmr)\r
97 {\r
98     ssc->SSC_RCMR = rcmr;\r
99     ssc->SSC_RFMR = rfmr;\r
100 }\r
101 \r
102 //------------------------------------------------------------------------------\r
103 /// Enables the transmitter of a SSC peripheral.\r
104 /// \param ssc  Pointer to an AT91S_SSC instance.\r
105 //------------------------------------------------------------------------------\r
106 void SSC_EnableTransmitter(AT91S_SSC *ssc)\r
107 {\r
108     ssc->SSC_CR = AT91C_SSC_TXEN;\r
109 }\r
110 \r
111 //------------------------------------------------------------------------------\r
112 /// Disables the transmitter of a SSC peripheral.\r
113 /// \param ssc  Pointer to an AT91S_SSC instance.\r
114 //------------------------------------------------------------------------------\r
115 void SSC_DisableTransmitter(AT91S_SSC *ssc)\r
116 {\r
117     ssc->SSC_CR = AT91C_SSC_TXDIS;\r
118 }\r
119 \r
120 //------------------------------------------------------------------------------\r
121 /// Enables the receiver of a SSC peripheral.\r
122 /// \param ssc  Pointer to an AT91S_SSC instance.\r
123 //------------------------------------------------------------------------------\r
124 void SSC_EnableReceiver(AT91S_SSC *ssc)\r
125 {\r
126     ssc->SSC_CR = AT91C_SSC_RXEN;\r
127 }\r
128 \r
129 //------------------------------------------------------------------------------\r
130 /// Disables the receiver of a SSC peripheral.\r
131 /// \param ssc  Pointer to an AT91S_SSC instance.\r
132 //------------------------------------------------------------------------------\r
133 void SSC_DisableReceiver(AT91S_SSC *ssc)\r
134 {\r
135     ssc->SSC_CR = AT91C_SSC_RXDIS;\r
136 }\r
137 \r
138 //------------------------------------------------------------------------------\r
139 /// Enables one or more interrupt sources of a SSC peripheral.\r
140 /// \param ssc  Pointer to an AT91S_SSC instance.\r
141 /// \param sources  Interrupt sources to enable.\r
142 //------------------------------------------------------------------------------\r
143 void SSC_EnableInterrupts(AT91S_SSC *ssc, unsigned int sources)\r
144 {\r
145     ssc->SSC_IER = sources;\r
146 }\r
147 \r
148 //------------------------------------------------------------------------------\r
149 /// Disables one or more interrupt sources of a SSC peripheral.\r
150 /// \param ssc  Pointer to an AT91S_SSC instance.\r
151 /// \param sources  Interrupt source to disable.\r
152 //------------------------------------------------------------------------------\r
153 void SSC_DisableInterrupts(AT91S_SSC *ssc, unsigned int sources)\r
154 {\r
155     ssc->SSC_IDR = sources;\r
156 }\r
157 \r
158 //------------------------------------------------------------------------------\r
159 /// Sends one data frame through a SSC peripheral. If another frame is currently\r
160 /// being sent, this function waits for the previous transfer to complete.\r
161 /// \param ssc  Pointer to an AT91S_SSC instance.\r
162 /// \param frame  Data frame to send.\r
163 //------------------------------------------------------------------------------\r
164 void SSC_Write(AT91S_SSC *ssc, unsigned int frame)\r
165 {\r
166     while ((ssc->SSC_SR & AT91C_SSC_TXRDY) == 0);\r
167     ssc->SSC_THR = frame;\r
168 }\r
169 \r
170 //------------------------------------------------------------------------------\r
171 /// Sends the contents of a data buffer a SSC peripheral, using the PDC. Returns\r
172 /// true if the buffer has been queued for transmission; otherwise returns\r
173 /// false.\r
174 /// \param ssc  Pointer to an AT91S_SSC instance.\r
175 /// \param buffer  Data buffer to send.\r
176 /// \param length  Size of the data buffer.\r
177 //------------------------------------------------------------------------------\r
178 unsigned char SSC_WriteBuffer(AT91S_SSC *ssc,\r
179                                      void *buffer,\r
180                                      unsigned int length)\r
181 {\r
182     // Check if first bank is free\r
183     if (ssc->SSC_TCR == 0) {\r
184 \r
185         ssc->SSC_TPR = (unsigned int) buffer;\r
186         ssc->SSC_TCR = length;\r
187         ssc->SSC_PTCR = AT91C_PDC_TXTEN;\r
188         return 1;\r
189     }\r
190     // Check if second bank is free\r
191     else if (ssc->SSC_TNCR == 0) {\r
192 \r
193         ssc->SSC_TNPR = (unsigned int) buffer;\r
194         ssc->SSC_TNCR = length;\r
195         return 1;\r
196     }\r
197       \r
198     // No free banks\r
199     return 0;\r
200 }\r
201 \r
202 //------------------------------------------------------------------------------\r
203 /// Waits until one frame is received on a SSC peripheral, and returns it.\r
204 /// \param ssc  Pointer to an AT91S_SSC instance.\r
205 //------------------------------------------------------------------------------\r
206 unsigned int SSC_Read(AT91S_SSC *ssc)\r
207 {\r
208     while ((ssc->SSC_SR & AT91C_SSC_RXRDY) == 0);\r
209     return ssc->SSC_RHR;\r
210 }\r
211 \r
212 //------------------------------------------------------------------------------\r
213 /// Reads data coming from a SSC peripheral receiver and stores it into the\r
214 /// provided buffer. Returns true if the buffer has been queued for reception;\r
215 /// otherwise returns false.\r
216 /// \param ssc  Pointer to an AT91S_SSC instance.\r
217 /// \param buffer  Data buffer used for reception.\r
218 /// \param length  Size in bytes of the data buffer.\r
219 //------------------------------------------------------------------------------\r
220 unsigned char SSC_ReadBuffer(AT91S_SSC *ssc,\r
221                                     void *buffer,\r
222                                     unsigned int length)\r
223 {\r
224     // Check if the first bank is free\r
225     if (ssc->SSC_RCR == 0) {\r
226 \r
227         ssc->SSC_RPR = (unsigned int) buffer;\r
228         ssc->SSC_RCR = length;\r
229         ssc->SSC_PTCR = AT91C_PDC_RXTEN;\r
230         return 1;\r
231     }\r
232     // Check if second bank is free\r
233     else if (ssc->SSC_RNCR == 0) {\r
234 \r
235         ssc->SSC_RNPR = (unsigned int) buffer;\r
236         ssc->SSC_RNCR = length;\r
237         return 1;\r
238     }\r
239 \r
240     // No free bank\r
241     return 0;\r
242 }\r
243 \r