BeRTOS
|
00001 00038 #include "cfg/cfg_i2c.h" 00039 00040 #define LOG_LEVEL I2C_LOG_LEVEL 00041 #define LOG_FORMAT I2C_LOG_FORMAT 00042 #include <cfg/log.h> 00043 00044 #include <cfg/debug.h> 00045 #include <cfg/macros.h> // BV() 00046 #include <cfg/module.h> 00047 00048 #include <cpu/power.h> 00049 #include <drv/gpio_stm32.h> 00050 #include <drv/irq_cm3.h> 00051 #include <drv/clock_stm32.h> 00052 #include <drv/i2c.h> 00053 #include <drv/timer.h> 00054 00055 #include <io/stm32.h> 00056 00057 00058 struct I2cHardware 00059 { 00060 struct stm32_i2c *base; 00061 uint32_t clk_i2c_en; 00062 uint32_t pin_mask; 00063 uint8_t cache[2]; 00064 bool cached; 00065 }; 00066 00067 #define WAIT_BTF(base) \ 00068 do { \ 00069 while (!(base->SR1 & BV(SR1_BTF))) \ 00070 cpu_relax(); \ 00071 } while (0) 00072 00073 #define WAIT_RXNE(base) \ 00074 do { \ 00075 while (!(base->SR1 & BV(SR1_RXNE))) \ 00076 cpu_relax(); \ 00077 } while (0) 00078 00079 INLINE uint32_t get_status(struct stm32_i2c *base) 00080 { 00081 return ((base->SR1 | (base->SR2 << 16)) & 0x00FFFFFF); 00082 } 00083 00084 /* 00085 * This fuction read the status registers of the i2c device 00086 * and waint until the selec event happen. If occur one error 00087 * the funtions return false. 00088 */ 00089 INLINE bool wait_event(I2c *i2c, uint32_t event) 00090 { 00091 while (true) 00092 { 00093 uint32_t stat = get_status(i2c->hw->base); 00094 00095 if (stat == event) 00096 break; 00097 00098 if (stat & SR1_ERR_MASK) 00099 { 00100 i2c->hw->base->SR1 &= ~SR1_ERR_MASK; 00101 return false; 00102 } 00103 cpu_relax(); 00104 } 00105 return true; 00106 } 00107 00108 00109 INLINE void start_w(struct I2c *i2c, uint16_t slave_addr) 00110 { 00111 /* 00112 * Loop on the select write sequence: when the eeprom is busy 00113 * writing previously sent data it will reply to the SLA_W 00114 * control byte with a NACK. In this case, we must 00115 * keep trying until the eeprom responds with an ACK. 00116 */ 00117 ticks_t start = timer_clock(); 00118 while (true) 00119 { 00120 i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_START_SET; 00121 00122 if(!wait_event(i2c, I2C_EVENT_MASTER_MODE_SELECT)) 00123 { 00124 LOG_ERR("ARBIT lost\n"); 00125 i2c->errors |= I2C_ARB_LOST; 00126 break; 00127 } 00128 00129 i2c->hw->base->DR = slave_addr & OAR1_ADD0_RESET; 00130 00131 if(wait_event(i2c, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) 00132 break; 00133 00134 if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT)) 00135 { 00136 LOG_ERR("Timeout on I2C START\n"); 00137 i2c->errors |= I2C_START_TIMEOUT; 00138 i2c->hw->base->CR1 |= CR1_STOP_SET; 00139 break; 00140 } 00141 } 00142 } 00143 00144 INLINE bool start_and_addr(struct I2c *i2c, uint16_t slave_addr) 00145 { 00146 i2c->hw->base->CR1 |= CR1_START_SET; 00147 if(!wait_event(i2c, I2C_EVENT_MASTER_MODE_SELECT)) 00148 { 00149 LOG_ERR("ARBIT lost\n"); 00150 i2c->errors |= I2C_ARB_LOST; 00151 i2c->hw->base->CR1 |= CR1_STOP_SET; 00152 return false; 00153 } 00154 00155 i2c->hw->base->DR = (slave_addr | OAR1_ADD0_SET); 00156 00157 if (i2c->xfer_size == 2) 00158 i2c->hw->base->CR1 |= CR1_ACK_SET | CR1_POS_SET; 00159 00160 if(!wait_event(i2c, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) 00161 { 00162 LOG_ERR("SLAR NACK:%08lx\n", get_status(i2c->hw->base)); 00163 i2c->errors |= I2C_NO_ACK; 00164 i2c->hw->base->CR1 |= CR1_STOP_SET; 00165 return false; 00166 } 00167 00168 return true; 00169 } 00170 00171 INLINE void start_r(struct I2c *i2c, uint16_t slave_addr) 00172 { 00173 if (!start_and_addr(i2c, slave_addr)) 00174 return; 00175 /* 00176 * Due to the hardware receive bytes from slave in automatically mode 00177 * we should manage contextually all cases that we want to read one, two or more 00178 * than two bytes. To comply this behaviour to our api we shoul bufferd some byte 00179 * to hide all special case that needs to use this device. 00180 */ 00181 if (i2c->xfer_size == 1) 00182 { 00183 i2c->hw->base->CR1 &= CR1_ACK_RESET; 00184 00185 cpu_flags_t irq; 00186 00187 IRQ_SAVE_DISABLE(irq); 00188 (void)i2c->hw->base->SR2; 00189 if (I2C_TEST_STOP(i2c->flags) == I2C_STOP) 00190 i2c->hw->base->CR1 |= CR1_STOP_SET; 00191 IRQ_RESTORE(irq); 00192 00193 WAIT_RXNE(i2c->hw->base); 00194 00195 i2c->hw->cache[0] = i2c->hw->base->DR; 00196 i2c->hw->cached = true; 00197 00198 if (I2C_TEST_STOP(i2c->flags) == I2C_STOP) 00199 while (i2c->hw->base->CR1 & CR1_STOP_SET); 00200 00201 i2c->hw->base->CR1 |= CR1_ACK_SET; 00202 } 00203 else if (i2c->xfer_size == 2) 00204 { 00205 cpu_flags_t irq; 00206 00207 IRQ_SAVE_DISABLE(irq); 00208 (void)i2c->hw->base->SR2; 00209 i2c->hw->base->CR1 &= CR1_ACK_RESET; 00210 IRQ_RESTORE(irq); 00211 00212 WAIT_BTF(i2c->hw->base); 00213 00214 IRQ_SAVE_DISABLE(irq); 00215 if (I2C_TEST_STOP(i2c->flags) == I2C_STOP) 00216 i2c->hw->base->CR1 |= CR1_STOP_SET; 00217 /* 00218 * We store read bytes like a fifo.. 00219 */ 00220 i2c->hw->cache[1] = i2c->hw->base->DR; 00221 i2c->hw->cache[0] = i2c->hw->base->DR; 00222 i2c->hw->cached = true; 00223 IRQ_RESTORE(irq); 00224 00225 i2c->hw->base->CR1 &= CR1_POS_RESET; 00226 i2c->hw->base->CR1 |= CR1_ACK_SET; 00227 } 00228 } 00229 00230 static void i2c_stm32_start(struct I2c *i2c, uint16_t slave_addr) 00231 { 00232 i2c->hw->cached = false; 00233 00234 if (I2C_TEST_START(i2c->flags) == I2C_START_W) 00235 start_w(i2c, slave_addr); 00236 else /* (I2C_TEST_START(i2c->flags) == I2C_START_R) */ 00237 start_r(i2c, slave_addr); 00238 } 00239 00240 static void i2c_stm32_putc(I2c *i2c, const uint8_t data) 00241 { 00242 i2c->hw->base->DR = data; 00243 00244 WAIT_BTF(i2c->hw->base); 00245 00246 /* Generate the stop if we finish to send all programmed bytes */ 00247 if ((i2c->xfer_size == 1) && (I2C_TEST_STOP(i2c->flags) == I2C_STOP)) 00248 { 00249 wait_event(i2c, I2C_EVENT_MASTER_BYTE_TRANSMITTED); 00250 i2c->hw->base->CR1 |= CR1_STOP_SET; 00251 } 00252 } 00253 00254 static uint8_t i2c_stm32_getc(I2c *i2c) 00255 { 00256 if (i2c->hw->cached) 00257 { 00258 ASSERT(i2c->xfer_size <= 2); 00259 return i2c->hw->cache[i2c->xfer_size - 1]; 00260 } 00261 else 00262 { 00263 WAIT_BTF(i2c->hw->base); 00264 00265 if (i2c->xfer_size == 3) 00266 { 00267 i2c->hw->base->CR1 &= CR1_ACK_RESET; 00268 00269 cpu_flags_t irq; 00270 IRQ_SAVE_DISABLE(irq); 00271 00272 uint8_t data = i2c->hw->base->DR; 00273 00274 if (I2C_TEST_STOP(i2c->flags) == I2C_STOP) 00275 i2c->hw->base->CR1 |= CR1_STOP_SET; 00276 00277 i2c->hw->cache[1] = i2c->hw->base->DR; 00278 00279 IRQ_RESTORE(irq); 00280 00281 WAIT_RXNE(i2c->hw->base); 00282 00283 i2c->hw->cache[0] = i2c->hw->base->DR; 00284 i2c->hw->cached = true; 00285 00286 if (I2C_TEST_STOP(i2c->flags) == I2C_STOP) 00287 while (i2c->hw->base->CR1 & CR1_STOP_SET); 00288 00289 return data; 00290 } 00291 else 00292 return i2c->hw->base->DR; 00293 } 00294 } 00295 00296 00297 static const I2cVT i2c_stm32_vt = 00298 { 00299 .start = i2c_stm32_start, 00300 .getc = i2c_stm32_getc, 00301 .putc = i2c_stm32_putc, 00302 .write = i2c_genericWrite, 00303 .read = i2c_genericRead, 00304 }; 00305 00306 static struct I2cHardware i2c_stm32_hw[] = 00307 { 00308 { /* I2C1 */ 00309 .base = (struct stm32_i2c *)I2C1_BASE, 00310 .clk_i2c_en = RCC_APB1_I2C1, 00311 .pin_mask = (GPIO_I2C1_SCL_PIN | GPIO_I2C1_SDA_PIN), 00312 }, 00313 { /* I2C2 */ 00314 .base = (struct stm32_i2c *)I2C2_BASE, 00315 .clk_i2c_en = RCC_APB1_I2C2, 00316 .pin_mask = (GPIO_I2C2_SCL_PIN | GPIO_I2C2_SDA_PIN), 00317 }, 00318 }; 00319 00323 void i2c_hw_init(I2c *i2c, int dev, uint32_t clock) 00324 { 00325 00326 i2c->hw = &i2c_stm32_hw[dev]; 00327 i2c->vt = &i2c_stm32_vt; 00328 00329 RCC->APB2ENR |= RCC_APB2_GPIOB; 00330 RCC->APB1ENR |= i2c->hw->clk_i2c_en; 00331 00332 /* Set gpio to use I2C driver */ 00333 stm32_gpioPinConfig((struct stm32_gpio *)GPIOB_BASE, i2c->hw->pin_mask, 00334 GPIO_MODE_AF_OD, GPIO_SPEED_50MHZ); 00335 00336 /* Clear all needed registers */ 00337 i2c->hw->base->CR1 = 0; 00338 i2c->hw->base->CR2 = 0; 00339 i2c->hw->base->CCR = 0; 00340 i2c->hw->base->TRISE = 0; 00341 i2c->hw->base->OAR1 = 0; 00342 00343 /* Set PCLK1 frequency accornding to the master clock settings. See stm32_clock.c */ 00344 i2c->hw->base->CR2 |= CR2_FREQ_36MHZ; 00345 00346 /* Configure spi in standard mode */ 00347 ASSERT2(clock >= 100000, "fast mode not supported"); 00348 00349 i2c->hw->base->CCR |= (uint16_t)((CR2_FREQ_36MHZ * 1000000) / (clock << 1)); 00350 i2c->hw->base->TRISE |= (CR2_FREQ_36MHZ + 1); 00351 00352 i2c->hw->base->CR1 |= CR1_PE_SET; 00353 }