OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_AT91SAM3U256_IAR/] [AT91Lib/] [peripherals/] [twi/] [twi.c] - Blame information for rev 580

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 580 jeremybenn
/* ----------------------------------------------------------------------------
2
 *         ATMEL Microcontroller Software Support
3
 * ----------------------------------------------------------------------------
4
 * Copyright (c) 2008, Atmel Corporation
5
 *
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *
11
 * - Redistributions of source code must retain the above copyright notice,
12
 * this list of conditions and the disclaimer below.
13
 *
14
 * Atmel's name may not be used to endorse or promote products derived from
15
 * this software without specific prior written permission.
16
 *
17
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 * ----------------------------------------------------------------------------
28
 */
29
 
30
//------------------------------------------------------------------------------
31
/// \unit
32
///
33
/// !Purpose
34
///
35
/// Interface for configuration the Two Wire Interface (TWI) peripheral.
36
///
37
/// !Usage
38
///
39
/// -# Configures a TWI peripheral to operate in master mode, at the given
40
/// frequency (in Hz) using TWI_Configure().
41
/// -# Sends a STOP condition on the TWI using TWI_Stop().
42
/// -# Starts a read operation on the TWI bus with the specified slave using
43
/// TWI_StartRead(). Data must then be read using TWI_ReadByte() whenever
44
/// a byte is available (poll using TWI_ByteReceived()).
45
/// -# Starts a write operation on the TWI to access the selected slave using
46
/// TWI_StartWrite(). A byte of data must be provided to start the write;
47
/// other bytes are written next.
48
/// -# Sends a byte of data to one of the TWI slaves on the bus using TWI_WriteByte().
49
/// This function must be called once before TWI_StartWrite() with the first byte of data
50
/// to send, then it shall be called repeatedly after that to send the remaining bytes.
51
/// -# Check if a byte has been received and can be read on the given TWI
52
/// peripheral using TWI_ByteReceived().
53
/// Check if a byte has been sent using TWI_ByteSent().
54
/// -# Check if the current transmission is complete (the STOP has been sent)
55
/// using TWI_TransferComplete().
56
/// -# Enables & disable the selected interrupts sources on a TWI peripheral
57
/// using TWI_EnableIt() and TWI_DisableIt().
58
/// -# Get current status register of the given TWI peripheral using
59
/// TWI_GetStatus(). Get current status register of the given TWI peripheral, but
60
/// masking interrupt sources which are not currently enabled using
61
/// TWI_GetMaskedStatus().
62
//------------------------------------------------------------------------------
63
 
64
 
65
//------------------------------------------------------------------------------
66
//         Headers
67
//------------------------------------------------------------------------------
68
 
69
#include "twi.h"
70
#include <utility/math.h>
71
#include <utility/assert.h>
72
#include <utility/trace.h>
73
 
74
//------------------------------------------------------------------------------
75
//         Global functions
76
//------------------------------------------------------------------------------
77
 
