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); }
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 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_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); }