Changeset 175 for rtos_arduino/trunk/arduino_lib/hardware
- Timestamp:
- Mar 28, 2016, 2:09:46 PM (8 years ago)
- Location:
- rtos_arduino/trunk/arduino_lib/hardware/arduino/samd
- Files:
-
- 128 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/SERCOM.cpp
r136 r175 1 /* 2 Copyright (c) 2014 Arduino. All right reserved. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 See the GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with this library; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 1 19 #include "SERCOM.h" 2 20 #include "variant.h" 3 21 22 4 23 SERCOM::SERCOM(Sercom* s) 5 24 { 6 25 sercom = s; 7 26 } 8 27 … … 13 32 void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate) 14 33 { 34 initClockNVIC(); 15 35 resetUART(); 16 initClockNVIC();17 36 18 37 //Setting the CTRLA register … … 26 45 if ( mode == UART_INT_CLOCK ) 27 46 { 28 uint16_t sampleRateValue ; 29 30 if ( sampleRate == SAMPLE_RATE_x16 ) 31 { 32 sampleRateValue = 16 ; 47 uint16_t sampleRateValue; 48 49 if (sampleRate == SAMPLE_RATE_x16) { 50 sampleRateValue = 16; 51 } else { 52 sampleRateValue = 8; 33 53 } 34 else 35 { 36 if ( sampleRate == SAMPLE_RATE_x8 ) 37 { 38 sampleRateValue = 8 ; 39 } 40 else 41 { 42 sampleRateValue = 3 ; 43 } 44 } 45 46 // Asynchronous arithmetic mode 47 // 65535 * ( 1 - sampleRateValue * baudrate / SystemCoreClock); 48 // 65535 - 65535 * (sampleRateValue * baudrate / SystemCoreClock)); 49 sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SystemCoreClock)); 54 55 // Asynchronous fractional mode (Table 24-2 in datasheet) 56 // BAUD = fref / (sampleRateValue * fbaud) 57 // (multiply by 8, to calculate fractional piece) 58 uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate); 59 60 sercom->USART.BAUD.FRAC.FP = (baudTimes8 % 8); 61 sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8); 50 62 } 51 63 } 52 64 void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits) 53 65 { 54 55 56 57 58 59 60 61 66 //Setting the CTRLA register 67 sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) | 68 dataOrder << SERCOM_USART_CTRLA_DORD_Pos; 69 70 //Setting the CTRLB register 71 sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(charSize) | 72 nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos | 73 (parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value 62 74 } 63 75 64 76 void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad) 65 77 { 66 67 68 78 //Setting the CTRLA register 79 sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txPad) | 80 SERCOM_USART_CTRLA_RXPO(rxPad); 69 81 70 82 // Enable Transceiver and Receiver … … 85 97 void SERCOM::enableUART() 86 98 { 87 88 89 90 91 99 //Setting the enable bit to 1 100 sercom->USART.CTRLA.bit.ENABLE = 0x1u; 101 102 //Wait for then enable bit from SYNCBUSY is equal to 0; 103 while(sercom->USART.SYNCBUSY.bit.ENABLE); 92 104 } 93 105 94 106 void SERCOM::flushUART() 95 107 { 96 97 while(sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);108 // Wait for transmission to complete 109 while(!sercom->USART.INTFLAG.bit.TXC); 98 110 } 99 111 100 112 void SERCOM::clearStatusUART() 101 113 { 102 103 114 //Reset (with 0) the STATUS register 115 sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE; 104 116 } 105 117 106 118 bool SERCOM::availableDataUART() 107 119 { 108 //RXC : Receive Complete 109 return sercom->USART.INTFLAG.bit.RXC; 120 //RXC : Receive Complete 121 return sercom->USART.INTFLAG.bit.RXC; 122 } 123 124 bool SERCOM::isUARTError() 125 { 126 return sercom->USART.INTFLAG.bit.ERROR; 127 } 128 129 void SERCOM::acknowledgeUARTError() 130 { 131 sercom->USART.INTFLAG.bit.ERROR = 1; 110 132 } 111 133 112 134 bool SERCOM::isBufferOverflowErrorUART() 113 135 { 114 115 136 //BUFOVF : Buffer Overflow 137 return sercom->USART.STATUS.bit.BUFOVF; 116 138 } 117 139 118 140 bool SERCOM::isFrameErrorUART() 119 141 { 120 121 142 //FERR : Frame Error 143 return sercom->USART.STATUS.bit.FERR; 122 144 } 123 145 124 146 bool SERCOM::isParityErrorUART() 125 147 { 126 127 148 //PERR : Parity Error 149 return sercom->USART.STATUS.bit.PERR; 128 150 } 129 151 130 152 bool SERCOM::isDataRegisterEmptyUART() 131 153 { 132 133 154 //DRE : Data Register Empty 155 return sercom->USART.INTFLAG.bit.DRE; 134 156 } 135 157 136 158 uint8_t SERCOM::readDataUART() 137 159 { 138 160 return sercom->USART.DATA.bit.DATA; 139 161 } 140 162 141 163 int SERCOM::writeDataUART(uint8_t data) 142 164 { 143 //Flush UART buffer 144 flushUART();145 146 147 148 165 // Wait for data register to be empty 166 while(!isDataRegisterEmptyUART()); 167 168 //Put data into DATA register 169 sercom->USART.DATA.reg = (uint16_t)data; 170 return 1; 149 171 } 150 172 … … 155 177 void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) 156 178 { 179 resetSPI(); 180 initClockNVIC(); 181 182 //Setting the CTRLA register 183 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER | 184 SERCOM_SPI_CTRLA_DOPO(mosi) | 185 SERCOM_SPI_CTRLA_DIPO(miso) | 186 dataOrder << SERCOM_SPI_CTRLA_DORD_Pos; 187 188 //Setting the CTRLB register 189 sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) | 190 SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver. 191 192 193 } 194 195 void SERCOM::initSPIslave(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) 196 { 157 197 resetSPI(); 158 198 initClockNVIC(); 159 199 160 //Setting the CTRLA register 161 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER | 162 SERCOM_SPI_CTRLA_DOPO(mosi) | 163 SERCOM_SPI_CTRLA_DIPO(miso) | 164 dataOrder << SERCOM_SPI_CTRLA_DORD_Pos; 165 166 //Setting the CTRLB register 200 sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_SLAVE | 201 SERCOM_SPI_CTRLA_DOPO(mosi) | //provo a modificare 202 SERCOM_SPI_CTRLA_DIPO(miso) | //provo a modificare 203 dataOrder << SERCOM_SPI_CTRLA_DORD_Pos; 204 167 205 sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) | 168 SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver. 169 170 206 SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver. 207 171 208 } 172 209 173 210 void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) 174 211 { 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 212 //Extract data from clockMode 213 int cpha, cpol; 214 215 if((clockMode & (0x1ul)) == 0 ) 216 cpha = 0; 217 else 218 cpha = 1; 219 220 if((clockMode & (0x2ul)) == 0) 221 cpol = 0; 222 else 223 cpol = 1; 224 225 //Setting the CTRLA register 226 sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) | 227 ( cpol << SERCOM_SPI_CTRLA_CPOL_Pos ); 228 229 //Synchronous arithmetic 230 sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate); 194 231 } 195 232 196 233 void SERCOM::resetSPI() 197 234 { 198 199 200 201 202 235 //Setting the Software Reset bit to 1 236 sercom->SPI.CTRLA.bit.SWRST = 1; 237 238 //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0 239 while(sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.bit.SWRST); 203 240 } 204 241 205 242 void SERCOM::enableSPI() 206 243 { 207 208 209 210 244 //Setting the enable bit to 1 245 sercom->SPI.CTRLA.bit.ENABLE = 1; 246 247 while(sercom->SPI.SYNCBUSY.bit.ENABLE) 211 248 { 212 249 //Waiting then enable bit from SYNCBUSY is equal to 0; … … 216 253 void SERCOM::disableSPI() 217 254 { 218 219 220 221 255 //Setting the enable bit to 0 256 sercom->SPI.CTRLA.bit.ENABLE = 0; 257 258 while(sercom->SPI.SYNCBUSY.bit.ENABLE) 222 259 { 223 260 //Waiting then enable bit from SYNCBUSY is equal to 0; … … 227 264 void SERCOM::setDataOrderSPI(SercomDataOrder dataOrder) 228 265 { 229 //Register enable-protected 230 disableSPI(); 231 232 sercom->SPI.CTRLA.bit.DORD = dataOrder; 233 234 enableSPI(); 235 } 236 237 void SERCOM::setBaudrateSPI(uint8_t divider) 238 { 239 //Can't divide by 0 240 if(divider == 0) 241 return; 242 243 //Register enable-protected 244 disableSPI(); 245 246 sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider ); 247 248 enableSPI(); 266 //Register enable-protected 267 disableSPI(); 268 269 sercom->SPI.CTRLA.bit.DORD = dataOrder; 270 271 enableSPI(); 272 } 273 274 SercomDataOrder SERCOM::getDataOrderSPI() 275 { 276 return (sercom->SPI.CTRLA.bit.DORD ? LSB_FIRST : MSB_FIRST); 277 } 278 279 void SERCOM::setBaudrateSPI(uint16_t divider) 280 { 281 //Can't divide by 0 282 if(divider == 0) 283 return; 284 285 //Register enable-protected 286 disableSPI(); 287 288 sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider ); 289 290 enableSPI(); 249 291 } 250 292 251 293 void SERCOM::setClockModeSPI(SercomSpiClockMode clockMode) 252 294 { 253 int cpha, cpol; 254 if((clockMode & (0x1ul)) == 0) 255 cpha = 0; 256 else 257 cpha = 1; 258 259 if((clockMode & (0x2ul)) == 0) 260 cpol = 0; 261 else 262 cpol = 1; 263 264 //Register enable-protected 265 disableSPI(); 266 267 sercom->SPI.CTRLA.bit.CPOL = cpol; 268 sercom->SPI.CTRLA.bit.CPHA = cpha; 269 270 enableSPI(); 271 } 295 int cpha, cpol; 296 if((clockMode & (0x1ul)) == 0) 297 cpha = 0; 298 else 299 cpha = 1; 300 301 if((clockMode & (0x2ul)) == 0) 302 cpol = 0; 303 else 304 cpol = 1; 305 306 //Register enable-protected 307 disableSPI(); 308 309 sercom->SPI.CTRLA.bit.CPOL = cpol; 310 sercom->SPI.CTRLA.bit.CPHA = cpha; 311 312 enableSPI(); 313 } 314 272 315 void SERCOM::writeDataSPI(uint8_t data) 273 316 { … … 276 319 // Waiting Data Registry Empty 277 320 } 278 279 sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register 321 sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register 280 322 281 323 while( sercom->SPI.INTFLAG.bit.TXC == 0 || sercom->SPI.INTFLAG.bit.DRE == 0 ) … … 292 334 } 293 335 294 336 return sercom->SPI.DATA.bit.DATA; // Reading data 295 337 } 296 338 297 339 bool SERCOM::isBufferOverflowErrorSPI() 298 340 { 299 341 return sercom->SPI.STATUS.bit.BUFOVF; 300 342 } 301 343 302 344 bool SERCOM::isDataRegisterEmptySPI() 303 345 { 304 //DRE : Data Register Empty 305 return sercom->SPI.INTFLAG.bit.DRE; 306 } 346 //DRE : Data Register Empty 347 return sercom->SPI.INTFLAG.bit.DRE; 348 } 349 350 //bool SERCOM::isTransmitCompleteSPI() 351 //{ 352 // //TXC : Transmit complete 353 // return sercom->SPI.INTFLAG.bit.TXC; 354 //} 355 // 356 //bool SERCOM::isReceiveCompleteSPI() 357 //{ 358 // //RXC : Receive complete 359 // return sercom->SPI.INTFLAG.bit.RXC; 360 //} 307 361 308 362 uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) 309 363 { 310 364 return SERCOM_FREQ_REF / (2 * baudrate) - 1; 311 365 } 312 366 … … 315 369 * ===== Sercom WIRE 316 370 * ========================= 317 */ 318 371 */ 319 372 void SERCOM::resetWIRE() 320 373 { 321 322 323 324 325 326 327 374 //I2CM OR I2CS, no matter SWRST is the same bit. 375 376 //Setting the Software bit to 1 377 sercom->I2CM.CTRLA.bit.SWRST = 1; 378 379 //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0 380 while(sercom->I2CM.CTRLA.bit.SWRST || sercom->I2CM.SYNCBUSY.bit.SWRST); 328 381 } 329 382 … … 371 424 sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ; 372 425 373 // Enable Quick Command374 sercom->I2CM.CTRLB.bit.QCEN = 1 ;375 376 426 sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits 377 SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ; 427 SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ; // 0x3FF all bits set 378 428 379 429 // Set the interrupt register 380 sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_AMATCH | // Address Match 381 SERCOM_I2CS_INTENSET_DRDY ; // Data Ready 430 sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC | // Stop 431 SERCOM_I2CS_INTENSET_AMATCH | // Address Match 432 SERCOM_I2CS_INTENSET_DRDY ; // Data Ready 382 433 383 434 while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 ) … … 395 446 396 447 // Set master mode and enable SCL Clock Stretch mode (stretch after ACK bit) 397 sercom->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE( I2C_MASTER_OPERATION ); 448 sercom->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE( I2C_MASTER_OPERATION )/* | 449 SERCOM_I2CM_CTRLA_SCLSM*/ ; 398 450 399 451 // Enable Smart mode and Quick Command 452 //sercom->I2CM.CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN /*| SERCOM_I2CM_CTRLB_QCEN*/ ; 453 400 454 401 455 // Enable all interrupts 456 // sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ; 402 457 403 458 // Synchronous arithmetic baudrate … … 407 462 void SERCOM::prepareNackBitWIRE( void ) 408 463 { 409 // Send a NACK 410 sercom->I2CM.CTRLB.bit.ACKACT = 1; 464 if(isMasterWIRE()) { 465 // Send a NACK 466 sercom->I2CM.CTRLB.bit.ACKACT = 1; 467 } else { 468 sercom->I2CS.CTRLB.bit.ACKACT = 1; 469 } 411 470 } 412 471 413 472 void SERCOM::prepareAckBitWIRE( void ) 414 473 { 415 // Send an ACK 416 sercom->I2CM.CTRLB.bit.ACKACT = 0; 417 } 418 419 void SERCOM::prepareCommandBitsWire(SercomMasterCommandWire cmd) 420 { 421 sercom->I2CM.CTRLB.bit.CMD = cmd; 422 423 while(sercom->I2CM.SYNCBUSY.bit.SYSOP) 424 { 425 // Waiting for synchronization 474 if(isMasterWIRE()) { 475 // Send an ACK 476 sercom->I2CM.CTRLB.bit.ACKACT = 0; 477 } else { 478 sercom->I2CS.CTRLB.bit.ACKACT = 0; 479 } 480 } 481 482 void SERCOM::prepareCommandBitsWire(uint8_t cmd) 483 { 484 if(isMasterWIRE()) { 485 sercom->I2CM.CTRLB.bit.CMD = cmd; 486 487 while(sercom->I2CM.SYNCBUSY.bit.SYSOP) 488 { 489 // Waiting for synchronization 490 } 491 } else { 492 sercom->I2CS.CTRLB.bit.CMD = cmd; 426 493 } 427 494 } … … 432 499 address = (address << 0x1ul) | flag; 433 500 434 // Wait idle bus mode 435 while ( !isBusIdleWIRE() ); 501 502 // Wait idle or owner bus mode 503 while ( !isBusIdleWIRE() && !isBusOwnerWIRE() ); 436 504 437 505 // Send start and address 438 506 sercom->I2CM.ADDR.bit.ADDR = address; 507 439 508 440 509 // Address Transmitted … … 450 519 while( !sercom->I2CM.INTFLAG.bit.SB ) 451 520 { 521 // If the slave NACKS the address, the MB bit will be set. 522 // In that case, send a stop condition and return false. 523 if (sercom->I2CM.INTFLAG.bit.MB) { 524 sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition 525 return false; 526 } 452 527 // Wait transmission complete 453 528 } … … 471 546 bool SERCOM::sendDataMasterWIRE(uint8_t data) 472 547 { 473 //Send data 474 sercom->I2CM.DATA.bit.DATA = data; 475 476 //Wait transmission successful 477 while(!sercom->I2CM.INTFLAG.bit.MB); 478 479 //Problems on line? nack received? 480 if(sercom->I2CM.STATUS.bit.RXNACK) 481 return false; 482 else 483 return true; 548 //Send data 549 sercom->I2CM.DATA.bit.DATA = data; 550 551 //Wait transmission successful 552 while(!sercom->I2CM.INTFLAG.bit.MB) { 553 554 // If a bus error occurs, the MB bit may never be set. 555 // Check the bus error bit and bail if it's set. 556 if (sercom->I2CM.STATUS.bit.BUSERR) { 557 return false; 558 } 559 } 560 561 //Problems on line? nack received? 562 if(sercom->I2CM.STATUS.bit.RXNACK) 563 return false; 564 else 565 return true; 484 566 } 485 567 486 568 bool SERCOM::sendDataSlaveWIRE(uint8_t data) 487 569 { 488 489 490 491 492 493 494 495 496 497 498 570 //Send data 571 sercom->I2CS.DATA.bit.DATA = data; 572 573 //Wait data transmission successful 574 while(!sercom->I2CS.INTFLAG.bit.DRDY); 575 576 //Problems on line? nack received? 577 if(sercom->I2CS.STATUS.bit.RXNACK) 578 return false; 579 else 580 return true; 499 581 } 500 582 501 583 bool SERCOM::isMasterWIRE( void ) 502 584 { 503 585 return sercom->I2CS.CTRLA.bit.MODE == I2C_MASTER_OPERATION; 504 586 } 505 587 506 588 bool SERCOM::isSlaveWIRE( void ) 507 589 { 508 590 return sercom->I2CS.CTRLA.bit.MODE == I2C_SLAVE_OPERATION; 509 591 } 510 592 511 593 bool SERCOM::isBusIdleWIRE( void ) 512 594 { 513 return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE; 595 return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE; 596 } 597 598 bool SERCOM::isBusOwnerWIRE( void ) 599 { 600 return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE; 514 601 } 515 602 516 603 bool SERCOM::isDataReadyWIRE( void ) 517 604 { 518 605 return sercom->I2CS.INTFLAG.bit.DRDY; 519 606 } 520 607 521 608 bool SERCOM::isStopDetectedWIRE( void ) 522 609 { 523 610 return sercom->I2CS.INTFLAG.bit.PREC; 524 611 } 525 612 526 613 bool SERCOM::isRestartDetectedWIRE( void ) 527 614 { 528 615 return sercom->I2CS.STATUS.bit.SR; 529 616 } 530 617 531 618 bool SERCOM::isAddressMatch( void ) 532 619 { 533 620 return sercom->I2CS.INTFLAG.bit.AMATCH; 534 621 } 535 622 … … 546 633 int SERCOM::availableWIRE( void ) 547 634 { 548 549 550 551 635 if(isMasterWIRE()) 636 return sercom->I2CM.INTFLAG.bit.SB; 637 else 638 return sercom->I2CS.INTFLAG.bit.DRDY; 552 639 } 553 640 … … 572 659 void SERCOM::initClockNVIC( void ) 573 660 { 574 uint8_t clockId = 0; 575 IRQn_Type IdNvic; 576 577 if(sercom == SERCOM0) 578 { 579 clockId = GCM_SERCOM0_CORE; 580 IdNvic = SERCOM0_IRQn; 581 } 582 else if(sercom == SERCOM1) 583 { 584 clockId = GCM_SERCOM1_CORE; 585 IdNvic = SERCOM1_IRQn; 586 } 587 else if(sercom == SERCOM2) 588 { 589 clockId = GCM_SERCOM2_CORE; 590 IdNvic = SERCOM2_IRQn; 591 } 592 else if(sercom == SERCOM3) 593 { 594 clockId = GCM_SERCOM3_CORE; 595 IdNvic = SERCOM3_IRQn; 596 } 597 else if(sercom == SERCOM4) 598 { 599 clockId = GCM_SERCOM4_CORE; 600 IdNvic = SERCOM4_IRQn; 601 } 602 else if(sercom == SERCOM5) 603 { 604 clockId = GCM_SERCOM5_CORE; 605 IdNvic = SERCOM5_IRQn; 606 } 607 608 // Setting NVIC 609 NVIC_EnableIRQ(IdNvic); 610 NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */ 611 612 //Setting clock 613 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx) 614 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 615 GCLK_CLKCTRL_CLKEN ; 616 617 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 618 { 619 /* Wait for synchronization */ 620 } 621 622 } 661 uint8_t clockId = 0; 662 IRQn_Type IdNvic=PendSV_IRQn ; // Dummy init to intercept potential error later 663 664 if(sercom == SERCOM0) 665 { 666 clockId = GCM_SERCOM0_CORE; 667 IdNvic = SERCOM0_IRQn; 668 } 669 else if(sercom == SERCOM1) 670 { 671 clockId = GCM_SERCOM1_CORE; 672 IdNvic = SERCOM1_IRQn; 673 } 674 else if(sercom == SERCOM2) 675 { 676 clockId = GCM_SERCOM2_CORE; 677 IdNvic = SERCOM2_IRQn; 678 } 679 else if(sercom == SERCOM3) 680 { 681 clockId = GCM_SERCOM3_CORE; 682 IdNvic = SERCOM3_IRQn; 683 } 684 else if(sercom == SERCOM4) 685 { 686 clockId = GCM_SERCOM4_CORE; 687 IdNvic = SERCOM4_IRQn; 688 } 689 else if(sercom == SERCOM5) 690 { 691 clockId = GCM_SERCOM5_CORE; 692 IdNvic = SERCOM5_IRQn; 693 } 694 695 if ( IdNvic == PendSV_IRQn ) 696 { 697 // We got a problem here 698 return ; 699 } 700 701 // Setting NVIC 702 NVIC_EnableIRQ(IdNvic); 703 NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */ 704 705 //Setting clock 706 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx) 707 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source 708 GCLK_CLKCTRL_CLKEN ; 709 710 while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) 711 { 712 /* Wait for synchronization */ 713 } 714 } -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/SERCOM.h
r136 r175 1 /* 2 Copyright (c) 2014 Arduino. All right reserved. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 See the GNU Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with this library; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 1 19 #ifndef _SERCOM_CLASS_ 2 20 #define _SERCOM_CLASS_ … … 62 80 typedef enum 63 81 { 64 UART_TX_PAD_0 = 0x0ul, //Only for UART 65 UART_TX_PAD_2 = 0x1ul, //Only for UART 82 UART_TX_PAD_0 = 0x0ul, // Only for UART 83 UART_TX_PAD_2 = 0x1ul, // Only for UART 84 UART_TX_RTS_CTS_PAD_0_2_3 = 0x2ul, // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3 66 85 } SercomUartTXPad; 67 86 68 87 typedef enum 69 88 { 70 SAMPLE_RATE_x16 = 0, //Arithmetic 71 SAMPLE_RATE_x8 = 0x2, //Arithmetic 72 SAMPLE_RATE_x3 = 0x3 //Arithmetic 89 SAMPLE_RATE_x16 = 0x1, //Fractional 90 SAMPLE_RATE_x8 = 0x3, //Fractional 73 91 } SercomUartSampleRate; 74 92 … … 144 162 uint8_t readDataUART( void ) ; 145 163 int writeDataUART(uint8_t data) ; 164 bool isUARTError() ; 165 void acknowledgeUARTError() ; 146 166 147 167 /* ========== SPI ========== */ 148 168 void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ; 169 void initSPIslave(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder); 149 170 void initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) ; 150 171 … … 153 174 void disableSPI( void ) ; 154 175 void setDataOrderSPI(SercomDataOrder dataOrder) ; 155 void setBaudrateSPI(uint8_t divider) ; 176 SercomDataOrder getDataOrderSPI( void ) ; 177 void setBaudrateSPI(uint16_t divider) ; 156 178 void setClockModeSPI(SercomSpiClockMode clockMode) ; 157 179 void writeDataSPI(uint8_t data) ; … … 168 190 void resetWIRE( void ) ; 169 191 void enableWIRE( void ) ; 170 171 172 173 void prepareCommandBitsWire(SercomMasterCommandWirecmd);192 void disableWIRE( void ); 193 void prepareNackBitWIRE( void ) ; 194 void prepareAckBitWIRE( void ) ; 195 void prepareCommandBitsWire(uint8_t cmd); 174 196 bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ; 175 197 bool sendDataMasterWIRE(uint8_t data) ; … … 178 200 bool isSlaveWIRE( void ) ; 179 201 bool isBusIdleWIRE( void ) ; 202 bool isBusOwnerWIRE( void ) ; 180 203 bool isDataReadyWIRE( void ) ; 181 204 bool isStopDetectedWIRE( void ) ; … … 183 206 bool isAddressMatch( void ) ; 184 207 bool isMasterReadOperationWIRE( void ) ; 185 208 bool isRXNackReceivedWIRE( void ) ; 186 209 int availableWIRE( void ) ; 187 210 uint8_t readDataWIRE( void ) ; -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/wiring.c
r136 r175 80 80 ADC_CTRLB_RESSEL_10BIT; // Result on 10 bits 81 81 ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | // No Negative input (Internal Ground) 82 ADC_INPUTCTRL_GAIN_ 1X; // Gain setted to 182 ADC_INPUTCTRL_GAIN_DIV2; // Gain setted to 1/2 83 83 // Averaging (see table 31-2 p.816 datasheet) 84 84 ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_2 | // 2 samples -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/wiring_analog.c
r137 r175 64 64 void analogReference( eAnalogReference ulMode ) 65 65 { 66 67 // ATTENTION : On this board the default is not 5volts or 3.3volts BUT 1.65 volt68 69 66 70 67 -
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 -
rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/libraries/Wire/Wire.h
r136 r175 1 1 /* 2 * TwoWire.h - TWI/I2C library for Arduino Due 3 * Copyright (c) 2011 Cristian Maglie <c.maglie@bug.st>. 4 * All rights reserved. 2 * TWI/I2C library for Arduino Zero 3 * Copyright (c) 2015 Arduino LLC. All rights reserved. 5 4 * 6 5 * This library is free software; you can redistribute it and/or … … 22 21 #define TwoWire_h 23 22 24 //#include <include/twi.h>25 26 23 #include "Stream.h" 27 24 #include "variant.h" … … 32 29 #define BUFFER_LENGTH 32 33 30 31 // WIRE_HAS_END means Wire has end() 32 #define WIRE_HAS_END 1 34 33 35 34 class TwoWire : public Stream 36 35 { 37 public: 38 TwoWire(SERCOM *s); 39 void begin(); 40 void begin(uint8_t); 36 public: 37 TwoWire(SERCOM *s, uint8_t pinSDA, uint8_t pinSCL); 38 void begin(); 39 void begin(uint8_t); 40 void end(); 41 void setClock(uint32_t); 41 42 42 43 44 43 void beginTransmission(uint8_t); 44 uint8_t endTransmission(bool stopBit); 45 uint8_t endTransmission(void); 45 46 46 47 47 uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit); 48 uint8_t requestFrom(uint8_t address, size_t quantity); 48 49 49 50 50 size_t write(uint8_t data); 51 size_t write(const uint8_t * data, size_t quantity); 51 52 52 53 54 55 56 57 53 virtual int available(void); 54 virtual int read(void); 55 virtual int peek(void); 56 virtual void flush(void); 57 void onReceive(void(*)(int)); 58 void onRequest(void(*)(void)); 58 59 59 60 using Print::write; 60 61 61 62 void onService(void); 62 63 63 private: 64 SERCOM * sercom; 65 bool transmissionBegun; 64 private: 65 SERCOM * sercom; 66 uint8_t _uc_pinSDA; 67 uint8_t _uc_pinSCL; 66 68 67 // RX Buffer 68 RingBuffer rxBuffer; 69 bool transmissionBegun; 69 70 70 //TX buffer 71 RingBuffer txBuffer; 72 uint8_t txAddress; 71 // RX Buffer 72 RingBuffer rxBuffer; 73 74 //TX buffer 75 RingBuffer txBuffer; 76 uint8_t txAddress; 73 77 74 78 75 76 77 78 79 // Service buffer 80 //uint8_t srvBuffer[BUFFER_LENGTH]; 81 //uint8_t srvBufferIndex; 82 //uint8_t srvBufferLength; 79 83 80 81 82 84 // Callback user functions 85 void (*onRequestCallback)(void); 86 void (*onReceiveCallback)(int); 83 87 84 85 88 // TWI state 89 //enum TwoWireStatus 86 90 //{ 87 //UNINITIALIZED,88 //MASTER_IDLE,89 //MASTER_SEND,90 //MASTER_RECV,91 //SLAVE_IDLE,92 //SLAVE_RECV,93 //SLAVE_SEND94 95 91 // UNINITIALIZED, 92 // MASTER_IDLE, 93 // MASTER_SEND, 94 // MASTER_RECV, 95 // SLAVE_IDLE, 96 // SLAVE_RECV, 97 // SLAVE_SEND 98 //}; 99 //TwoWireStatus status; 96 100 97 98 101 // TWI clock frequency 102 static const uint32_t TWI_CLOCK = 100000; 99 103 100 101 102 104 // Timeouts 105 //static const uint32_t RECV_TIMEOUT = 100000; 106 //static const uint32_t XMIT_TIMEOUT = 100000; 103 107 }; 104 108 105 extern TwoWire Wire; 109 #if WIRE_INTERFACES_COUNT > 0 110 extern TwoWire Wire; 111 #endif 112 #if WIRE_INTERFACES_COUNT > 1 113 extern TwoWire Wire1; 114 #endif 115 #if WIRE_INTERFACES_COUNT > 2 116 extern TwoWire Wire2; 117 #endif 118 #if WIRE_INTERFACES_COUNT > 3 119 extern TwoWire Wire3; 120 #endif 121 #if WIRE_INTERFACES_COUNT > 4 122 extern TwoWire Wire4; 123 #endif 124 #if WIRE_INTERFACES_COUNT > 5 125 extern TwoWire Wire5; 126 #endif 106 127 107 128 #endif
Note:
See TracChangeset
for help on using the changeset viewer.