78
//------------------------------------------------------------------------------
79
/// Configures a TWI peripheral to operate in master mode, at the given
80
/// frequency (in Hz). The duty cycle of the TWI clock is set to 50%.
81
/// \param pTwi  Pointer to an AT91S_TWI instance.
82
/// \param twck  Desired TWI clock frequency.
83
/// \param mck  Master clock frequency.
84
//------------------------------------------------------------------------------
85
void TWI_ConfigureMaster(AT91S_TWI *pTwi, unsigned int twck, unsigned int mck)
86
{
87
    unsigned int ckdiv = 0;
88
    unsigned int cldiv;
89
    unsigned char ok = 0;
90
 
91
    TRACE_DEBUG("TWI_ConfigureMaster()\n\r");
92
    SANITY_CHECK(pTwi);
93
 
94
#ifdef AT91C_TWI_SVEN  // TWI slave
95
    // SVEN: TWI Slave Mode Enabled
96
    pTwi->TWI_CR = AT91C_TWI_SVEN;
97
#endif
98
    // Reset the TWI
99
    pTwi->TWI_CR = AT91C_TWI_SWRST;
100
    pTwi->TWI_RHR;
101
 
102
    // TWI Slave Mode Disabled, TWI Master Mode Disabled
103
#ifdef AT91C_TWI_SVEN  // TWI slave
104
    pTwi->TWI_CR = AT91C_TWI_SVDIS;
105
#endif
106
    pTwi->TWI_CR = AT91C_TWI_MSDIS;
107
 
108
    // Set master mode
109
    pTwi->TWI_CR = AT91C_TWI_MSEN;
110
 
111
    // Configure clock
112
    while (!ok) {
113
        cldiv = ((mck / (2 * twck)) - 3) / power(2, ckdiv);
114
        if (cldiv <= 255) {
115
 
116
            ok = 1;
117
        }
118
        else {
119
 
120
            ckdiv++;
121
        }
122
    }
123
 
124
    ASSERT(ckdiv < 8, "-F- Cannot find valid TWI clock parameters\n\r");
125
    TRACE_DEBUG("Using CKDIV = %u and CLDIV/CHDIV = %u\n\r", ckdiv, cldiv);
126
    pTwi->TWI_CWGR = 0;
127
    pTwi->TWI_CWGR = (ckdiv << 16) | (cldiv << 8) | cldiv;
128
}
129
 
130
 
131
 
132
#ifdef AT91C_TWI_SVEN  // TWI slave
133
//------------------------------------------------------------------------------
134
/// Configures a TWI peripheral to operate in slave mode
135
/// \param pTwi  Pointer to an AT91S_TWI instance.
136
//------------------------------------------------------------------------------
137
void TWI_ConfigureSlave(AT91S_TWI *pTwi, unsigned char slaveAddress)
138
{
139
    unsigned int i;
140
 
141
    // TWI software reset
142
    pTwi->TWI_CR = AT91C_TWI_SWRST;
143
    pTwi->TWI_RHR;
144
 
145
    // Wait at least 10 ms
146
    for (i=0; i < 1000000; i++);
147
 
148
    // TWI Slave Mode Disabled, TWI Master Mode Disabled
149
    pTwi->TWI_CR = AT91C_TWI_SVDIS | AT91C_TWI_MSDIS;
150
 
151
    // Slave Address
152
    pTwi->TWI_SMR = 0;
153
    pTwi->TWI_SMR = (slaveAddress << 16) & AT91C_TWI_SADR;
154
 
155
    // SVEN: TWI Slave Mode Enabled
156
    pTwi->TWI_CR = AT91C_TWI_SVEN;
157
 
158
    // Wait at least 10 ms
159
    for (i=0; i < 1000000; i++);
160
    ASSERT( (pTwi->TWI_CR & AT91C_TWI_SVDIS)!=AT91C_TWI_SVDIS, "Problem slave mode");
161
}
162
#endif
163
 
164
//------------------------------------------------------------------------------
165
/// Sends a STOP condition on the TWI.
166
/// \param pTwi  Pointer to an AT91S_TWI instance.
167
//------------------------------------------------------------------------------
168
void TWI_Stop(AT91S_TWI *pTwi)
169
{
170
    SANITY_CHECK(pTwi);
171
 
172
    pTwi->TWI_CR = AT91C_TWI_STOP;
173
}
174
 
175
//------------------------------------------------------------------------------
176
/// Starts a read operation on the TWI bus with the specified slave, and returns
177
/// immediately. Data must then be read using TWI_ReadByte() whenever a byte is
178
/// available (poll using TWI_ByteReceived()).
179
/// \param pTwi  Pointer to an AT91S_TWI instance.
180
/// \param address  Slave address on the bus.
181
/// \param iaddress  Optional internal address bytes.
182
/// \param isize  Number of internal address bytes.
183
//-----------------------------------------------------------------------------
184
void TWI_StartRead(
185
    AT91S_TWI *pTwi,
186
    unsigned char address,
187
    unsigned int iaddress,
188
    unsigned char isize)
