diff --git a/bsp/lpc408x/drivers/drv_lpccan.c b/bsp/lpc408x/drivers/drv_lpccan.c index 368949371..b390ad861 100644 --- a/bsp/lpc408x/drivers/drv_lpccan.c +++ b/bsp/lpc408x/drivers/drv_lpccan.c @@ -27,698 +27,781 @@ #include "lpc_exti.h" #include "lpc_clkpwr.h" -struct lpccandata { - en_CAN_unitId id; -}; -static const rt_uint32_t LPCBAUDTAB[] = { - 1000000, - 800000, - 500000, - 250000, - 125000, - 100000, - 50000, - 20000, - 10000, +struct lpccandata +{ + en_CAN_unitId id; }; + static LPC_CAN_TypeDef* lcpcan_get_reg_base(rt_uint32_t id) { - LPC_CAN_TypeDef* pCan; + LPC_CAN_TypeDef* pCan; - switch (id) { - case CAN_ID_1: - pCan = LPC_CAN1; - break; + switch (id) + { + case CAN_ID_1: + pCan = LPC_CAN1; + break; - case CAN_ID_2: - pCan = LPC_CAN2; - break; - default: - pCan = NULL; - } - return pCan; + case CAN_ID_2: + pCan = LPC_CAN2; + break; + default: + pCan = NULL; + } + return pCan; } + static void lpccan_irqstate_init(rt_uint32_t id) { - LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id); + LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id); + volatile rt_int32_t i; - pCan->MOD = 1; // Enter Reset Mode - pCan->IER = 0; // Disable All CAN Interrupts - pCan->GSR = 0; + pCan->MOD = 1; // Enter Reset Mode + pCan->IER = 0; // Disable All CAN Interrupts + pCan->GSR = 0; - /* Request command to release Rx, Tx buffer and clear data overrun */ - //pCan->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO; - pCan->CMR = (1 << 1) | (1 << 2) | (1 << 3); + /* Request command to release Rx, Tx buffer and clear data overrun */ + //pCan->CMR = CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO; + pCan->CMR = (1 << 1) | (1 << 2) | (1 << 3); - /* Read to clear interrupt pending in interrupt capture register */ - rt_int32_t i = pCan->ICR; - pCan->MOD = 0;// Return Normal operating + /* Read to clear interrupt pending in interrupt capture register */ + i = pCan->ICR; + i = i; + + pCan->MOD = 0;// Return Normal operating } -static void lpccan_baud_set(rt_uint32_t id, rt_uint32_t baud) + +static rt_err_t lpccan_baud_set(rt_uint32_t id, rt_uint32_t baud) { - uint32_t result = 0; - uint8_t NT, TSEG1, TSEG2; - uint32_t CANPclk = 0; - uint32_t BRP; - LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id); + uint32_t result = 0; + uint8_t NT, TSEG1, TSEG2; + uint32_t CANPclk = 0; + uint32_t BRP; + LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(id); - CANPclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); - result = CANPclk / LPCBAUDTAB[baud]; - /* Calculate suitable nominal time value - * NT (nominal time) = (TSEG1 + TSEG2 + 3) - * NT <= 24 - * TSEG1 >= 2*TSEG2 - */ - for(NT = 24; NT > 0; NT = NT-2) - { - if ((result%NT) == 0) - { - BRP = result / NT - 1; - NT--; - TSEG2 = (NT/3) - 1; - TSEG1 = NT -(NT/3) - 1; - break; - } - } - /* Enter reset mode */ - pCan->MOD = 0x01; - /* Set bit timing - * Default: SAM = 0x00; - * SJW = 0x03; - */ - pCan->BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP; - /* Return to normal operating */ - pCan->MOD = 0; + CANPclk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + result = CANPclk / baud; + + /* Calculate suitable nominal time value + * NT (nominal time) = (TSEG1 + TSEG2 + 3) + * NT <= 24 + * TSEG1 >= 2*TSEG2 + */ + for(NT = 24; NT > 0; NT = NT-2) + { + if ((result % NT) == 0) + { + BRP = result / NT - 1; + NT--; + TSEG2 = (NT/3) - 1; + TSEG1 = NT -(NT/3) - 1; + break; + } + } + + /* Enter reset mode */ + pCan->MOD = 0x01; + /* Set bit timing + * Default: SAM = 0x00; + * SJW = 0x03; + */ + pCan->BTR = (TSEG2 << 20) | (TSEG1 << 16) | (3 << 14) | BRP; + /* Return to normal operating */ + pCan->MOD = 0; + + return RT_EOK; } + static void lpccan_init_alut_ram(void) { - //Reset CANAF value - LPC_CANAF->AFMR = 0x01; - //clear ALUT RAM - rt_memset((void *)LPC_CANAF_RAM->mask, 0, 2048); - LPC_CANAF->SFF_sa = 0; - LPC_CANAF->SFF_GRP_sa = 0; - LPC_CANAF->EFF_sa = 0; - LPC_CANAF->EFF_GRP_sa = 0; - LPC_CANAF->ENDofTable = 0; - LPC_CANAF->AFMR = 0x00; - // Set AF Mode - CAN_SetAFMode(CAN_NORMAL); + //Reset CANAF value + LPC_CANAF->AFMR = 0x01; + //clear ALUT RAM + rt_memset((void *)LPC_CANAF_RAM->mask, 0, 2048); + LPC_CANAF->SFF_sa = 0; + LPC_CANAF->SFF_GRP_sa = 0; + LPC_CANAF->EFF_sa = 0; + LPC_CANAF->EFF_GRP_sa = 0; + LPC_CANAF->ENDofTable = 0; + LPC_CANAF->AFMR = 0x00; + // Set AF Mode + CAN_SetAFMode(CAN_NORMAL); } + #ifdef RT_USING_LPCCAN1 static void lpccan1_turnon_clk(void) { - CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE); + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN1, ENABLE); } + static void lpccan1_filter_init(struct rt_can_device *can) { } -static void lpccan1_hw_init(enum CANBAUD baud, CAN_MODE_Type mode) + +static void lpccan1_hw_init(uint32_t baud, CAN_MODE_Type mode) { - if(mode != CAN_SELFTEST_MODE) { + if(mode != CAN_SELFTEST_MODE) + { #ifndef LPCCAN1_USEING_GPIO_SECOND - PINSEL_ConfigPin (0, 0, 1); - PINSEL_ConfigPin (0, 1, 1); + PINSEL_ConfigPin (0, 0, 1); + PINSEL_ConfigPin (0, 1, 1); #else - PINSEL_ConfigPin (0, 21, 4); - PINSEL_ConfigPin (0, 22, 4); + PINSEL_ConfigPin (0, 21, 4); + PINSEL_ConfigPin (0, 22, 4); #endif - } - lpccan1_turnon_clk(); - lpccan_irqstate_init(CAN_1); - lpccan_init_alut_ram(); - lpccan1_turnon_clk(); - lpccan_baud_set(CAN_1, baud); - CAN_ModeConfig(CAN_1, mode, ENABLE); - if(mode == CAN_SELFTEST_MODE) { - //CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE); - CAN_SetAFMode(CAN_ACC_BP); - } + } + lpccan1_turnon_clk(); + lpccan_irqstate_init(CAN_1); + lpccan_init_alut_ram(); + lpccan1_turnon_clk(); + lpccan_baud_set(CAN_1, baud); + CAN_ModeConfig(CAN_1, mode, ENABLE); + if(mode == CAN_SELFTEST_MODE) + { + //CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE); + CAN_SetAFMode(CAN_ACC_BP); + } } #endif /*RT_USING_LPCCAN1*/ + #ifdef RT_USING_LPCCAN2 static void lpccan2_turnon_clk(void) { - CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE); + CLKPWR_ConfigPPWR(CLKPWR_PCONP_PCAN2, ENABLE); } + static void lpccan2_filter_init(struct rt_can_device *can) { } -static void lpccan2_hw_init(enum CANBAUD baud, CAN_MODE_Type mode) + +static void lpccan2_hw_init(uint32_t baud, CAN_MODE_Type mode) { - if(mode != CAN_SELFTEST_MODE) { + if(mode != CAN_SELFTEST_MODE) + { #ifndef LPCCAN2_USEING_GPIO_SECOND - PINSEL_ConfigPin (0, 4, 2); - PINSEL_ConfigPin (0, 5, 2); + PINSEL_ConfigPin (0, 4, 2); + PINSEL_ConfigPin (0, 5, 2); #else - PINSEL_ConfigPin (2, 7, 1); - PINSEL_ConfigPin (2, 8, 1); + PINSEL_ConfigPin (2, 7, 1); + PINSEL_ConfigPin (2, 8, 1); #endif - } - lpccan2_turnon_clk(); - lpccan_irqstate_init(CAN_2); + } + lpccan2_turnon_clk(); + lpccan_irqstate_init(CAN_2); #ifndef RT_USING_LPCCAN1 - lpccan_init_alut_ram(); + lpccan_init_alut_ram(); #endif /*RT_USING_LPCCAN1*/ - lpccan_baud_set(CAN_2, baud); - CAN_ModeConfig(CAN_2, mode, ENABLE); - if(mode == CAN_SELFTEST_MODE) { - CAN_SetAFMode(CAN_ACC_BP); - } + lpccan_baud_set(CAN_2, baud); + CAN_ModeConfig(CAN_2, mode, ENABLE); + if(mode == CAN_SELFTEST_MODE) + { + CAN_SetAFMode(CAN_ACC_BP); + } } #endif /*RT_USING_LPCCAN2*/ + static rt_err_t configure(struct rt_can_device *can, struct can_configure *cfg) { - CAN_MODE_Type mode; - switch(cfg->mode) { - case RT_CAN_MODE_NORMAL: - mode = CAN_OPERATING_MODE; - break; - case RT_CAN_MODE_LISEN: - mode = CAN_LISTENONLY_MODE; - break; - case RT_CAN_MODE_LOOPBACKANLISEN: - mode = CAN_SELFTEST_MODE; - break; - default: - return RT_EIO; - } - rt_uint32_t canid; - canid = ((struct lpccandata *) can->parent.user_data)->id; -#ifdef RT_USING_LPCCAN1 - if(canid == CAN_1) - { - lpccan1_hw_init(cfg->baud_rate, mode); - lpccan1_filter_init(can); - } + CAN_MODE_Type mode; + rt_uint32_t canid; + + switch(cfg->mode) + { + case RT_CAN_MODE_NORMAL: + mode = CAN_OPERATING_MODE; + break; + case RT_CAN_MODE_LISEN: + mode = CAN_LISTENONLY_MODE; + break; + case RT_CAN_MODE_LOOPBACKANLISEN: + mode = CAN_SELFTEST_MODE; + break; + default: + return RT_EIO; + } + + canid = ((struct lpccandata *) can->parent.user_data)->id; +#ifdef RT_USING_LPCCAN1 + if(canid == CAN_1) + { + lpccan1_hw_init(cfg->baud_rate, mode); + lpccan1_filter_init(can); + } #endif /*RT_USING_LPCCAN1*/ #ifdef RT_USING_LPCCAN2 #ifdef RT_USING_LPCCAN1 - else + else #endif /*RT_USING_LPCCAN1*/ - { - lpccan2_hw_init(cfg->baud_rate, mode); - lpccan2_filter_init(can); - } + { + lpccan2_hw_init(cfg->baud_rate, mode); + lpccan2_filter_init(can); + } #endif /*RT_USING_LPCCAN2*/ - return RT_EOK; + return RT_EOK; } + static CAN_ERROR findfilter(struct lpccandata* plpccan, struct rt_can_filter_item* pitem, rt_int32_t* pos) { - extern uint16_t CANAF_FullCAN_cnt; - extern uint16_t CANAF_std_cnt; - extern uint16_t CANAF_gstd_cnt; - extern uint16_t CANAF_ext_cnt; - extern uint16_t CANAF_gext_cnt; + extern uint16_t CANAF_FullCAN_cnt; + extern uint16_t CANAF_std_cnt; + extern uint16_t CANAF_gstd_cnt; + extern uint16_t CANAF_ext_cnt; + extern uint16_t CANAF_gext_cnt; - rt_uint32_t buf0 = 0, buf1 = 0; - rt_int16_t cnt1 = 0, cnt2 = 0, bound1 = 0; - CAN_ID_FORMAT_Type format; - *pos = -1; - if(pitem->ide) { - format = EXT_ID_FORMAT; - } else { - format = STD_ID_FORMAT; - } - if(pitem->mode) { - rt_uint32_t id = pitem->id; - if(format == STD_ID_FORMAT) - { - id &= 0x07FF; + rt_uint32_t buf0 = 0, buf1 = 0; + rt_int16_t cnt1 = 0, cnt2 = 0, bound1 = 0; + CAN_ID_FORMAT_Type format; + *pos = -1; + if(pitem->ide) + { + format = EXT_ID_FORMAT; + } + else + { + format = STD_ID_FORMAT; + } + if(pitem->mode) + { + rt_uint32_t id = pitem->id; + if(format == STD_ID_FORMAT) + { + id &= 0x07FF; - id |= plpccan->id << 13;/* Add controller number */ + id |= plpccan->id << 13;/* Add controller number */ - if (CANAF_std_cnt == 0) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else if (CANAF_std_cnt == 1) - { - cnt2 = (CANAF_FullCAN_cnt + 1) >> 1; - if(id != LPC_CANAF_RAM->mask[cnt2] >> 16) { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - } - else - { - cnt1 = (CANAF_FullCAN_cnt+1)>>1; + if (CANAF_std_cnt == 0) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else if (CANAF_std_cnt == 1) + { + cnt2 = (CANAF_FullCAN_cnt + 1) >> 1; + if(id != LPC_CANAF_RAM->mask[cnt2] >> 16) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + } + else + { + cnt1 = (CANAF_FullCAN_cnt+1)>>1; - bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); + bound1 = ((CANAF_FullCAN_cnt+1)>>1)+((CANAF_std_cnt+1)>>1); - while (cnt1 < bound1) - { - /* Loop through standard existing IDs */ - if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) == id) - { - *pos = cnt1 * 2; - return CAN_OK; - } + while (cnt1 < bound1) + { + /* Loop through standard existing IDs */ + if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) == id) + { + *pos = cnt1 * 2; + return CAN_OK; + } - if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) == id) - { - *pos = cnt1 * 2 + 1; - return CAN_OK; - } - if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } + if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) == id) + { + *pos = cnt1 * 2 + 1; + return CAN_OK; + } + if (((LPC_CANAF_RAM->mask[cnt1] >> 16) & 0xE7FF) > id) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } - if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - cnt1++; - } - return CAN_ENTRY_NOT_EXIT_ERROR; - } - } - /*********** Add Explicit Extended Identifier Frame Format entry *********/ - else - { - /* Add controller number */ - id |= plpccan->id << 29; + if ((LPC_CANAF_RAM->mask[cnt1] & 0x0000E7FF) > id) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + cnt1++; + } + return CAN_ENTRY_NOT_EXIT_ERROR; + } + } + /*********** Add Explicit Extended Identifier Frame Format entry *********/ + else + { + /* Add controller number */ + id |= plpccan->id << 29; - cnt1 = ((CANAF_FullCAN_cnt+1) >> 1) + (((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt); + cnt1 = ((CANAF_FullCAN_cnt+1) >> 1) + (((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt); - cnt2 = 0; + cnt2 = 0; - while (cnt2 < CANAF_ext_cnt) - { - /* Loop through extended existing masks*/ - if (LPC_CANAF_RAM->mask[cnt1] == id) - { - *pos = cnt2; - return CAN_OK; - } - if (LPC_CANAF_RAM->mask[cnt1] > id) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - cnt1++; - cnt2++; - } - } - } else { - rt_uint32_t lowerID = pitem->id; - rt_uint32_t upperID = pitem->mask; - rt_uint32_t LID,UID; - if(lowerID > upperID) - return CAN_CONFLICT_ID_ERROR; - if(format == STD_ID_FORMAT) - { - lowerID &=0x7FF; //mask ID - upperID &=0x7FF; - cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1); - if(CANAF_gstd_cnt == 0) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else - { - bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt; - while(cnt1 < bound1) - { //compare controller first - while((LPC_CANAF_RAM->mask[cnt1] >> 29) < (plpccan->id))//increase until meet greater or equal controller - cnt1++; - buf0 = LPC_CANAF_RAM->mask[cnt1]; - if((LPC_CANAF_RAM->mask[cnt1] >> 29) > (plpccan->id)) //meet greater controller - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else //meet equal controller - { - LID = (buf0 >> 16)&0x7FF; - UID = buf0 & 0x7FF; - if (upperID == LID && lowerID == UID) - { - *pos = cnt1; - return CAN_OK; - } - if (upperID < LID) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else if (lowerID >= UID) - { - cnt1 ++; - } - else - return CAN_CONFLICT_ID_ERROR; - } - } - if(cnt1 >= bound1) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - } - } - /*********Add Group of Extended Identifier Frame Format************/ - else - { - lowerID &= 0x1FFFFFFF; //mask ID - upperID &= 0x1FFFFFFF; - cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt; - //if this is the first Group standard ID entry - if(CANAF_gext_cnt == 0) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else - { - bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \ - + CANAF_ext_cnt + (CANAF_gext_cnt<<1); - while(cnt1 < bound1) - { - while((LPC_CANAF_RAM->mask[cnt1] >>29)< plpccan->id ) //increase until meet greater or equal controller - cnt1++; - buf0 = LPC_CANAF_RAM->mask[cnt1]; - buf1 = LPC_CANAF_RAM->mask[cnt1+1]; - if((LPC_CANAF_RAM->mask[cnt1] >> 29) > plpccan->id ) //meet greater controller - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else //meet equal controller - { - LID = buf0 & 0x1FFFFFFF; //mask ID - UID = buf1 & 0x1FFFFFFF; - if (upperID == LID && lowerID == UID) - { - *pos = cnt1; - return CAN_OK; - } - if (upperID < LID) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - else if (lowerID >= UID) - { - //load next entry to compare - cnt1 +=2; - } - else - return CAN_CONFLICT_ID_ERROR; - } - } - if(cnt1 >= bound1) - { - return CAN_ENTRY_NOT_EXIT_ERROR; - } - } - } - } - return CAN_ENTRY_NOT_EXIT_ERROR; + while (cnt2 < CANAF_ext_cnt) + { + /* Loop through extended existing masks*/ + if (LPC_CANAF_RAM->mask[cnt1] == id) + { + *pos = cnt2; + return CAN_OK; + } + if (LPC_CANAF_RAM->mask[cnt1] > id) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + cnt1++; + cnt2++; + } + } + } + else + { + rt_uint32_t lowerID = pitem->id; + rt_uint32_t upperID = pitem->mask; + rt_uint32_t LID,UID; + if(lowerID > upperID) + return CAN_CONFLICT_ID_ERROR; + if(format == STD_ID_FORMAT) + { + lowerID &=0x7FF; //mask ID + upperID &=0x7FF; + cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1); + if(CANAF_gstd_cnt == 0) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt; + while(cnt1 < bound1) + { + //compare controller first + while((LPC_CANAF_RAM->mask[cnt1] >> 29) < (plpccan->id))//increase until meet greater or equal controller + cnt1++; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + if((LPC_CANAF_RAM->mask[cnt1] >> 29) > (plpccan->id)) //meet greater controller + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else //meet equal controller + { + LID = (buf0 >> 16)&0x7FF; + UID = buf0 & 0x7FF; + if (upperID == LID && lowerID == UID) + { + *pos = cnt1; + return CAN_OK; + } + if (upperID < LID) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else if (lowerID >= UID) + { + cnt1 ++; + } + else + return CAN_CONFLICT_ID_ERROR; + } + } + if(cnt1 >= bound1) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + } + } + /*********Add Group of Extended Identifier Frame Format************/ + else + { + lowerID &= 0x1FFFFFFF; //mask ID + upperID &= 0x1FFFFFFF; + cnt1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt + CANAF_ext_cnt; + //if this is the first Group standard ID entry + if(CANAF_gext_cnt == 0) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else + { + bound1 = ((CANAF_FullCAN_cnt+1)>>1) + ((CANAF_std_cnt + 1) >> 1) + CANAF_gstd_cnt \ + + CANAF_ext_cnt + (CANAF_gext_cnt<<1); + while(cnt1 < bound1) + { + while((LPC_CANAF_RAM->mask[cnt1] >>29)< plpccan->id ) //increase until meet greater or equal controller + cnt1++; + buf0 = LPC_CANAF_RAM->mask[cnt1]; + buf1 = LPC_CANAF_RAM->mask[cnt1+1]; + if((LPC_CANAF_RAM->mask[cnt1] >> 29) > plpccan->id ) //meet greater controller + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else //meet equal controller + { + LID = buf0 & 0x1FFFFFFF; //mask ID + UID = buf1 & 0x1FFFFFFF; + if (upperID == LID && lowerID == UID) + { + *pos = cnt1; + return CAN_OK; + } + if (upperID < LID) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + else if (lowerID >= UID) + { + //load next entry to compare + cnt1 +=2; + } + else + return CAN_CONFLICT_ID_ERROR; + } + } + if(cnt1 >= bound1) + { + return CAN_ENTRY_NOT_EXIT_ERROR; + } + } + } + } + return CAN_ENTRY_NOT_EXIT_ERROR; } + static rt_err_t setfilter(struct lpccandata* plpccan,struct rt_can_filter_config *pconfig) { - struct rt_can_filter_item* pitem = pconfig->items; - rt_uint32_t count = pconfig->count; - rt_int32_t pos; - CAN_ID_FORMAT_Type format; - CAN_ERROR lpccanres; - while(count) { - if(pitem->ide) { - format = EXT_ID_FORMAT; - } else { - format = STD_ID_FORMAT; - } - lpccanres = findfilter(plpccan, pitem, &pos); - if(pconfig->actived && lpccanres != CAN_OK) { - if(pitem->mode) { - lpccanres = CAN_LoadGroupEntry(plpccan->id, pitem->id, pitem->mask, format); - } else { - lpccanres = CAN_LoadExplicitEntry(plpccan->id, pitem->id, format); - } - } else if(!pconfig->actived && lpccanres == CAN_OK) { - AFLUT_ENTRY_Type type; - if(pitem->mode) { - if(format == EXT_ID_FORMAT) { - type = GROUP_EXTEND_ENTRY; - } else { - type = GROUP_STANDARD_ENTRY; - } - } else { - if(format == EXT_ID_FORMAT) { - type = EXPLICIT_EXTEND_ENTRY; - } else { - type = EXPLICIT_STANDARD_ENTRY; - } - } - lpccanres = CAN_RemoveEntry(type, (rt_uint16_t)(pos)); - } else if(!pconfig->actived && lpccanres != CAN_OK) { - lpccanres = CAN_OK; - } - if(lpccanres != CAN_OK) { - return RT_EIO; - } - pitem++; - count--; - } - return RT_EOK; + struct rt_can_filter_item* pitem = pconfig->items; + rt_uint32_t count = pconfig->count; + rt_int32_t pos; + CAN_ID_FORMAT_Type format; + CAN_ERROR lpccanres; + while(count) + { + if(pitem->ide) + { + format = EXT_ID_FORMAT; + } + else + { + format = STD_ID_FORMAT; + } + lpccanres = findfilter(plpccan, pitem, &pos); + if(pconfig->actived && lpccanres != CAN_OK) + { + if(pitem->mode) + { + lpccanres = CAN_LoadGroupEntry(plpccan->id, pitem->id, pitem->mask, format); + } + else + { + lpccanres = CAN_LoadExplicitEntry(plpccan->id, pitem->id, format); + } + } + else if(!pconfig->actived && lpccanres == CAN_OK) + { + AFLUT_ENTRY_Type type; + if(pitem->mode) + { + if(format == EXT_ID_FORMAT) + { + type = GROUP_EXTEND_ENTRY; + } + else + { + type = GROUP_STANDARD_ENTRY; + } + } + else + { + if(format == EXT_ID_FORMAT) + { + type = EXPLICIT_EXTEND_ENTRY; + } + else + { + type = EXPLICIT_STANDARD_ENTRY; + } + } + lpccanres = CAN_RemoveEntry(type, (rt_uint16_t)(pos)); + } + else if(!pconfig->actived && lpccanres != CAN_OK) + { + lpccanres = CAN_OK; + } + if(lpccanres != CAN_OK) + { + return RT_EIO; + } + pitem++; + count--; + } + return RT_EOK; } + static rt_err_t control(struct rt_can_device *can, int cmd, void *arg) { - struct lpccandata* plpccan; - rt_uint32_t argval; - CAN_MODE_Type mode; - plpccan = (struct lpccandata* ) can->parent.user_data; - RT_ASSERT(plpccan != RT_NULL); - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - argval = (rt_uint32_t) arg; - if(argval == RT_DEVICE_FLAG_INT_RX) - { - CAN_IRQCmd(plpccan->id, CANINT_RIE, DISABLE); - CAN_IRQCmd(plpccan->id, CANINT_DOIE, DISABLE); - } else if(argval == RT_DEVICE_FLAG_INT_TX) { - CAN_IRQCmd(plpccan->id, CANINT_TIE1, DISABLE); - CAN_IRQCmd(plpccan->id, CANINT_TIE2, DISABLE); - CAN_IRQCmd(plpccan->id, CANINT_TIE3, DISABLE); - } else if(argval == RT_DEVICE_CAN_INT_ERR) { - CAN_IRQCmd(plpccan->id, CANINT_EIE, DISABLE); - } - break; - case RT_DEVICE_CTRL_SET_INT: - argval = (rt_uint32_t) arg; - if(argval == RT_DEVICE_FLAG_INT_RX) - { - CAN_IRQCmd(plpccan->id, CANINT_RIE, ENABLE); - CAN_IRQCmd(plpccan->id, CANINT_DOIE, ENABLE); - } else if(argval == RT_DEVICE_FLAG_INT_TX) { - CAN_IRQCmd(plpccan->id, CANINT_TIE1, ENABLE); - CAN_IRQCmd(plpccan->id, CANINT_TIE2, ENABLE); - CAN_IRQCmd(plpccan->id, CANINT_TIE3, ENABLE); - } else if(argval == RT_DEVICE_CAN_INT_ERR) { - CAN_IRQCmd(plpccan->id, CANINT_EIE, ENABLE); - } - break; - case RT_CAN_CMD_SET_FILTER: - return setfilter(plpccan, (struct rt_can_filter_config*) arg); - case RT_CAN_CMD_SET_MODE: - argval = (rt_uint32_t) arg; - if(argval != RT_CAN_MODE_NORMAL || - argval != RT_CAN_MODE_LISEN) { - return RT_ERROR; - } - if(argval != can->config.mode) - { - can->config.mode = argval; - switch(argval) { - case RT_CAN_MODE_NORMAL: - mode = CAN_OPERATING_MODE; - break; - case RT_CAN_MODE_LISEN: - mode = CAN_LISTENONLY_MODE; - break; - case RT_CAN_MODE_LOOPBACKANLISEN: - mode = CAN_SELFTEST_MODE; - break; - default: - return RT_EIO; - } - CAN_ModeConfig(plpccan->id, mode, ENABLE); - if(mode == CAN_SELFTEST_MODE) { - //CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE); - CAN_SetAFMode(CAN_ACC_BP); - } - } - break; - case RT_CAN_CMD_SET_BAUD: - argval = (rt_uint32_t) arg; - if(argval != CAN1MBaud && - argval != CAN800kBaud && - argval != CAN500kBaud && - argval != CAN250kBaud && - argval != CAN125kBaud && - argval != CAN100kBaud && - argval != CAN50kBaud && - argval != CAN20kBaud && - argval != CAN10kBaud ) { - return RT_ERROR; - } - if(argval != can->config.baud_rate) - { - can->config.baud_rate = argval; - lpccan_baud_set(plpccan->id, (rt_uint32_t) arg); - } - break; - case RT_CAN_CMD_SET_PRIV: - argval = (rt_uint32_t) arg; - if(argval != RT_CAN_MODE_PRIV || - argval != RT_CAN_MODE_NOPRIV) { - return RT_ERROR; - } - if(argval != can->config.privmode) - { - can->config.privmode = argval; - CAN_ModeConfig(plpccan->id, CAN_TXPRIORITY_MODE, ENABLE); - } - break; - case RT_CAN_CMD_GET_STATUS: - { - rt_uint32_t errtype; - can->status.rcverrcnt = 0; - can->status.snderrcnt = 0; - can->status.errcode = 0; - if(arg != &can->status) { - rt_memcpy(arg,&can->status,sizeof(can->status)); - } - } - break; - } - return RT_EOK; + struct lpccandata* plpccan; + rt_uint32_t argval; + CAN_MODE_Type mode; + + plpccan = (struct lpccandata* ) can->parent.user_data; + RT_ASSERT(plpccan != RT_NULL); + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + argval = (rt_uint32_t) arg; + if(argval == RT_DEVICE_FLAG_INT_RX) + { + CAN_IRQCmd(plpccan->id, CANINT_RIE, DISABLE); + CAN_IRQCmd(plpccan->id, CANINT_DOIE, DISABLE); + } + else if(argval == RT_DEVICE_FLAG_INT_TX) + { + CAN_IRQCmd(plpccan->id, CANINT_TIE1, DISABLE); + CAN_IRQCmd(plpccan->id, CANINT_TIE2, DISABLE); + CAN_IRQCmd(plpccan->id, CANINT_TIE3, DISABLE); + } + else if(argval == RT_DEVICE_CAN_INT_ERR) + { + CAN_IRQCmd(plpccan->id, CANINT_EIE, DISABLE); + } + break; + + case RT_DEVICE_CTRL_SET_INT: + argval = (rt_uint32_t) arg; + if(argval == RT_DEVICE_FLAG_INT_RX) + { + CAN_IRQCmd(plpccan->id, CANINT_RIE, ENABLE); + CAN_IRQCmd(plpccan->id, CANINT_DOIE, ENABLE); + } + else if(argval == RT_DEVICE_FLAG_INT_TX) + { + CAN_IRQCmd(plpccan->id, CANINT_TIE1, ENABLE); + CAN_IRQCmd(plpccan->id, CANINT_TIE2, ENABLE); + CAN_IRQCmd(plpccan->id, CANINT_TIE3, ENABLE); + } + else if(argval == RT_DEVICE_CAN_INT_ERR) + { + CAN_IRQCmd(plpccan->id, CANINT_EIE, ENABLE); + } + break; + + case RT_CAN_CMD_SET_FILTER: + return setfilter(plpccan, (struct rt_can_filter_config*) arg); + + case RT_CAN_CMD_SET_MODE: + argval = (rt_uint32_t) arg; + if(argval != RT_CAN_MODE_NORMAL || + argval != RT_CAN_MODE_LISEN) + { + return RT_ERROR; + } + if(argval != can->config.mode) + { + can->config.mode = argval; + switch(argval) + { + case RT_CAN_MODE_NORMAL: + mode = CAN_OPERATING_MODE; + break; + case RT_CAN_MODE_LISEN: + mode = CAN_LISTENONLY_MODE; + break; + case RT_CAN_MODE_LOOPBACKANLISEN: + mode = CAN_SELFTEST_MODE; + break; + default: + return RT_EIO; + } + CAN_ModeConfig(plpccan->id, mode, ENABLE); + if(mode == CAN_SELFTEST_MODE) + { + //CAN_ModeConfig(CAN_1, CAN_TEST_MODE, ENABLE); + CAN_SetAFMode(CAN_ACC_BP); + } + } + break; + + case RT_CAN_CMD_SET_BAUD: + argval = (rt_uint32_t) arg; + if(argval != can->config.baud_rate) + { + can->config.baud_rate = argval; + return lpccan_baud_set(plpccan->id, (rt_uint32_t) arg); + } + break; + + case RT_CAN_CMD_SET_PRIV: + argval = (rt_uint32_t) arg; + if(argval != RT_CAN_MODE_PRIV || + argval != RT_CAN_MODE_NOPRIV) + { + return RT_ERROR; + } + if(argval != can->config.privmode) + { + can->config.privmode = argval; + CAN_ModeConfig(plpccan->id, CAN_TXPRIORITY_MODE, ENABLE); + } + break; + + case RT_CAN_CMD_GET_STATUS: + { + can->status.rcverrcnt = 0; + can->status.snderrcnt = 0; + can->status.errcode = 0; + if(arg != &can->status) + { + rt_memcpy(arg,&can->status,sizeof(can->status)); + } + } + break; + + } + return RT_EOK; } + static int sendmsg(struct rt_can_device *can, const void* buf, rt_uint32_t boxno) { - struct lpccandata* plpccan; - plpccan = (struct lpccandata* ) can->parent.user_data; - RT_ASSERT(plpccan != RT_NULL); - LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(plpccan->id); - RT_ASSERT(pCan != RT_NULL); - struct rt_can_msg* pmsg = (struct rt_can_msg*) buf; - rt_uint32_t SR_Mask; - if(boxno > 2) { - return RT_ERROR; - } - rt_uint32_t CMRMsk = 0x01 | (0x01 << (boxno + 5)); - SR_Mask = 0x01 <<(boxno * 8 + 2); - volatile unsigned int *pTFI = (&pCan->TFI1 + 0 + 4 * boxno); - volatile unsigned int *pTID = (&pCan->TFI1 + 1 + 4 * boxno); - volatile unsigned int *pTDA = (&pCan->TFI1 + 2 + 4 * boxno); - volatile unsigned int *pTDB = (&pCan->TFI1 + 3 + 4 * boxno); - rt_uint32_t data; - if(pCan->SR & SR_Mask) { - /* Transmit Channel 1 is available */ - /* Write frame informations and frame data into its CANxTFI1, - * CANxTID1, CANxTDA1, CANxTDB1 register */ - *pTFI &= ~ 0x000F0000; - *pTFI |= (pmsg->len) << 16; - if(pmsg->rtr == REMOTE_FRAME) - { - *pTFI |= (1 << 30); //set bit RTR - } - else - { - *pTFI &= ~(1 << 30); - } + struct lpccandata* plpccan; + LPC_CAN_TypeDef* pCan; + struct rt_can_msg* pmsg; + rt_uint32_t SR_Mask; + rt_uint32_t CMRMsk; - if(pmsg->ide == EXT_ID_FORMAT) - { - *pTFI |= (((uint32_t)1) << 31); //set bit FF - } - else - { - *pTFI &= ~(((uint32_t)1) << 31); - } - if(can->config.privmode) { - *pTFI &= ~0x000000FF; - *pTFI |= pmsg->priv; - } - /* Write CAN ID*/ - *pTID = pmsg->id; - /*Write first 4 data bytes*/ - data = (pmsg->data[0]) | (((pmsg->data[1]))<< 8) | ((pmsg->data[2]) << 16) | ((pmsg->data[3]) << 24); - *pTDA = data; - /*Write second 4 data bytes*/ - data = (pmsg->data[4]) | (((pmsg->data[5])) << 8) | ((pmsg->data[6]) << 16) | ((pmsg->data[7]) << 24); - *pTDB = data; - /*Write transmission request*/ - pCan->CMR = CMRMsk; - return RT_EOK; - } else { - return RT_ERROR; - } + plpccan = (struct lpccandata* ) can->parent.user_data; + RT_ASSERT(plpccan != RT_NULL); + + pCan = lcpcan_get_reg_base(plpccan->id); + RT_ASSERT(pCan != RT_NULL); + + pmsg = (struct rt_can_msg*) buf; + + if(boxno > 2) + { + return RT_ERROR; + } + + CMRMsk = 0x01 | (0x01 << (boxno + 5)); + SR_Mask = 0x01 <<(boxno * 8 + 2); + + if(pCan->SR & SR_Mask) + { + volatile unsigned int *pTFI = (&pCan->TFI1 + 0 + 4 * boxno); + volatile unsigned int *pTID = (&pCan->TFI1 + 1 + 4 * boxno); + volatile unsigned int *pTDA = (&pCan->TFI1 + 2 + 4 * boxno); + volatile unsigned int *pTDB = (&pCan->TFI1 + 3 + 4 * boxno); + rt_uint32_t data; + + /* Transmit Channel 1 is available */ + /* Write frame informations and frame data into its CANxTFI1, + * CANxTID1, CANxTDA1, CANxTDB1 register */ + *pTFI &= ~ 0x000F0000; + *pTFI |= (pmsg->len) << 16; + if(pmsg->rtr == REMOTE_FRAME) + { + *pTFI |= (1 << 30); //set bit RTR + } + else + { + *pTFI &= ~(1 << 30); + } + + if(pmsg->ide == EXT_ID_FORMAT) + { + *pTFI |= (((uint32_t)1) << 31); //set bit FF + } + else + { + *pTFI &= ~(((uint32_t)1) << 31); + } + if(can->config.privmode) + { + *pTFI &= ~0x000000FF; + *pTFI |= pmsg->priv; + } + /* Write CAN ID*/ + *pTID = pmsg->id; + /*Write first 4 data bytes*/ + data = (pmsg->data[0]) | (((pmsg->data[1]))<< 8) | ((pmsg->data[2]) << 16) | ((pmsg->data[3]) << 24); + *pTDA = data; + /*Write second 4 data bytes*/ + data = (pmsg->data[4]) | (((pmsg->data[5])) << 8) | ((pmsg->data[6]) << 16) | ((pmsg->data[7]) << 24); + *pTDB = data; + /*Write transmission request*/ + pCan->CMR = CMRMsk; + return RT_EOK; + } + else + { + return RT_ERROR; + } } + static int recvmsg(struct rt_can_device *can, void* buf, rt_uint32_t boxno) { - struct lpccandata* plpccan; - plpccan = (struct lpccandata* ) can->parent.user_data; - RT_ASSERT(plpccan != RT_NULL); - LPC_CAN_TypeDef* pCan = lcpcan_get_reg_base(plpccan->id); - RT_ASSERT(pCan != RT_NULL); - //CAN_ReceiveMsg - uint32_t data; - struct rt_can_msg* pmsg = (struct rt_can_msg*) buf; - //check status of Receive Buffer - if((pCan->SR &0x00000001)) - { - /* Receive message is available */ - /* Read frame informations */ - pmsg->ide = (uint8_t)(((pCan->RFS) & 0x80000000) >> 31); - pmsg->rtr = (uint8_t)(((pCan->RFS) & 0x40000000) >> 30); - pmsg->len = (uint8_t)(((pCan->RFS) & 0x000F0000) >> 16); - /* Read CAN message identifier */ - pmsg->id = pCan->RID; - /* Read the data if received message was DATA FRAME */ - if (!pmsg->rtr) - { - /* Read first 4 data bytes */ - data = pCan->RDA; - pmsg->data[0] = data & 0x000000FF; - pmsg->data[1] = (data & 0x0000FF00) >> 8; - pmsg->data[2] = (data & 0x00FF0000) >> 16; - pmsg->data[3] = (data & 0xFF000000) >> 24; - /* Read second 4 data bytes */ - if(pmsg->len > 4) { - data = pCan->RDB; - pmsg->data[4] = data & 0x000000FF; - pmsg->data[5] = (data & 0x0000FF00) >> 8; - pmsg->data[6] = (data & 0x00FF0000) >> 16; - pmsg->data[7] = (data & 0xFF000000) >> 24; - } - pmsg->hdr = 0; - /*release receive buffer*/ - pCan->CMR = 0x04; - } - else - { - /* Received Frame is a Remote Frame, not have data, we just receive - * message information only */ - pCan->CMR = 0x04; /*release receive buffer*/ - return SUCCESS; - } - } - else - { - // no receive message available - return ERROR; - } - return RT_EOK; + struct lpccandata* plpccan; + LPC_CAN_TypeDef* pCan; + + plpccan = (struct lpccandata* ) can->parent.user_data; + RT_ASSERT(plpccan != RT_NULL); + pCan = lcpcan_get_reg_base(plpccan->id); + RT_ASSERT(pCan != RT_NULL); + + //CAN_ReceiveMsg + //check status of Receive Buffer + if((pCan->SR &0x00000001)) + { + uint32_t data; + struct rt_can_msg* pmsg = (struct rt_can_msg*) buf; + + /* Receive message is available */ + /* Read frame informations */ + pmsg->ide = (uint8_t)(((pCan->RFS) & 0x80000000) >> 31); + pmsg->rtr = (uint8_t)(((pCan->RFS) & 0x40000000) >> 30); + pmsg->len = (uint8_t)(((pCan->RFS) & 0x000F0000) >> 16); + /* Read CAN message identifier */ + pmsg->id = pCan->RID; + /* Read the data if received message was DATA FRAME */ + if (!pmsg->rtr) + { + /* Read first 4 data bytes */ + data = pCan->RDA; + pmsg->data[0] = data & 0x000000FF; + pmsg->data[1] = (data & 0x0000FF00) >> 8; + pmsg->data[2] = (data & 0x00FF0000) >> 16; + pmsg->data[3] = (data & 0xFF000000) >> 24; + /* Read second 4 data bytes */ + if(pmsg->len > 4) + { + data = pCan->RDB; + pmsg->data[4] = data & 0x000000FF; + pmsg->data[5] = (data & 0x0000FF00) >> 8; + pmsg->data[6] = (data & 0x00FF0000) >> 16; + pmsg->data[7] = (data & 0xFF000000) >> 24; + } + pmsg->hdr = 0; + /*release receive buffer*/ + pCan->CMR = 0x04; + } + else + { + /* Received Frame is a Remote Frame, not have data, we just receive + * message information only */ + pCan->CMR = 0x04; /*release receive buffer*/ + return SUCCESS; + } + } + else + { + // no receive message available + return ERROR; + } + return RT_EOK; } static const struct rt_can_ops canops = { - configure, - control, - sendmsg, - recvmsg, + configure, + control, + sendmsg, + recvmsg, }; + #ifdef RT_USING_LPCCAN1 #ifdef RT_CAN_USING_LED #endif -static struct lpccandata lpccandata1 = { - CAN_1, +static struct lpccandata lpccandata1 = +{ + CAN_ID_1, }; static struct rt_can_device lpccan1; #endif /*RT_USINGLPCCAN1*/ @@ -726,11 +809,13 @@ static struct rt_can_device lpccan1; #ifdef RT_USING_LPCCAN2 #ifdef RT_CAN_USING_LED #endif -static struct lpccandata lpccandata2 = { - CAN_2, +static struct lpccandata lpccandata2 = +{ + CAN_ID_2, }; static struct rt_can_device lpccan2; #endif /*RT_USINGLPCCAN2*/ + /*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/ /*********************************************************************//** * @brief Event Router IRQ Handler @@ -739,234 +824,267 @@ static struct rt_can_device lpccan2; **********************************************************************/ void CAN_IRQHandler(void) { - rt_uint32_t IntStatus; + rt_uint32_t IntStatus; #ifdef RT_USING_LPCCAN1 - IntStatus = CAN_IntGetStatus(CAN_1); - //check receive interrupt - if((IntStatus >> 0) & 0x01) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RX_IND | 0<<8); - } - //check Transmit Interrupt interrupt1 - if((IntStatus >> 1) & 0x01) - { - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS); - if(state & (0x01 << 3)) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8); - } else { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8); - } - } - //check Error Warning Interrupt - if((IntStatus >> 2) & 0x01) - { - rt_uint32_t errtype; - errtype = (IntStatus >> 16); - if(errtype & 0x1F && lpccan1.status.lasterrtype == (errtype & 0x1F)) { - switch((errtype & 0x1F)) { - case 00011: // Start of Frame - case 00010: // ID28 ... ID21 - case 00110: //ID20 ... ID18 - case 00100: // SRTR Bit - case 00101: // IDE bit - case 00111: // ID17 ... 13 - case 01111: // ID12 ... ID5 - case 01110: // ID4 ... ID0 - case 01100: // RTR Bit - case 01011: // Data Length Code - case 01010: // Data Field - lpccan1.status.formaterrcnt++; - break; - case 01101: // Reserved Bit 1 - case 01001: // Reserved Bit 0 - lpccan1.status.bitpaderrcnt++; - break; - case 01000: // CRC Sequence - case 11000: // CRC Delimiter - lpccan1.status.crcerrcnt++; - break; - case 11001: // Acknowledge Slot - case 11011: // Acknowledge Delimiter - lpccan1.status.ackerrcnt++; - break; - case 11010: // End of Frame - case 10010: // Intermission - lpccan1.status.formaterrcnt++; - break; - } - lpccan1.status.lasterrtype = errtype & 0x1F; - } - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_1, CANCTRL_GLOBAL_STS); - lpccan1.status.rcverrcnt = (state >> 16) & 0xFF; - lpccan1.status.snderrcnt = (state >> 24) & 0xFF; - lpccan1.status.errcode = (state >> 5) & 0x06; - } - //check Data Overrun Interrupt Interrupt - if((IntStatus >> 3) & 0x01) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8); - } - //check Transmit Interrupt interrupt2 - if((IntStatus >> 9) & 0x01) - { - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS); - if(state & (0x01 << 11)) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8); - } else { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8); - } - } - //check Transmit Interrupt interrupt3 - if((IntStatus >> 10) & 0x01) - { - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS); - if(state & (0x01 << 19)) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8); - } else { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8); - } - } + IntStatus = CAN_IntGetStatus(CAN_1); + //check receive interrupt + if((IntStatus >> 0) & 0x01) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RX_IND | 0<<8); + } + //check Transmit Interrupt interrupt1 + if((IntStatus >> 1) & 0x01) + { + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS); + if(state & (0x01 << 3)) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8); + } + else + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8); + } + } + //check Error Warning Interrupt + if((IntStatus >> 2) & 0x01) + { + rt_uint32_t errtype; + rt_uint32_t state; + + errtype = (IntStatus >> 16); + if(errtype & 0x1F && lpccan1.status.lasterrtype == (errtype & 0x1F)) + { + switch((errtype & 0x1F)) + { + case 00011: // Start of Frame + case 00010: // ID28 ... ID21 + case 00110: //ID20 ... ID18 + case 00100: // SRTR Bit + case 00101: // IDE bit + case 00111: // ID17 ... 13 + case 01111: // ID12 ... ID5 + case 01110: // ID4 ... ID0 + case 01100: // RTR Bit + case 01011: // Data Length Code + case 01010: // Data Field + lpccan1.status.formaterrcnt++; + break; + case 01101: // Reserved Bit 1 + case 01001: // Reserved Bit 0 + lpccan1.status.bitpaderrcnt++; + break; + case 01000: // CRC Sequence + case 11000: // CRC Delimiter + lpccan1.status.crcerrcnt++; + break; + case 11001: // Acknowledge Slot + case 11011: // Acknowledge Delimiter + lpccan1.status.ackerrcnt++; + break; + case 11010: // End of Frame + case 10010: // Intermission + lpccan1.status.formaterrcnt++; + break; + } + lpccan1.status.lasterrtype = errtype & 0x1F; + } + + state = CAN_GetCTRLStatus(CAN_1, CANCTRL_GLOBAL_STS); + lpccan1.status.rcverrcnt = (state >> 16) & 0xFF; + lpccan1.status.snderrcnt = (state >> 24) & 0xFF; + lpccan1.status.errcode = (state >> 5) & 0x06; + } + //check Data Overrun Interrupt Interrupt + if((IntStatus >> 3) & 0x01) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8); + } + //check Transmit Interrupt interrupt2 + if((IntStatus >> 9) & 0x01) + { + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS); + if(state & (0x01 << 11)) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8); + } + else + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8); + } + } + //check Transmit Interrupt interrupt3 + if((IntStatus >> 10) & 0x01) + { + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_1, CANCTRL_STS); + if(state & (0x01 << 19)) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8); + } + else + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8); + } + } #endif /*RT_USING_LPCCAN1*/ + #ifdef RT_USING_LPCCAN2 - IntStatus = CAN_IntGetStatus(CAN_2); - //check receive interrupt - if((IntStatus >> 0) & 0x01) - { - rt_hw_can_isr(&lpccan2,RT_CAN_EVENT_RX_IND | 0<<8); - } - //check Transmit Interrupt interrupt1 - if((IntStatus >> 1) & 0x01) - { - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS); - if(state & (0x01 << 3)) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8); - } else { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8); - } - } - //check Error Warning Interrupt - if((IntStatus >> 2) & 0x01) - { - rt_uint32_t errtype; - errtype = (IntStatus >> 16); - if(errtype & 0x1F && lpccan2.status.lasterrtype == (errtype & 0x1F)) { - switch((errtype & 0x1F)) { - case 00011: // Start of Frame - case 00010: // ID28 ... ID21 - case 00110: //ID20 ... ID18 - case 00100: // SRTR Bit - case 00101: // IDE bit - case 00111: // ID17 ... 13 - case 01111: // ID12 ... ID5 - case 01110: // ID4 ... ID0 - case 01100: // RTR Bit - case 01011: // Data Length Code - case 01010: // Data Field - lpccan2.status.formaterrcnt++; - break; - case 01101: // Reserved Bit 1 - case 01001: // Reserved Bit 0 - lpccan2.status.bitpaderrcnt++; - break; - case 01000: // CRC Sequence - case 11000: // CRC Delimiter - lpccan2.status.crcerrcnt++; - break; - case 11001: // Acknowledge Slot - case 11011: // Acknowledge Delimiter - lpccan2.status.ackerrcnt++; - break; - case 11010: // End of Frame - case 10010: // Intermission - lpccan2.status.formaterrcnt++; - break; - } - lpccan2.status.lasterrtype = errtype & 0x1F; - } - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_2, CANCTRL_GLOBAL_STS); - lpccan2.status.rcverrcnt = (state >> 16) & 0xFF; - lpccan2.status.snderrcnt = (state >> 24) & 0xFF; - lpccan2.status.errcode = (state >> 5) & 0x06; - } - //check Data Overrun Interrupt Interrupt - if((IntStatus >> 3) & 0x01) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8); - } - //check Transmit Interrupt interrupt2 - if((IntStatus >> 9) & 0x01) - { - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS); - if(state & (0x01 << 11)) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8); - } else { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8); - } - } - //check Transmit Interrupt interrupt3 - if((IntStatus >> 10) & 0x01) - { - rt_uint32_t state = 0; - state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS); - if(state & (0x01 << 19)) - { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8); - } else { - rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8); - } - } + IntStatus = CAN_IntGetStatus(CAN_2); + //check receive interrupt + if((IntStatus >> 0) & 0x01) + { + rt_hw_can_isr(&lpccan2,RT_CAN_EVENT_RX_IND | 0<<8); + } + //check Transmit Interrupt interrupt1 + if((IntStatus >> 1) & 0x01) + { + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS); + if(state & (0x01 << 3)) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 0<<8); + } + else + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 0<<8); + } + } + + //check Error Warning Interrupt + if((IntStatus >> 2) & 0x01) + { + rt_uint32_t errtype; + errtype = (IntStatus >> 16); + if(errtype & 0x1F && lpccan2.status.lasterrtype == (errtype & 0x1F)) + { + switch((errtype & 0x1F)) + { + case 00011: // Start of Frame + case 00010: // ID28 ... ID21 + case 00110: //ID20 ... ID18 + case 00100: // SRTR Bit + case 00101: // IDE bit + case 00111: // ID17 ... 13 + case 01111: // ID12 ... ID5 + case 01110: // ID4 ... ID0 + case 01100: // RTR Bit + case 01011: // Data Length Code + case 01010: // Data Field + lpccan2.status.formaterrcnt++; + break; + case 01101: // Reserved Bit 1 + case 01001: // Reserved Bit 0 + lpccan2.status.bitpaderrcnt++; + break; + case 01000: // CRC Sequence + case 11000: // CRC Delimiter + lpccan2.status.crcerrcnt++; + break; + case 11001: // Acknowledge Slot + case 11011: // Acknowledge Delimiter + lpccan2.status.ackerrcnt++; + break; + case 11010: // End of Frame + case 10010: // Intermission + lpccan2.status.formaterrcnt++; + break; + } + lpccan2.status.lasterrtype = errtype & 0x1F; + } + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_2, CANCTRL_GLOBAL_STS); + lpccan2.status.rcverrcnt = (state >> 16) & 0xFF; + lpccan2.status.snderrcnt = (state >> 24) & 0xFF; + lpccan2.status.errcode = (state >> 5) & 0x06; + } + + //check Data Overrun Interrupt Interrupt + if((IntStatus >> 3) & 0x01) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_RXOF_IND | 0<<8); + } + + //check Transmit Interrupt interrupt2 + if((IntStatus >> 9) & 0x01) + { + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS); + if(state & (0x01 << 11)) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 1<<8); + } + else + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 1<<8); + } + } + + //check Transmit Interrupt interrupt3 + if((IntStatus >> 10) & 0x01) + { + rt_uint32_t state = 0; + state = CAN_GetCTRLStatus(CAN_2, CANCTRL_STS); + if(state & (0x01 << 19)) + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_DONE | 2<<8); + } + else + { + rt_hw_can_isr(&lpccan1,RT_CAN_EVENT_TX_FAIL | 2<<8); + } + } #endif /*RT_USING_LPCCAN2*/ } + int lpc_can_init(void) { #ifdef RT_USING_LPCCAN1 - lpccan1.config.baud_rate=CAN1MBaud; - lpccan1.config.msgboxsz=16; - lpccan1.config.sndboxnumber=3; - lpccan1.config.mode=RT_CAN_MODE_NORMAL; - lpccan1.config.privmode=0; + lpccan1.config.baud_rate=CAN1MBaud; + lpccan1.config.msgboxsz=16; + lpccan1.config.sndboxnumber=3; + lpccan1.config.mode=RT_CAN_MODE_NORMAL; + lpccan1.config.privmode=0; + #ifdef RT_CAN_USING_LED -#endif - lpccan1.config.ticks = 50; -#ifdef RT_CAN_USING_HDR -#endif - //Enable CAN Interrupt - NVIC_EnableIRQ(CAN_IRQn); - rt_hw_can_register(&lpccan1, "lpccan1", &canops, &lpccandata1); #endif + lpccan1.config.ticks = 50; + +#ifdef RT_CAN_USING_HDR +#endif + + //Enable CAN Interrupt + NVIC_EnableIRQ(CAN_IRQn); + rt_hw_can_register(&lpccan1, "lpccan1", &canops, &lpccandata1); +#endif /*RT_USING_LPCCAN1*/ + #ifdef RT_USING_LPCCAN2 - lpccan2.config.baud_rate=CAN1MBaud; - lpccan2.config.msgboxsz=16; - lpccan2.config.sndboxnumber=3; - lpccan2.config.mode=RT_CAN_MODE_NORMAL; - lpccan2.config.privmode=0; + lpccan2.config.baud_rate=CAN1MBaud; + lpccan2.config.msgboxsz=16; + lpccan2.config.sndboxnumber=3; + lpccan2.config.mode=RT_CAN_MODE_NORMAL; + lpccan2.config.privmode=0; + #ifdef RT_CAN_USING_LED -#endif - lpccan2.config.ticks = 50; +#endif + + lpccan2.config.ticks = 50; + #ifdef RT_CAN_USING_HDR #endif -#ifndef RT_USING_LPCCAN1 - //Enable CAN Interrupt - NVIC_EnableIRQ(CAN_IRQn); -#endif + + //Enable CAN Interrupt + NVIC_EnableIRQ(CAN_IRQn); + #ifdef RT_CAN_USING_HDR #endif - rt_hw_can_register(&lpccan2, "lpccan2", &canops, &lpccandata2); -#endif - return RT_EOK; + + rt_hw_can_register(&lpccan2, "lpccan2", &canops, &lpccandata2); +#endif /*RT_USING_LPCCAN2*/ + + return RT_EOK; } INIT_BOARD_EXPORT(lpc_can_init); diff --git a/components/drivers/include/drivers/can.h b/components/drivers/include/drivers/can.h index 9323443c1..71b577eba 100644 --- a/components/drivers/include/drivers/can.h +++ b/components/drivers/include/drivers/can.h @@ -37,15 +37,15 @@ enum CANBAUD { - CAN1MBaud = 0, /* 1 MBit/sec */ - CAN800kBaud, /* 800 kBit/sec */ - CAN500kBaud, /* 500 kBit/sec */ - CAN250kBaud, /* 250 kBit/sec */ - CAN125kBaud, /* 125 kBit/sec */ - CAN100kBaud, /* 100 kBit/sec */ - CAN50kBaud, /* 50 kBit/sec */ - CAN20kBaud, /* 20 kBit/sec */ - CAN10kBaud /* 10 kBit/sec */ + CAN1MBaud = 1000UL * 1000,/* 1 MBit/sec */ + CAN800kBaud = 1000UL * 800, /* 800 kBit/sec */ + CAN500kBaud = 1000UL * 500, /* 500 kBit/sec */ + CAN250kBaud = 1000UL * 250, /* 250 kBit/sec */ + CAN125kBaud = 1000UL * 125, /* 125 kBit/sec */ + CAN100kBaud = 1000UL * 100, /* 100 kBit/sec */ + CAN50kBaud = 1000UL * 50, /* 50 kBit/sec */ + CAN20kBaud = 1000UL * 20, /* 20 kBit/sec */ + CAN10kBaud = 1000UL * 10 /* 10 kBit/sec */ }; #define RT_CAN_MODE_NORMAL 0