amiro-os / kernel / patches / I2C-without-DMA.patch @ 732a4657
History | View | Annotate | Download (27.04 KB)
| 1 | 22be62dc | Thomas Schöpping | diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
|---|---|---|---|
| 2 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
||
| 3 | +++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.c
|
||
| 4 | @@ -34,6 +34,7 @@
|
||
| 5 | 732a4657 | Thomas Schöpping | /* Driver local definitions. */
|
| 6 | /*===========================================================================*/
|
||
| 7 | |||
| 8 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 9 | #define I2C1_RX_DMA_CHANNEL \ |
||
| 10 | STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_RX_DMA_STREAM, \
|
||
| 11 | STM32_I2C1_RX_DMA_CHN) |
||
| 12 | 22be62dc | Thomas Schöpping | @@ -41,7 +42,9 @@
|
| 13 | 732a4657 | Thomas Schöpping | #define I2C1_TX_DMA_CHANNEL \ |
| 14 | STM32_DMA_GETCHANNEL(STM32_I2C_I2C1_TX_DMA_STREAM, \
|
||
| 15 | STM32_I2C1_TX_DMA_CHN) |
||
| 16 | +#endif
|
||
| 17 | |||
| 18 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 19 | #define I2C2_RX_DMA_CHANNEL \ |
||
| 20 | STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_RX_DMA_STREAM, \
|
||
| 21 | STM32_I2C2_RX_DMA_CHN) |
||
| 22 | 22be62dc | Thomas Schöpping | @@ -49,7 +52,9 @@
|
| 23 | 732a4657 | Thomas Schöpping | #define I2C2_TX_DMA_CHANNEL \ |
| 24 | STM32_DMA_GETCHANNEL(STM32_I2C_I2C2_TX_DMA_STREAM, \
|
||
| 25 | STM32_I2C2_TX_DMA_CHN) |
||
| 26 | +#endif
|
||
| 27 | |||
| 28 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 29 | #define I2C3_RX_DMA_CHANNEL \ |
||
| 30 | STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_RX_DMA_STREAM, \
|
||
| 31 | STM32_I2C3_RX_DMA_CHN) |
||
| 32 | 22be62dc | Thomas Schöpping | @@ -57,6 +62,7 @@
|
| 33 | 732a4657 | Thomas Schöpping | #define I2C3_TX_DMA_CHANNEL \ |
| 34 | STM32_DMA_GETCHANNEL(STM32_I2C_I2C3_TX_DMA_STREAM, \
|
||
| 35 | STM32_I2C3_TX_DMA_CHN) |
||
| 36 | +#endif
|
||
| 37 | |||
| 38 | /*===========================================================================*/
|
||
| 39 | /* Driver constants. */
|
||
| 40 | 22be62dc | Thomas Schöpping | @@ -72,6 +78,20 @@
|
| 41 | 732a4657 | Thomas Schöpping | #define I2C_EV6_MASTER_REC_MODE_SELECTED \ |
| 42 | ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_ADDR))
|
||
| 43 | |||
| 44 | +#define I2C_EV7_MASTER_REC_BYTE_RECEIVED \
|
||
| 45 | + ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | I2C_SR1_RXNE))
|
||
| 46 | +
|
||
| 47 | +#define I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP \
|
||
| 48 | + ((uint32_t)(I2C_SR1_RXNE))
|
||
| 49 | +
|
||
| 50 | +#define I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED \
|
||
| 51 | + ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY)<< 16) | \
|
||
| 52 | + I2C_SR1_BTF | I2C_SR1_RXNE))
|
||
| 53 | +
|
||
| 54 | +#define I2C_EV8_MASTER_BYTE_TRANSMITTING \
|
||
| 55 | + ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA)<< 16) | \
|
||
| 56 | + I2C_SR1_TXE))
|
||
| 57 | +
|
||
| 58 | #define I2C_EV8_2_MASTER_BYTE_TRANSMITTED \ |
||
| 59 | ((uint32_t)(((I2C_SR2_MSL | I2C_SR2_BUSY | I2C_SR2_TRA) << 16) | \ |
||
| 60 | I2C_SR1_BTF | I2C_SR1_TXE)) |
||
| 61 | 22be62dc | Thomas Schöpping | @@ -129,8 +149,24 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) { |
| 62 | 732a4657 | Thomas Schöpping | dp->SR1 = 0;
|
| 63 | |||
| 64 | /* Stops the associated DMA streams.*/
|
||
| 65 | - dmaStreamDisable(i2cp->dmatx);
|
||
| 66 | - dmaStreamDisable(i2cp->dmarx);
|
||
| 67 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
| 68 | + if (&I2CD1 == i2cp) {
|
||
| 69 | + dmaStreamDisable(i2cp->dmatx);
|
||
| 70 | + dmaStreamDisable(i2cp->dmarx);
|
||
| 71 | + }
|
||
| 72 | +#endif
|
||
| 73 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
| 74 | + if (&I2CD2 == i2cp) {
|
||
| 75 | + dmaStreamDisable(i2cp->dmatx);
|
||
| 76 | + dmaStreamDisable(i2cp->dmarx);
|
||
| 77 | + }
|
||
| 78 | +#endif
|
||
| 79 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
| 80 | + if (&I2CD3 == i2cp) {
|
||
| 81 | + dmaStreamDisable(i2cp->dmatx);
|
||
| 82 | + dmaStreamDisable(i2cp->dmarx);
|
||
| 83 | + }
|
||
| 84 | +#endif
|
||
| 85 | } |
||
| 86 | |||
| 87 | /**
|
||
| 88 | @@ -235,14 +271,18 @@ static void i2c_lld_set_opmode(I2CDriver *i2cp) { |
||
| 89 | dp->CR1 = regCR1; |
||
| 90 | } |
||
| 91 | |||
| 92 | +#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
||
| 93 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
| 94 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) || \
|
||
| 95 | + defined(__DOXYGEN__)
|
||
| 96 | /**
|
||
| 97 | - * @brief I2C shared ISR code.
|
||
| 98 | + * @brief I2C shared ISR code for DMA access.
|
||
| 99 | * |
||
| 100 | * @param[in] i2cp pointer to the @p I2CDriver object |
||
| 101 | * |
||
| 102 | * @notapi
|
||
| 103 | */ |
||
| 104 | -static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) {
|
||
| 105 | +static void i2c_lld_serve_event_interrupt_dma(I2CDriver *i2cp) {
|
||
| 106 | I2C_TypeDef *dp = i2cp->i2c; |
||
| 107 | uint32_t regSR2 = dp->SR2; |
||
| 108 | uint32_t event = dp->SR1; |
||
| 109 | 22be62dc | Thomas Schöpping | @@ -252,7 +292,7 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) { |
| 110 | 732a4657 | Thomas Schöpping | done by the DMA.*/ |
| 111 | switch (I2C_EV_MASK & (event | (regSR2 << 16))) { |
||
| 112 | case I2C_EV5_MASTER_MODE_SELECT:
|
||
| 113 | - if ((i2cp->addr >> 8) > 0) {
|
||
| 114 | + if ((i2cp->addr >> 8) > 0) {
|
||
| 115 | /* 10-bit address: 1 1 1 1 0 X X R/W */
|
||
| 116 | dp->DR = 0xF0 | (0x6 & (i2cp->addr >> 8)) | (0x1 & i2cp->addr); |
||
| 117 | } else {
|
||
| 118 | @@ -293,7 +333,146 @@ static void i2c_lld_serve_event_interrupt(I2CDriver *i2cp) { |
||
| 119 | if (event & (I2C_SR1_ADDR | I2C_SR1_ADD10))
|
||
| 120 | (void)dp->SR2;
|
||
| 121 | } |
||
| 122 | +#endif /* any I2CDx uses DMA mode */
|
||
| 123 | +
|
||
| 124 | +#if (STM32_I2C_USE_I2C1 && !STM32_I2C_I2C1_USE_DMA) || \
|
||
| 125 | + (STM32_I2C_USE_I2C2 && !STM32_I2C_I2C2_USE_DMA) || \
|
||
| 126 | + (STM32_I2C_USE_I2C3 && !STM32_I2C_I2C3_USE_DMA) || \
|
||
| 127 | + defined(__DOXYGEN__)
|
||
| 128 | +/**
|
||
| 129 | + * @brief I2C shared ISR code for non-DMA access.
|
||
| 130 | + *
|
||
| 131 | + * @param[in] i2cp pointer to the @p I2CDriver object
|
||
| 132 | + *
|
||
| 133 | + * @notapi
|
||
| 134 | + */
|
||
| 135 | +static void i2c_lld_serve_event_interrupt_isr(I2CDriver *i2cp) {
|
||
| 136 | + I2C_TypeDef *dp = i2cp->i2c;
|
||
| 137 | + uint32_t regSR2 = dp->SR2;
|
||
| 138 | + uint32_t event = dp->SR1;
|
||
| 139 | +
|
||
| 140 | + switch (I2C_EV_MASK & (event | (regSR2 << 16))) {
|
||
| 141 | + case I2C_EV5_MASTER_MODE_SELECT:
|
||
| 142 | + dp->CR2 |= I2C_CR2_ITBUFEN;
|
||
| 143 | + dp->DR = i2cp->addr;
|
||
| 144 | + break;
|
||
| 145 | + case I2C_EV6_MASTER_TRA_MODE_SELECTED:
|
||
| 146 | + (void)dp->SR2; // clear ADDR flag
|
||
| 147 | + /* EV8_1 */
|
||
| 148 | + dp->DR = *(i2cp->txbuf);
|
||
| 149 | +
|
||
| 150 | + ++i2cp->txbuf;
|
||
| 151 | + --i2cp->txbytes;
|
||
| 152 | +
|
||
| 153 | + /* if N == 1, skip the I2C_EV8_MASTER_BYTE_TRANSMITTING event
|
||
| 154 | + * but enter I2C_EV8_2_MASTER_BYTE_TRANSMITTED next */
|
||
| 155 | + if (i2cp->txbytes == 0) {
|
||
| 156 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
| 157 | + }
|
||
| 158 | + break;
|
||
| 159 | + case I2C_EV6_MASTER_REC_MODE_SELECTED:
|
||
| 160 | + switch (i2cp->rxbytes) {
|
||
| 161 | + case 1:
|
||
| 162 | + dp->CR1 &= ~I2C_CR1_ACK;
|
||
| 163 | + (void)dp->SR2; // clear ADDR flag
|
||
| 164 | + dp->CR1 |= I2C_CR1_STOP;
|
||
| 165 | + break;
|
||
| 166 | + case 2:
|
||
| 167 | + (void)dp->SR2; // clear ADDR flag
|
||
| 168 | + /* EV6_1 */
|
||
| 169 | + dp->CR1 |= I2C_CR1_POS;
|
||
| 170 | + dp->CR1 &= ~I2C_CR1_ACK;
|
||
| 171 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
| 172 | + break;
|
||
| 173 | + case 3: /* N == 3 is a very special case, since EV7 is completely skipped */
|
||
| 174 | + (void)dp->SR2; // clear ADDR flag
|
||
| 175 | + /* Disable the I2C_EV7_MASTER_REC_BYTE_RECEIVED event
|
||
| 176 | + * but enter I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP next */
|
||
| 177 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
| 178 | + break;
|
||
| 179 | + default: /* N > 2 */
|
||
| 180 | + (void)dp->SR2; // clear ADDR flag
|
||
| 181 | + break;
|
||
| 182 | + }
|
||
| 183 | + break;
|
||
| 184 | + case I2C_EV7_MASTER_REC_BYTE_RECEIVED:
|
||
| 185 | + if (i2cp->rxbytes > 3) {
|
||
| 186 | + *(i2cp->rxbuf) = dp->DR;
|
||
| 187 | + ++i2cp->rxbuf;
|
||
| 188 | + --i2cp->rxbytes;
|
||
| 189 | + }
|
||
| 190 | + if (i2cp->rxbytes == 3) {
|
||
| 191 | + /* Disable this event for DataN-2, but force into event
|
||
| 192 | + * I2C_EV7_2_EV7_3_MASTER_REC_BYTE_RECEIVED_QUEUED by not reading dp->DR. */
|
||
| 193 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
| 194 | + }
|
||
| 195 | + break;
|
||
| 196 | + case I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP:
|
||
| 197 | + osalDbgAssert(i2cp->rxbytes == 1, "more than 1 byte to be received");
|
||
| 198 | + *(i2cp->rxbuf) = dp->DR;
|
||
| 199 | + --i2cp->rxbytes;
|
||
| 200 | + dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
|
||
| 201 | + _i2c_wakeup_isr(i2cp);
|
||
| 202 | + break;
|
||
| 203 | + case I2C_EV7_2_EV7_3_MASTER_REC_BYTE_QUEUED:
|
||
| 204 | + if (i2cp->rxbytes == 3) {
|
||
| 205 | + /* EV7_2 (N > 2) */
|
||
| 206 | + dp->CR1 &= ~I2C_CR1_ACK;
|
||
| 207 | + *(i2cp->rxbuf) = dp->DR;
|
||
| 208 | + ++i2cp->rxbuf;
|
||
| 209 | + dp->CR1 |= I2C_CR1_STOP;
|
||
| 210 | + *(i2cp->rxbuf) = dp->DR;
|
||
| 211 | + ++i2cp->rxbuf;
|
||
| 212 | + i2cp->rxbytes -= 2;
|
||
| 213 | + /* enable I2C_EV7_MASTER_REC_BYTE_RECEIVED_STOP event */
|
||
| 214 | + dp->CR2 |= I2C_CR2_ITBUFEN;
|
||
| 215 | + } else {
|
||
| 216 | + /* EV7_3 (N == 2) */
|
||
| 217 | + dp->CR1 |= I2C_CR1_STOP;
|
||
| 218 | + *(i2cp->rxbuf) = dp->DR;
|
||
| 219 | + ++i2cp->rxbuf;
|
||
| 220 | + *(i2cp->rxbuf) = dp->DR;
|
||
| 221 | + i2cp->rxbytes -= 2;
|
||
| 222 | +
|
||
| 223 | + dp->CR1 &= ~I2C_CR1_POS;
|
||
| 224 | + dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
|
||
| 225 | +
|
||
| 226 | + _i2c_wakeup_isr(i2cp);
|
||
| 227 | + }
|
||
| 228 | + break;
|
||
| 229 | + case I2C_EV8_MASTER_BYTE_TRANSMITTING:
|
||
| 230 | + dp->DR = *(i2cp->txbuf);
|
||
| 231 | + ++i2cp->txbuf;
|
||
| 232 | + --i2cp->txbytes;
|
||
| 233 | +
|
||
| 234 | + /* if this was the last byte, ensure that this event is not entered again */
|
||
| 235 | + if (i2cp->txbytes == 0) {
|
||
| 236 | + dp->CR2 &= ~I2C_CR2_ITBUFEN;
|
||
| 237 | + }
|
||
| 238 | + break;
|
||
| 239 | + case I2C_EV8_2_MASTER_BYTE_TRANSMITTED:
|
||
| 240 | + if (i2cp->rxbytes > 0) {
|
||
| 241 | + /* start "read after write" operation (LSB of address = 1 => read) */
|
||
| 242 | + i2cp->addr |= 0x01;
|
||
| 243 | + dp->CR1 |= I2C_CR1_START | I2C_CR1_ACK;
|
||
| 244 | + } else {
|
||
| 245 | + dp->CR1 |= I2C_CR1_STOP;
|
||
| 246 | + dp->CR2 &= ~(I2C_CR2_ITEVTEN | I2C_CR2_ITBUFEN);
|
||
| 247 | + _i2c_wakeup_isr(i2cp);
|
||
| 248 | + }
|
||
| 249 | + break;
|
||
| 250 | + default:
|
||
| 251 | + osalDbgAssert(i2cp->rxbytes != 1, "more than 1 byte to be received");
|
||
| 252 | + break;
|
||
| 253 | + }
|
||
| 254 | +}
|
||
| 255 | +#endif /* any I2CDx uses non-DMA mode */
|
||
| 256 | |||
| 257 | +
|
||
| 258 | +#if (STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
||
| 259 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
| 260 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA) || \
|
||
| 261 | + defined(__DOXYGEN__)
|
||
| 262 | /**
|
||
| 263 | * @brief DMA RX end IRQ handler.
|
||
| 264 | * |
||
| 265 | @@ -347,6 +526,7 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { |
||
| 266 | of R/W transaction itself.*/ |
||
| 267 | dp->CR2 |= I2C_CR2_ITEVTEN; |
||
| 268 | } |
||
| 269 | +#endif /* any I2CDx uses DMA mode */
|
||
| 270 | |||
| 271 | /**
|
||
| 272 | * @brief I2C error handler.
|
||
| 273 | @@ -359,8 +539,24 @@ static void i2c_lld_serve_tx_end_irq(I2CDriver *i2cp, uint32_t flags) { |
||
| 274 | static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint16_t sr) { |
||
| 275 | |||
| 276 | /* Clears interrupt flags just to be safe.*/
|
||
| 277 | - dmaStreamDisable(i2cp->dmatx);
|
||
| 278 | - dmaStreamDisable(i2cp->dmarx);
|
||
| 279 | +#if STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA
|
||
| 280 | + if (&I2CD1 == i2cp) {
|
||
| 281 | + dmaStreamDisable(i2cp->dmatx);
|
||
| 282 | + dmaStreamDisable(i2cp->dmarx);
|
||
| 283 | + }
|
||
| 284 | +#endif
|
||
| 285 | +#if STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA
|
||
| 286 | + if (&I2CD2 == i2cp) {
|
||
| 287 | + dmaStreamDisable(i2cp->dmatx);
|
||
| 288 | + dmaStreamDisable(i2cp->dmarx);
|
||
| 289 | + }
|
||
| 290 | +#endif
|
||
| 291 | +#if STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA
|
||
| 292 | + if (&I2CD3 == i2cp) {
|
||
| 293 | + dmaStreamDisable(i2cp->dmatx);
|
||
| 294 | + dmaStreamDisable(i2cp->dmarx);
|
||
| 295 | + }
|
||
| 296 | +#endif
|
||
| 297 | |||
| 298 | i2cp->errors = I2C_NO_ERROR; |
||
| 299 | |||
| 300 | @@ -407,7 +603,11 @@ OSAL_IRQ_HANDLER(STM32_I2C1_EVENT_HANDLER) {
|
||
| 301 | |||
| 302 | OSAL_IRQ_PROLOGUE(); |
||
| 303 | |||
| 304 | - i2c_lld_serve_event_interrupt(&I2CD1);
|
||
| 305 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 306 | + i2c_lld_serve_event_interrupt_dma(&I2CD1);
|
||
| 307 | +#else
|
||
| 308 | + i2c_lld_serve_event_interrupt_isr(&I2CD1);
|
||
| 309 | +#endif
|
||
| 310 | |||
| 311 | OSAL_IRQ_EPILOGUE(); |
||
| 312 | } |
||
| 313 | @@ -437,7 +637,11 @@ OSAL_IRQ_HANDLER(STM32_I2C2_EVENT_HANDLER) {
|
||
| 314 | |||
| 315 | OSAL_IRQ_PROLOGUE(); |
||
| 316 | |||
| 317 | - i2c_lld_serve_event_interrupt(&I2CD2);
|
||
| 318 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 319 | + i2c_lld_serve_event_interrupt_dma(&I2CD2);
|
||
| 320 | +#else
|
||
| 321 | + i2c_lld_serve_event_interrupt_isr(&I2CD2);
|
||
| 322 | +#endif
|
||
| 323 | |||
| 324 | OSAL_IRQ_EPILOGUE(); |
||
| 325 | } |
||
| 326 | @@ -469,7 +673,11 @@ OSAL_IRQ_HANDLER(STM32_I2C3_EVENT_HANDLER) {
|
||
| 327 | |||
| 328 | OSAL_IRQ_PROLOGUE(); |
||
| 329 | |||
| 330 | - i2c_lld_serve_event_interrupt(&I2CD3);
|
||
| 331 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 332 | + i2c_lld_serve_event_interrupt_dma(&I2CD3);
|
||
| 333 | +#else
|
||
| 334 | + i2c_lld_serve_event_interrupt_isr(&I2CD3);
|
||
| 335 | +#endif
|
||
| 336 | |||
| 337 | OSAL_IRQ_EPILOGUE(); |
||
| 338 | } |
||
| 339 | @@ -540,19 +748,22 @@ void i2c_lld_start(I2CDriver *i2cp) { |
||
| 340 | /* If in stopped state then enables the I2C and DMA clocks.*/
|
||
| 341 | if (i2cp->state == I2C_STOP) {
|
||
| 342 | |||
| 343 | - i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 344 | - STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 345 | - STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 346 | - STM32_DMA_CR_DIR_M2P;
|
||
| 347 | - i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 348 | - STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 349 | - STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 350 | - STM32_DMA_CR_DIR_P2M;
|
||
| 351 | -
|
||
| 352 | #if STM32_I2C_USE_I2C1
|
||
| 353 | if (&I2CD1 == i2cp) {
|
||
| 354 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 355 | + i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 356 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 357 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 358 | + STM32_DMA_CR_DIR_M2P;
|
||
| 359 | + i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 360 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 361 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 362 | + STM32_DMA_CR_DIR_P2M;
|
||
| 363 | +#endif
|
||
| 364 | +
|
||
| 365 | rccResetI2C1(); |
||
| 366 | |||
| 367 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 368 | i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C1_RX_DMA_STREAM, |
||
| 369 | STM32_I2C_I2C1_IRQ_PRIORITY, |
||
| 370 | (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
||
| 371 | @@ -563,22 +774,50 @@ void i2c_lld_start(I2CDriver *i2cp) { |
||
| 372 | (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
||
| 373 | (void *)i2cp);
|
||
| 374 | osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
||
| 375 | +#endif
|
||
| 376 | |||
| 377 | rccEnableI2C1(true);
|
||
| 378 | nvicEnableVector(I2C1_EV_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY); |
||
| 379 | nvicEnableVector(I2C1_ER_IRQn, STM32_I2C_I2C1_IRQ_PRIORITY); |
||
| 380 | |||
| 381 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 382 | i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | |
||
| 383 | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); |
||
| 384 | i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) | |
||
| 385 | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); |
||
| 386 | +
|
||
| 387 | + /* I2C registers pointed by the DMA.*/
|
||
| 388 | + dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
| 389 | + dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
| 390 | +#endif
|
||
| 391 | +
|
||
| 392 | + /* Reset i2c peripheral.*/
|
||
| 393 | + dp->CR1 = I2C_CR1_SWRST;
|
||
| 394 | + dp->CR1 = 0;
|
||
| 395 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 396 | + dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
| 397 | +#else
|
||
| 398 | + dp->CR2 = I2C_CR2_ITERREN;
|
||
| 399 | +#endif
|
||
| 400 | } |
||
| 401 | #endif /* STM32_I2C_USE_I2C1 */ |
||
| 402 | |||
| 403 | #if STM32_I2C_USE_I2C2
|
||
| 404 | if (&I2CD2 == i2cp) {
|
||
| 405 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 406 | + i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 407 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 408 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 409 | + STM32_DMA_CR_DIR_M2P;
|
||
| 410 | + i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 411 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 412 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 413 | + STM32_DMA_CR_DIR_P2M;
|
||
| 414 | +#endif
|
||
| 415 | +
|
||
| 416 | rccResetI2C2(); |
||
| 417 | |||
| 418 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 419 | i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C2_RX_DMA_STREAM, |
||
| 420 | STM32_I2C_I2C2_IRQ_PRIORITY, |
||
| 421 | (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
||
| 422 | @@ -589,22 +828,50 @@ void i2c_lld_start(I2CDriver *i2cp) { |
||
| 423 | (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
||
| 424 | (void *)i2cp);
|
||
| 425 | osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
||
| 426 | +#endif
|
||
| 427 | |||
| 428 | rccEnableI2C2(true);
|
||
| 429 | nvicEnableVector(I2C2_EV_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY); |
||
| 430 | nvicEnableVector(I2C2_ER_IRQn, STM32_I2C_I2C2_IRQ_PRIORITY); |
||
| 431 | |||
| 432 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 433 | i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) | |
||
| 434 | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); |
||
| 435 | i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) | |
||
| 436 | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); |
||
| 437 | +
|
||
| 438 | + /* I2C registers pointed by the DMA.*/
|
||
| 439 | + dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
| 440 | + dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
| 441 | +#endif
|
||
| 442 | +
|
||
| 443 | + /* Reset i2c peripheral.*/
|
||
| 444 | + dp->CR1 = I2C_CR1_SWRST;
|
||
| 445 | + dp->CR1 = 0;
|
||
| 446 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 447 | + dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
| 448 | +#else
|
||
| 449 | + dp->CR2 = I2C_CR2_ITERREN;
|
||
| 450 | +#endif
|
||
| 451 | } |
||
| 452 | #endif /* STM32_I2C_USE_I2C2 */ |
||
| 453 | |||
| 454 | #if STM32_I2C_USE_I2C3
|
||
| 455 | if (&I2CD3 == i2cp) {
|
||
| 456 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 457 | + i2cp->txdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 458 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 459 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 460 | + STM32_DMA_CR_DIR_M2P;
|
||
| 461 | + i2cp->rxdmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE |
|
||
| 462 | + STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE |
|
||
| 463 | + STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE |
|
||
| 464 | + STM32_DMA_CR_DIR_P2M;
|
||
| 465 | +#endif
|
||
| 466 | +
|
||
| 467 | rccResetI2C3(); |
||
| 468 | |||
| 469 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 470 | i2cp->dmarx = dmaStreamAllocI(STM32_I2C_I2C3_RX_DMA_STREAM, |
||
| 471 | STM32_I2C_I2C3_IRQ_PRIORITY, |
||
| 472 | (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, |
||
| 473 | @@ -615,28 +882,35 @@ void i2c_lld_start(I2CDriver *i2cp) { |
||
| 474 | (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, |
||
| 475 | (void *)i2cp);
|
||
| 476 | osalDbgAssert(i2cp->dmatx != NULL, "unable to allocate stream"); |
||
| 477 | +#endif
|
||
| 478 | |||
| 479 | rccEnableI2C3(true);
|
||
| 480 | nvicEnableVector(I2C3_EV_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY); |
||
| 481 | nvicEnableVector(I2C3_ER_IRQn, STM32_I2C_I2C3_IRQ_PRIORITY); |
||
| 482 | |||
| 483 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 484 | i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) | |
||
| 485 | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); |
||
| 486 | i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) | |
||
| 487 | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); |
||
| 488 | +
|
||
| 489 | + /* I2C registers pointed by the DMA.*/
|
||
| 490 | + dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
| 491 | + dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
| 492 | +#endif
|
||
| 493 | +
|
||
| 494 | + /* Reset i2c peripheral.*/
|
||
| 495 | + dp->CR1 = I2C_CR1_SWRST;
|
||
| 496 | + dp->CR1 = 0;
|
||
| 497 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 498 | + dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
| 499 | +#else
|
||
| 500 | + dp->CR2 = I2C_CR2_ITERREN;
|
||
| 501 | +#endif
|
||
| 502 | } |
||
| 503 | #endif /* STM32_I2C_USE_I2C3 */ |
||
| 504 | } |
||
| 505 | |||
| 506 | - /* I2C registers pointed by the DMA.*/
|
||
| 507 | - dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR);
|
||
| 508 | - dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR);
|
||
| 509 | -
|
||
| 510 | - /* Reset i2c peripheral.*/
|
||
| 511 | - dp->CR1 = I2C_CR1_SWRST;
|
||
| 512 | - dp->CR1 = 0;
|
||
| 513 | - dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN;
|
||
| 514 | -
|
||
| 515 | /* Setup I2C parameters.*/
|
||
| 516 | i2c_lld_set_clock(i2cp); |
||
| 517 | i2c_lld_set_opmode(i2cp); |
||
| 518 | @@ -659,13 +933,15 @@ void i2c_lld_stop(I2CDriver *i2cp) { |
||
| 519 | |||
| 520 | /* I2C disable.*/
|
||
| 521 | i2c_lld_abort_operation(i2cp); |
||
| 522 | - dmaStreamFreeI(i2cp->dmatx);
|
||
| 523 | - dmaStreamFreeI(i2cp->dmarx);
|
||
| 524 | - i2cp->dmatx = NULL;
|
||
| 525 | - i2cp->dmarx = NULL;
|
||
| 526 | |||
| 527 | #if STM32_I2C_USE_I2C1
|
||
| 528 | if (&I2CD1 == i2cp) {
|
||
| 529 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 530 | + dmaStreamFreeI(i2cp->dmatx);
|
||
| 531 | + dmaStreamFreeI(i2cp->dmarx);
|
||
| 532 | + i2cp->dmatx = NULL;
|
||
| 533 | + i2cp->dmarx = NULL;
|
||
| 534 | +#endif
|
||
| 535 | nvicDisableVector(I2C1_EV_IRQn); |
||
| 536 | nvicDisableVector(I2C1_ER_IRQn); |
||
| 537 | rccDisableI2C1(); |
||
| 538 | @@ -674,6 +950,12 @@ void i2c_lld_stop(I2CDriver *i2cp) { |
||
| 539 | |||
| 540 | #if STM32_I2C_USE_I2C2
|
||
| 541 | if (&I2CD2 == i2cp) {
|
||
| 542 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 543 | + dmaStreamFreeI(i2cp->dmatx);
|
||
| 544 | + dmaStreamFreeI(i2cp->dmarx);
|
||
| 545 | + i2cp->dmatx = NULL;
|
||
| 546 | + i2cp->dmarx = NULL;
|
||
| 547 | +#endif
|
||
| 548 | nvicDisableVector(I2C2_EV_IRQn); |
||
| 549 | nvicDisableVector(I2C2_ER_IRQn); |
||
| 550 | rccDisableI2C2(); |
||
| 551 | @@ -682,6 +964,12 @@ void i2c_lld_stop(I2CDriver *i2cp) { |
||
| 552 | |||
| 553 | #if STM32_I2C_USE_I2C3
|
||
| 554 | if (&I2CD3 == i2cp) {
|
||
| 555 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 556 | + dmaStreamFreeI(i2cp->dmatx);
|
||
| 557 | + dmaStreamFreeI(i2cp->dmarx);
|
||
| 558 | + i2cp->dmatx = NULL;
|
||
| 559 | + i2cp->dmarx = NULL;
|
||
| 560 | +#endif
|
||
| 561 | nvicDisableVector(I2C3_EV_IRQn); |
||
| 562 | nvicDisableVector(I2C3_ER_IRQn); |
||
| 563 | rccDisableI2C3(); |
||
| 564 | @@ -732,10 +1020,43 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||
| 565 | /* Releases the lock from high level driver.*/
|
||
| 566 | osalSysUnlock(); |
||
| 567 | |||
| 568 | - /* RX DMA setup.*/
|
||
| 569 | - dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 570 | - dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 571 | - dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 572 | + /* RX (DMA) setup.*/
|
||
| 573 | +#if STM32_I2C_USE_I2C1
|
||
| 574 | + if (&I2CD1 == i2cp) {
|
||
| 575 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 576 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 577 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 578 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 579 | +#else
|
||
| 580 | + i2cp->rxbuf = rxbuf;
|
||
| 581 | + i2cp->rxbytes = rxbytes;
|
||
| 582 | +#endif
|
||
| 583 | + }
|
||
| 584 | +#endif
|
||
| 585 | +#if STM32_I2C_USE_I2C2
|
||
| 586 | + if (&I2CD2 == i2cp) {
|
||
| 587 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 588 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 589 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 590 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 591 | +#else
|
||
| 592 | + i2cp->rxbuf = rxbuf;
|
||
| 593 | + i2cp->rxbytes = rxbytes;
|
||
| 594 | +#endif
|
||
| 595 | + }
|
||
| 596 | +#endif
|
||
| 597 | +#if STM32_I2C_USE_I2C3
|
||
| 598 | + if (&I2CD3 == i2cp) {
|
||
| 599 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 600 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 601 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 602 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 603 | +#else
|
||
| 604 | + i2cp->rxbuf = rxbuf;
|
||
| 605 | + i2cp->rxbytes = rxbytes;
|
||
| 606 | +#endif
|
||
| 607 | + }
|
||
| 608 | +#endif
|
||
| 609 | |||
| 610 | /* Calculating the time window for the timeout on the busy bus condition.*/
|
||
| 611 | start = osalOsGetSystemTimeX(); |
||
| 612 | @@ -812,15 +1133,61 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||
| 613 | /* Releases the lock from high level driver.*/
|
||
| 614 | osalSysUnlock(); |
||
| 615 | |||
| 616 | - /* TX DMA setup.*/
|
||
| 617 | - dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
| 618 | - dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
| 619 | - dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
| 620 | -
|
||
| 621 | - /* RX DMA setup.*/
|
||
| 622 | - dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 623 | - dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 624 | - dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 625 | + /* TX (DMA) and RX (DMA) setup.*/
|
||
| 626 | +#if STM32_I2C_USE_I2C1
|
||
| 627 | + if (&I2CD1 == i2cp) {
|
||
| 628 | +#if STM32_I2C_I2C1_USE_DMA
|
||
| 629 | + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
| 630 | + dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
| 631 | + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
| 632 | +
|
||
| 633 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 634 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 635 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 636 | +#else
|
||
| 637 | + i2cp->txbuf = txbuf;
|
||
| 638 | + i2cp->txbytes = txbytes;
|
||
| 639 | + i2cp->rxbuf = rxbuf;
|
||
| 640 | + i2cp->rxbytes = rxbytes;
|
||
| 641 | +#endif
|
||
| 642 | + }
|
||
| 643 | +#endif
|
||
| 644 | +#if STM32_I2C_USE_I2C2
|
||
| 645 | + if (&I2CD2 == i2cp) {
|
||
| 646 | +#if STM32_I2C_I2C2_USE_DMA
|
||
| 647 | + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
| 648 | + dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
| 649 | + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
| 650 | +
|
||
| 651 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 652 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 653 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 654 | +#else
|
||
| 655 | + i2cp->txbuf = txbuf;
|
||
| 656 | + i2cp->txbytes = txbytes;
|
||
| 657 | + i2cp->rxbuf = rxbuf;
|
||
| 658 | + i2cp->rxbytes = rxbytes;
|
||
| 659 | +#endif
|
||
| 660 | + }
|
||
| 661 | +#endif
|
||
| 662 | +#if STM32_I2C_USE_I2C3
|
||
| 663 | + if (&I2CD3 == i2cp) {
|
||
| 664 | +#if STM32_I2C_I2C3_USE_DMA
|
||
| 665 | + dmaStreamSetMode(i2cp->dmatx, i2cp->txdmamode);
|
||
| 666 | + dmaStreamSetMemory0(i2cp->dmatx, txbuf);
|
||
| 667 | + dmaStreamSetTransactionSize(i2cp->dmatx, txbytes);
|
||
| 668 | +
|
||
| 669 | + dmaStreamSetMode(i2cp->dmarx, i2cp->rxdmamode);
|
||
| 670 | + dmaStreamSetMemory0(i2cp->dmarx, rxbuf);
|
||
| 671 | + dmaStreamSetTransactionSize(i2cp->dmarx, rxbytes);
|
||
| 672 | +#else
|
||
| 673 | + i2cp->txbuf = txbuf;
|
||
| 674 | + i2cp->txbytes = txbytes;
|
||
| 675 | + i2cp->rxbuf = rxbuf;
|
||
| 676 | + i2cp->rxbytes = rxbytes;
|
||
| 677 | +#endif
|
||
| 678 | + }
|
||
| 679 | +#endif
|
||
| 680 | |||
| 681 | /* Calculating the time window for the timeout on the busy bus condition.*/
|
||
| 682 | start = osalOsGetSystemTimeX(); |
||
| 683 | 22be62dc | Thomas Schöpping | diff --git a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
| 684 | --- a/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
| 685 | +++ b/os/hal/ports/STM32/LLD/I2Cv1/hal_i2c_lld.h
|
||
| 686 | 732a4657 | Thomas Schöpping | @@ -103,6 +103,33 @@
|
| 687 | #define STM32_I2C_I2C3_IRQ_PRIORITY 10 |
||
| 688 | #endif
|
||
| 689 | |||
| 690 | +/**
|
||
| 691 | + * @brief I2C1 DMA enable switch.
|
||
| 692 | + * @details If set to @p TRUE the I2C1 driver will use DMA.
|
||
| 693 | + * @note The default is @p TRUE.
|
||
| 694 | + */
|
||
| 695 | +#if !defined(STM32_I2C_I2C1_USE_DMA) || defined(__DOXYGEN__)
|
||
| 696 | +#define STM32_I2C_I2C1_USE_DMA TRUE
|
||
| 697 | +#endif
|
||
| 698 | +
|
||
| 699 | +/**
|
||
| 700 | + * @brief I2C2 DMA enable switch.
|
||
| 701 | + * @details If set to @p TRUE the I2C2 driver will use DMA.
|
||
| 702 | + * @note The default is @p TRUE.
|
||
| 703 | + */
|
||
| 704 | +#if !defined(STM32_I2C_I2C2_USE_DMA) || defined(__DOXYGEN__)
|
||
| 705 | +#define STM32_I2C_I2C2_USE_DMA TRUE
|
||
| 706 | +#endif
|
||
| 707 | +
|
||
| 708 | +/**
|
||
| 709 | + * @brief I2C3 DMA enable switch.
|
||
| 710 | + * @details If set to @p TRUE the I2C3 driver will use DMA.
|
||
| 711 | + * @note The default is @p TRUE.
|
||
| 712 | + */
|
||
| 713 | +#if !defined(STM32_I2C_I2C3_USE_DMA) || defined(__DOXYGEN__)
|
||
| 714 | +#define STM32_I2C_I2C3_USE_DMA TRUE
|
||
| 715 | +#endif
|
||
| 716 | +
|
||
| 717 | /**
|
||
| 718 | * @brief I2C1 DMA priority (0..3|lowest..highest). |
||
| 719 | * @note The priority level is used for both the TX and RX DMA streams but |
||
| 720 | 22be62dc | Thomas Schöpping | @@ -250,16 +277,19 @@
|
| 721 | 732a4657 | Thomas Schöpping | #endif
|
| 722 | |||
| 723 | #if STM32_I2C_USE_I2C1 && \ |
||
| 724 | + STM32_I2C_I2C1_USE_DMA && \
|
||
| 725 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C1_DMA_PRIORITY) |
||
| 726 | #error "Invalid DMA priority assigned to I2C1" |
||
| 727 | #endif
|
||
| 728 | |||
| 729 | #if STM32_I2C_USE_I2C2 && \ |
||
| 730 | + STM32_I2C_I2C2_USE_DMA && \
|
||
| 731 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C2_DMA_PRIORITY) |
||
| 732 | #error "Invalid DMA priority assigned to I2C2" |
||
| 733 | #endif
|
||
| 734 | |||
| 735 | #if STM32_I2C_USE_I2C3 && \ |
||
| 736 | + STM32_I2C_I2C3_USE_DMA && \
|
||
| 737 | !STM32_DMA_IS_VALID_PRIORITY(STM32_I2C_I2C3_DMA_PRIORITY) |
||
| 738 | #error "Invalid DMA priority assigned to I2C3" |
||
| 739 | #endif
|
||
| 740 | 22be62dc | Thomas Schöpping | @@ -316,7 +346,10 @@
|
| 741 | 732a4657 | Thomas Schöpping | #endif
|
| 742 | #endif /* STM32_ADVANCED_DMA */ |
||
| 743 | |||
| 744 | -#if !defined(STM32_DMA_REQUIRED)
|
||
| 745 | +#if ((STM32_I2C_USE_I2C1 && STM32_I2C_I2C1_USE_DMA) || \
|
||
| 746 | + (STM32_I2C_USE_I2C2 && STM32_I2C_I2C2_USE_DMA) || \
|
||
| 747 | + (STM32_I2C_USE_I2C3 && STM32_I2C_I2C3_USE_DMA)) && \
|
||
| 748 | + !defined(STM32_DMA_REQUIRED)
|
||
| 749 | #define STM32_DMA_REQUIRED
|
||
| 750 | #endif
|
||
| 751 | |||
| 752 | 22be62dc | Thomas Schöpping | @@ -437,21 +470,52 @@ struct I2CDriver { |
| 753 | 732a4657 | Thomas Schöpping | */ |
| 754 | i2caddr_t addr; |
||
| 755 | /**
|
||
| 756 | - * @brief RX DMA mode bit mask.
|
||
| 757 | - */
|
||
| 758 | - uint32_t rxdmamode;
|
||
| 759 | - /**
|
||
| 760 | - * @brief TX DMA mode bit mask.
|
||
| 761 | - */
|
||
| 762 | - uint32_t txdmamode;
|
||
| 763 | - /**
|
||
| 764 | - * @brief Receive DMA channel.
|
||
| 765 | - */
|
||
| 766 | - const stm32_dma_stream_t *dmarx;
|
||
| 767 | - /**
|
||
| 768 | - * @brief Transmit DMA channel.
|
||
| 769 | + * @brief Anonymous union to store transmission related data for either DMA or non-DMA mode.
|
||
| 770 | */ |
||
| 771 | - const stm32_dma_stream_t *dmatx;
|
||
| 772 | + union {
|
||
| 773 | + /**
|
||
| 774 | + * @brief Anonymous struct to store data for DMA mode.
|
||
| 775 | + */
|
||
| 776 | + struct {
|
||
| 777 | + /**
|
||
| 778 | + * @brief RX DMA mode bit mask.
|
||
| 779 | + */
|
||
| 780 | + uint32_t rxdmamode;
|
||
| 781 | + /**
|
||
| 782 | + * @brief TX DMA mode bit mask.
|
||
| 783 | + */
|
||
| 784 | + uint32_t txdmamode;
|
||
| 785 | + /**
|
||
| 786 | + * @brief Receive DMA channel.
|
||
| 787 | + */
|
||
| 788 | + const stm32_dma_stream_t *dmarx;
|
||
| 789 | + /**
|
||
| 790 | + * @brief Transmit DMA channel.
|
||
| 791 | + */
|
||
| 792 | + const stm32_dma_stream_t *dmatx;
|
||
| 793 | + };
|
||
| 794 | + /**
|
||
| 795 | + * @brief Anonymous struct to store data for non-DMA mode.
|
||
| 796 | + */
|
||
| 797 | + struct {
|
||
| 798 | + /**
|
||
| 799 | + * @brief Receive buffer.
|
||
| 800 | + */
|
||
| 801 | + uint8_t *rxbuf;
|
||
| 802 | + /**
|
||
| 803 | + * @brief Size of the receive buffer.
|
||
| 804 | + */
|
||
| 805 | + size_t rxbytes;
|
||
| 806 | + /**
|
||
| 807 | + * @brief Transmit buffer.
|
||
| 808 | + */
|
||
| 809 | + const uint8_t *txbuf;
|
||
| 810 | + /**
|
||
| 811 | + * @brief Size of the transmit buffer.
|
||
| 812 | + */
|
||
| 813 | + size_t txbytes;
|
||
| 814 | + };
|
||
| 815 | + };
|
||
| 816 | /**
|
||
| 817 | * @brief Pointer to the I2Cx registers block.
|
||
| 818 | */ |