189
{
190
    //TRACE_DEBUG("TWI_StartRead()\n\r");
191
    SANITY_CHECK(pTwi);
192
    SANITY_CHECK((address & 0x80) == 0);
193
    SANITY_CHECK((iaddress & 0xFF000000) == 0);
194
    SANITY_CHECK(isize < 4);
195
 
196
    // Set slave address and number of internal address bytes
197
    pTwi->TWI_MMR = 0;
198
    pTwi->TWI_MMR = (isize << 8) | AT91C_TWI_MREAD | (address << 16);
199
 
200
    // Set internal address bytes
201
    pTwi->TWI_IADR = 0;
202
    pTwi->TWI_IADR = iaddress;
203
 
204
    // Send START condition
205
    pTwi->TWI_CR = AT91C_TWI_START;
206
}
207
 
208
//-----------------------------------------------------------------------------
209
/// Reads a byte from the TWI bus. The read operation must have been started
210
/// using TWI_StartRead() and a byte must be available (check with
211
/// TWI_ByteReceived()).
212
/// Returns the byte read.
213
/// \param pTwi  Pointer to an AT91S_TWI instance.
214
//-----------------------------------------------------------------------------
215
unsigned char TWI_ReadByte(AT91S_TWI *pTwi)
216
{
217
    SANITY_CHECK(pTwi);
218
 
219
    return pTwi->TWI_RHR;
220
}
221
 
222
//-----------------------------------------------------------------------------
223
/// Sends a byte of data to one of the TWI slaves on the bus. This function
224
/// must be called once before TWI_StartWrite() with the first byte of data
225
/// to send, then it shall be called repeatedly after that to send the
226
/// remaining bytes.
227
/// \param pTwi  Pointer to an AT91S_TWI instance.
228
/// \param byte  Byte to send.
229
//-----------------------------------------------------------------------------
230
void TWI_WriteByte(AT91S_TWI *pTwi, unsigned char byte)
231
{
232
    SANITY_CHECK(pTwi);
233
 
234
    pTwi->TWI_THR = byte;
235
}
236
 
237
//-----------------------------------------------------------------------------
238
/// Starts a write operation on the TWI to access the selected slave, then
239
/// returns immediately. A byte of data must be provided to start the write;
240
/// other bytes are written next.
241
/// \param pTwi  Pointer to an AT91S_TWI instance.
242
/// \param address  Address of slave to acccess on the bus.
243
/// \param iaddress  Optional slave internal address.
244
/// \param isize  Number of internal address bytes.
245
/// \param byte  First byte to send.
246
//-----------------------------------------------------------------------------
247
void TWI_StartWrite(
248
    AT91S_TWI *pTwi,
249
    unsigned char address,
250
    unsigned int iaddress,
251
    unsigned char isize,
252
    unsigned char byte)
253
{
254
    //TRACE_DEBUG("TWI_StartWrite()\n\r");
255
    SANITY_CHECK(pTwi);
256
    SANITY_CHECK((address & 0x80) == 0);
257
    SANITY_CHECK((iaddress & 0xFF000000) == 0);
258
    SANITY_CHECK(isize < 4);
259
 
260
    // Set slave address and number of internal address bytes
261
    pTwi->TWI_MMR = 0;
262
    pTwi->TWI_MMR = (isize << 8) | (address << 16);
263
 
264
    // Set internal address bytes
265
    pTwi->TWI_IADR = 0;
266
    pTwi->TWI_IADR = iaddress;
267
 
268
    // Write first byte to send
269
    TWI_WriteByte(pTwi, byte);
270
}
271
 
272
//-----------------------------------------------------------------------------
273
/// Returns 1 if a byte has been received and can be read on the given TWI
274
/// peripheral; otherwise, returns 0. This function resets the status register
275
/// of the TWI.
276
/// \param pTwi  Pointer to an AT91S_TWI instance.
277
//-----------------------------------------------------------------------------
278
unsigned char TWI_ByteReceived(AT91S_TWI *pTwi)
279
{
280
    return ((pTwi->TWI_SR & AT91C_TWI_RXRDY) == AT91C_TWI_RXRDY);
281
}
282
 
