/* Function to init EEPROM driver and I2C peripheral */ void eeprom_init(void) { /* Enable GPIOB clock. */ rcc_periph_clock_enable(RCC_GPIOB); /* set I2C1_SCL and I2C1_SDA, external pull-up resistors */ gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6 | GPIO7); /* Open Drain, Speed 100 MHz */ gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, GPIO6 | GPIO7); /* Alternate Function: I2C1 */ gpio_set_af(GPIOB, GPIO_AF4, GPIO6 | GPIO7); /* Enable I2C1 clock. */ rcc_periph_clock_enable(RCC_I2C1); /* Enable I2C1 interrupt. */ nvic_enable_irq(NVIC_I2C1_EV_IRQ); /* reset I2C1 */ i2c_reset(I2C1); /* standard mode */ i2c_set_standard_mode(I2C1); /* clock and bus frequencies */ i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_2MHZ); i2c_set_ccr(I2C1, 20); /* enable error event interrupt only */ i2c_enable_interrupt(I2C1, I2C_CR2_ITERREN); /* enable I2C */ i2c_peripheral_enable(I2C1); }
static void stmpe811_i2c_init() { rcc_periph_clock_enable(RCC_GPIOA); rcc_periph_clock_enable(RCC_GPIOC); rcc_periph_clock_enable(RCC_I2C3); gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO8); gpio_set_output_options(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO8); gpio_set_af(GPIOA, GPIO_AF4, GPIO8); gpio_mode_setup(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9); gpio_set_output_options(GPIOC, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO9); gpio_set_af(GPIOC, GPIO_AF4, GPIO9); i2c_peripheral_disable(I2C3); /* disable i2c during setup */ i2c_reset(I2C3); i2c_set_fast_mode(I2C3); i2c_set_clock_frequency(I2C3, I2C_CR2_FREQ_42MHZ); i2c_set_ccr(I2C3, 35); i2c_set_trise(I2C3, 43); i2c_peripheral_enable(I2C3); /* finally enable i2c */ i2c_set_own_7bit_slave_address(I2C3, 0x00); }
static void i2c_setup(void) { /* Enable clocks for I2C2 and AFIO. */ rcc_periph_clock_enable(RCC_I2C2); rcc_periph_clock_enable(RCC_AFIO); /* Set alternate functions for the SCL and SDA pins of I2C2. */ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO_I2C2_SCL | GPIO_I2C2_SDA); /* Disable the I2C before changing any configuration. */ i2c_peripheral_disable(I2C2); /* APB1 is running at 36MHz. */ i2c_set_clock_frequency(I2C2, I2C_CR2_FREQ_36MHZ); /* 400KHz - I2C Fast Mode */ i2c_set_fast_mode(I2C2); /* * fclock for I2C is 36MHz APB2 -> cycle time 28ns, low time at 400kHz * incl trise -> Thigh = 1600ns; CCR = tlow/tcycle = 0x1C,9; * Datasheet suggests 0x1e. */ i2c_set_ccr(I2C2, 0x1e); /* * fclock for I2C is 36MHz -> cycle time 28ns, rise time for * 400kHz => 300ns and 100kHz => 1000ns; 300ns/28ns = 10; * Incremented by 1 -> 11. */ i2c_set_trise(I2C2, 0x0b); /* * This is our slave address - needed only if we want to receive from * other masters. */ i2c_set_own_7bit_slave_address(I2C2, 0x32); /* If everything is configured -> enable the peripheral. */ i2c_peripheral_enable(I2C2); }
void tmp_peripheral_setup(void) { gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO6 | GPIO7); gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO6 | GPIO7); // Set this manually due to a big in libopencm3 /*gpio_set_af(GPIOB, GPIO_AF4, GPIO6 | GPIO7);*/ GPIOB_AFRL = (4<<(6*4)) | (4<<(7*4)); i2c_reset(I2C1); i2c_peripheral_disable(I2C1); i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_30MHZ); i2c_set_standard_mode(I2C1); i2c_set_ccr(I2C1, 1600); i2c_set_trise(I2C1, 0x10); i2c_peripheral_enable(I2C1); }
static void i2c_init(void) { /* i2c control lines */ rcc_periph_clock_enable(RCC_GPIOB); gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO6 | GPIO7); gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ /* GPIO_OSPEED_2MHZ */, GPIO6 | GPIO7); gpio_set_af(GPIOB, GPIO_AF4, GPIO6 | GPIO7); rcc_periph_clock_enable(I2C_CLOCK); i2c_reset(I2C_PORT); i2c_peripheral_disable(I2C_PORT); i2c_set_standard_mode(I2C_PORT); i2c_enable_ack(I2C_PORT); i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2); /* default, no need to do this really */ i2c_set_clock_frequency(I2C_PORT, I2C_FREQ); /* CCR is the number of APB bus cycles in *half* an I2C bus * cycle. For Sm (100Khz) this ends up as: * freq * 1MHz / 2 * 100KHz * freq * 1000000 / 200000 * freq * 5 * * Similar trise is the number of APB bus cycles in the rise * time (plus 1). For Sm (1us) this ends up as: * freq * 1Mhz / (1/1us) + 1 * freq * 1MHz / 1MHz + 1 * freq + 1 */ /* 42MHz / (100kHz * 2) */ i2c_set_ccr(I2C_PORT, I2C_FREQ * 5); /* standard mode, freqMhz+1*/ i2c_set_trise(I2C_PORT, I2C_FREQ + 1); i2c_set_own_7bit_slave_address(I2C_PORT, OWN_ADDRESS); i2c_peripheral_enable(I2C_PORT); }
void init_i2c(const i2c_config *ip) { // Enable periph clock. // Configure GPIO. // Reset I²C. uint32_t base = ip->i_base_address; enum rcc_periph_clken clken; switch (base) { case I2C1: clken = RCC_I2C1; break; case I2C2: clken = RCC_I2C2; break; default: assert(false && "unknown I2C base address"); } rcc_periph_clock_enable(clken); gpio_init_pins(ip->i_pins, (&ip->i_pins)[1] - ip->i_pins); uint32_t i2c_freq_mhz = rcc_apb1_frequency / 1000000; uint32_t ccr = rcc_apb1_frequency / I2C_BAUD / 2 + 1; if (ccr < 4) ccr = 4; i2c_peripheral_disable(base); i2c_set_clock_frequency(base, i2c_freq_mhz); i2c_set_trise(base, i2c_freq_mhz + 1); i2c_set_ccr(base, ccr); I2C_CR1(base) = 0; I2C_OAR1(base) = ip->i_own_address; i2c_peripheral_enable(base); }
void i2c_setbitrate(struct i2c_periph *periph, int bitrate) { // If NOT Busy if (i2c_idle(periph)) { volatile int devider; volatile int risetime; uint32_t i2c = (uint32_t) periph->reg_addr; /***************************************************** Bitrate: -CR2 + CCR + TRISE registers -only change when PE=0 e.g. 10kHz: 36MHz + Standard 0x708 + 0x25 70kHz: 36MHz + Standard 0x101 + 400kHz: 36MHz + Fast 0x1E + 0xb // 1) Program peripheral input clock CR2: to get correct timings // 2) Configure clock control registers // 3) Configure rise time register ******************************************************/ if (bitrate < 3000) bitrate = 3000; // rcc_ppre1_frequency is normally configured to max: 36MHz on F1 and 42MHz on F4 // in fast mode: 2counts low 1 count high -> / 3: // in standard mode: 1 count low, 1 count high -> /2: devider = (rcc_ppre1_frequency/2000) / (bitrate/1000); // never allow faster than 600kbps if (devider < 20) devider = 20; // no overflow either if (devider >=4095) devider = 4095; // risetime can be up to 1/6th of the period risetime = 1000000 / (bitrate/1000) / 6 / 28; if (risetime < 10) risetime = 10; // more will overflow the register: for more you should lower the FREQ if (risetime >=31) risetime = 31; // we do not expect an interrupt as the interface should have been idle, but just in case... __disable_irq(); // this code is in user space: // CCR can only be written when PE is disabled // p731 note 5 i2c_peripheral_disable(i2c); // 1) #ifdef STM32F1 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_36MHZ); #else // STM32F4 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_42MHZ); #endif // 2) //i2c_set_fast_mode(i2c); i2c_set_ccr(i2c, devider); // 3) i2c_set_trise(i2c, risetime); // Re-Enable i2c_peripheral_enable(i2c); __enable_irq(); #ifdef I2C_DEBUG_LED __disable_irq(); // this code is in user space: LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); LED2_ON(); LED1_ON(); LED2_OFF(); LED1_OFF(); __enable_irq(); #endif } }
static uint8_t u8g_board_com_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { switch (msg) { case U8G_COM_MSG_INIT: //debug("u8com: init"); /* configure I2C */ i2c_peripheral_disable(I2C1); i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_36MHZ); i2c_set_fast_mode(I2C1); i2c_set_ccr(I2C1, 0x1e); i2c_set_trise(I2C1, 0x0b); i2c_set_own_7bit_slave_address(I2C1, 0x32); /* XXX do we really want to be here? */ i2c_peripheral_enable(I2C1); break; case U8G_COM_MSG_STOP: i2c_peripheral_disable(I2C1); break; case U8G_COM_MSG_ADDRESS: /* force a new start on address change */ // com_send_stop(); /* select address for command vs. data */ current_address = arg_val ? 0x36 : 0x3c; break; case U8G_COM_MSG_CHIP_SELECT: if (arg_val) { //debug("u8com: select"); /* do nothing here */ } else { //debug("u8com: deselect"); // com_send_stop(); } break; case U8G_COM_MSG_RESET: break; case U8G_COM_MSG_WRITE_BYTE: //debug("u8com: send 0x%02x", arg_val); com_send_data(arg_val); break; case U8G_COM_MSG_WRITE_SEQ: case U8G_COM_MSG_WRITE_SEQ_P: //debug("u8com: seq %d", arg_val); { uint8_t *ptr = (uint8_t *)arg_ptr; while (arg_val-- > 0) { //debug("u8com: 0x%02x", *ptr); com_send_data(*ptr++); } } break; } return 1; }
static void setup_i2c_port(enum I2C_FREQ I2C_speed) { // Disable I2C if it happens to be enabled i2c_peripheral_disable(I2C_PORT); dma_channel_reset(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); i2c_disable_interrupt(I2C_PORT, (I2C_CR2_ITEVTEN | I2C_CR2_ITERREN)); DISABLE_I2C_INTERRUPT(); reset_i2c_pins(); // set: Source, Destination, and Amount (DMA channel must be disabled) dma_set_peripheral_address(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, (uint32_t)&I2C_DR(I2C_PORT)); dma_set_memory_address(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, 0); dma_set_number_of_data(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, 0); // set the DMA Configuration (DMA_CCRx) // (BIT 14) mem2mem_mode disabled dma_set_priority(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_PL_HIGH); // (BIT 12:13) dma_set_memory_size(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_MSIZE_8BIT); // (BIT 10:11) dma_set_peripheral_size(I2C_TX_DMA, I2C_TX_DMA_CHANNEL, DMA_CCR_PSIZE_8BIT); // (BIT 8:9) dma_enable_memory_increment_mode(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 7) dma_disable_peripheral_increment_mode(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 6) // (BIT 5) Circular mode is disabled dma_set_read_from_memory(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 4) dma_enable_transfer_error_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 3) dma_disable_half_transfer_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 2) dma_enable_transfer_complete_interrupt(I2C_TX_DMA, I2C_TX_DMA_CHANNEL); // (BIT 1) // This is the slave address when not transmitting data i2c_set_own_7bit_slave_address(I2C_PORT, 0x32); // do not respond to the specified slave address i2c_disable_ack(I2C_PORT); // Use DMA to send I2C data i2c_enable_dma(I2C_PORT); // set which interrupts I2C uses i2c_enable_interrupt(I2C_PORT, (I2C_CR2_ITEVTEN | I2C_CR2_ITERREN)); // APB1 is running at 36MHz = T(PCLK1) = 1/36000000 sec. i2c_set_clock_frequency(I2C_PORT, I2C_CR2_FREQ_36MHZ); // Set up the hardware for the particular speed switch (I2C_speed) { // Values found on Internet for the I2C standard // STANDARD : SCL max rise time = 1000ns = 1000/1000000000 sec // FAST : SCL max rise time = 300ns = 300/1000000000 sec // // DATASHEET Function: // TRISE = (T(MAX_SCL_RISE) / T(PCLK1)) + 1 // // DATASHEET Functions: // STANDARD : // T(high) = CCR * T(PCLK1) // T(low) = CCR * T(PCLK1) // FAST (DUTY=I2C_CCR_DUTY_DIV2) // T(high) = CCR * T(PCLK1) // T(low) = 2 * CCR * T(PCLK1) // FAST (DUTY=I2C_CCR_DUTY_16_DIV_9) [To reach 400KHz] // T(high) = 9 * CCR * T(PCLK1) // T(low) = 16 * CCR * T(PCLK1) // // I2C PERIOD: // STANDARD // PERIOD = T(high) + T(low) = (2 * CCR * T(PCLK1)) // FAST (DUTY=I2C_CCR_DUTY_DIV2) // PERIOD = T(high) + T(low) = (3 * CCR * T(PCLK1)) // FAST (DUTY=I2C_CCR_DUTY_16_DIV_9) // PERIOD = T(high) + T(low) = (25 * CCR * T(PCLK1)) case I2C_400KHz: // I2C PERIOD: 400KHz = 400000Hz = 1/400000 sec. i2c_set_fast_mode(I2C_PORT); // I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9 i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_16_DIV_9); // CCR = PERIOD / (25 * T(PCLK1)) // CCR = (1/400000) / (25/36000000) = 18/5 = 3.6 // CCR = 4 => I2C PERIOD = 360kHz // CCR = 3 => I2C PERIOD = 480kHz i2c_set_ccr(I2C_PORT, 4); // Only fast mode can have a value less than 0x04 // TRISE = ( (300/1000000000) / (1/36000000) ) + 1 = 59/5 = 11.8 // TRISE = 12 => SCL max rise time ~= 305.555ns // TRISE = 11 => SCL max rise time ~= 277.777ns i2c_set_trise(I2C_PORT, 11); break; case I2C_100KHz: // I2C PERIOD: 100KHz = 100000Hz = 1/100000 sec. i2c_set_standard_mode(I2C_PORT); // I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9 i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2); // CCR = PERIOD / (2 * T(PCLK1)) // CCR = (1/100000) / (2/36000000) = 180 i2c_set_ccr(I2C_PORT, 180); // TRISE = ( (1000/1000000000) / (1/36000000) ) + 1 = 37 i2c_set_trise(I2C_PORT, 37); break; case I2C_53KHz: // ~= 52.91kHz is the slowest I could get to work // CCR value of 341 works but not 342 or higher case I2C_50KHz: default: // I2C PERIOD: 50KHz = 50000Hz = 1/50000 sec. i2c_set_standard_mode(I2C_PORT); // I2C_CCR_DUTY_DIV2 or I2C_CCR_DUTY_16_DIV_9 i2c_set_dutycycle(I2C_PORT, I2C_CCR_DUTY_DIV2); // CCR = PERIOD / (2 * T(PCLK1)) // CCR = (1/50000) / (2/36000000) = 360 // (341 works but not 342 or higher) i2c_set_ccr(I2C_PORT, 341); // TRISE = ( (1000/1000000000) / (1/36000000) ) + 1 = 37 i2c_set_trise(I2C_PORT, 37); break; } i2c_peripheral_enable(I2C_PORT); // set the priorities for the interrupts nvic_set_priority(I2C_EV_IRQ, IRQ_PRI_I2C); nvic_set_priority(I2C_ER_IRQ, IRQ_PRI_ER_I2C); nvic_set_priority(I2C_DMA_IRQ, IRQ_PRI_DMA_I2C); }
static void setup_stm32f1_peripherals(void) { rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_I2C1EN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); /* GPIO pin for I2C1 SCL, SDA */ /* VESNA v1.0 gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO6); gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, GPIO7); */ /* VESNA v1.1 */ AFIO_MAPR |= AFIO_MAPR_I2C1_REMAP; gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, TDA_PIN_SCL); gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN, TDA_PIN_SDA); /* GPIO pin for TDA18219 IRQ */ gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, TDA_PIN_IRQ); /* GPIO pin for TDA18219 IF AGC */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TDA_PIN_IF_AGC); /* Set to lowest gain for now */ gpio_clear(GPIOA, TDA_PIN_IF_AGC); /* GPIO pin for AD8307 ENB */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, TDA_PIN_ENB); /* ADC pin for AD8307 output */ gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_ANALOG, TDA_PIN_OUT); /* Setup I2C */ i2c_peripheral_disable(I2C1); /* 400 kHz - I2C Fast Mode */ i2c_set_clock_frequency(I2C1, I2C_CR2_FREQ_24MHZ); i2c_set_fast_mode(I2C1); /* 400 kHz */ i2c_set_ccr(I2C1, 0x14); /* 300 ns rise time */ i2c_set_trise(I2C1, 0x08); i2c_peripheral_enable(I2C1); /* Make sure the ADC doesn't run during config. */ adc_off(ADC1); /* We configure everything for one single conversion. */ adc_disable_scan_mode(ADC1); adc_set_single_conversion_mode(ADC1); adc_enable_discontinous_mode_regular(ADC1); adc_disable_external_trigger_regular(ADC1); adc_set_right_aligned(ADC1); adc_set_conversion_time_on_all_channels(ADC1, ADC_SMPR_SMP_28DOT5CYC); adc_on(ADC1); /* Wait for ADC starting up. */ int i; for (i = 0; i < 800000; i++) /* Wait a bit. */ __asm__("nop"); adc_reset_calibration(ADC1); adc_calibration(ADC1); uint8_t channel_array[16]; /* Select the channel we want to convert. */ if(TDA_PIN_OUT == GPIO0) { channel_array[0] = 0; } else if(TDA_PIN_OUT == GPIO2) { channel_array[0] = 2; } adc_set_regular_sequence(ADC1, 1, channel_array); }