Ignore:
Timestamp:
Mar 28, 2016, 2:09:46 PM (8 years ago)
Author:
ertl-honda
Message:

ライブラリを Arduino IDE 1.7.9 にupdate

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/libraries/Wire/Wire.cpp

    r136 r175  
    11/*
    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.
    64 *
    75 * This library is free software; you can redistribute it and/or
     
    2422}
    2523
     24#include <Arduino.h>
     25#include <wiring_private.h>
     26
    2627#include "Wire.h"
    27 #include "variant.h"
    28 #include "wiring_digital.h"
    29 
    30 TwoWire::TwoWire(SERCOM * s)
    31 {
    32         this->sercom = s;
    33         transmissionBegun = false;
     28
     29TwoWire::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;
    3435}
    3536
    3637void TwoWire::begin(void) {
    37         //Master Mode
    38         sercom->initMasterWIRE(TWI_CLOCK);
    39         sercom->enableWIRE();
    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);
    4344}
    4445
    4546void 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
     55void TwoWire::setClock(uint32_t baudrate) {
     56  sercom->disableWIRE();
     57  sercom->initMasterWIRE(baudrate);
     58  sercom->enableWIRE();
     59}
     60
     61void TwoWire::end() {
     62  sercom->disableWIRE();
    4963}
    5064
    5165uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool stopBit)
    52 { 
     66{
    5367  if(quantity == 0)
    5468  {
     
    5670  }
    5771
    58 
    5972  size_t byteRead = 0;
    6073
    6174  if(sercom->startTransmissionWIRE(address, WIRE_READ_FLAG))
    6275  {
    63  
    6476    // Read first data
    6577    rxBuffer.store_char(sercom->readDataWIRE());
    6678
    6779    // 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
     98uint8_t TwoWire::requestFrom(uint8_t address, size_t quantity)
     99{
     100  return requestFrom(address, quantity, true);
     101}
     102
     103void 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
     117uint8_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
     147uint8_t TwoWire::endTransmission()
     148{
     149  return endTransmission(true);
     150}
     151
     152size_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
     177size_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
     191int TwoWire::available(void)
     192{
     193  return rxBuffer.available();
     194}
     195
     196int TwoWire::read(void)
     197{
     198  return rxBuffer.read_char();
     199}
     200
     201int TwoWire::peek(void)
     202{
     203  return rxBuffer.peek();
     204}
     205
     206void TwoWire::flush(void)
     207{
     208  // Do nothing, use endTransmission(..) to force
     209  // data transfer.
     210}
     211
     212void TwoWire::onReceive(void(*function)(int))
     213{
     214  onReceiveCallback = function;
     215}
     216
     217void TwoWire::onRequest(void(*function)(void))
     218{
     219  onRequestCallback = function;
     220}
     221
     222void 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)
    72234      {
    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());
    76236      }
    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 ?
    78246      {
    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        }
    82256      }
    83257    }
    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}
    329273
    330274#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.