diff --git a/ChangeLog b/ChangeLog index 3e2a46e5e6..5276d2f032 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2380,4 +2380,6 @@ pins were being used. * arch/arm/src/stm32/chip/stm32f10xxx_gpio.h: Correct offset to one AFIO EXICR register. + * arch/arm/src/lpc17xx/lpc17_can.c: Added "advanced" configuration options + to specify the CAN TSEG1 and TSEG2 clock counts specifically. diff --git a/arch/arm/src/lpc17xx/lpc17_can.c b/arch/arm/src/lpc17xx/lpc17_can.c index 5096ee142b..d4206cfd72 100755 --- a/arch/arm/src/lpc17xx/lpc17_can.c +++ b/arch/arm/src/lpc17xx/lpc17_can.c @@ -132,6 +132,27 @@ # endif #endif +/* User-defined TSEG1 and TSEG2 settings may be used. + * + * CONFIG_CAN_TSEG1 = the number of CAN time quanta in segment 1 + * CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2 + * CAN_BIT_QUANTA = The number of CAN time quanta in on bit time + */ + +#ifndef CONFIG_CAN_TSEG1 +# define CONFIG_CAN_TSEG1 6 +#endif + +#if CONFIG_CAN_TSEG1 < 1 || CONFIG_CAN_TSEG1 > CAN_BTR_TSEG1_MAX +# errror "CONFIG_CAN_TSEG1 is out of range" +#endif + +#ifndef CONFIG_CAN_TSEG2 +# define CONFIG_CAN_TSEG2 7 +#endif + +#define CAN_BIT_QUANTA (CONFIG_CAN_TSEG1 + CONFIG_CAN_TSEG2 + 3) + /* Debug ********************************************************************/ /* Non-standard debug that may be enabled just for testing CAN */ @@ -1087,8 +1108,7 @@ static int can_bittiming(struct up_dev_s *priv) canllvdbg("CAN%d PCLK: %d baud: %d\n", priv->port, CAN_CLOCK_FREQUENCY(priv->divisor), priv->baud); - /* Try to get 16 quanta in one bit_time. That is based on the idea that the ideal - * would be ts1=6 nd ts2=7 and (3 + ts1 + ts2) = 16. + /* Try to get CAN_BIT_QUANTA quanta in one bit_time. * * bit_time = Tq*(3 + ts1 + ts2) * nquanta = bit_time/Tq @@ -1103,7 +1123,7 @@ static int can_bittiming(struct up_dev_s *priv) */ nclks = CAN_CLOCK_FREQUENCY(priv->divisor) / priv->baud; - if (nclks < 16) + if (nclks < CAN_BIT_QUANTA) { /* At the smallest brp value (1), there are already too few bit times * (CAN_CLOCK / baud) to meet our goal. brp must be one and we need @@ -1116,22 +1136,23 @@ static int can_bittiming(struct up_dev_s *priv) ts1 = (nclks - 1) >> 1; ts2 = nclks - ts1 - 3; - if (ts1 == ts2 && ts1 > 1 && ts2 < 16) + if (ts1 == ts2 && ts1 > 1 && ts2 < CAN_BTR_TSEG2_MAX) { ts1--; ts2++; } } - /* Otherwise, nquanta is 16, ts1 is 6, ts2 is 7 and we calculate brp to - * achieve 16 quanta in the bit time + /* Otherwise, nquanta is CAN_BIT_QUANTA, ts1 is CONFIG_CAN_TSEG1, ts2 is + * CONFIG_CAN_TSEG2 and we calculate brp to achieve CAN_BIT_QUANTA quanta + * in the bit time */ else { - ts1 = 6; - ts2 = 7; - brp = (nclks + 8) / 16; + ts1 = CONFIG_CAN_TSEG1; + ts2 = CONFIG_CAN_TSEG2; + brp = (nclks + (CAN_BIT_QUANTA/2)) / CAN_BIT_QUANTA; DEBUGASSERT(brp >=1 && brp < 1024); } @@ -1141,10 +1162,10 @@ static int can_bittiming(struct up_dev_s *priv) /* Configure bit timing */ - btr = ((brp - 1) << CAN_BTR_BRP_SHIFT) | - ((ts1 - 1) << CAN_BTR_TESG1_SHIFT) | - ((ts2 - 1) << CAN_BTR_TESG2_SHIFT) | - ((sjw - 1) << CAN_BTR_SJW_SHIFT); + btr = (((brp - 1) << CAN_BTR_BRP_SHIFT) | + ((ts1 - 1) << CAN_BTR_TSEG1_SHIFT) | + ((ts2 - 1) << CAN_BTR_TSEG2_SHIFT) | + ((sjw - 1) << CAN_BTR_SJW_SHIFT)); #ifdef CONFIG_CAN_SAM /* The bus is sampled 3 times (recommended for low to medium speed buses diff --git a/arch/arm/src/lpc17xx/lpc17_can.h b/arch/arm/src/lpc17xx/lpc17_can.h index d743925f8a..0950dffe5c 100755 --- a/arch/arm/src/lpc17xx/lpc17_can.h +++ b/arch/arm/src/lpc17xx/lpc17_can.h @@ -364,12 +364,16 @@ /* Bits 10-13: Reserved */ #define CAN_BTR_SJW_SHIFT (14) /* Bits 14-15: Synchronization Jump Width */ #define CAN_BTR_SJW_MASK (3 << CAN_BTR_SJW_SHIFT) -#define CAN_BTR_TESG1_SHIFT (16) /* Bits 16-19: Sync to sample delay */ -#define CAN_BTR_TESG1_MASK (15 << CAN_BTR_TESG1_SHIFT) -#define CAN_BTR_TESG2_SHIFT (20) /* Bits 20-22: smaple to next delay */ -#define CAN_BTR_TESG2_MASK (7 << CAN_BTR_TESG2_SHIFT) +#define CAN_BTR_TSEG1_SHIFT (16) /* Bits 16-19: Sync to sample delay */ +#define CAN_BTR_TSEG1_MASK (15 << CAN_BTR_TSEG1_SHIFT) +#define CAN_BTR_TSEG2_SHIFT (20) /* Bits 20-22: smaple to next delay */ +#define CAN_BTR_TSEG2_MASK (7 << CAN_BTR_TSEG2_SHIFT) #define CAN_BTR_SAM (1 << 23) /* Bit 23: Sampling */ /* Bits 24-31: Reserved */ +#define CAN_BTR_BRP_MAX (1024) /* Maximum BTR value (without decrement) */ +#define CAN_BTR_TSEG1_MAX (16) /* Maximum TSEG value (without decrement) */ +#define CAN_BTR_TSEG2_MAX (8) /* Maximum TSEG value (without decrement) */ + /* Error Warning Limit */ #define CAN_EWL_SHIFT (0) /* Bits 0-7: Error warning limit */ diff --git a/configs/lpcxpresso-lpc1768/README.txt b/configs/lpcxpresso-lpc1768/README.txt index d7cbdb93e8..76cf35e7a6 100755 --- a/configs/lpcxpresso-lpc1768/README.txt +++ b/configs/lpcxpresso-lpc1768/README.txt @@ -655,6 +655,8 @@ LPCXpresso Configuration Options CONFIG_CAN2_DIVISOR - CAN2 is clocked at CCLK divided by this number. (the CCLK frequency is divided by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + CONFIG_CAN_TSEG1 - The number of CAN time quanta in segment 1. Default: 6 + CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2. Default: 7 LPC17xx specific PHY/Ethernet device driver settings. These setting also require CONFIG_NET and CONFIG_LPC17_ETHERNET. diff --git a/configs/mbed/README.txt b/configs/mbed/README.txt index 289b2e2cf0..94d87b275f 100755 --- a/configs/mbed/README.txt +++ b/configs/mbed/README.txt @@ -295,6 +295,8 @@ mbed Configuration Options CONFIG_CAN2_DIVISOR - CAN2 is clocked at CCLK divided by this number. (the CCLK frequency is divided by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + CONFIG_CAN_TSEG1 - The number of CAN time quanta in segment 1. Default: 6 + CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2. Default: 7 LPC17xx specific PHY/Ethernet device driver settings. These setting also require CONFIG_NET and CONFIG_LPC17_ETHERNET. diff --git a/configs/nucleus2g/README.txt b/configs/nucleus2g/README.txt index c3c53dd879..35bb31d5cd 100755 --- a/configs/nucleus2g/README.txt +++ b/configs/nucleus2g/README.txt @@ -407,6 +407,8 @@ Nucleus 2G Configuration Options CONFIG_CAN2_DIVISOR - CAN2 is clocked at CCLK divided by this number. (the CCLK frequency is divided by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + CONFIG_CAN_TSEG1 - The number of CAN time quanta in segment 1. Default: 6 + CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2. Default: 7 LPC17xx specific PHY/Ethernet device driver settings. These setting also require CONFIG_NET and CONFIG_LPC17_ETHERNET. diff --git a/configs/olimex-lpc1766stk/README.txt b/configs/olimex-lpc1766stk/README.txt index 8c03f437e3..d3bf2c98b3 100755 --- a/configs/olimex-lpc1766stk/README.txt +++ b/configs/olimex-lpc1766stk/README.txt @@ -704,6 +704,8 @@ Olimex LPC1766-STK Configuration Options CONFIG_CAN2_DIVISOR - CAN2 is clocked at CCLK divided by this number. (the CCLK frequency is divided by this number to get the CAN clock). Options = {1,2,4,6}. Default: 4. + CONFIG_CAN_TSEG1 - The number of CAN time quanta in segment 1. Default: 6 + CONFIG_CAN_TSEG2 = the number of CAN time quanta in segment 2. Default: 7 LPC17xx specific PHY/Ethernet device driver settings. These setting also require CONFIG_NET and CONFIG_LPC17_ETHERNET.