Ejemplo n.º 1
0
/* 	=========================
 *	===== Sercom UART
 *	=========================
*/
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
{
  initClockNVIC();
  resetUART();

  //Setting the CTRLA register
  sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
                SERCOM_USART_CTRLA_SAMPR(sampleRate);

  //Setting the Interrupt register
  sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
                                SERCOM_USART_INTENSET_ERROR; //All others errors

  if ( mode == UART_INT_CLOCK )
  {
    uint16_t sampleRateValue;

    if (sampleRate == SAMPLE_RATE_x16) {
      sampleRateValue = 16;
    } else {
      sampleRateValue = 8;
    }

    // Asynchronous fractional mode (Table 24-2 in datasheet)
    //   BAUD = fref / (sampleRateValue * fbaud)
    // (multiply by 8, to calculate fractional piece)
    uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate);

    sercom->USART.BAUD.FRAC.FP   = (baudTimes8 % 8);
    sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
  }
}
Ejemplo n.º 2
0
/* 	=========================
 *	===== Sercom UART
 *	=========================
*/
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
{
#if (SAML21)
  // On the SAML21, SERCOM5 is on PD0, which is a low power domain on a different bridge than the other SERCOMs.
  // SERCOM5 does not support SAMPLE_RATE_x8 or SAMPLE_RATE_x3.
  if (sercom == SERCOM5) {
    sampleRate = SAMPLE_RATE_x16;
  }
#endif

  initClockNVIC();
  resetUART();

  //Setting the CTRLA register
  sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
                SERCOM_USART_CTRLA_SAMPR(sampleRate);

  //Setting the Interrupt register
  sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
                                SERCOM_USART_INTENSET_ERROR; //All others errors

  if ( mode == UART_INT_CLOCK )
  {
    uint16_t sampleRateValue;

    if (sampleRate == SAMPLE_RATE_x16) {
      sampleRateValue = 16;
    } else {
      sampleRateValue = 8;
    }

#if 0
    // Asynchronous arithmetic mode
    // 65535 * ( 1 - sampleRateValue * baudrate / SercomClock);
    // 65535 - 65535 * (sampleRateValue * baudrate / SercomClock));
    // sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SercomCoreClock));  // this pulls in 3KB of floating point math code
    // make numerator much larger than denominator so result is integer (avoid floating point).
    uint64_t numerator = ((sampleRateValue * (uint64_t)baudrate) << 32); // 32 bits of shifting ensures no loss of precision.
    uint64_t ratio = divide64(numerator, SercomClock);
    uint64_t scale = ((uint64_t)1 << 32) - ratio;
    uint64_t baudValue = (65536 * scale) >> 32;
    sercom->USART.BAUD.reg = baudValue;
#endif
    // Asynchronous fractional mode (Table 24-2 in datasheet)
    //   BAUD = fref / (sampleRateValue * fbaud)
    // (multiply by 8, to calculate fractional piece)
    uint32_t baudTimes8 = (SercomClock * 8) / (sampleRateValue * baudrate);

    sercom->USART.BAUD.FRAC.FP   = (baudTimes8 % 8);
    sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8);
  }
Ejemplo n.º 3
0
/*	=========================
 *	===== Sercom SPI
 *	=========================
*/
void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
{
    resetSPI();
    initClockNVIC();

    //Setting the CTRLA register
    sercom->SPI.CTRLA.reg =	SERCOM_SPI_CTRLA_MODE_SPI_MASTER |
                            SERCOM_SPI_CTRLA_DOPO(mosi) |
                            SERCOM_SPI_CTRLA_DIPO(miso) |
                            dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;

    //Setting the CTRLB register
    sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
                            SERCOM_SPI_CTRLB_RXEN;	//Active the SPI receiver.


}
Ejemplo n.º 4
0
void SERCOM::initMasterWIRE( uint32_t baudrate )
{
    // Initialize the peripheral clock and interruption
    initClockNVIC() ;

    resetWIRE() ;

    // Set master mode and enable SCL Clock Stretch mode (stretch after ACK bit)
    sercom->I2CM.CTRLA.reg =  SERCOM_I2CM_CTRLA_MODE( I2C_MASTER_OPERATION )/* |
                            SERCOM_I2CM_CTRLA_SCLSM*/ ;

    // Enable Smart mode and Quick Command
    //sercom->I2CM.CTRLB.reg =  SERCOM_I2CM_CTRLB_SMEN /*| SERCOM_I2CM_CTRLB_QCEN*/ ;


    // Enable all interrupts
//  sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ;

    // Synchronous arithmetic baudrate
    sercom->I2CM.BAUD.bit.BAUD = SystemCoreClock / ( 2 * baudrate) - 1 ;
}
Ejemplo n.º 5
0
void SERCOM::initSlaveWIRE( uint8_t ucAddress )
{
    // Initialize the peripheral clock and interruption
    initClockNVIC() ;
    resetWIRE() ;

    // Set slave mode
    sercom->I2CS.CTRLA.bit.MODE = I2C_SLAVE_OPERATION ;

    sercom->I2CS.ADDR.reg = SERCOM_I2CS_ADDR_ADDR( ucAddress & 0x7Ful ) | // 0x7F, select only 7 bits
                            SERCOM_I2CS_ADDR_ADDRMASK( 0x3FFul ) ;    // 0x3FF all bits set

    // Set the interrupt register
    sercom->I2CS.INTENSET.reg = SERCOM_I2CS_INTENSET_PREC |   // Stop
                                SERCOM_I2CS_INTENSET_AMATCH | // Address Match
                                SERCOM_I2CS_INTENSET_DRDY ;   // Data Ready

    while ( sercom->I2CM.SYNCBUSY.bit.SYSOP != 0 )
    {
        // Wait the SYSOP bit from SYNCBUSY to come back to 0
    }
}
Ejemplo n.º 6
0
/* 	=========================
 *	===== Sercom UART
 *	=========================
*/
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
{
    initClockNVIC();
    resetUART();

    //Setting the CTRLA register
    sercom->USART.CTRLA.reg =	SERCOM_USART_CTRLA_MODE(mode) |
                                SERCOM_USART_CTRLA_SAMPR(sampleRate);

    //Setting the Interrupt register
    sercom->USART.INTENSET.reg =	SERCOM_USART_INTENSET_RXC |  //Received complete
                                    SERCOM_USART_INTENSET_ERROR; //All others errors

    if ( mode == UART_INT_CLOCK )
    {
        uint16_t sampleRateValue ;

        if ( sampleRate == SAMPLE_RATE_x16 )
        {
            sampleRateValue = 16 ;
        }
        else
        {
            if ( sampleRate == SAMPLE_RATE_x8 )
            {
                sampleRateValue = 8 ;
            }
            else
            {
                sampleRateValue = 3 ;
            }
        }

        // Asynchronous arithmetic mode
        // 65535 * ( 1 - sampleRateValue * baudrate / SystemCoreClock);
        // 65535 - 65535 * (sampleRateValue * baudrate / SystemCoreClock));
        sercom->USART.BAUD.reg = 65535.0f * ( 1.0f - (float)(sampleRateValue) * (float)(baudrate) / (float)(SystemCoreClock));
    }
}