Skip to content

Commit 22a8fab

Browse files
committed
Revert "Wire library to the 1.5 format"
This reverts commit a318576.
1 parent 8a966f3 commit 22a8fab

File tree

9 files changed

+792
-0
lines changed

9 files changed

+792
-0
lines changed

libraries/Wire/Wire.cpp

+384
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
/*
2+
* TwoWire.h - TWI/I2C library for Arduino Due
3+
* Copyright (c) 2011 Cristian Maglie <[email protected]>.
4+
* All rights reserved.
5+
*
6+
* This library is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 2.1 of the License, or (at your option) any later version.
10+
*
11+
* This library is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public
17+
* License along with this library; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
extern "C" {
22+
#include <string.h>
23+
}
24+
25+
#include "Wire.h"
26+
27+
static inline bool TWI_FailedAcknowledge(Twi *pTwi) {
28+
return pTwi->TWI_SR & TWI_SR_NACK;
29+
}
30+
31+
static inline bool TWI_WaitTransferComplete(Twi *_twi, uint32_t _timeout) {
32+
while (!TWI_TransferComplete(_twi)) {
33+
if (TWI_FailedAcknowledge(_twi))
34+
return false;
35+
if (--_timeout == 0)
36+
return false;
37+
}
38+
return true;
39+
}
40+
41+
static inline bool TWI_WaitByteSent(Twi *_twi, uint32_t _timeout) {
42+
while (!TWI_ByteSent(_twi)) {
43+
if (TWI_FailedAcknowledge(_twi))
44+
return false;
45+
if (--_timeout == 0)
46+
return false;
47+
}
48+
return true;
49+
}
50+
51+
static inline bool TWI_WaitByteReceived(Twi *_twi, uint32_t _timeout) {
52+
while (!TWI_ByteReceived(_twi)) {
53+
if (TWI_FailedAcknowledge(_twi))
54+
return false;
55+
if (--_timeout == 0)
56+
return false;
57+
}
58+
return true;
59+
}
60+
61+
static inline bool TWI_STATUS_SVREAD(uint32_t status) {
62+
return (status & TWI_SR_SVREAD) == TWI_SR_SVREAD;
63+
}
64+
65+
static inline bool TWI_STATUS_SVACC(uint32_t status) {
66+
return (status & TWI_SR_SVACC) == TWI_SR_SVACC;
67+
}
68+
69+
static inline bool TWI_STATUS_GACC(uint32_t status) {
70+
return (status & TWI_SR_GACC) == TWI_SR_GACC;
71+
}
72+
73+
static inline bool TWI_STATUS_EOSACC(uint32_t status) {
74+
return (status & TWI_SR_EOSACC) == TWI_SR_EOSACC;
75+
}
76+
77+
static inline bool TWI_STATUS_NACK(uint32_t status) {
78+
return (status & TWI_SR_NACK) == TWI_SR_NACK;
79+
}
80+
81+
TwoWire::TwoWire(Twi *_twi, void(*_beginCb)(void)) :
82+
twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0),
83+
txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status(
84+
UNINITIALIZED), onBeginCallback(_beginCb) {
85+
// Empty
86+
}
87+
88+
void TwoWire::begin(void) {
89+
if (onBeginCallback)
90+
onBeginCallback();
91+
92+
// Disable PDC channel
93+
twi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
94+
95+
TWI_ConfigureMaster(twi, TWI_CLOCK, VARIANT_MCK);
96+
status = MASTER_IDLE;
97+
}
98+
99+
void TwoWire::begin(uint8_t address) {
100+
if (onBeginCallback)
101+
onBeginCallback();
102+
103+
// Disable PDC channel
104+
twi->TWI_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
105+
106+
TWI_ConfigureSlave(twi, address);
107+
status = SLAVE_IDLE;
108+
TWI_EnableIt(twi, TWI_IER_SVACC);
109+
//| TWI_IER_RXRDY | TWI_IER_TXRDY | TWI_IER_TXCOMP);
110+
}
111+
112+
void TwoWire::begin(int address) {
113+
begin((uint8_t) address);
114+
}
115+
116+
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
117+
if (quantity > BUFFER_LENGTH)
118+
quantity = BUFFER_LENGTH;
119+
120+
// perform blocking read into buffer
121+
int readed = 0;
122+
TWI_StartRead(twi, address, 0, 0);
123+
do {
124+
// Stop condition must be set during the reception of last byte
125+
if (readed + 1 == quantity)
126+
TWI_SendSTOPCondition( twi);
127+
128+
TWI_WaitByteReceived(twi, RECV_TIMEOUT);
129+
rxBuffer[readed++] = TWI_ReadByte(twi);
130+
} while (readed < quantity);
131+
TWI_WaitTransferComplete(twi, RECV_TIMEOUT);
132+
133+
// set rx buffer iterator vars
134+
rxBufferIndex = 0;
135+
rxBufferLength = readed;
136+
137+
return readed;
138+
}
139+
140+
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) {
141+
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
142+
}
143+
144+
uint8_t TwoWire::requestFrom(int address, int quantity) {
145+
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) true);
146+
}
147+
148+
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) {
149+
return requestFrom((uint8_t) address, (uint8_t) quantity, (uint8_t) sendStop);
150+
}
151+
152+
void TwoWire::beginTransmission(uint8_t address) {
153+
status = MASTER_SEND;
154+
155+
// save address of target and empty buffer
156+
txAddress = address;
157+
txBufferLength = 0;
158+
}
159+
160+
void TwoWire::beginTransmission(int address) {
161+
beginTransmission((uint8_t) address);
162+
}
163+
164+
//
165+
// Originally, 'endTransmission' was an f(void) function.
166+
// It has been modified to take one parameter indicating
167+
// whether or not a STOP should be performed on the bus.
168+
// Calling endTransmission(false) allows a sketch to
169+
// perform a repeated start.
170+
//
171+
// WARNING: Nothing in the library keeps track of whether
172+
// the bus tenure has been properly ended with a STOP. It
173+
// is very possible to leave the bus in a hung state if
174+
// no call to endTransmission(true) is made. Some I2C
175+
// devices will behave oddly if they do not see a STOP.
176+
//
177+
uint8_t TwoWire::endTransmission(uint8_t sendStop) {
178+
// transmit buffer (blocking)
179+
TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);
180+
TWI_WaitByteSent(twi, XMIT_TIMEOUT);
181+
int sent = 1;
182+
while (sent < txBufferLength) {
183+
TWI_WriteByte(twi, txBuffer[sent++]);
184+
TWI_WaitByteSent(twi, XMIT_TIMEOUT);
185+
}
186+
TWI_Stop( twi);
187+
TWI_WaitTransferComplete(twi, XMIT_TIMEOUT);
188+
189+
// empty buffer
190+
txBufferLength = 0;
191+
192+
status = MASTER_IDLE;
193+
return sent;
194+
}
195+
196+
// This provides backwards compatibility with the original
197+
// definition, and expected behaviour, of endTransmission
198+
//
199+
uint8_t TwoWire::endTransmission(void)
200+
{
201+
return endTransmission(true);
202+
}
203+
204+
size_t TwoWire::write(uint8_t data) {
205+
if (status == MASTER_SEND) {
206+
if (txBufferLength >= BUFFER_LENGTH)
207+
return 0;
208+
txBuffer[txBufferLength++] = data;
209+
return 1;
210+
} else {
211+
if (srvBufferLength >= BUFFER_LENGTH)
212+
return 0;
213+
srvBuffer[srvBufferLength++] = data;
214+
return 1;
215+
}
216+
}
217+
218+
size_t TwoWire::write(const uint8_t *data, size_t quantity) {
219+
if (status == MASTER_SEND) {
220+
for (size_t i = 0; i < quantity; ++i) {
221+
if (txBufferLength >= BUFFER_LENGTH)
222+
return i;
223+
txBuffer[txBufferLength++] = data[i];
224+
}
225+
} else {
226+
for (size_t i = 0; i < quantity; ++i) {
227+
if (srvBufferLength >= BUFFER_LENGTH)
228+
return i;
229+
srvBuffer[srvBufferLength++] = data[i];
230+
}
231+
}
232+
return quantity;
233+
}
234+
235+
int TwoWire::available(void) {
236+
return rxBufferLength - rxBufferIndex;
237+
}
238+
239+
int TwoWire::read(void) {
240+
if (rxBufferIndex < rxBufferLength)
241+
return rxBuffer[rxBufferIndex++];
242+
return -1;
243+
}
244+
245+
int TwoWire::peek(void) {
246+
if (rxBufferIndex < rxBufferLength)
247+
return rxBuffer[rxBufferIndex];
248+
return -1;
249+
}
250+
251+
void TwoWire::flush(void) {
252+
// Do nothing, use endTransmission(..) to force
253+
// data transfer.
254+
}
255+
256+
void TwoWire::onReceive(void(*function)(int)) {
257+
onReceiveCallback = function;
258+
}
259+
260+
void TwoWire::onRequest(void(*function)(void)) {
261+
onRequestCallback = function;
262+
}
263+
264+
void TwoWire::onService(void) {
265+
// Retrieve interrupt status
266+
uint32_t sr = TWI_GetStatus(twi);
267+
268+
if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
269+
TWI_DisableIt(twi, TWI_IDR_SVACC);
270+
TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
271+
| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);
272+
273+
srvBufferLength = 0;
274+
srvBufferIndex = 0;
275+
276+
// Detect if we should go into RECV or SEND status
277+
// SVREAD==1 means *master* reading -> SLAVE_SEND
278+
if (!TWI_STATUS_SVREAD(sr)) {
279+
status = SLAVE_RECV;
280+
} else {
281+
status = SLAVE_SEND;
282+
283+
// Alert calling program to generate a response ASAP
284+
if (onRequestCallback)
285+
onRequestCallback();
286+
else
287+
// create a default 1-byte response
288+
write((uint8_t) 0);
289+
}
290+
}
291+
292+
if (status != SLAVE_IDLE) {
293+
if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) {
294+
if (status == SLAVE_RECV && onReceiveCallback) {
295+
// Copy data into rxBuffer
296+
// (allows to receive another packet while the
297+
// user program reads actual data)
298+
for (uint8_t i = 0; i < srvBufferLength; ++i)
299+
rxBuffer[i] = srvBuffer[i];
300+
rxBufferIndex = 0;
301+
rxBufferLength = srvBufferLength;
302+
303+
// Alert calling program
304+
onReceiveCallback( rxBufferLength);
305+
}
306+
307+
// Transfer completed
308+
TWI_EnableIt(twi, TWI_SR_SVACC);
309+
TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
310+
| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
311+
status = SLAVE_IDLE;
312+
}
313+
}
314+
315+
if (status == SLAVE_RECV) {
316+
if (TWI_STATUS_RXRDY(sr)) {
317+
if (srvBufferLength < BUFFER_LENGTH)
318+
srvBuffer[srvBufferLength++] = TWI_ReadByte(twi);
319+
}
320+
}
321+
322+
if (status == SLAVE_SEND) {
323+
if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
324+
uint8_t c = 'x';
325+
if (srvBufferIndex < srvBufferLength)
326+
c = srvBuffer[srvBufferIndex++];
327+
TWI_WriteByte(twi, c);
328+
}
329+
}
330+
}
331+
332+
#if WIRE_INTERFACES_COUNT > 0
333+
static void Wire_Init(void) {
334+
pmc_enable_periph_clk(WIRE_INTERFACE_ID);
335+
PIO_Configure(
336+
g_APinDescription[PIN_WIRE_SDA].pPort,
337+
g_APinDescription[PIN_WIRE_SDA].ulPinType,
338+
g_APinDescription[PIN_WIRE_SDA].ulPin,
339+
g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
340+
PIO_Configure(
341+
g_APinDescription[PIN_WIRE_SCL].pPort,
342+
g_APinDescription[PIN_WIRE_SCL].ulPinType,
343+
g_APinDescription[PIN_WIRE_SCL].ulPin,
344+
g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);
345+
346+
NVIC_DisableIRQ(TWI1_IRQn);
347+
NVIC_ClearPendingIRQ(TWI1_IRQn);
348+
NVIC_SetPriority(TWI1_IRQn, 0);
349+
NVIC_EnableIRQ(TWI1_IRQn);
350+
}
351+
352+
TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init);
353+
354+
void WIRE_ISR_HANDLER(void) {
355+
Wire.onService();
356+
}
357+
#endif
358+
359+
#if WIRE_INTERFACES_COUNT > 1
360+
static void Wire1_Init(void) {
361+
pmc_enable_periph_clk(WIRE1_INTERFACE_ID);
362+
PIO_Configure(
363+
g_APinDescription[PIN_WIRE1_SDA].pPort,
364+
g_APinDescription[PIN_WIRE1_SDA].ulPinType,
365+
g_APinDescription[PIN_WIRE1_SDA].ulPin,
366+
g_APinDescription[PIN_WIRE1_SDA].ulPinConfiguration);
367+
PIO_Configure(
368+
g_APinDescription[PIN_WIRE1_SCL].pPort,
369+
g_APinDescription[PIN_WIRE1_SCL].ulPinType,
370+
g_APinDescription[PIN_WIRE1_SCL].ulPin,
371+
g_APinDescription[PIN_WIRE1_SCL].ulPinConfiguration);
372+
373+
NVIC_DisableIRQ(TWI0_IRQn);
374+
NVIC_ClearPendingIRQ(TWI0_IRQn);
375+
NVIC_SetPriority(TWI0_IRQn, 0);
376+
NVIC_EnableIRQ(TWI0_IRQn);
377+
}
378+
379+
TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init);
380+
381+
void WIRE1_ISR_HANDLER(void) {
382+
Wire1.onService();
383+
}
384+
#endif

0 commit comments

Comments
 (0)