summaryrefslogtreecommitdiffstats
path: root/app/i2c_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/i2c_hw.c')
-rw-r--r--app/i2c_hw.c273
1 files changed, 172 insertions, 101 deletions
diff --git a/app/i2c_hw.c b/app/i2c_hw.c
index 1dd352c..35bde08 100644
--- a/app/i2c_hw.c
+++ b/app/i2c_hw.c
@@ -1,12 +1,15 @@
#include "project.h"
-#define I2C I2C1
+#define SCL1 GPIO6
+#define SDA1 GPIO7
+#define SCL1_PORT GPIOB
+#define SDA1_PORT GPIOB
-#define SCL GPIO6
-#define SDA GPIO7
-#define SCL_PORT GPIOB
-#define SDA_PORT GPIOB
+#define SCL2 GPIO10
+#define SDA2 GPIO11
+#define SCL2_PORT GPIOB
+#define SDA2_PORT GPIOB
void
i2c_clear_start (uint32_t i2c)
@@ -14,66 +17,53 @@ i2c_clear_start (uint32_t i2c)
I2C_CR1 (i2c) &= ~(uint32_t) I2C_CR1_START;
}
-#if 0
-static void
-i2cp_ds (void)
-{
- uint32_t i2c = I2C;
- printf ("CR1=%08x CR2=%08x\n", (unsigned) I2C_CR1 (i2c),
- (unsigned) I2C_CR2 (i2c));
- printf ("SR1=%08x SR2=%08x\n", (unsigned) I2C_SR1 (i2c),
- (unsigned) I2C_SR2 (i2c));
-
-
- usart1_drain ();
-}
-#endif
-
-
-void
-i2cp_start (void)
+int
+i2cp_start (uint32_t i2c)
{
- i2c_send_start (I2C);
- while (!((I2C_SR1 (I2C) & I2C_SR1_SB)
- & (I2C_SR2 (I2C) & (I2C_SR2_MSL | I2C_SR2_BUSY))));
+ uint32_t timeout = 1000;
+ i2c_send_start (i2c);
+ while (!((I2C_SR1 (i2c) & I2C_SR1_SB)
+ & (I2C_SR2 (i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY))) && (timeout--));
+
+ return timeout ? 0 : -1;
}
void
-i2cp_abort_start (void)
+i2cp_abort_start (uint32_t i2c)
{
- i2c_clear_start (I2C);
+ i2c_clear_start (i2c);
delay_us (10);
}
void
-i2cp_stop (void)
+i2cp_stop (uint32_t i2c)
{
- i2c_send_stop (I2C);
+ i2c_send_stop (i2c);
}
void
-i2cp_abort_stop (void)
+i2cp_abort_stop (uint32_t i2c)
{
- i2c_clear_stop (I2C);
+ i2c_clear_stop (i2c);
delay_us (10);
}
int
-i2cp_send (uint8_t v)
+i2cp_send (uint32_t i2c, uint8_t v)
{
uint32_t reg;
uint32_t timeout = 1000;
- i2c_send_data (I2C, v);
+ i2c_send_data (i2c, v);
while (!
((reg =
- I2C_SR1 (I2C)) & (I2C_SR1_BTF | I2C_SR1_BERR | I2C_SR1_ARLO |
+ I2C_SR1 (i2c)) & (I2C_SR1_BTF | I2C_SR1_BERR | I2C_SR1_ARLO |
I2C_SR1_AF | I2C_SR1_PECERR | I2C_SR1_TIMEOUT |
I2C_SR1_SMBALERT)) && (timeout--));
- I2C_SR1 (I2C) =
+ I2C_SR1 (i2c) =
reg & ~(I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_PECERR |
I2C_SR1_TIMEOUT | I2C_SR1_SMBALERT);
@@ -86,32 +76,32 @@ i2cp_send (uint8_t v)
/*0 on success 1 on failure*/
int
-i2cp_start_transaction (uint8_t a, int wnr)
+i2cp_start_transaction (uint32_t i2c, uint8_t a, int wnr)
{
uint32_t reg;
uint32_t __attribute__((unused)) dummy;
uint32_t timeout = 1000;
- i2c_send_start (I2C);
- while (!((I2C_SR1 (I2C) & I2C_SR1_SB)
- & (I2C_SR2 (I2C) & (I2C_SR2_MSL | I2C_SR2_BUSY))) && (timeout--));
+ i2c_send_start (i2c);
+ while (!((I2C_SR1 (i2c) & I2C_SR1_SB)
+ & (I2C_SR2 (i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY))) && (timeout--));
if (!timeout)
return -1;
- i2c_send_7bit_address (I2C, a, wnr);
+ i2c_send_7bit_address (i2c, a, wnr);
while (!
((reg =
- I2C_SR1 (I2C)) & (I2C_SR1_ADDR | I2C_SR1_BERR | I2C_SR1_ARLO |
+ I2C_SR1 (i2c)) & (I2C_SR1_ADDR | I2C_SR1_BERR | I2C_SR1_ARLO |
I2C_SR1_AF | I2C_SR1_PECERR | I2C_SR1_TIMEOUT |
I2C_SR1_SMBALERT)) && (timeout--));
if (!timeout)
return -1;
- dummy = I2C_SR2 (I2C);
+ dummy = I2C_SR2 (i2c);
- I2C_SR1 (I2C) =
+ I2C_SR1 (i2c) =
reg & ~(I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_PECERR |
I2C_SR1_TIMEOUT | I2C_SR1_SMBALERT);
@@ -122,40 +112,75 @@ i2cp_start_transaction (uint8_t a, int wnr)
/*This is stupid, it bit bangs a dummy transaction to get the host i2c controller back in the game */
void
-i2cp_reset_sm (void)
+i2cp1_reset_sm (void)
{
int i;
- MAP_OUTPUT_PP (SCL);
- MAP_OUTPUT_PP (SDA);
+ MAP_OUTPUT_PP (SCL1);
+ MAP_OUTPUT_PP (SDA1);
- SET (SDA);
- SET (SCL);
+ SET (SDA1);
+ SET (SCL1);
delay_us (10);
- CLEAR (SDA);
+ CLEAR (SDA1);
delay_us (10);
- CLEAR (SCL);
+ CLEAR (SCL1);
for (i = 0; i < 9; ++i)
{
delay_us (10);
- SET (SCL);
+ SET (SCL1);
delay_us (10);
- CLEAR (SCL);
+ CLEAR (SCL1);
delay_us (10);
}
- SET (SCL);
+ SET (SCL1);
delay_us (10);
- SET (SDA);
+ SET (SDA1);
delay_us (10);
- MAP_AF_OD (SCL);
- MAP_AF_OD (SDA);
+ MAP_AF_OD (SCL1);
+ MAP_AF_OD (SDA1);
}
void
-i2cp_start_dma (uint8_t * buf, int len)
+i2cp2_reset_sm (void)
+{
+ int i;
+
+ MAP_OUTPUT_PP (SCL2);
+ MAP_OUTPUT_PP (SDA2);
+
+ SET (SDA2);
+ SET (SCL2);
+ delay_us (10);
+ CLEAR (SDA2);
+ delay_us (10);
+ CLEAR (SCL2);
+
+ for (i = 0; i < 9; ++i)
+ {
+ delay_us (10);
+ SET (SCL2);
+ delay_us (10);
+ CLEAR (SCL2);
+ delay_us (10);
+ }
+ SET (SCL2);
+ delay_us (10);
+ SET (SDA2);
+ delay_us (10);
+
+ MAP_AF_OD (SCL2);
+ MAP_AF_OD (SDA2);
+
+}
+
+
+
+void
+i2cp1_start_dma (uint8_t * buf, int len)
{
dma_channel_reset (DMA1, DMA_CHANNEL6);
dma_set_peripheral_address (DMA1, DMA_CHANNEL6, (uint32_t) & I2C1_DR);
@@ -171,103 +196,149 @@ i2cp_start_dma (uint8_t * buf, int len)
dma_enable_channel (DMA1, DMA_CHANNEL6);
i2c_enable_dma (I2C1);
+}
+
+void
+i2cp2_start_dma (uint8_t * buf, int len)
+{
+ dma_channel_reset (DMA1, DMA_CHANNEL4);
+ dma_set_peripheral_address (DMA1, DMA_CHANNEL4, (uint32_t) & I2C2_DR);
+ dma_set_memory_address (DMA1, DMA_CHANNEL4, (uint32_t) buf);
+ dma_set_number_of_data (DMA1, DMA_CHANNEL4, len);
+ dma_set_read_from_memory (DMA1, DMA_CHANNEL4);
+ dma_enable_memory_increment_mode (DMA1, DMA_CHANNEL4);
+ dma_set_peripheral_size (DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT);
+ dma_set_memory_size (DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT);
+ dma_set_priority (DMA1, DMA_CHANNEL4, DMA_CCR_PL_MEDIUM);
+ dma_enable_transfer_complete_interrupt (DMA1, DMA_CHANNEL4);
+ dma_enable_transfer_error_interrupt (DMA1, DMA_CHANNEL4);
+ dma_enable_channel (DMA1, DMA_CHANNEL4);
+
+ i2c_enable_dma (I2C2);
}
+
int
-i2cp_dma_in_progress (void)
+i2cp1_dma_in_progress (void)
{
return !(DMA1_ISR & (DMA_ISR_TCIF6 | DMA_ISR_TEIF6));
}
void
-i2cp_stop_dma (void)
+i2cp1_stop_dma (void)
{
- DMA1_IFCR |= DMA_IFCR_CTCIF7 | DMA_IFCR_CTEIF6 | DMA_IFCR_CGIF6;
+ DMA1_IFCR |= DMA_IFCR_CTCIF6 | DMA_IFCR_CTEIF6 | DMA_IFCR_CGIF6;
dma_disable_transfer_complete_interrupt (DMA1, DMA_CHANNEL6);
dma_disable_transfer_error_interrupt (DMA1, DMA_CHANNEL6);
i2c_disable_dma (I2C1);
- dma_disable_channel (DMA1, DMA_CHANNEL7);
+ dma_disable_channel (DMA1, DMA_CHANNEL6);
+}
+
+void
+i2cp2_stop_dma (void)
+{
+ DMA1_IFCR |= DMA_IFCR_CTCIF4 | DMA_IFCR_CTEIF4 | DMA_IFCR_CGIF4;
+
+ dma_disable_transfer_complete_interrupt (DMA1, DMA_CHANNEL4);
+ dma_disable_transfer_error_interrupt (DMA1, DMA_CHANNEL4);
+
+ i2c_disable_dma (I2C2);
+ dma_disable_channel (DMA1, DMA_CHANNEL4);
}
+
void
-i2cp_reset (void)
+i2cp_reset (uint32_t i2c)
{
while (i2c_lock ());
- i2cp_start ();
- i2cp_abort_start ();
- i2cp_stop ();
- i2cp_abort_stop ();
-
- i2cp_start ();
- i2cp_abort_start ();
- i2cp_stop ();
- i2cp_abort_stop ();
+ i2cp_start (i2c);
+ i2cp_abort_start (i2c);
+ i2cp_stop (i2c);
+ i2cp_abort_stop (i2c);
+
+ i2cp_start (i2c);
+ i2cp_abort_start (i2c);
+ i2cp_stop (i2c);
+ i2cp_abort_stop (i2c);
i2c_unlock ();
}
void
-i2cp_scan (void)
+i2cp_scan (uint32_t i2c)
{
int i, r;
- i2cp_reset ();
+ i2cp_reset (i2c);
printf ("Probing bus\n");
for (i = 0; i < 128; ++i)
{
printf ("%d\n", i);
while (i2c_lock ());
- i2cp_start ();
- i2cp_abort_start ();
- i2cp_stop ();
- i2cp_abort_stop ();
+ i2cp_start (i2c);
+ i2cp_abort_start (i2c);
+ i2cp_stop (i2c);
+ i2cp_abort_stop (i2c);
delay_ms (10);
- r = i2cp_start_transaction (i, I2C_WRITE);
- i2cp_stop ();
+ r = i2cp_start_transaction (i2c, i, I2C_WRITE);
+ i2cp_stop (i2c);
i2c_unlock ();
if (!r)
printf ("Found device at address 0x%x\n", i);
usart1_drain ();
}
printf ("Done\n");
- i2cp_reset ();
+ i2cp_reset (i2c);
}
-void
-i2cp_init (void)
+static void
+i2cp_bringup (uint32_t i2c)
{
- rcc_periph_clock_enable (RCC_I2C1);
- rcc_periph_clock_enable (RCC_DMA1);
+ i2c_peripheral_enable (i2c);
+ i2c_clear_start (i2c);
+ i2c_clear_stop (i2c);
+ i2c_reset (i2c);
+ i2c_peripheral_enable (i2c);
- while (i2c_lock ());
+ I2C_CR1 (i2c) |= I2C_CR1_SWRST;
+ delay_us (1000);
+ I2C_CR1 (i2c) &= ~I2C_CR1_SWRST;
- i2c_peripheral_enable (I2C);
- i2c_clear_start (I2C);
- i2c_clear_stop (I2C);
- i2c_reset (I2C);
- i2c_peripheral_enable (I2C);
+ if (i2c == I2C1)
+ i2cp1_reset_sm ();
+ else
+ i2cp2_reset_sm ();
- I2C_CR1 (I2C) |= I2C_CR1_SWRST;
- delay_us (1000);
- I2C_CR1 (I2C) &= ~I2C_CR1_SWRST;
+ i2c_set_clock_frequency (i2c, I2C_CR2_FREQ_36MHZ);
+ i2c_set_standard_mode (i2c);
+ i2c_set_ccr (i2c, 0x80); /* t_high=t_high=CCR * Tpclk1 */
+ i2c_set_trise (i2c, 0x0b);
+
+ i2c_set_own_7bit_slave_address (i2c, 0x00);
+
+ i2c_peripheral_enable (i2c);
+}
- i2cp_reset_sm ();
- i2c_set_clock_frequency (I2C, I2C_CR2_FREQ_36MHZ);
- i2c_set_standard_mode (I2C);
- i2c_set_ccr (I2C, 0x80); /* t_high=t_high=CCR * Tpclk1 */
- i2c_set_trise (I2C, 0x0b);
+void
+i2cp_init (void)
+{
+ rcc_periph_clock_enable (RCC_I2C1);
+ rcc_periph_clock_enable (RCC_I2C2);
+ rcc_periph_clock_enable (RCC_DMA1);
+
+ while (i2c_lock ());
- i2c_set_own_7bit_slave_address (I2C, 0x00);
+ i2cp_bringup (I2C1);
+ i2cp_bringup (I2C2);
- i2c_peripheral_enable (I2C);
i2c_unlock ();
}