semf
stm32f4i2cslave.cpp
Go to the documentation of this file.
1
12
13#if defined(STM32F4) && defined (HAL_I2C_MODULE_ENABLED)
14
15namespace semf
16{
17void Stm32F4I2cSlave::clearBusyFlagErratum(GPIO_TypeDef* sclPort, uint16_t sclPin,
18 GPIO_TypeDef* sdaPort, uint16_t sdaPin, uint8_t alternate)
19{
20 if (__HAL_I2C_GET_FLAG(hardwareHandle(), I2C_FLAG_BUSY) == RESET)
21 return;
22
23 GPIO_InitTypeDef GPIO_InitStructure;
24
25 // 1. Clear PE bit.
26 hardwareHandle()->Instance->CR1 &= ~(0x0001);
27
28 // 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
29 GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
30 // GPIO_InitStructure.Alternate = I2C_PIN_MAP;
31 GPIO_InitStructure.Pull = GPIO_PULLUP;
32 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
33
34 GPIO_InitStructure.Pin = sclPin;
35 HAL_GPIO_Init(sclPort, &GPIO_InitStructure);
36 HAL_GPIO_WritePin(sclPort, sclPin, GPIO_PIN_SET);
37
38 GPIO_InitStructure.Pin = sdaPin;
39 HAL_GPIO_Init(sdaPort, &GPIO_InitStructure);
40 HAL_GPIO_WritePin(sdaPort, sdaPin, GPIO_PIN_SET);
41
42 // 3. Check SCL and SDA High level in GPIOx_IDR.
43 while (GPIO_PIN_SET != HAL_GPIO_ReadPin(sclPort, sclPin))
44 {
45 asm("nop");
46 }
47
48 while (GPIO_PIN_SET != HAL_GPIO_ReadPin(sdaPort, sdaPin))
49 {
50 asm("nop");
51 }
52
53 // 4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
54 HAL_GPIO_WritePin(sdaPort, sdaPin, GPIO_PIN_RESET);
55
56 // 5. Check SDA Low level in GPIOx_IDR.
57 while (GPIO_PIN_RESET != HAL_GPIO_ReadPin(sdaPort, sdaPin))
58 {
59 asm("nop");
60 }
61
62 // 6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to GPIOx_ODR).
63 HAL_GPIO_WritePin(sclPort, sclPin, GPIO_PIN_RESET);
64
65 // 7. Check SCL Low level in GPIOx_IDR.
66 while (GPIO_PIN_RESET != HAL_GPIO_ReadPin(sclPort, sclPin))
67 {
68 asm("nop");
69 }
70
71 // 8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR).
72 HAL_GPIO_WritePin(sclPort, sclPin, GPIO_PIN_SET);
73
74 // 9. Check SCL High level in GPIOx_IDR.
75 while (GPIO_PIN_SET != HAL_GPIO_ReadPin(sclPort, sclPin))
76 {
77 asm("nop");
78 }
79
80 // 10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to GPIOx_ODR).
81 HAL_GPIO_WritePin(sdaPort, sdaPin, GPIO_PIN_SET);
82
83 // 11. Check SDA High level in GPIOx_IDR.
84 while (GPIO_PIN_SET != HAL_GPIO_ReadPin(sdaPort, sdaPin))
85 {
86 asm("nop");
87 }
88
89 // 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
90 GPIO_InitStructure.Mode = GPIO_MODE_AF_OD;
91 GPIO_InitStructure.Alternate = alternate;
92
93 GPIO_InitStructure.Pin = sclPin;
94 HAL_GPIO_Init(sclPort, &GPIO_InitStructure);
95
96 GPIO_InitStructure.Pin = sdaPin;
97 HAL_GPIO_Init(sdaPort, &GPIO_InitStructure);
98
99 // 13. Set SWRST bit in I2Cx_CR1 register.
100 hardwareHandle()->Instance->CR1 |= 0x8000;
101
102 asm("nop");
103
104 // 14. Clear SWRST bit in I2Cx_CR1 register.
105 hardwareHandle()->Instance->CR1 &= ~0x8000;
106
107 asm("nop");
108
109 // 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register
110 hardwareHandle()->Instance->CR1 |= 0x0001;
111
112 // Call initialization function.
113 HAL_I2C_Init(hardwareHandle());
114}
115
116void Stm32F4I2cSlave::setFrequencyHardware(uint32_t hz)
117{
118 if (hz > 400000)
119 {
120 SEMF_ERROR("frequency not supported, max frequency is 400kHz");
121 onError(Error(kSemfClassId, static_cast<uint8_t>(ErrorCode::SetFrequencyHardware_FrequencyNotSupported)));
122 return;
123 }
124
125 hardwareHandle()->Init.ClockSpeed = hz;
126}
127} // namespace semf
128#endif
#define SEMF_ERROR(...)
Definition: debug.h:39