source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/libraries/Wire/Wire.cpp@ 175

Last change on this file since 175 was 175, checked in by ertl-honda, 8 years ago

ライブラリを Arduino IDE 1.7.9 にupdate

File size: 7.4 KB
RevLine 
[136]1/*
[175]2 * TWI/I2C library for Arduino Zero
3 * Copyright (c) 2015 Arduino LLC. All rights reserved.
[136]4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20extern "C" {
21#include <string.h>
22}
23
[175]24#include <Arduino.h>
25#include <wiring_private.h>
26
[136]27#include "Wire.h"
28
[175]29TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL)
[136]30{
[175]31 this->sercom = s;
32 this->_uc_pinSDA=pinSDA;
33 this->_uc_pinSCL=pinSCL;
34 transmissionBegun = false;
[136]35}
36
37void TwoWire::begin(void) {
[175]38 //Master Mode
39 sercom->initMasterWIRE(TWI_CLOCK);
40 sercom->enableWIRE();
[136]41
[175]42 pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType);
43 pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType);
[136]44}
45
46void TwoWire::begin(uint8_t address) {
[175]47 //Slave mode
48 sercom->initSlaveWIRE(address);
49 sercom->enableWIRE();
50
51 pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType);
52 pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType);
[136]53}
54
[175]55void TwoWire::setClock(uint32_t baudrate) {
56 sercom->disableWIRE();
57 sercom->initMasterWIRE(baudrate);
58 sercom->enableWIRE();
59}
60
61void TwoWire::end() {
62 sercom->disableWIRE();
63}
64
[136]65uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit)
[175]66{
[136]67 if(quantity == 0)
68 {
69 return 0;
70 }
71
72 size_t byteRead = 0;
73
74 if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG))
75 {
76 // Read first data
77 rxBuffer.store_char(sercom->readDataWIRE());
78
79 // Connected to slave
[175]80 for (byteRead = 1; byteRead < quantity; ++byteRead)
[136]81 {
[175]82 sercom->prepareAckBitWIRE(); // Prepare Acknowledge
83 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_READ); // Prepare the ACK command for the slave
84 rxBuffer.store_char(sercom->readDataWIRE()); // Read data and send the ACK
[136]85 }
[175]86 sercom->prepareNackBitWIRE(); // Prepare NACK to stop slave transmission
87 //sercom->readDataWIRE(); // Clear data register to send NACK
88
89 if (stopBit)
90 {
91 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); // Send Stop
92 }
[136]93 }
94
95 return byteRead;
96}
97
98uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity)
99{
[175]100 return requestFrom(address, quantity, true);
[136]101}
102
103void TwoWire::beginTransmission(uint8_t address) {
[175]104 // save address of target and clear buffer
105 txAddress = address;
106 txBuffer.clear();
[136]107
[175]108 transmissionBegun = true;
[136]109}
110
111// Errors:
[175]112// 0 : Success
113// 1 : Data too long
114// 2 : NACK on transmit of address
115// 3 : NACK on transmit of data
116// 4 : Other error
[136]117uint8_t TwoWire::endTransmission(bool stopBit)
118{
[175]119 transmissionBegun = false ;
[136]120
[175]121 // Start I2C transmission
122 if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG ) )
[136]123 {
[175]124 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
125 return 2 ; // Address error
[136]126 }
127
[175]128 // Send all buffer
129 while( txBuffer.available() )
[136]130 {
[175]131 // Trying to send data
132 if ( !sercom->sendDataMasterWIRE( txBuffer.read_char() ) )
[136]133 {
134 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
[175]135 return 3 ; // Nack or error
[136]136 }
[175]137 }
138
139 if (stopBit)
140 {
141 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP);
142 }
[136]143
[175]144 return 0;
[136]145}
146
147uint8_t TwoWire::endTransmission()
148{
[175]149 return endTransmission(true);
[136]150}
151
152size_t TwoWire::write(uint8_t ucData)
153{
[175]154 if(sercom->isMasterWIRE())
155 {
156 // No writing, without begun transmission or a full buffer
157 if ( !transmissionBegun || txBuffer.isFull() )
[136]158 {
159 return 0 ;
160 }
161
[175]162 txBuffer.store_char( ucData ) ;
[136]163
[175]164 return 1 ;
165 }
166 else
167 {
168 if(sercom->sendDataSlaveWIRE( ucData ))
[136]169 {
[175]170 return 1;
[136]171 }
[175]172 }
[136]173
[175]174 return 0;
[136]175}
176
177size_t TwoWire::write(const uint8_t *data, size_t quantity)
178{
[175]179 //Try to store all data
180 for(size_t i = 0; i < quantity; ++i)
181 {
182 //Return the number of data stored, when the buffer is full (if write return 0)
183 if(!write(data[i]))
184 return i;
185 }
[136]186
[175]187 //All data stored
188 return quantity;
[136]189}
190
191int TwoWire::available(void)
192{
[175]193 return rxBuffer.available();
[136]194}
195
196int TwoWire::read(void)
197{
[175]198 return rxBuffer.read_char();
[136]199}
200
201int TwoWire::peek(void)
202{
[175]203 return rxBuffer.peek();
[136]204}
205
206void TwoWire::flush(void)
207{
[175]208 // Do nothing, use endTransmission(..) to force
209 // data transfer.
[136]210}
211
212void TwoWire::onReceive(void(*function)(int))
213{
[175]214 onReceiveCallback = function;
[136]215}
216
217void TwoWire::onRequest(void(*function)(void))
218{
[175]219 onRequestCallback = function;
[136]220}
221
222void TwoWire::onService(void)
223{
[175]224 if ( sercom->isSlaveWIRE() )
225 {
226 if(sercom->isStopDetectedWIRE() ||
227 (sercom->isAddressMatch() && sercom->isRestartDetectedWIRE() && !sercom->isMasterReadOperationWIRE())) //Stop or Restart detected
228 {
229 sercom->prepareAckBitWIRE();
230 sercom->prepareCommandBitsWire(0x03);
[136]231
[175]232 //Calling onReceiveCallback, if exists
233 if(onReceiveCallback)
234 {
235 onReceiveCallback(available());
236 }
237
238 rxBuffer.clear();
239 }
240 else if(sercom->isAddressMatch()) //Address Match
241 {
242 sercom->prepareAckBitWIRE();
243 sercom->prepareCommandBitsWire(0x03);
[136]244
[175]245 if(sercom->isMasterReadOperationWIRE()) //Is a request ?
246 {
247 // wait for data ready flag,
248 // before calling request callback
249 while(!sercom->isDataReadyWIRE());
[136]250
[175]251 //Calling onRequestCallback, if exists
252 if(onRequestCallback)
253 {
254 onRequestCallback();
255 }
256 }
257 }
258 else if(sercom->isDataReadyWIRE()) //Received data
259 {
260 if (rxBuffer.isFull()) {
261 sercom->prepareNackBitWIRE();
262 } else {
263 //Store data
264 rxBuffer.store_char(sercom->readDataWIRE());
[136]265
[175]266 sercom->prepareAckBitWIRE();
267 }
[136]268
[175]269 sercom->prepareCommandBitsWire(0x03);
270 }
271 }
272}
[136]273
[175]274#if WIRE_INTERFACES_COUNT > 0
275 /* In case new variant doesn't define these macros,
276 * we put here the ones for Arduino Zero.
277 *
278 * These values should be different on some variants!
279 */
280 #ifndef PERIPH_WIRE
281 #define PERIPH_WIRE sercom3
282 #define WIRE_IT_HANDLER SERCOM3_Handler
283 #endif // PERIPH_WIRE
284 TwoWire Wire(&PERIPH_WIRE, PIN_WIRE_SDA, PIN_WIRE_SCL);
[136]285
[175]286 void WIRE_IT_HANDLER(void) {
287 Wire.onService();
288 }
289#endif
[136]290
[175]291#if WIRE_INTERFACES_COUNT > 1
292 TwoWire Wire1(&PERIPH_WIRE1, PIN_WIRE1_SDA, PIN_WIRE1_SCL);
[136]293
[175]294 void WIRE1_IT_HANDLER(void) {
295 Wire1.onService();
296 }
297#endif
[136]298
[175]299#if WIRE_INTERFACES_COUNT > 2
300 TwoWire Wire2(&PERIPH_WIRE2, PIN_WIRE2_SDA, PIN_WIRE2_SCL);
[136]301
[175]302 void WIRE2_IT_HANDLER(void) {
303 Wire2.onService();
304 }
305#endif
[136]306
[175]307#if WIRE_INTERFACES_COUNT > 3
308 TwoWire Wire3(&PERIPH_WIRE3, PIN_WIRE3_SDA, PIN_WIRE3_SCL);
[136]309
[175]310 void WIRE3_IT_HANDLER(void) {
311 Wire3.onService();
312 }
313#endif
[136]314
[175]315#if WIRE_INTERFACES_COUNT > 4
316 TwoWire Wire4(&PERIPH_WIRE4, PIN_WIRE4_SDA, PIN_WIRE4_SCL);
[136]317
[175]318 void WIRE4_IT_HANDLER(void) {
319 Wire4.onService();
320 }
321#endif
[136]322
[175]323#if WIRE_INTERFACES_COUNT > 5
324 TwoWire Wire5(&PERIPH_WIRE5, PIN_WIRE5_SDA, PIN_WIRE5_SCL);
[136]325
[175]326 void WIRE5_IT_HANDLER(void) {
327 Wire5.onService();
328 }
329#endif
[136]330
Note: See TracBrowser for help on using the repository browser.