283
//-----------------------------------------------------------------------------
284
/// Returns 1 if a byte has been sent, so another one can be stored for
285
/// transmission; otherwise returns 0. This function clears the status register
286
/// of the TWI.
287
/// \param pTwi  Pointer to an AT91S_TWI instance.
288
//-----------------------------------------------------------------------------
289
unsigned char TWI_ByteSent(AT91S_TWI *pTwi)
290
{
291
    return ((pTwi->TWI_SR & AT91C_TWI_TXRDY) == AT91C_TWI_TXRDY);
292
}
293
 
294
//-----------------------------------------------------------------------------
295
/// Returns 1 if the current transmission is complete (the STOP has been sent);
296
/// otherwise returns 0.
297
/// \param pTwi  Pointer to an AT91S_TWI instance.
298
//-----------------------------------------------------------------------------
299
unsigned char TWI_TransferComplete(AT91S_TWI *pTwi)
300
{
301
    return ((pTwi->TWI_SR & AT91C_TWI_TXCOMP) == AT91C_TWI_TXCOMP);
302
}
303
 
304
//-----------------------------------------------------------------------------
305
/// Enables the selected interrupts sources on a TWI peripheral.
306
/// \param pTwi  Pointer to an AT91S_TWI instance.
307
/// \param sources  Bitwise OR of selected interrupt sources.
308
//-----------------------------------------------------------------------------
309
void TWI_EnableIt(AT91S_TWI *pTwi, unsigned int sources)
310
{
311
    SANITY_CHECK(pTwi);
312
    SANITY_CHECK((sources & 0xFFFFF088) == 0);
313
 
314
    pTwi->TWI_IER = sources;
315
}
316
 
317
//-----------------------------------------------------------------------------
318
/// Disables the selected interrupts sources on a TWI peripheral.
319
/// \param pTwi  Pointer to an AT91S_TWI instance.
320
/// \param sources  Bitwise OR of selected interrupt sources.
321
//-----------------------------------------------------------------------------
322
void TWI_DisableIt(AT91S_TWI *pTwi, unsigned int sources)
323
{
324
    SANITY_CHECK(pTwi);
325
    SANITY_CHECK((sources & 0xFFFFF088) == 0);
326
 
327
    pTwi->TWI_IDR = sources;
328
}
329
 
330
//-----------------------------------------------------------------------------
331
/// Returns the current status register of the given TWI peripheral. This
332
/// resets the internal value of the status register, so further read may yield
333
/// different values.
334
/// \param pTwi  Pointer to an AT91S_TWI instance.
335
//-----------------------------------------------------------------------------
336
unsigned int TWI_GetStatus(AT91S_TWI *pTwi)
337
{
338
    SANITY_CHECK(pTwi);
339
 
340
    return pTwi->TWI_SR;
341
}
342
 
343
//-----------------------------------------------------------------------------
344
/// Returns the current status register of the given TWI peripheral, but
345
/// masking interrupt sources which are not currently enabled.
346
/// This resets the internal value of the status register, so further read may
347
/// yield different values.
348
/// \param pTwi  Pointer to an AT91S_TWI instance.
349
//-----------------------------------------------------------------------------
350
unsigned int TWI_GetMaskedStatus(AT91S_TWI *pTwi)
351
{
352
    unsigned int status;
353
 
354
    SANITY_CHECK(pTwi);
355
 
356
    status = pTwi->TWI_SR;
357
    status &= pTwi->TWI_IMR;
358
 
359
    return status;
360
}
361
//-----------------------------------------------------------------------------
362
/// Sends a STOP condition. STOP Condition is sent just after completing
363
/// the current byte transmission in master read mode.
364
/// \param pTwi  Pointer to an AT91S_TWI instance.
365
//-----------------------------------------------------------------------------
366
void TWI_SendSTOPCondition(AT91S_TWI *pTwi)
367
{
368
    SANITY_CHECK(pTwi);
369
 
370
    pTwi->TWI_CR |= AT91C_TWI_STOP;
371
}
372
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.