From b420e83da43641089727dd7a68cb205d513121cb Mon Sep 17 00:00:00 2001 From: gbcwbz Date: Wed, 13 Apr 2016 21:24:36 +0800 Subject: [PATCH 1/2] fix can baud rate config error in bsp/stm32f10x fix #597 enum CANBAUD was changed in components/drivers/include/drivers/can.h , which causes array index out of bound in bsp/stm32f10x/drivers/bxcan.c temporarily remove RT_CAN_USING_BUS_HOOK, because there are some bugs in bsp/stm32f10x/applications/canapp.c function can_bus_hook --- bsp/stm32f10x/applications/canapp.c | 2 + bsp/stm32f10x/drivers/bxcan.c | 84 ++++++++++++++++++++++------- bsp/stm32f10x/rtconfig.h | 4 +- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/bsp/stm32f10x/applications/canapp.c b/bsp/stm32f10x/applications/canapp.c index d5294250bf..b04a9d628f 100644 --- a/bsp/stm32f10x/applications/canapp.c +++ b/bsp/stm32f10x/applications/canapp.c @@ -245,10 +245,12 @@ int rt_can_app_init(void) 512, RT_THREAD_PRIORITY_MAX / 3 - 1, 20); if (tid != RT_NULL) rt_thread_startup(tid); +#ifdef USING_BXCAN2 tid = rt_thread_create("canapp2", rt_can_thread_entry, &can_data[1], 512, RT_THREAD_PRIORITY_MAX / 3 - 1, 20); if (tid != RT_NULL) rt_thread_startup(tid); +#endif return 0; } diff --git a/bsp/stm32f10x/drivers/bxcan.c b/bsp/stm32f10x/drivers/bxcan.c index 071d05e8cc..6df1a544b1 100644 --- a/bsp/stm32f10x/drivers/bxcan.c +++ b/bsp/stm32f10x/drivers/bxcan.c @@ -69,6 +69,11 @@ struct stm_bxcan const rt_uint32_t fifo1filteroff; const struct stm_bxcanfiltermap filtermap[2]; }; +struct stm_baud_rate_tab +{ + rt_uint32_t baud_rate; + rt_uint32_t confdata; +}; static void calcfiltermasks(struct stm_bxcan *pbxcan); static void bxcan1_filter_init(struct rt_can_device *can) { @@ -254,26 +259,64 @@ static void bxcan2_filter_init(struct rt_can_device *can) #define MK_BKCAN_BAUD(SJW,BS1,BS2,PRES) \ ((SJW << SJWSHIFT) | (BS1 << BS1SHIFT) | (BS2 << BS2SHIFT) | (PRES << RRESCLSHIFT)) -static const rt_uint32_t bxcan_baud_rate_tab[] = +static const struct stm_baud_rate_tab bxcan_baud_rate_tab[] = { +#ifdef STM32F10X_CL // 48 M - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 3), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_6tq, CAN_BS2_3tq, 6), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 5), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 11), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 23), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 29), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 59), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_14tq, CAN_BS2_3tq, 149), - MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_16tq, CAN_BS2_8tq, 199), + {1000UL * 1000, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 3)}, + {1000UL * 800, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_6tq, CAN_BS2_3tq, 6)}, + {1000UL * 500, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 5)}, + {1000UL * 250, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 11)},//1 + {1000UL * 125, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 23)}, + {1000UL * 100, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 29)}, + {1000UL * 50, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_12tq, CAN_BS2_3tq, 59)}, + {1000UL * 20, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_14tq, CAN_BS2_3tq, 149)}, + {1000UL * 10, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_16tq, CAN_BS2_8tq, 199)} +#else + // 36 M + {1000UL * 1000, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_8tq, CAN_BS2_3tq, 3)}, + {1000UL * 800, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_11tq, CAN_BS2_3tq, 3)}, + {1000UL * 500, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_2tq, 6)}, + {1000UL * 250, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_13tq, CAN_BS2_2tq, 9)},//1 + {1000UL * 125, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_13tq, CAN_BS2_2tq, 18)}, + {1000UL * 100, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_9tq, CAN_BS2_2tq, 30)}, + {1000UL * 50, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_13tq, CAN_BS2_2tq, 45)}, + {1000UL * 20, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_14tq, CAN_BS2_3tq, 100)}, + {1000UL * 10, MK_BKCAN_BAUD(CAN_SJW_2tq, CAN_BS1_14tq, CAN_BS2_3tq, 200)} +#endif }; #define BAUD_DATA(TYPE,NO) \ - ((bxcan_baud_rate_tab[NO] & TYPE##MASK) >> TYPE##SHIFT) + ((bxcan_baud_rate_tab[NO].confdata & TYPE##MASK) >> TYPE##SHIFT) + +static rt_uint32_t bxcan_get_baud_index(rt_uint32_t baud) +{ + rt_uint32_t len, index, default_index; + + len = sizeof(bxcan_baud_rate_tab)/sizeof(bxcan_baud_rate_tab[0]); + default_index = len; + + for(index = 0; index < len; index++) + { + if(bxcan_baud_rate_tab[index].baud_rate == baud) + return index; + + if(bxcan_baud_rate_tab[index].baud_rate == 1000UL * 250) + default_index = index; + } + + if(default_index != len) + return default_index; + + return 0; +} + static void bxcan_init(CAN_TypeDef *pcan, rt_uint32_t baud, rt_uint32_t mode) { CAN_InitTypeDef CAN_InitStructure; + + rt_uint32_t baud_index = bxcan_get_baud_index(baud); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = ENABLE; @@ -296,10 +339,10 @@ static void bxcan_init(CAN_TypeDef *pcan, rt_uint32_t baud, rt_uint32_t mode) CAN_InitStructure.CAN_Mode = CAN_Mode_Silent_LoopBack; break; } - CAN_InitStructure.CAN_SJW = BAUD_DATA(SJW, baud); - CAN_InitStructure.CAN_BS1 = BAUD_DATA(BS1, baud); - CAN_InitStructure.CAN_BS2 = BAUD_DATA(BS2, baud); - CAN_InitStructure.CAN_Prescaler = BAUD_DATA(RRESCL, baud); + CAN_InitStructure.CAN_SJW = BAUD_DATA(SJW, baud_index); + CAN_InitStructure.CAN_BS1 = BAUD_DATA(BS1, baud_index); + CAN_InitStructure.CAN_BS2 = BAUD_DATA(BS2, baud_index); + CAN_InitStructure.CAN_Prescaler = BAUD_DATA(RRESCL, baud_index); CAN_Init(pcan, &CAN_InitStructure); } @@ -439,6 +482,9 @@ static rt_err_t bxcan_set_privmode(CAN_TypeDef *pcan, rt_uint32_t mode) static rt_err_t bxcan_set_baud_rate(CAN_TypeDef *pcan, rt_uint32_t baud) { rt_uint32_t mode; + + rt_uint32_t baud_index = bxcan_get_baud_index(baud); + if (bxcan_enter_init(pcan) != RT_EOK) { return RT_ERROR; @@ -446,10 +492,10 @@ static rt_err_t bxcan_set_baud_rate(CAN_TypeDef *pcan, rt_uint32_t baud) pcan->BTR = 0; mode = pcan->BTR & ((rt_uint32_t)0x03 << 30); pcan->BTR = (mode | \ - ((BAUD_DATA(SJW, baud)) << 24) | \ - ((BAUD_DATA(BS1, baud)) << 16) | \ - ((BAUD_DATA(BS2, baud)) << 20) | \ - (BAUD_DATA(RRESCL, baud))); + ((BAUD_DATA(SJW, baud_index)) << 24) | \ + ((BAUD_DATA(BS1, baud_index)) << 16) | \ + ((BAUD_DATA(BS2, baud_index)) << 20) | \ + (BAUD_DATA(RRESCL, baud_index))); if (bxcan_exit_init(pcan) != RT_EOK) { return RT_ERROR; diff --git a/bsp/stm32f10x/rtconfig.h b/bsp/stm32f10x/rtconfig.h index e233006509..01ef716a19 100644 --- a/bsp/stm32f10x/rtconfig.h +++ b/bsp/stm32f10x/rtconfig.h @@ -82,9 +82,9 @@ #define RT_USING_PIN -//#define RT_USING_CAN +#define RT_USING_CAN -#define RT_CAN_USING_BUS_HOOK +//#define RT_CAN_USING_BUS_HOOK #define RT_CAN_USING_HDR /* SECTION: device filesystem */ From 0d63eb5f6d2f94ca3507df72072d50f1c0e94698 Mon Sep 17 00:00:00 2001 From: gbcwbz Date: Thu, 14 Apr 2016 23:47:32 +0800 Subject: [PATCH 2/2] fix hardfault when RT_CAN_USING_BUS_HOOK is enabled in bsp/stm32f10x function `rt_pin_write` is invoked by function `can_bus_hook`, and it should to be initialized by gpio.c. but gpio.c was not added in SConscript --- bsp/stm32f10x/drivers/SConscript | 3 +++ bsp/stm32f10x/rtconfig.h | 2 +- components/drivers/misc/pin.c | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bsp/stm32f10x/drivers/SConscript b/bsp/stm32f10x/drivers/SConscript index 6be188e0f0..6a1ab42bb7 100644 --- a/bsp/stm32f10x/drivers/SConscript +++ b/bsp/stm32f10x/drivers/SConscript @@ -12,6 +12,9 @@ led.c usart.c """) +if GetDepend(['RT_USING_PIN']): + src += ['gpio.c'] + # add canbus driver. if GetDepend('RT_USING_CAN'): src += ['bxcan.c'] diff --git a/bsp/stm32f10x/rtconfig.h b/bsp/stm32f10x/rtconfig.h index 01ef716a19..f448846001 100644 --- a/bsp/stm32f10x/rtconfig.h +++ b/bsp/stm32f10x/rtconfig.h @@ -84,7 +84,7 @@ #define RT_USING_CAN -//#define RT_CAN_USING_BUS_HOOK +#define RT_CAN_USING_BUS_HOOK #define RT_CAN_USING_HDR /* SECTION: device filesystem */ diff --git a/components/drivers/misc/pin.c b/components/drivers/misc/pin.c index f3577a11d5..0a200af5aa 100644 --- a/components/drivers/misc/pin.c +++ b/components/drivers/misc/pin.c @@ -101,18 +101,21 @@ int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void /* RT-Thread Hardware PIN APIs */ void rt_pin_mode(rt_base_t pin, rt_base_t mode) { + RT_ASSERT(_hw_pin.ops != RT_NULL); _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode); } FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_mode, pinMode, set hardware pin mode); void rt_pin_write(rt_base_t pin, rt_base_t value) { + RT_ASSERT(_hw_pin.ops != RT_NULL); _hw_pin.ops->pin_write(&_hw_pin.parent, pin, value); } FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_write, pinWrite, write value to hardware pin); int rt_pin_read(rt_base_t pin) { + RT_ASSERT(_hw_pin.ops != RT_NULL); return _hw_pin.ops->pin_read(&_hw_pin.parent, pin); } FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);