Esempio n. 1
0
void i2c_set_clock_frequency(u32 i2c, u8 freq)
{
	u16 reg16;
	reg16 = I2C_CR2(i2c) & 0xffc0; /* Clear bits [5:0]. */
	reg16 |= freq;
	I2C_CR2(i2c) = reg16;
}
Esempio n. 2
0
void i2c3_ev_isr(void) {
  uint32_t i2c = (uint32_t) i2c3.reg_addr;
  I2C_CR2(i2c) &= ~I2C_CR2_ITERREN;
  i2c_irq(&i2c3);
  i2c3_watchdog_counter = 0;
  I2C_CR2(i2c) |= I2C_CR2_ITERREN;
}
Esempio n. 3
0
void i2c1_er_isr(void) {
  uint32_t i2c = (uint32_t) i2c1.reg_addr;
  I2C_CR2(i2c) &= ~I2C_CR2_ITEVTEN;
  i2c_irq(&i2c1);
  i2c1_watchdog_counter = 0;
  I2C_CR2(i2c) |= I2C_CR2_ITEVTEN;
}
Esempio n. 4
0
static inline void PPRZ_I2C_SEND_START(struct i2c_periph *periph)
{
  uint32_t i2c = (uint32_t) periph->reg_addr;

  // Reset the buffer pointer to the first byte
  periph->idx_buf = 0;

#ifdef I2C_DEBUG_LED
  LED_SHOW_ACTIVE_BITS(regs);

  LED2_ON();
  LED1_ON();
  LED1_OFF();
  LED1_ON();
  LED1_OFF();
  LED1_ON();
  LED1_OFF();
  LED2_OFF();
#endif

  // Enable Error IRQ, Event IRQ but disable Buffer IRQ
  I2C_CR2(i2c) |= I2C_CR2_ITERREN;
  I2C_CR2(i2c) |= I2C_CR2_ITEVTEN;
  I2C_CR2(i2c) &= ~ I2C_CR2_ITBUFEN;

  // Issue a new start
  I2C_CR1(i2c) =  (I2C_CR1_START | I2C_CR1_PE);
  periph->status = I2CStartRequested;

}
Esempio n. 5
0
// Doc ID 13902 Rev 11 p 714/1072
// Transfer Sequence Diagram for Master Receiver for N=1
static inline enum STMI2CSubTransactionStatus stmi2c_read1(uint32_t i2c, struct i2c_periph *periph, struct i2c_transaction *trans)
{
  uint16_t SR1 = I2C_SR1(i2c);

  // Start Condition Was Just Generated
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_SB, SR1 ) )
  {
    I2C_CR2(i2c) &= ~ I2C_CR2_ITBUFEN;
    I2C_DR(i2c) = trans->slave_addr | 0x01;

    // Document the current Status
    periph->status = I2CAddrRdSent;
  }
  // Address Was Sent
  else if (BIT_X_IS_SET_IN_REG(I2C_SR1_ADDR, SR1) )
  {
    // First Clear the ACK bit: after the next byte we do not want new bytes
    I2C_CR1(i2c) &= ~ I2C_CR1_POS;
    I2C_CR1(i2c) &= ~ I2C_CR1_ACK;

    // --- next to steps MUST be executed together to avoid missing the stop
    __I2C_REG_CRITICAL_ZONE_START;

    // Only after setting ACK, read SR2 to clear the ADDR (next byte will start arriving)
    uint16_t SR2 __attribute__ ((unused)) = I2C_SR2(i2c);

    // Schedule a Stop
    PPRZ_I2C_SEND_STOP(i2c);

    __I2C_REG_CRITICAL_ZONE_STOP;
    // --- end of critical zone -----------

    // Enable the RXNE: it will trigger as soon as the 1 byte is received to get the result
    I2C_CR2(i2c) |= I2C_CR2_ITBUFEN;

    // Document the current Status
    periph->status = I2CReadingLastByte;
  }
  // As soon as there is 1 byte ready to read, we have our byte
  else if (BIT_X_IS_SET_IN_REG(I2C_SR1_RxNE, SR1) )
  {
    I2C_CR2(i2c) &= ~ I2C_CR2_ITBUFEN;
    trans->buf[0] = I2C_DR(i2c);

    // We got all the results (stop condition might still be in progress but this is the last interrupt)
    trans->status = I2CTransSuccess;

    // Document the current Status:
    // -the stop was actually already requested in the previous step
    periph->status = I2CStopRequested;

    return STMI2C_SubTra_Ready_StopRequested;
  }
  else // Event Logic Error
  {
    return STMI2C_SubTra_Error;
  }

  return STMI2C_SubTra_Busy;
}
Esempio n. 6
0
void i2c_set_clock_frequency(uint32_t i2c, uint8_t freq)
{
	uint16_t reg16;
	reg16 = I2C_CR2(i2c) & 0xffc0; /* Clear bits [5:0]. */
	reg16 |= freq;
	I2C_CR2(i2c) = reg16;
}
Esempio n. 7
0
static inline void stmi2c_clear_pending_interrupts(uint32_t i2c)
{
  uint16_t SR1 = I2C_SR1(i2c);

  // Certainly do not wait for buffer interrupts:
  // -------------------------------------------
  I2C_CR2(i2c) &= ~ I2C_CR2_ITBUFEN;			// Disable TXE, RXNE

  // Error interrupts are handled separately:
  // ---------------------------------------

  // Clear Event interrupt conditions:
  // --------------------------------

  // Start Condition Was Generated
  if (BIT_X_IS_SET_IN_REG( I2C_SR1_SB, SR1 ) )
  {
    // SB: cleared by software when reading SR1 and writing to DR
    I2C_DR(i2c) = 0x00;
  }
  // Address Was Sent
  if (BIT_X_IS_SET_IN_REG(I2C_SR1_ADDR, SR1) )
  {
    // ADDR: Cleared by software when reading SR1 and then SR2
    uint16_t SR2 __attribute__ ((unused)) = I2C_SR2(i2c);
  }
  // Byte Transfer Finished
  if (BIT_X_IS_SET_IN_REG(I2C_SR1_BTF, SR1) )
  {
    // SB: cleared by software when reading SR1 and reading/writing to DR
    uint8_t dummy __attribute__ ((unused)) = I2C_DR(i2c);
    I2C_DR(i2c) = 0x00;
  }

}
Esempio n. 8
0
void i2c2_hw_init(void) {

  i2c2.reg_addr = (void *)I2C2;
  i2c2.init_struct = NULL;
  i2c2.errors = &i2c2_errors;
  i2c2_watchdog_counter = 0;

  /* zeros error counter */
  ZEROS_ERR_COUNTER(i2c2_errors);

  /* reset peripheral to default state ( sometimes not achieved on reset :(  ) */
  //i2c_reset(I2C2);

  /* Configure priority grouping 0 bits for pre-emption priority and 4 bits for sub-priority. */
  scb_set_priority_grouping(SCB_AIRCR_PRIGROUP_NOGROUP_SUB16);

  /* Configure and enable I2C2 event interrupt --------------------------------*/
  nvic_set_priority(NVIC_I2C2_EV_IRQ, 0);
  nvic_enable_irq(NVIC_I2C2_EV_IRQ);

  /* Configure and enable I2C2 err interrupt ----------------------------------*/
  nvic_set_priority(NVIC_I2C2_ER_IRQ, 1);
  nvic_enable_irq(NVIC_I2C2_ER_IRQ);

  /* Enable peripheral clocks -------------------------------------------------*/
  /* Enable I2C2 clock */
  rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_I2C2EN);
  /* Enable GPIO clock */
  gpio_enable_clock(I2C2_GPIO_PORT);
