Skip to content

Instantly share code, notes, and snippets.

@shima-529
Created August 24, 2021 12:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shima-529/c837b89ed2a65ab26980a3b3d5276f61 to your computer and use it in GitHub Desktop.
Save shima-529/c837b89ed2a65ab26980a3b3d5276f61 to your computer and use it in GitHub Desktop.
#include "stm32f0xx.h"
#include "i2c.h"
#include "sysclk_systick.h"
static void i2c_io_init(void) {
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB->MODER |= (GPIO_MODE_AF_PP << GPIO_MODER_MODER6_Pos); // PB6 as SCL
GPIOB->AFR[0] |= (GPIO_AF1_I2C1 << (4 * 6));
GPIOB->PUPDR |= (GPIO_PULLUP << GPIO_PUPDR_PUPDR6_Pos);
GPIOB->OTYPER |= GPIO_OTYPER_OT_6;
GPIOB->MODER |= (GPIO_MODE_AF_PP << GPIO_MODER_MODER7_Pos); // PB7 as SDA
GPIOB->AFR[0] |= (GPIO_AF1_I2C1 << (4 * 7));
GPIOB->PUPDR |= (GPIO_PULLUP << GPIO_PUPDR_PUPDR7_Pos);
GPIOB->OTYPER |= GPIO_OTYPER_OT_7;
}
void i2c_init(void) {
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
i2c_io_init();
I2C1->CR2 |= I2C_CR2_AUTOEND; // Master Mode: automatically send STOP condition
I2C1->TIMINGR |= (15 << I2C_TIMINGR_PRESC_Pos); // no prescale
I2C1->TIMINGR |= (1 << I2C_TIMINGR_SCLDEL_Pos); // Data setup time > 180ns
I2C1->TIMINGR |= (1 << I2C_TIMINGR_SDADEL_Pos); // Data hold time
I2C1->TIMINGR |= (127 << I2C_TIMINGR_SCLH_Pos); // High Frequency
I2C1->TIMINGR |= (127 << I2C_TIMINGR_SCLL_Pos); // Low Frequency
I2C1->CR1 |= I2C_CR1_PE; // peripheral enable
}
// fundamental function(hindered to other files)
void i2c_send(uint8_t addr, uint8_t *dat, int size, int wait_ms) {
while( I2C1->ISR & I2C_ISR_BUSY );
I2C1->CR2 &= ~I2C_CR2_SADD_Msk;
I2C1->CR2 |= (addr << I2C_CR2_SADD_Pos); // slave address
I2C1->CR2 |= (0 << I2C_CR2_ADD10_Pos); // 7bit
I2C1->CR2 &= ~I2C_CR2_RD_WRN_Msk;
I2C1->CR2 |= ((addr & 1) << I2C_CR2_RD_WRN_Pos); // write mode
I2C1->CR2 &= ~I2C_CR2_NBYTES_Msk; // data size
I2C1->CR2 |= (size << I2C_CR2_NBYTES_Pos); // data size
I2C1->CR2 |= I2C_CR2_START;
for(uint8_t i=0; i<size; i++) {
while( !(I2C1->ISR & I2C_ISR_TXE) );
I2C1->TXDR = dat[i];
ms_wait(wait_ms);
}
while( !(I2C1->ISR & I2C_ISR_STOPF) ); // wait until STOP condition is issued
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment