Skip to content

Commit e9b89d5

Browse files
committed
fix(bsp/gd32): 修复硬件iic和pwm驱动的一些问题
- 硬件i2c主机接收驱动采用方案B,但不支持接收小于3字节,现修复该问题 - 硬件i2c主机接收驱动增加方案A - 修复drv_pwm.c编译问题 - 修正PWM时钟获取逻辑,使其能正确得到APB1/APB2上的定时器时钟源频率,添加在pwm结构体通道引脚资源配置项
1 parent 85b656b commit e9b89d5

2 files changed

Lines changed: 450 additions & 302 deletions

File tree

bsp/gd32/arm/libraries/gd32_drivers/drv_hard_i2c.c

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Change Logs:
77
* Date Author Notes
88
* 2021-12-20 BruceOu the first version
9+
* 2026-01-11 ShiHongchao Fix the I2C master receive mode B software
10+
* flow and add support for mode A
911
*/
1012

1113
#include "drv_hard_i2c.h"
@@ -112,8 +114,8 @@ static const struct gd32_i2c_bus gd_i2c_config[] = {
112114

113115
RCU_I2C0, RCU_GPIOB, RCU_GPIOB, /* periph clock, scl gpio clock, sda gpio clock */
114116

115-
GPIOB, GPIO_AF_4, GPIO_PIN_6, /* scl port, scl alternate, scl pin */
116-
GPIOB, GPIO_AF_4, GPIO_PIN_7, /* sda port, sda alternate, sda pin */
117+
GPIOB, GPIO_AF_4, GPIO_PIN_8, /* scl port, scl alternate, scl pin */
118+
GPIOB, GPIO_AF_4, GPIO_PIN_9, /* sda port, sda alternate, sda pin */
117119

118120
&i2c0,
119121
"hwi2c0",
@@ -229,28 +231,69 @@ static void gd32_i2c_gpio_init(const struct gd32_i2c_bus *i2c)
229231
static uint8_t gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint8_t *p_buffer, rt_uint16_t data_byte)
230232
{
231233
if (data_byte == 0) return 1;
232-
/* while there is data to be read */
233234

235+
#ifdef BSP_USING_RECEIVING_A
236+
/*
237+
In single-byte reception, disable ACK because the master needs to send
238+
NACK after receiving the first byte,indicating no more data will be
239+
received, then immediately send the stop condition
240+
*/
241+
if(data_byte == 1)
242+
{
243+
/* disable acknowledge */
244+
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
245+
/* send a stop condition to I2C bus */
246+
i2c_stop_on_bus(i2c_periph);
247+
}
248+
#endif
249+
250+
/* while there is data to be read */
234251
while(data_byte)
235252
{
236253
#if defined (SOC_SERIES_GD32F5xx) || defined (SOC_SERIES_GD32F4xx)
237254
if(IS_I2C_LEGACY(i2c_periph))
238255
{
256+
#ifdef BSP_USING_RECEIVING_A
257+
/*
258+
After receiving the second-to-last byte, ACK should be disabled
259+
and STOP should be set, to ensure that NACK is sent after receiving
260+
the last byte and the stop condition is transmitted
261+
*/
262+
if(2 == data_byte)
263+
{
264+
/* wait until BTC bit is set */
265+
while(!i2c_flag_get(i2c_periph, I2C_FLAG_RBNE));
266+
/* disable acknowledge */
267+
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
268+
/* send a stop condition to I2C bus */
269+
i2c_stop_on_bus(i2c_periph);
270+
}
271+
#elif defined(BSP_USING_RECEIVING_B)
272+
/*
273+
For 3-byte reception: Wait for byte transfer completion, then
274+
disable ACK so NACK is automatically sent after receiving the
275+
last byte
276+
For 2-byte reception: Wait for byte transfer completion, then
277+
send stop condition to ensure direct stop after receiving the
278+
last byte instead of sending ACK
279+
*/
239280
if(3 == data_byte)
240281
{
241282
/* wait until BTC bit is set */
242283
while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC));
243284
/* disable acknowledge */
244285
i2c_ack_config(i2c_periph, I2C_ACK_DISABLE);
245286
}
246-
247-
if(2 == data_byte)
287+
else if(2 == data_byte)
248288
{
249289
/* wait until BTC bit is set */
250290
while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC));
251291
/* send a stop condition to I2C bus */
252292
i2c_stop_on_bus(i2c_periph);
253293
}
294+
#else
295+
#error "Please select the receiving scheme."
296+
#endif
254297
/* wait until RBNE bit is set */
255298
if(i2c_flag_get(i2c_periph, I2C_FLAG_RBNE))
256299
{
@@ -379,26 +422,45 @@ static rt_ssize_t gd32_i2c_master_xfer(struct rt_i2c_bus_device *bus, struct rt_
379422
{
380423
i2c_stop_on_bus(gd32_i2c->i2c_periph);
381424
}
382-
/* enable acknowledge */
425+
/* enable acknowledge */
383426
i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_ENABLE);
384-
/* i2c master sends start signal only when the bus is idle */
427+
/* i2c master sends start signal only when the bus is idle */
385428
while(i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY));
386-
/* send the start signal */
429+
#ifdef BSP_USING_RECEIVING_B
430+
/* */
431+
if(msg->len == 2)
432+
{
433+
i2c_ackpos_config(gd32_i2c->i2c_periph, I2C_ACKPOS_NEXT);
434+
}
435+
#endif
436+
/* send the start signal */
387437
i2c_start_on_bus(gd32_i2c->i2c_periph);
388438
/* i2c master sends START signal successfully */
389439
while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND));
390440

391441
i2c_master_addressing(gd32_i2c->i2c_periph, msg->addr, I2C_RECEIVER);
392442

393443
while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND));
394-
/* address flag set means i2c slave sends ACK */
444+
#ifdef BSP_USING_RECEIVING_B
445+
if(msg->len <= 2)
446+
{
447+
i2c_ack_config(gd32_i2c->i2c_periph, I2C_ACK_DISABLE);
448+
}
449+
#endif
450+
/* address flag set means i2c slave sends ACK */
395451
i2c_flag_clear(gd32_i2c->i2c_periph, I2C_FLAG_ADDSEND);
452+
#ifdef BSP_USING_RECEIVING_B
453+
if(msg->len == 1)
454+
{
455+
i2c_stop_on_bus(gd32_i2c->i2c_periph);
456+
}
457+
#endif
396458

397459
}else {
398-
/* configure slave address */
460+
/* configure slave address */
399461
while(i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_I2CBSY));
400-
//i2c_transfer_byte_number_config(gd32_i2c->i2c_periph, w_total_byte);
401-
/* send a start condition to I2C bus */
462+
//i2c_transfer_byte_number_config(gd32_i2c->i2c_periph, w_total_byte);
463+
/* send a start condition to I2C bus */
402464
i2c_start_on_bus(gd32_i2c->i2c_periph);
403465
while(!i2c_flag_get(gd32_i2c->i2c_periph, I2C_FLAG_SBSEND));
404466

0 commit comments

Comments
 (0)