X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fstm%2Fao_i2c_stm.c;h=779e227503110971abcb3c8aa14744ef1594b1ed;hb=f221c78e6237e0a118ebe85c25e433fe16a7735d;hp=c4a6c5a38e1078f609fd4b42148d6bfe934c7962;hpb=b0b7f5da2d29716959c6793d744e47a3d435c247;p=fw%2Faltos diff --git a/src/stm/ao_i2c_stm.c b/src/stm/ao_i2c_stm.c index c4a6c5a3..779e2275 100644 --- a/src/stm/ao_i2c_stm.c +++ b/src/stm/ao_i2c_stm.c @@ -23,6 +23,8 @@ struct ao_i2c_stm_info { struct stm_i2c *stm_i2c; }; +#define I2C_FAST 1 + #define I2C_TIMEOUT 100 #define I2C_IDLE 0 @@ -33,6 +35,33 @@ static uint8_t ao_i2c_state[STM_NUM_I2C]; static uint16_t ao_i2c_addr[STM_NUM_I2C]; uint8_t ao_i2c_mutex[STM_NUM_I2C]; +# define I2C_HIGH_SLOW 5000 /* ns, 100kHz clock */ +#ifdef MEGAMETRUM +# define I2C_HIGH_FAST 2000 /* ns, 167kHz clock */ +#else +# define I2C_HIGH_FAST 1000 /* ns, 333kHz clock */ +#endif + +# define I2C_RISE_SLOW 500 /* ns */ +# define I2C_RISE_FAST 100 /* ns */ + +/* Clock period in ns */ +#define CYCLES(period) (((period) * (AO_PCLK1 / 1000)) / 1000000) + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define I2C_CCR_HIGH_SLOW max(4,CYCLES(I2C_HIGH_SLOW)) +#define I2C_CCR_HIGH_FAST max(4,CYCLES(I2C_HIGH_FAST)) +#define I2C_TRISE_SLOW (CYCLES(I2C_RISE_SLOW) + 1) +#define I2C_TRISE_FAST (CYCLES(I2C_RISE_FAST) + 1) + +#if I2C_FAST +#define I2C_TRISE I2C_TRISE_FAST +#define I2C_CCR_HIGH I2C_CCR_HIGH_FAST +#else +#define I2C_TRISE I2C_TRISE_SLOW +#define I2C_CCR_HIGH I2C_CCR_HIGH_SLOW +#endif + #if AO_PCLK1 == 2000000 # define AO_STM_I2C_CR2_FREQ STM_I2C_CR2_FREQ_2_MHZ #endif @@ -168,13 +197,13 @@ ao_i2c_start(uint8_t index, uint16_t addr) break; } ao_alarm(AO_MS_TO_TICKS(250)); - cli(); + ao_arch_block_interrupts(); stm_i2c->cr2 = AO_STM_I2C_CR2 | (1 << STM_I2C_CR2_ITEVTEN) | (1 << STM_I2C_CR2_ITERREN); ao_i2c_ev_isr(index); while (ao_i2c_state[index] == I2C_IDLE) if (ao_sleep(&ao_i2c_state[index])) break; - sei(); + ao_arch_release_interrupts(); ao_clear_alarm(); return ao_i2c_state[index] == I2C_RUNNING; } @@ -234,7 +263,7 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop) ao_dma_start(tx_dma_index); ao_alarm(1 + len); - cli(); + ao_arch_block_interrupts(); while (!ao_dma_done[tx_dma_index]) if (ao_sleep(&ao_dma_done[tx_dma_index])) break; @@ -245,7 +274,7 @@ ao_i2c_send(void *block, uint16_t len, uint8_t index, uint8_t stop) if (ao_sleep(&ao_i2c_state[index])) break; stm_i2c->cr2 = AO_STM_I2C_CR2; - sei(); + ao_arch_release_interrupts(); if (stop) { stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP); ao_i2c_wait_stop(index); @@ -299,11 +328,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop) stm_i2c->cr1 = AO_STM_I2C_CR1 | (1 << STM_I2C_CR1_STOP); ao_alarm(1); - cli(); + ao_arch_block_interrupts(); while (ao_i2c_recv_len[index]) if (ao_sleep(&ao_i2c_recv_len[index])) break; - sei(); + ao_arch_release_interrupts(); ret = ao_i2c_recv_len[index] == 0; ao_clear_alarm(); } else { @@ -329,11 +358,11 @@ ao_i2c_recv(void *block, uint16_t len, uint8_t index, uint8_t stop) ao_dma_start(rx_dma_index); ao_alarm(len); - cli(); + ao_arch_block_interrupts(); while (!ao_dma_done[rx_dma_index]) if (ao_sleep(&ao_dma_done[rx_dma_index])) break; - sei(); + ao_arch_release_interrupts(); ao_clear_alarm(); ret = ao_dma_done[rx_dma_index]; ao_dma_done_transfer(rx_dma_index); @@ -364,15 +393,23 @@ ao_i2c_channel_init(uint8_t index) stm_i2c->sr1 = 0; stm_i2c->sr2 = 0; - stm_i2c->ccr = ((0 << STM_I2C_CCR_FS) | + stm_i2c->ccr = ((I2C_FAST << STM_I2C_CCR_FS) | (0 << STM_I2C_CCR_DUTY) | - (80 << STM_I2C_CCR_CCR)); + (I2C_CCR_HIGH << STM_I2C_CCR_CCR)); - stm_i2c->trise = 17; + stm_i2c->trise = I2C_TRISE; stm_i2c->cr1 = AO_STM_I2C_CR1; } +static inline void +i2c_pin_set(struct stm_gpio *gpio, int pin) +{ + stm_afr_set(gpio, pin, STM_AFR_AF4); + stm_ospeedr_set(gpio, pin, STM_OSPEEDR_400kHz); + stm_pupdr_set(gpio, pin, STM_PUPDR_PULL_UP); +} + void ao_i2c_init(void) { @@ -380,12 +417,12 @@ ao_i2c_init(void) stm_rcc.ahbenr |= (1 << STM_RCC_AHBENR_GPIOBEN); #if HAS_I2C_1 # if I2C_1_PB6_PB7 - stm_afr_set(&stm_gpiob, 6, STM_AFR_AF4); - stm_afr_set(&stm_gpiob, 7, STM_AFR_AF4); + i2c_pin_set(&stm_gpiob, 6); + i2c_pin_set(&stm_gpiob, 7); # else # if I2C_1_PB8_PB9 - stm_afr_set(&stm_gpiob, 8, STM_AFR_AF4); - stm_afr_set(&stm_gpiob, 9, STM_AFR_AF4); + i2c_pin_set(&stm_gpiob, 8); + i2c_pin_set(&stm_gpiob, 9); # else # error "No I2C_1 port configuration specified" # endif @@ -395,15 +432,15 @@ ao_i2c_init(void) ao_i2c_channel_init(0); stm_nvic_set_enable(STM_ISR_I2C1_EV_POS); - stm_nvic_set_priority(STM_ISR_I2C1_EV_POS, 3); + stm_nvic_set_priority(STM_ISR_I2C1_EV_POS, AO_STM_NVIC_MED_PRIORITY); stm_nvic_set_enable(STM_ISR_I2C1_ER_POS); - stm_nvic_set_priority(STM_ISR_I2C1_ER_POS, 3); + stm_nvic_set_priority(STM_ISR_I2C1_ER_POS, AO_STM_NVIC_MED_PRIORITY); #endif #if HAS_I2C_2 # if I2C_2_PB10_PB11 - stm_afr_set(&stm_gpiob, 10, STM_AFR_AF4); - stm_afr_set(&stm_gpiob, 11, STM_AFR_AF4); + i2c_pin_set(&stm_gpiob, 10); + i2c_pin_set(&stm_gpiob, 11); # else # error "No I2C_2 port configuration specified" # endif @@ -411,8 +448,8 @@ ao_i2c_init(void) ao_i2c_channel_init(1); stm_nvic_set_enable(STM_ISR_I2C2_EV_POS); - stm_nvic_set_priority(STM_ISR_I2C2_EV_POS, 3); + stm_nvic_set_priority(STM_ISR_I2C2_EV_POS, AO_STM_NVIC_MED_PRIORITY); stm_nvic_set_enable(STM_ISR_I2C2_ER_POS); - stm_nvic_set_priority(STM_ISR_I2C2_ER_POS, 3); + stm_nvic_set_priority(STM_ISR_I2C2_ER_POS, AO_STM_NVIC_MED_PRIORITY); #endif }