#if defined(STM32F1)
  gpio_set_mode(I2C2_GPIO_PORT, GPIO_MODE_OUTPUT_2_MHZ,
                GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN,
                I2C2_GPIO_SCL | I2C2_GPIO_SDA);
#elif defined(STM32F4)
  gpio_mode_setup(I2C2_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE,
                  I2C2_GPIO_SCL | I2C2_GPIO_SDA);
  gpio_set_output_options(I2C2_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ,
                          I2C2_GPIO_SCL | I2C2_GPIO_SDA);
  gpio_set_af(I2C2_GPIO_PORT, GPIO_AF4,
              I2C2_GPIO_SCL | I2C2_GPIO_SDA);
#endif

  i2c_reset(I2C2);

  // enable peripheral
  i2c_peripheral_enable(I2C2);

  /*
   * XXX: there is a function to do that already in libopencm3 but I am not
   * sure if it is correct, using direct register instead (esden)
   */
  //i2c_set_own_7bit_slave_address(I2C2, 0);
  I2C_OAR1(I2C2) = 0 | 0x4000;

  // enable error interrupts
  I2C_CR2(I2C1) |= I2C_CR2_ITERREN;

  i2c_setbitrate(&i2c2, I2C2_CLOCK_SPEED);
}
Esempio n. 9
0
void i2c3_er_isr(void) {
  uint32_t i2c = (uint32_t) i2c3.reg_addr;
  i2c_disable_interrupt(i2c, I2C_CR2_ITEVTEN);
  I2C_CR2(i2c) &= ~I2C_CR2_ITEVTEN;
  i2c3.watchdog = 0;  // restart watchdog
  i2c_irq(&i2c3);
  i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN);
}
Esempio n. 10
0
uint8_t i2c_is_start(uint32_t i2c)
{
	if ((I2C_CR2(i2c) & I2C_CR2_START) != 0) {
		return 1;
	}

	return 0;
}
Esempio n. 11
0
void i2c3_hw_init(void) {

  i2c3.reg_addr = (void *)I2C3;
  i2c3.init_struct = NULL;
  i2c3.errors = &i2c3_errors;
  i2c3_watchdog_counter = 0;

  /* zeros error counter */
  ZEROS_ERR_COUNTER(i2c3_errors);

  /* reset peripheral to default state ( sometimes not achieved on reset :(  ) */
  //i2c_reset(I2C3);

  /* Configure and enable I2C3 event interrupt --------------------------------*/
  nvic_set_priority(NVIC_I2C3_EV_IRQ, NVIC_I2C3_IRQ_PRIO);
  nvic_enable_irq(NVIC_I2C3_EV_IRQ);

  /* Configure and enable I2C3 err interrupt ----------------------------------*/
  nvic_set_priority(NVIC_I2C3_ER_IRQ, NVIC_I2C3_IRQ_PRIO+1);
  nvic_enable_irq(NVIC_I2C3_ER_IRQ);

  /* Enable peripheral clocks -------------------------------------------------*/
  /* Enable I2C3 clock */
  rcc_periph_clock_enable(RCC_I2C3);
  /* Enable GPIO clock */
  gpio_enable_clock(I2C3_GPIO_PORT_SCL);
  gpio_mode_setup(I2C3_GPIO_PORT_SCL, GPIO_MODE_AF, GPIO_PUPD_NONE, I2C3_GPIO_SCL);
  gpio_set_output_options(I2C3_GPIO_PORT_SCL, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ,
                          I2C3_GPIO_SCL);
  gpio_set_af(I2C3_GPIO_PORT_SCL, GPIO_AF4, I2C3_GPIO_SCL);

  gpio_enable_clock(I2C3_GPIO_PORT_SDA);
  gpio_mode_setup(I2C3_GPIO_PORT_SDA, GPIO_MODE_AF, GPIO_PUPD_NONE, I2C3_GPIO_SDA);
  gpio_set_output_options(I2C3_GPIO_PORT_SDA, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ,
                          I2C3_GPIO_SDA);
  gpio_set_af(I2C3_GPIO_PORT_SDA, GPIO_AF4, I2C3_GPIO_SDA);

  i2c_reset(I2C3);

  // enable peripheral
  i2c_peripheral_enable(I2C3);

  /*
   * XXX: there is a function to do that already in libopencm3 but I am not
   * sure if it is correct, using direct register instead (esden)
   */
  //i2c_set_own_7bit_slave_address(I2C3, 0);
  I2C_OAR1(I2C3) = 0 | 0x4000;

  // enable error interrupts
  I2C_CR2(I2C1) |= I2C_CR2_ITERREN;

  i2c_setbitrate(&i2c3, I2C3_CLOCK_SPEED);
}
Esempio n. 12
0
static void init_i2c2(void) {
    *RCC_APB1ENR |= RCC_APB1ENR_I2C2EN;     /* Enable I2C2 Clock */
    *RCC_AHB1ENR |= RCC_AHB1ENR_GPIOBEN;    /* Enable GPIOB Clock */

    /* Set PB8 and PB9 to alternative function I2C
     * See stm32f4_ref.pdf pg 141 and stm32f407.pdf pg 51 */

    /* I2C2_SCL */
    gpio_moder(GPIOB, I2C2_SCL, GPIO_MODER_ALT);
    gpio_afr(GPIOB, I2C2_SCL, GPIO_AF_I2C);
    gpio_otyper(GPIOB, I2C2_SCL, GPIO_OTYPER_OD);
    gpio_pupdr(GPIOB, I2C2_SCL, GPIO_PUPDR_NONE);
    gpio_ospeedr(GPIOB, I2C2_SCL, GPIO_OSPEEDR_50M);

    /* I2C2_SDA */
    gpio_moder(GPIOB, I2C2_SDA, GPIO_MODER_ALT);
    gpio_afr(GPIOB, I2C2_SDA, GPIO_AF_I2C);
    gpio_otyper(GPIOB, I2C2_SDA, GPIO_OTYPER_OD);
    gpio_pupdr(GPIOB, I2C2_SDA, GPIO_PUPDR_NONE);
    gpio_ospeedr(GPIOB, I2C2_SDA, GPIO_OSPEEDR_50M);

    /* Configure peripheral */
    *I2C_CR2(2) |= I2C_CR2_FREQ(42);

    /* Set I2C to 300kHz */
    *I2C_CCR(2) |= I2C_CCR_CCR(140);
    *I2C_TRISE(2) = 43;

    /* Enable */
    *I2C_CR1(2) |= I2C_CR1_PE;

    /* Pre-initialized */
    //init_semaphore(&i2c2_semaphore);

    i2c2.ready = 1;
}
Esempio n. 13
0
void i2c_set_7bit_address(uint32_t i2c, uint8_t addr)
{
	I2C_CR2(i2c) = (I2C_CR2(i2c) & ~I2C_CR2_SADD_7BIT_MASK) |
		       ((addr & 0x7F) << I2C_CR2_SADD_7BIT_SHIFT);
}
Esempio n. 14
0
void i2c_set_10bit_addr_mode(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_ADD10;
}
Esempio n. 15
0
void i2c_set_7bit_addr_mode(uint32_t i2c)
{
	I2C_CR2(i2c) &= ~I2C_CR2_ADD10;
}
Esempio n. 16
0
void i2c_send_stop(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_STOP;
}
Esempio n. 17
0
/** @brief I2C Clear DMA last transfer

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_clear_dma_last_transfer(uint32_t i2c)
{
	I2C_CR2(i2c) &= ~I2C_CR2_LAST;
}
Esempio n. 18
0
/** @brief I2C Set DMA last transfer

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_set_dma_last_transfer(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_LAST;
}
Esempio n. 19
0
void i2c_disable_autoend(uint32_t i2c)
{
	I2C_CR2(i2c) &= ~I2C_CR2_AUTOEND;
}
Esempio n. 20
0
/** @brief I2C Disable DMA

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_disable_dma(u32 i2c)
{
	I2C_CR2(i2c) &= ~I2C_CR2_DMAEN;
}
Esempio n. 21
0
void i2c_set_read_transfer_dir(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_RD_WRN;
}
Esempio n. 22
0
void i2c_set_10bit_address(uint32_t i2c, uint16_t addr)
{
	I2C_CR2(i2c) = (I2C_CR2(i2c) & ~I2C_CR2_SADD_10BIT_MASK) |
		       ((addr & 0x3FF) << I2C_CR2_SADD_10BIT_SHIFT);
}
Esempio n. 23
0
void i2c_set_write_transfer_dir(uint32_t i2c)
{
	I2C_CR2(i2c) &= ~I2C_CR2_RD_WRN;
}
Esempio n. 24
0
/** @brief I2C Enable Interrupt

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] interrupt Unsigned int32. Interrupt to enable.
*/
void i2c_enable_interrupt(uint32_t i2c, uint32_t interrupt)
{
	I2C_CR2(i2c) |= interrupt;
}
Esempio n. 25
0
void i2c_set_bytes_to_transfer(uint32_t i2c, uint32_t n_bytes)
{
	I2C_CR2(i2c) = (I2C_CR2(i2c) & ~I2C_CR2_NBYTES_MASK) |
		       (n_bytes << I2C_CR2_NBYTES_SHIFT);
}
Esempio n. 26
0
/** @brief I2C Disable Interrupt

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] interrupt Unsigned int32. Interrupt to disable.
*/
void i2c_disable_interrupt(uint32_t i2c, uint32_t interrupt)
{
	I2C_CR2(i2c) &= ~interrupt;
}
Esempio n. 27
0
void i2c_enable_autoend(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_AUTOEND;
}
Esempio n. 28
0
/** @brief I2C Enable DMA

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_enable_dma(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_DMAEN;
}
Esempio n. 29
0
void i2c_send_start(uint32_t i2c)
{
	I2C_CR2(i2c) |= I2C_CR2_START;
}
Esempio n. 30
0
/** @brief I2C Disable DMA

@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_disable_dma(uint32_t i2c)
{
	I2C_CR2(i2c) &= ~I2C_CR2_DMAEN;
}