1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2020-08-08 thread-liu first version
9 */
10
11 #include "board.h"
12
13 #include "mfxstm32l152.h"
14 #define DRV_DEBUG
15 #define LOG_TAG "drv.mfx"
16 #include <drv_log.h>
17
18 #define CHIP_ADDRESS 0x42 /* mfx address */
19 #define I2C_NAME "i2c2"
20
21 struct st_mfx
22 {
23 struct rt_device dev;
24 struct rt_i2c_bus_device *i2c_bus;
25 rt_uint8_t id;
26 rt_uint16_t type;
27 };
28 static struct st_mfx rt_mfx = {0};
29 static IO_DrvTypeDef *IoDrv = NULL;
30
read_reg(struct rt_i2c_bus_device * bus,rt_uint8_t reg,rt_uint16_t len,rt_uint8_t * buf)31 static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint16_t len, rt_uint8_t *buf)
32 {
33 struct rt_i2c_msg msg[2] = {0, 0};
34
35 RT_ASSERT(bus != RT_NULL);
36
37 msg[0].addr = CHIP_ADDRESS;
38 msg[0].flags = RT_I2C_WR;
39 msg[0].buf = ®
40 msg[0].len = 1;
41
42 msg[1].addr = CHIP_ADDRESS;
43 msg[1].flags = RT_I2C_RD;
44 msg[1].len = len;
45 msg[1].buf = buf;
46
47 if (rt_i2c_transfer(bus, msg, 2) == 2)
48 {
49 return RT_EOK;
50 }
51
52 return -RT_ERROR;
53 }
54
55 /* i2c write reg */
write_reg(struct rt_i2c_bus_device * bus,rt_uint8_t reg,rt_uint8_t data)56 static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
57 {
58 rt_uint8_t buf[2];
59 struct rt_i2c_msg msgs;
60
61 RT_ASSERT(bus != RT_NULL);
62 buf[0] = reg;
63 buf[1] = data;
64
65 msgs.addr = CHIP_ADDRESS;
66 msgs.flags = RT_I2C_WR;
67 msgs.buf = buf;
68 msgs.len = sizeof(buf);
69
70 if (rt_i2c_transfer(bus, &msgs, 1) == 1)
71 {
72 return RT_EOK;
73 }
74
75 return -RT_ERROR;
76 }
77
MFX_IO_Init(void)78 void MFX_IO_Init(void)
79 {
80 rt_mfx.i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
81 if (rt_mfx.i2c_bus == RT_NULL)
82 {
83 LOG_E("can't find %c deivce", I2C_NAME);
84 }
85 }
86
MFX_IO_DeInit(void)87 void MFX_IO_DeInit(void)
88 {
89 }
90
MFX_IO_ITConfig(void)91 void MFX_IO_ITConfig(void)
92 {
93 static rt_uint8_t mfx_io_it_enabled = 0;
94 GPIO_InitTypeDef gpio_init_structure;
95
96 if(mfx_io_it_enabled == 0)
97 {
98 mfx_io_it_enabled = 1;
99 /* Enable the GPIO EXTI clock */
100 __HAL_RCC_GPIOI_CLK_ENABLE();
101
102 gpio_init_structure.Pin = GPIO_PIN_8;
103 gpio_init_structure.Pull = GPIO_NOPULL;
104 gpio_init_structure.Speed = GPIO_SPEED_FREQ_LOW;
105 gpio_init_structure.Mode = GPIO_MODE_IT_RISING;
106 HAL_GPIO_Init(GPIOI, &gpio_init_structure);
107
108 /* Enable and set GPIO EXTI Interrupt to the lowest priority */
109 HAL_NVIC_SetPriority((IRQn_Type)(EXTI8_IRQn), 0x04, 0x00);
110 HAL_NVIC_EnableIRQ((IRQn_Type)(EXTI8_IRQn));
111 }
112 }
113
MFX_IO_Write(rt_uint16_t Addr,rt_uint8_t Reg,rt_uint8_t Value)114 void MFX_IO_Write(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t Value)
115 {
116 write_reg(rt_mfx.i2c_bus, Reg, Value);
117 }
118
MFX_IO_Read(rt_uint16_t Addr,rt_uint8_t Reg)119 rt_uint8_t MFX_IO_Read(rt_uint16_t Addr, rt_uint8_t Reg)
120 {
121 rt_uint8_t value = 0;
122 read_reg(rt_mfx.i2c_bus, Reg, 1, &value);
123
124 return value;
125 }
126
MFX_IO_ReadMultiple(rt_uint16_t Addr,rt_uint8_t Reg,rt_uint8_t * Buffer,rt_uint16_t Length)127 rt_uint16_t MFX_IO_ReadMultiple(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t *Buffer, rt_uint16_t Length)
128 {
129 return read_reg(rt_mfx.i2c_bus, Reg, Length, Buffer);
130 }
131
MFX_IO_Delay(rt_uint32_t Delay)132 rt_weak void MFX_IO_Delay(rt_uint32_t Delay)
133 {
134 rt_thread_delay(Delay);
135 }
136
MFX_IO_Wakeup(void)137 rt_weak void MFX_IO_Wakeup(void)
138 {
139 }
140
MFX_IO_EnableWakeupPin(void)141 rt_weak void MFX_IO_EnableWakeupPin(void)
142 {
143 }
144
BSP_IO_DeInit(void)145 rt_uint8_t BSP_IO_DeInit(void)
146 {
147 IoDrv = NULL;
148 return RT_EOK;
149 }
150
BSP_IO_ITGetStatus(rt_uint32_t IoPin)151 rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin)
152 {
153 /* Return the IO Pin IT status */
154 return (IoDrv->ITStatus(0, IoPin));
155 }
156
157 /**
158 * @brief Clears all the IO IT pending bits.
159 * @retval None
160 */
BSP_IO_ITClear(void)161 void BSP_IO_ITClear(void)
162 {
163 /* Clear all IO IT pending bits */
164 IoDrv->ClearIT(0, MFXSTM32L152_GPIO_PINS_ALL);
165 }
166
BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear)167 void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear)
168 {
169 /* Clear only the selected list of IO IT pending bits */
170 IoDrv->ClearIT(0, IO_Pins_To_Clear);
171 }
172
173 /**
174 * @brief Configures the IO pin(s) according to IO mode structure value.
175 * @param IoPin: IO pin(s) to be configured.
176 * This parameter can be one of the following values:
177 * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
178 * @param IoMode: IO pin mode to configure
179 * This parameter can be one of the following values:
180 * @arg IO_MODE_INPUT
181 * @arg IO_MODE_OUTPUT
182 * @arg IO_MODE_IT_RISING_EDGE
183 * @arg IO_MODE_IT_FALLING_EDGE
184 * @arg IO_MODE_IT_LOW_LEVEL
185 * @arg IO_MODE_IT_HIGH_LEVEL
186 * @arg IO_MODE_ANALOG
187 * @arg IO_MODE_OFF
188 * @arg IO_MODE_INPUT_PU,
189 * @arg IO_MODE_INPUT_PD,
190 * @arg IO_MODE_OUTPUT_OD,
191 * @arg IO_MODE_OUTPUT_OD_PU,
192 * @arg IO_MODE_OUTPUT_OD_PD,
193 * @arg IO_MODE_OUTPUT_PP,
194 * @arg IO_MODE_OUTPUT_PP_PU,
195 * @arg IO_MODE_OUTPUT_PP_PD,
196 * @arg IO_MODE_IT_RISING_EDGE_PU
197 * @arg IO_MODE_IT_FALLING_EDGE_PU
198 * @arg IO_MODE_IT_LOW_LEVEL_PU
199 * @arg IO_MODE_IT_HIGH_LEVEL_PU
200 * @arg IO_MODE_IT_RISING_EDGE_PD
201 * @arg IO_MODE_IT_FALLING_EDGE_PD
202 * @arg IO_MODE_IT_LOW_LEVEL_PD
203 * @arg IO_MODE_IT_HIGH_LEVEL_PD
204 * @retval RT_EOK if all initializations are OK. Other value if error.
205 */
rt_mfx_pin_mode(rt_uint32_t IoPin,IO_ModeTypedef IoMode)206 rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode)
207 {
208 /* Configure the selected IO pin(s) mode */
209 IoDrv->Config(0, IoPin, IoMode);
210
211 return RT_EOK;
212 }
213
214 /**
215 * @brief Sets the IRQ_OUT pin polarity and type
216 * @param IoIrqOutPinPolarity: High/Low
217 * @param IoIrqOutPinType: OpenDrain/PushPull
218 * @retval OK
219 */
rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity,rt_uint8_t IoIrqOutPinType)220 rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType)
221 {
222 if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
223 {
224 /* Initialize the IO driver structure */
225 mfxstm32l152_SetIrqOutPinPolarity(0, IoIrqOutPinPolarity);
226 mfxstm32l152_SetIrqOutPinType(0, IoIrqOutPinType);
227 }
228
229 return RT_EOK;
230 }
231
232 /**
233 * @brief Sets the selected pins state.
234 * @param IoPin: Selected pins to write.
235 * This parameter can be any combination of the IO pins.
236 * @param PinState: New pins state to write
237 * @retval None
238 */
rt_mfx_pin_write(rt_uint32_t IoPin,rt_base_t PinState)239 void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState)
240 {
241 /* Set the Pin state */
242 IoDrv->WritePin(0, IoPin, PinState);
243 }
244
245 /**
246 * @brief Gets the selected pins current state.
247 * @param IoPin: Selected pins to read.
248 * This parameter can be any combination of the IO pins.
249 * @retval The current pins state
250 */
rt_mfx_pin_read(rt_uint32_t IoPin)251 rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin)
252 {
253 return(IoDrv->ReadPin(0, IoPin));
254 }
255
256 /**
257 * @brief Toggles the selected pins state.
258 * @param IoPin: Selected pins to toggle.
259 * This parameter can be any combination of the IO pins.
260 * @note This function is only used to toggle one pin in the same time
261 * @retval None
262 */
rt_mfx_pin_toggle(rt_uint32_t IoPin)263 void rt_mfx_pin_toggle(rt_uint32_t IoPin)
264 {
265 /* Toggle the current pin state */
266 if(IoDrv->ReadPin(0, IoPin) != 0)
267 {
268 IoDrv->WritePin(0, IoPin, 0); /* Reset */
269 }
270 else
271 {
272 IoDrv->WritePin(0, IoPin, 1); /* Set */
273 }
274 }
275
rt_mfx_init(void)276 int rt_mfx_init(void)
277 {
278 /* Read ID and verify the MFX is ready */
279 rt_mfx.id = mfxstm32l152_io_drv.ReadID(0);
280 if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
281 {
282 /* Initialize the IO driver structure */
283 IoDrv = &mfxstm32l152_io_drv;
284
285 /* Initialize MFX */
286 IoDrv->Init(0);
287 IoDrv->Start(0, IO_PIN_ALL);
288
289 LOG_I("mfx init success, id: 0x%x", rt_mfx.id);
290
291 return RT_EOK;
292 }
293 LOG_I("mfx init error, id: 0x%x", rt_mfx.id);
294
295 return -RT_ERROR;
296 }
297 INIT_DEVICE_EXPORT(rt_mfx_init);
298