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

ライブラリを Arduino IDE 1.7.9 にupdate

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
    119#include "SERCOM.h"
    220#include "variant.h"
    321
     22
    423SERCOM::SERCOM(Sercom* s)
    524{
    6         sercom = s;
     25  sercom = s;
    726}
    827
     
    1332void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
    1433{
     34  initClockNVIC();
    1535  resetUART();
    16   initClockNVIC();
    1736
    1837  //Setting the CTRLA register
     
    2645  if ( mode == UART_INT_CLOCK )
    2746  {
    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;
    3353    }
    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);
    5062  }
    5163}
    5264void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
    5365{
    54         //Setting the CTRLA register
    55         sercom->USART.CTRLA.reg |=      SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) |
    56                                                                 dataOrder << SERCOM_USART_CTRLA_DORD_Pos;
    57 
    58         //Setting the CTRLB register
    59         sercom->USART.CTRLB.reg |=      SERCOM_USART_CTRLB_CHSIZE(charSize) |
    60                                                                 nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos |
    61                                                                 (parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value
     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
    6274}
    6375
    6476void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad)
    6577{
    66         //Setting the CTRLA register
    67         sercom->USART.CTRLA.reg |=      SERCOM_USART_CTRLA_TXPO(txPad) |
    68                                                                 SERCOM_USART_CTRLA_RXPO(rxPad);
     78  //Setting the CTRLA register
     79  sercom->USART.CTRLA.reg |=    SERCOM_USART_CTRLA_TXPO(txPad) |
     80                SERCOM_USART_CTRLA_RXPO(rxPad);
    6981
    7082  // Enable Transceiver and Receiver
     
    8597void SERCOM::enableUART()
    8698{
    87         //Setting  the enable bit to 1
    88         sercom->USART.CTRLA.bit.ENABLE = 0x1u;
    89 
    90         //Wait for then enable bit from SYNCBUSY is equal to 0;
    91         while(sercom->USART.SYNCBUSY.bit.ENABLE);
     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);
    92104}
    93105
    94106void SERCOM::flushUART()
    95107{
    96         // Wait for transmission to complete
    97         while(sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
     108  // Wait for transmission to complete
     109  while(!sercom->USART.INTFLAG.bit.TXC);
    98110}
    99111
    100112void SERCOM::clearStatusUART()
    101113{
    102         //Reset (with 0) the STATUS register
    103         sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
     114  //Reset (with 0) the STATUS register
     115  sercom->USART.STATUS.reg = SERCOM_USART_STATUS_RESETVALUE;
    104116}
    105117
    106118bool SERCOM::availableDataUART()
    107119{
    108         //RXC : Receive Complete
    109         return sercom->USART.INTFLAG.bit.RXC;
     120  //RXC : Receive Complete
     121  return sercom->USART.INTFLAG.bit.RXC;
     122}
     123
     124bool SERCOM::isUARTError()
     125{
     126  return sercom->USART.INTFLAG.bit.ERROR;
     127}
     128
     129void SERCOM::acknowledgeUARTError()
     130{
     131  sercom->USART.INTFLAG.bit.ERROR = 1;
    110132}
    111133
    112134bool SERCOM::isBufferOverflowErrorUART()
    113135{
    114         //BUFOVF : Buffer Overflow
    115         return sercom->USART.STATUS.bit.BUFOVF;
     136  //BUFOVF : Buffer Overflow
     137  return sercom->USART.STATUS.bit.BUFOVF;
    116138}
    117139
    118140bool SERCOM::isFrameErrorUART()
    119141{
    120         //FERR : Frame Error
    121         return sercom->USART.STATUS.bit.FERR;
     142  //FERR : Frame Error
     143  return sercom->USART.STATUS.bit.FERR;
    122144}
    123145
    124146bool SERCOM::isParityErrorUART()
    125147{
    126         //PERR : Parity Error
    127         return sercom->USART.STATUS.bit.PERR;
     148  //PERR : Parity Error
     149  return sercom->USART.STATUS.bit.PERR;
    128150}
    129151
    130152bool SERCOM::isDataRegisterEmptyUART()
    131153{
    132         //DRE : Data Register Empty
    133         return sercom->USART.INTFLAG.bit.DRE;
     154  //DRE : Data Register Empty
     155  return sercom->USART.INTFLAG.bit.DRE;
    134156}
    135157
    136158uint8_t SERCOM::readDataUART()
    137159{
    138         return sercom->USART.DATA.bit.DATA;
     160  return sercom->USART.DATA.bit.DATA;
    139161}
    140162
    141163int SERCOM::writeDataUART(uint8_t data)
    142164{
    143         //Flush UART buffer
    144         flushUART();
    145 
    146         //Put data into DATA register
    147         sercom->USART.DATA.reg = (uint16_t)data;
    148         return 1;
     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;
    149171}
    150172
     
    155177void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
    156178{
     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
     195void SERCOM::initSPIslave(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
     196{
    157197        resetSPI();
    158198        initClockNVIC();
    159199
    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
    167205        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                                                                               
    171208}
    172209
    173210void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate)
    174211{
    175         //Extract data from clockMode
    176         int cpha, cpol;
    177 
    178         if((clockMode & (0x1ul)) == 0 )
    179                 cpha = 0;
    180         else
    181                 cpha = 1;
    182 
    183         if((clockMode & (0x2ul)) == 0)
    184                 cpol = 0;
    185         else
    186                 cpol = 1;
    187 
    188         //Setting the CTRLA register
    189         sercom->SPI.CTRLA.reg |=        ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) |
    190                                                                             ( cpol << SERCOM_SPI_CTRLA_CPOL_Pos );
    191 
    192         //Synchronous arithmetic
    193         sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);
     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);
    194231}
    195232
    196233void SERCOM::resetSPI()
    197234{
    198         //Setting the Software Reset bit to 1
    199         sercom->SPI.CTRLA.bit.SWRST = 1;
    200 
    201         //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
    202         while(sercom->SPI.CTRLA.bit.SWRST || sercom->SPI.SYNCBUSY.bit.SWRST);
     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);
    203240}
    204241
    205242void SERCOM::enableSPI()
    206243{
    207         //Setting the enable bit to 1
    208         sercom->SPI.CTRLA.bit.ENABLE = 1;
    209 
    210         while(sercom->SPI.SYNCBUSY.bit.ENABLE)
     244  //Setting the enable bit to 1
     245  sercom->SPI.CTRLA.bit.ENABLE = 1;
     246
     247  while(sercom->SPI.SYNCBUSY.bit.ENABLE)
    211248  {
    212249    //Waiting then enable bit from SYNCBUSY is equal to 0;
     
    216253void SERCOM::disableSPI()
    217254{
    218         //Setting the enable bit to 0
    219         sercom->SPI.CTRLA.bit.ENABLE = 0;
    220 
    221         while(sercom->SPI.SYNCBUSY.bit.ENABLE)
     255  //Setting the enable bit to 0
     256  sercom->SPI.CTRLA.bit.ENABLE = 0;
     257
     258  while(sercom->SPI.SYNCBUSY.bit.ENABLE)
    222259  {
    223260    //Waiting then enable bit from SYNCBUSY is equal to 0;
     
    227264void SERCOM::setDataOrderSPI(SercomDataOrder dataOrder)
    228265{
    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
     274SercomDataOrder SERCOM::getDataOrderSPI()
     275{
     276  return (sercom->SPI.CTRLA.bit.DORD ? LSB_FIRST : MSB_FIRST);
     277}
     278
     279void 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();
    249291}
    250292
    251293void SERCOM::setClockModeSPI(SercomSpiClockMode clockMode)
    252294{
    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
    272315void SERCOM::writeDataSPI(uint8_t data)
    273316{
     
    276319    // Waiting Data Registry Empty
    277320  }
    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
    280322
    281323  while( sercom->SPI.INTFLAG.bit.TXC == 0 || sercom->SPI.INTFLAG.bit.DRE == 0 )
     
    292334  }
    293335
    294         return sercom->SPI.DATA.bit.DATA;  // Reading data
     336  return sercom->SPI.DATA.bit.DATA;  // Reading data
    295337}
    296338
    297339bool SERCOM::isBufferOverflowErrorSPI()
    298340{
    299         return sercom->SPI.STATUS.bit.BUFOVF;
     341  return sercom->SPI.STATUS.bit.BUFOVF;
    300342}
    301343
    302344bool SERCOM::isDataRegisterEmptySPI()
    303345{
    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//}
    307361
    308362uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
    309363{
    310         return SERCOM_FREQ_REF / (2 * baudrate) - 1;
     364  return SERCOM_FREQ_REF / (2 * baudrate) - 1;
    311365}
    312366
     
    315369 *      ===== Sercom WIRE
    316370 *      =========================
    317 */
    318 
     371 */
    319372void SERCOM::resetWIRE()
    320373{
    321         //I2CM OR I2CS, no matter SWRST is the same bit.
    322 
    323         //Setting the Software bit to 1
    324         sercom->I2CM.CTRLA.bit.SWRST = 1;
    325 
    326         //Wait both bits Software Reset from CTRLA and SYNCBUSY are equal to 0
    327         while(sercom->I2CM.CTRLA.bit.SWRST || sercom->I2CM.SYNCBUSY.bit.SWRST);
     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);
    328381}
    329382
     
    371424  sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;
    372425
    373   // Enable Quick Command
    374   sercom->I2CM.CTRLB.bit.QCEN = 1 ;
    375 
    376426  sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
    377                           SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ;        // 0x3FF all bits set
     427                          SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ;    // 0x3FF all bits set
    378428
    379429  // 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
    382433
    383434  while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
     
    395446
    396447  // 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*/ ;
    398450
    399451  // Enable Smart mode and Quick Command
     452  //sercom->I2CM.CTRLB.reg =  SERCOM_I2CM_CTRLB_SMEN /*| SERCOM_I2CM_CTRLB_QCEN*/ ;
     453
    400454
    401455  // Enable all interrupts
     456//  sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ;
    402457
    403458  // Synchronous arithmetic baudrate
     
    407462void SERCOM::prepareNackBitWIRE( void )
    408463{
    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  }
    411470}
    412471
    413472void SERCOM::prepareAckBitWIRE( void )
    414473{
    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
     482void 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;
    426493  }
    427494}
     
    432499  address = (address << 0x1ul) | flag;
    433500
    434   // Wait idle bus mode
    435   while ( !isBusIdleWIRE() );
     501
     502  // Wait idle or owner bus mode
     503  while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
    436504
    437505  // Send start and address
    438506  sercom->I2CM.ADDR.bit.ADDR = address;
     507 
    439508
    440509  // Address Transmitted
     
    450519    while( !sercom->I2CM.INTFLAG.bit.SB )
    451520    {
     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        }
    452527      // Wait transmission complete
    453528    }
     
    471546bool SERCOM::sendDataMasterWIRE(uint8_t data)
    472547{
    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;
    484566}
    485567
    486568bool SERCOM::sendDataSlaveWIRE(uint8_t data)
    487569{
    488         //Send data
    489         sercom->I2CS.DATA.bit.DATA = data;
    490 
    491         //Wait data transmission successful
    492         while(!sercom->I2CS.INTFLAG.bit.DRDY);
    493 
    494         //Problems on line? nack received?
    495         if(sercom->I2CS.STATUS.bit.RXNACK)
    496                 return false;
    497         else
    498                 return true;
     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;
    499581}
    500582
    501583bool SERCOM::isMasterWIRE( void )
    502584{
    503         return sercom->I2CS.CTRLA.bit.MODE == I2C_MASTER_OPERATION;
     585  return sercom->I2CS.CTRLA.bit.MODE == I2C_MASTER_OPERATION;
    504586}
    505587
    506588bool SERCOM::isSlaveWIRE( void )
    507589{
    508         return sercom->I2CS.CTRLA.bit.MODE == I2C_SLAVE_OPERATION;
     590  return sercom->I2CS.CTRLA.bit.MODE == I2C_SLAVE_OPERATION;
    509591}
    510592
    511593bool SERCOM::isBusIdleWIRE( void )
    512594{
    513         return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE;
     595  return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_IDLE_STATE;
     596}
     597
     598bool SERCOM::isBusOwnerWIRE( void )
     599{
     600  return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
    514601}
    515602
    516603bool SERCOM::isDataReadyWIRE( void )
    517604{
    518         return sercom->I2CS.INTFLAG.bit.DRDY;
     605  return sercom->I2CS.INTFLAG.bit.DRDY;
    519606}
    520607
    521608bool SERCOM::isStopDetectedWIRE( void )
    522609{
    523         return sercom->I2CS.INTFLAG.bit.PREC;
     610  return sercom->I2CS.INTFLAG.bit.PREC;
    524611}
    525612
    526613bool SERCOM::isRestartDetectedWIRE( void )
    527614{
    528         return sercom->I2CS.STATUS.bit.SR;
     615  return sercom->I2CS.STATUS.bit.SR;
    529616}
    530617
    531618bool SERCOM::isAddressMatch( void )
    532619{
    533         return sercom->I2CS.INTFLAG.bit.AMATCH;
     620  return sercom->I2CS.INTFLAG.bit.AMATCH;
    534621}
    535622
     
    546633int SERCOM::availableWIRE( void )
    547634{
    548         if(isMasterWIRE())
    549                 return sercom->I2CM.INTFLAG.bit.SB;
    550         else
    551                 return sercom->I2CS.INTFLAG.bit.DRDY;
     635  if(isMasterWIRE())
     636    return sercom->I2CM.INTFLAG.bit.SB;
     637  else
     638    return sercom->I2CS.INTFLAG.bit.DRDY;
    552639}
    553640
     
    572659void SERCOM::initClockNVIC( void )
    573660{
    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
    119#ifndef _SERCOM_CLASS_
    220#define _SERCOM_CLASS_
     
    6280typedef enum
    6381{
    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
    6685} SercomUartTXPad;
    6786
    6887typedef enum
    6988{
    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
    7391} SercomUartSampleRate;
    7492
     
    144162                uint8_t readDataUART( void ) ;
    145163                int writeDataUART(uint8_t data) ;
     164                bool isUARTError() ;
     165                void acknowledgeUARTError() ;
    146166
    147167                /* ========== SPI ========== */
    148168                void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ;
     169                void initSPIslave(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder);
    149170                void initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) ;
    150171
     
    153174                void disableSPI( void ) ;
    154175                void setDataOrderSPI(SercomDataOrder dataOrder) ;
    155                 void setBaudrateSPI(uint8_t divider) ;
     176                SercomDataOrder getDataOrderSPI( void ) ;
     177                void setBaudrateSPI(uint16_t divider) ;
    156178                void setClockModeSPI(SercomSpiClockMode clockMode) ;
    157179                void writeDataSPI(uint8_t data) ;
     
    168190                void resetWIRE( void ) ;
    169191                void enableWIRE( void ) ;
    170         void disableWIRE( void );
    171         void prepareNackBitWIRE( void ) ;
    172         void prepareAckBitWIRE( void ) ;
    173         void prepareCommandBitsWire(SercomMasterCommandWire cmd);
     192    void disableWIRE( void );
     193    void prepareNackBitWIRE( void ) ;
     194    void prepareAckBitWIRE( void ) ;
     195    void prepareCommandBitsWire(uint8_t cmd);
    174196                bool startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag) ;
    175197                bool sendDataMasterWIRE(uint8_t data) ;
     
    178200                bool isSlaveWIRE( void ) ;
    179201                bool isBusIdleWIRE( void ) ;
     202                bool isBusOwnerWIRE( void ) ;
    180203                bool isDataReadyWIRE( void ) ;
    181204                bool isStopDetectedWIRE( void ) ;
     
    183206                bool isAddressMatch( void ) ;
    184207                bool isMasterReadOperationWIRE( void ) ;
    185         bool isRXNackReceivedWIRE( void ) ;
     208    bool isRXNackReceivedWIRE( void ) ;
    186209                int availableWIRE( void ) ;
    187210                uint8_t readDataWIRE( void ) ;
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/wiring.c

    r136 r175  
    8080                   ADC_CTRLB_RESSEL_10BIT;          // Result on 10 bits
    8181    ADC->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND | // No Negative input (Internal Ground)
    82                          ADC_INPUTCTRL_GAIN_1X;     // Gain setted to 1
     82                         ADC_INPUTCTRL_GAIN_DIV2;     // Gain setted to 1/2
    8383  // Averaging (see table 31-2 p.816 datasheet)
    8484  ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_2 |      // 2 samples
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/wiring_analog.c

    r137 r175  
    6464void analogReference( eAnalogReference ulMode )
    6565{
    66 
    67   // ATTENTION : On this board the default is not 5volts or 3.3volts BUT 1.65 volt
    68 
    6966   
    7067   
  • 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
  • rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/libraries/Wire/Wire.h

    r136 r175  
    11/*
    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.
    54 *
    65 * This library is free software; you can redistribute it and/or
     
    2221#define TwoWire_h
    2322
    24 //#include <include/twi.h>
    25 
    2623#include "Stream.h"
    2724#include "variant.h"
     
    3229#define BUFFER_LENGTH 32
    3330
     31 // WIRE_HAS_END means Wire has end()
     32#define WIRE_HAS_END 1
    3433
    3534class TwoWire : public Stream
    3635{
    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);
    4142
    42                 void beginTransmission(uint8_t);
    43                 uint8_t endTransmission(bool stopBit);
    44                 uint8_t endTransmission(void);
     43    void beginTransmission(uint8_t);
     44    uint8_t endTransmission(bool stopBit);
     45    uint8_t endTransmission(void);
    4546
    46                 uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit);
    47                 uint8_t requestFrom(uint8_t address, size_t quantity);
     47    uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit);
     48    uint8_t requestFrom(uint8_t address, size_t quantity);
    4849
    49                 size_t write(uint8_t data);
    50                 size_t write(const uint8_t * data, size_t quantity);
     50    size_t write(uint8_t data);
     51    size_t write(const uint8_t * data, size_t quantity);
    5152
    52                 virtual int available(void);
    53                 virtual int read(void);
    54                 virtual int peek(void);
    55                 virtual void flush(void);
    56                 void onReceive(void(*)(int));
    57                 void onRequest(void(*)(void));
     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));
    5859
    59                 using Print::write;
     60    using Print::write;
    6061
    61                 void onService(void);
     62    void onService(void);
    6263
    63         private:
    64                 SERCOM * sercom;
    65                 bool transmissionBegun;
     64  private:
     65    SERCOM * sercom;
     66    uint8_t _uc_pinSDA;
     67    uint8_t _uc_pinSCL;
    6668
    67                 // RX Buffer
    68                 RingBuffer rxBuffer;
     69    bool transmissionBegun;
    6970
    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;
    7377
    7478
    75                 // Service buffer
    76                 //uint8_t srvBuffer[BUFFER_LENGTH];
    77                 //uint8_t srvBufferIndex;
    78                 //uint8_t srvBufferLength;
     79    // Service buffer
     80    //uint8_t srvBuffer[BUFFER_LENGTH];
     81    //uint8_t srvBufferIndex;
     82    //uint8_t srvBufferLength;
    7983
    80                 // Callback user functions
    81                 void (*onRequestCallback)(void);
    82                 void (*onReceiveCallback)(int);
     84    // Callback user functions
     85    void (*onRequestCallback)(void);
     86    void (*onReceiveCallback)(int);
    8387
    84                 // TWI state
    85                 //enum TwoWireStatus
     88    // TWI state
     89    //enum TwoWireStatus
    8690    //{
    87                 //      UNINITIALIZED,
    88                 //      MASTER_IDLE,
    89                 //      MASTER_SEND,
    90                 //      MASTER_RECV,
    91                 //      SLAVE_IDLE,
    92                 //      SLAVE_RECV,
    93                 //      SLAVE_SEND
    94                 //};
    95                 //TwoWireStatus status;
     91    //  UNINITIALIZED,
     92    //  MASTER_IDLE,
     93    //  MASTER_SEND,
     94    //  MASTER_RECV,
     95    //  SLAVE_IDLE,
     96    //  SLAVE_RECV,
     97    //  SLAVE_SEND
     98    //};
     99    //TwoWireStatus status;
    96100
    97                 // TWI clock frequency
    98                 static const uint32_t TWI_CLOCK = 100000;
     101    // TWI clock frequency
     102    static const uint32_t TWI_CLOCK = 100000;
    99103
    100                 // Timeouts
    101                 //static const uint32_t RECV_TIMEOUT = 100000;
    102                 //static const uint32_t XMIT_TIMEOUT = 100000;
     104    // Timeouts
     105    //static const uint32_t RECV_TIMEOUT = 100000;
     106    //static const uint32_t XMIT_TIMEOUT = 100000;
    103107};
    104108
    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
    106127
    107128#endif
Note: See TracChangeset for help on using the changeset viewer.