vllogic / vllink_lite

低成本CMSIS-DAP V2调试器,IO时序SPI优化,速度级别200KB/S至450KB/S
GNU General Public License v3.0
289 stars 81 forks source link

IO操作库的一个bug #7

Closed posystorage closed 2 years ago

posystorage commented 2 years ago

io.c的这个文件写法似乎是有问题的 static const uint32_t gpio_reg_base_list[GPIO_COUNT] = {

if GPIOA_ENABLE

GPIOA_BASE,
#endif
#if GPIOB_ENABLE
GPIOB_BASE,
#endif
#if GPIOC_ENABLE
GPIOC_BASE,
#endif
#if GPIOD_ENABLE
GPIOD_BASE,
#endif
#if GPIOF_ENABLE
GPIOF_BASE,
#endif

}; 如果在宏定义设置为这样的情况下,

define GPIOA_ENABLE 1

define GPIOB_ENABLE 1

define GPIOC_ENABLE 0

define GPIOD_ENABLE 0

define GPIOF_ENABLE 1

数组实际上是 static const uint32_t gpio_reg_base_list[GPIO_COUNT] = { GPIOA_BASE, GPIOB_BASE, GPIOF_BASE, }; 使用GPIOF的时候 传入的参数GPIO_COUNT = 5的,因为在下面这个emum里面并不是浮动的IDX enum gpio_idx_t {

if GPIOA_ENABLE

GPIOA_IDX = 0,
#endif
#if GPIOB_ENABLE
GPIOB_IDX = 1,
#endif
#if GPIOC_ENABLE
GPIOC_IDX = 2,
#endif
#if GPIOD_ENABLE
GPIOD_IDX = 3,
#endif
#if GPIOF_ENABLE
GPIOF_IDX = 5,
#endif
GPIO_IDX_NUM,
GPIO_INVALID_IDX,

}; 这种情况下就超越gpio_reg_base_list数组界限取值了,最后的表现是操作PF0/PF1没任何反应。

建议改为 static const uint32_t gpio_reg_base_list[GPIO_COUNT] = { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOF_BASE, };

posystorage commented 2 years ago

更正 应该是改为 static const uint32_t gpio_reg_base_list[5] = { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOF_BASE };

posystorage commented 2 years ago

再更正 因为GPIOF_IDX = 5 这里没有GPIOE,不然还是不对 static const uint32_t gpio_reg_base_list[6] = { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, 0x00000000, GPIOF_BASE };

talpachen commented 2 years ago

感谢反馈。

enum gpio_idx_t {
#if GPIOA_ENABLE
GPIOA_IDX = 0,
#endif
#if GPIOB_ENABLE
GPIOB_IDX = 1,
#endif
#if GPIOC_ENABLE
GPIOC_IDX = 2,
#endif
#if GPIOD_ENABLE
GPIOD_IDX = 3,
#endif
#if GPIOF_ENABLE
GPIOF_IDX = 5,
#endif
GPIO_IDX_NUM,
GPIO_INVALID_IDX,
};

应改为

enum gpio_idx_t {
#if GPIOA_ENABLE
GPIOA_IDX,
#endif
#if GPIOB_ENABLE
GPIOB_IDX,
#endif
#if GPIOC_ENABLE
GPIOC_IDX,
#endif
#if GPIOD_ENABLE
GPIOD_IDX,
#endif
#if GPIOF_ENABLE
GPIOF_IDX,
#endif
GPIO_IDX_NUM,
GPIO_INVALID_IDX,
};
posystorage commented 2 years ago

不行,这样是不对的,你用idx移位了ahb时钟使能,idx号不可以变的 void vsfhal_gpio_init(enum gpio_idx_t idx) { if (idx == GPIO_INVALID_IDX) return; VSF_HAL_ASSERT(idx < GPIO_IDX_NUM);

RCU_AHBEN |= RCU_AHBEN_PAEN << idx;

}

void vsfhal_gpio_fini(enum gpio_idx_t idx) { if (idx == GPIO_INVALID_IDX) return; VSF_HAL_ASSERT(idx < GPIO_IDX_NUM);

RCU_AHBEN &= ~(RCU_AHBEN_PAEN << idx);

}

talpachen commented 2 years ago

哦,这儿还有干系。

RCU_AHBEN |= RCU_AHBEN_PAEN << idx;

这种写法应该是不合适的,换成switch写法就可以了。