- Timestamp:
- Mar 28, 2016, 2:09:46 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/libraries/Wire/Wire.cpp
r136 r175 1 1 /* 2 * TwoWire.h - TWI/I2C library for Arduino Zero 3 * based on Copyright (c) 2011 Cristian Maglie <c.maglie@bug.st>. 4 * Copyright (c) 2014 Arduino. 5 * All rights reserved. 2 * TWI/I2C library for Arduino Zero 3 * Copyright (c) 2015 Arduino LLC. All rights reserved. 6 4 * 7 5 * This library is free software; you can redistribute it and/or … … 24 22 } 25 23 24 #include <Arduino.h> 25 #include <wiring_private.h> 26 26 27 #include "Wire.h" 27 #include "variant.h" 28 #include "wiring_digital.h" 29 30 TwoWire::TwoWire(SERCOM * s) 31 { 32 this->sercom = s;33 28 29 TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL) 30 { 31 this->sercom = s; 32 this->_uc_pinSDA=pinSDA; 33 this->_uc_pinSCL=pinSCL; 34 transmissionBegun = false; 34 35 } 35 36 36 37 void TwoWire::begin(void) { 37 38 39 40 41 pinPeripheral( PIN_WIRE_SDA, g_APinDescription[PIN_WIRE_SDA].ulPinType);42 pinPeripheral( PIN_WIRE_SCL, g_APinDescription[PIN_WIRE_SCL].ulPinType);38 //Master Mode 39 sercom->initMasterWIRE(TWI_CLOCK); 40 sercom->enableWIRE(); 41 42 pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType); 43 pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType); 43 44 } 44 45 45 46 void TwoWire::begin(uint8_t address) { 46 //Slave mode 47 sercom->initSlaveWIRE(address); 48 sercom->enableWIRE(); 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); 53 } 54 55 void TwoWire::setClock(uint32_t baudrate) { 56 sercom->disableWIRE(); 57 sercom->initMasterWIRE(baudrate); 58 sercom->enableWIRE(); 59 } 60 61 void TwoWire::end() { 62 sercom->disableWIRE(); 49 63 } 50 64 51 65 uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit) 52 { 66 { 53 67 if(quantity == 0) 54 68 { … … 56 70 } 57 71 58 59 72 size_t byteRead = 0; 60 73 61 74 if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG)) 62 75 { 63 64 76 // Read first data 65 77 rxBuffer.store_char(sercom->readDataWIRE()); 66 78 67 79 // Connected to slave 68 //while(toRead--) 69 for(byteRead = 0; byteRead < quantity; ++byteRead) 70 { 71 if( byteRead == quantity - 1) // Stop transmission 80 for (byteRead = 1; byteRead < quantity; ++byteRead) 81 { 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 85 } 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 } 93 } 94 95 return byteRead; 96 } 97 98 uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity) 99 { 100 return requestFrom(address, quantity, true); 101 } 102 103 void TwoWire::beginTransmission(uint8_t address) { 104 // save address of target and clear buffer 105 txAddress = address; 106 txBuffer.clear(); 107 108 transmissionBegun = true; 109 } 110 111 // Errors: 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 117 uint8_t TwoWire::endTransmission(bool stopBit) 118 { 119 transmissionBegun = false ; 120 121 // Start I2C transmission 122 if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG ) ) 123 { 124 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); 125 return 2 ; // Address error 126 } 127 128 // Send all buffer 129 while( txBuffer.available() ) 130 { 131 // Trying to send data 132 if ( !sercom->sendDataMasterWIRE( txBuffer.read_char() ) ) 133 { 134 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); 135 return 3 ; // Nack or error 136 } 137 } 138 139 if (stopBit) 140 { 141 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); 142 } 143 144 return 0; 145 } 146 147 uint8_t TwoWire::endTransmission() 148 { 149 return endTransmission(true); 150 } 151 152 size_t TwoWire::write(uint8_t ucData) 153 { 154 if(sercom->isMasterWIRE()) 155 { 156 // No writing, without begun transmission or a full buffer 157 if ( !transmissionBegun || txBuffer.isFull() ) 158 { 159 return 0 ; 160 } 161 162 txBuffer.store_char( ucData ) ; 163 164 return 1 ; 165 } 166 else 167 { 168 if(sercom->sendDataSlaveWIRE( ucData )) 169 { 170 return 1; 171 } 172 } 173 174 return 0; 175 } 176 177 size_t TwoWire::write(const uint8_t *data, size_t quantity) 178 { 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 } 186 187 //All data stored 188 return quantity; 189 } 190 191 int TwoWire::available(void) 192 { 193 return rxBuffer.available(); 194 } 195 196 int TwoWire::read(void) 197 { 198 return rxBuffer.read_char(); 199 } 200 201 int TwoWire::peek(void) 202 { 203 return rxBuffer.peek(); 204 } 205 206 void TwoWire::flush(void) 207 { 208 // Do nothing, use endTransmission(..) to force 209 // data transfer. 210 } 211 212 void TwoWire::onReceive(void(*function)(int)) 213 { 214 onReceiveCallback = function; 215 } 216 217 void TwoWire::onRequest(void(*function)(void)) 218 { 219 onRequestCallback = function; 220 } 221 222 void TwoWire::onService(void) 223 { 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); 231 232 //Calling onReceiveCallback, if exists 233 if(onReceiveCallback) 72 234 { 73 sercom->prepareNackBitWIRE(); // Prepare NACK to stop slave transmission 74 //sercom->readDataWIRE(); // Clear data register to send NACK 75 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); // Send Stop 235 onReceiveCallback(available()); 76 236 } 77 else // Continue transmission 237 238 rxBuffer.clear(); 239 } 240 else if(sercom->isAddressMatch()) //Address Match 241 { 242 sercom->prepareAckBitWIRE(); 243 sercom->prepareCommandBitsWire(0x03); 244 245 if(sercom->isMasterReadOperationWIRE()) //Is a request ? 78 246 { 79 sercom->prepareAckBitWIRE(); // Prepare Acknowledge 80 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_READ); // Prepare the ACK command for the slave 81 rxBuffer.store_char( sercom->readDataWIRE() ); // Read data and send the ACK 247 // wait for data ready flag, 248 // before calling request callback 249 while(!sercom->isDataReadyWIRE()); 250 251 //Calling onRequestCallback, if exists 252 if(onRequestCallback) 253 { 254 onRequestCallback(); 255 } 82 256 } 83 257 } 84 } 85 86 return byteRead; 87 } 88 89 uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity) 90 { 91 return requestFrom(address, quantity, true); 92 } 93 94 void TwoWire::beginTransmission(uint8_t address) { 95 // save address of target and clear buffer 96 txAddress = address; 97 txBuffer.clear(); 98 99 transmissionBegun = true; 100 } 101 102 // Errors: 103 // 0 : Success 104 // 1 : Data too long 105 // 2 : NACK on transmit of address 106 // 3 : NACK on transmit of data 107 // 4 : Other error 108 uint8_t TwoWire::endTransmission(bool stopBit) 109 { 110 transmissionBegun = false ; 111 112 // Check if there are data to send 113 if ( txBuffer.available() == 0) 114 { 115 return 4 ; 116 } 117 118 // Start I2C transmission 119 if ( !sercom->startTransmissionWIRE( txAddress, WIRE_WRITE_FLAG ) ) 120 { 121 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); 122 return 2 ; // Address error 123 } 124 125 // Send all buffer 126 while( txBuffer.available() ) 127 { 128 129 // Trying to send data 130 if ( !sercom->sendDataMasterWIRE( txBuffer.read_char() ) ) 131 { 132 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); 133 return 3 ; // Nack or error 134 } 135 136 137 if(txBuffer.available() == 0) 138 { 139 sercom->prepareCommandBitsWire(WIRE_MASTER_ACT_STOP); 140 } 141 } 142 143 return 0; 144 } 145 146 uint8_t TwoWire::endTransmission() 147 { 148 return endTransmission(true); 149 } 150 151 size_t TwoWire::write(uint8_t ucData) 152 { 153 if(sercom->isMasterWIRE()) 154 { 155 // No writing, without begun transmission or a full buffer 156 if ( !transmissionBegun || txBuffer.isFull() ) 157 { 158 return 0 ; 159 } 160 161 txBuffer.store_char( ucData ) ; 162 163 return 1 ; 164 } 165 else 166 { 167 if(sercom->sendDataSlaveWIRE( ucData )) 168 { 169 return 1; 170 } 171 } 172 173 return 0; 174 } 175 176 size_t TwoWire::write(const uint8_t *data, size_t quantity) 177 { 178 //Try to store all data 179 for(size_t i = 0; i < quantity; ++i) 180 { 181 //Return the number of data stored, when the buffer is full (if write return 0) 182 if(!write(data[i])) 183 return i; 184 } 185 186 //All data stored 187 return quantity; 188 } 189 190 int TwoWire::available(void) 191 { 192 return rxBuffer.available(); 193 } 194 195 int TwoWire::read(void) 196 { 197 return rxBuffer.read_char(); 198 } 199 200 int TwoWire::peek(void) 201 { 202 return rxBuffer.peek(); 203 } 204 205 void TwoWire::flush(void) 206 { 207 // Do nothing, use endTransmission(..) to force 208 // data transfer. 209 } 210 211 void TwoWire::onReceive(void(*function)(int)) 212 { 213 onReceiveCallback = function; 214 } 215 216 void TwoWire::onRequest(void(*function)(void)) 217 { 218 onRequestCallback = function; 219 } 220 221 222 void TwoWire::onService(void) 223 { 224 if ( sercom->isSlaveWIRE() ) 225 { 226 //Received data 227 if(sercom->isDataReadyWIRE()) 228 { 229 //Store data 230 rxBuffer.store_char(sercom->readDataWIRE()); 231 232 //Stop or Restart detected 233 if(sercom->isStopDetectedWIRE() || sercom->isRestartDetectedWIRE()) 234 { 235 //Calling onReceiveCallback, if exists 236 if(onReceiveCallback) 237 { 238 onReceiveCallback(available()); 239 } 240 } 241 } 242 243 //Address Match 244 if(sercom->isAddressMatch()) 245 { 246 //Is a request ? 247 if(sercom->isMasterReadOperationWIRE()) 248 { 249 //Calling onRequestCallback, if exists 250 if(onRequestCallback) 251 { 252 onRequestCallback(); 253 } 254 } 255 } 256 } 257 } 258 259 /* 260 void TwoWire::onService(void) 261 { 262 // Retrieve interrupt status 263 uint32_t sr = TWI_GetStatus(twi); 264 265 if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) { 266 TWI_DisableIt(twi, TWI_IDR_SVACC); 267 TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK 268 | TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP); 269 270 srvBufferLength = 0; 271 srvBufferIndex = 0; 272 273 // Detect if we should go into RECV or SEND status 274 // SVREAD==1 means *master* reading -> SLAVE_SEND 275 if (!TWI_STATUS_SVREAD(sr)) { 276 status = SLAVE_RECV; 277 } else { 278 status = SLAVE_SEND; 279 280 // Alert calling program to generate a response ASAP 281 if (onRequestCallback) 282 onRequestCallback(); 283 else 284 // create a default 1-byte response 285 write((uint8_t) 0); 286 } 287 } 288 289 if (status != SLAVE_IDLE) { 290 if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) { 291 if (status == SLAVE_RECV && onReceiveCallback) { 292 // Copy data into rxBuffer 293 // (allows to receive another packet while the 294 // user program reads actual data) 295 for (uint8_t i = 0; i < srvBufferLength; ++i) 296 rxBuffer[i] = srvBuffer[i]; 297 rxBufferIndex = 0; 298 rxBufferLength = srvBufferLength; 299 300 // Alert calling program 301 onReceiveCallback( rxBufferLength); 302 } 303 304 // Transfer completed 305 TWI_EnableIt(twi, TWI_SR_SVACC); 306 TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK 307 | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP); 308 status = SLAVE_IDLE; 309 } 310 } 311 312 if (status == SLAVE_RECV) { 313 if (TWI_STATUS_RXRDY(sr)) { 314 if (srvBufferLength < BUFFER_LENGTH) 315 srvBuffer[srvBufferLength++] = TWI_ReadByte(twi); 316 } 317 } 318 319 if (status == SLAVE_SEND) { 320 if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) { 321 uint8_t c = 'x'; 322 if (srvBufferIndex < srvBufferLength) 323 c = srvBuffer[srvBufferIndex++]; 324 TWI_WriteByte(twi, c); 325 } 326 } 327 } 328 */ 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()); 265 266 sercom->prepareAckBitWIRE(); 267 } 268 269 sercom->prepareCommandBitsWire(0x03); 270 } 271 } 272 } 329 273 330 274 #if WIRE_INTERFACES_COUNT > 0 331 /*static void Wire_Init(void) { 332 pmc_enable_periph_clk(WIRE_INTERFACE_ID); 333 PIO_Configure( 334 g_APinDescription[PIN_WIRE_SDA].pPort, 335 g_APinDescription[PIN_WIRE_SDA].ulPinType, 336 g_APinDescription[PIN_WIRE_SDA].ulPin, 337 g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration); 338 PIO_Configure( 339 g_APinDescription[PIN_WIRE_SCL].pPort, 340 g_APinDescription[PIN_WIRE_SCL].ulPinType, 341 g_APinDescription[PIN_WIRE_SCL].ulPin, 342 g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration); 343 344 NVIC_DisableIRQ(WIRE_ISR_ID); 345 NVIC_ClearPendingIRQ(WIRE_ISR_ID); 346 NVIC_SetPriority(WIRE_ISR_ID, 0); 347 NVIC_EnableIRQ(WIRE_ISR_ID); 348 }*/ 349 350 351 TwoWire Wire(&sercom3); 352 353 void SERCOM3_Handler(void) { 354 Wire.onService(); 355 } 356 357 #endif 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); 285 286 void WIRE_IT_HANDLER(void) { 287 Wire.onService(); 288 } 289 #endif 290 291 #if WIRE_INTERFACES_COUNT > 1 292 TwoWire Wire1(&PERIPH_WIRE1, PIN_WIRE1_SDA, PIN_WIRE1_SCL); 293 294 void WIRE1_IT_HANDLER(void) { 295 Wire1.onService(); 296 } 297 #endif 298 299 #if WIRE_INTERFACES_COUNT > 2 300 TwoWire Wire2(&PERIPH_WIRE2, PIN_WIRE2_SDA, PIN_WIRE2_SCL); 301 302 void WIRE2_IT_HANDLER(void) { 303 Wire2.onService(); 304 } 305 #endif 306 307 #if WIRE_INTERFACES_COUNT > 3 308 TwoWire Wire3(&PERIPH_WIRE3, PIN_WIRE3_SDA, PIN_WIRE3_SCL); 309 310 void WIRE3_IT_HANDLER(void) { 311 Wire3.onService(); 312 } 313 #endif 314 315 #if WIRE_INTERFACES_COUNT > 4 316 TwoWire Wire4(&PERIPH_WIRE4, PIN_WIRE4_SDA, PIN_WIRE4_SCL); 317 318 void WIRE4_IT_HANDLER(void) { 319 Wire4.onService(); 320 } 321 #endif 322 323 #if WIRE_INTERFACES_COUNT > 5 324 TwoWire Wire5(&PERIPH_WIRE5, PIN_WIRE5_SDA, PIN_WIRE5_SCL); 325 326 void WIRE5_IT_HANDLER(void) { 327 Wire5.onService(); 328 } 329 #endif 330
Note:
See TracChangeset
for help on using the changeset viewer.