Added Raw CAN (unlocked can read api) and updated the code for the

rxInterrupt to work for all CAN instances
pull/14688/head
Mohammed Mubeen 2021-06-29 12:46:21 +05:30
parent 033b08de19
commit 1a2d624828
12 changed files with 126 additions and 7 deletions

View File

@ -0,0 +1,69 @@
/* mbed Microcontroller Library
* Copyright (c) 2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef RAWCAN_H
#define RAWCAN_H
#include "platform/platform.h"
#include "drivers/CAN.h"
#if DEVICE_CAN || defined(DOXYGEN_ONLY)
#include "interfaces/InterfaceCAN.h"
#include "hal/can_api.h"
#include "platform/Callback.h"
#include "platform/PlatformMutex.h"
namespace mbed {
class RawCAN: public CAN {
public:
RawCAN(PinName rd, PinName td);
/** Initialize CAN interface and set the frequency
*
* @param rd the read pin
* @param td the transmit pin
* @param hz the bus frequency in hertz
*/
RawCAN(PinName rd, PinName td, int hz);
/** Initialize CAN interface
*
* @param pinmap reference to structure which holds static pinmap
* @param td the transmit pin
* @param hz the bus frequency in hertz
*/
virtual ~RawCAN() {};
/** Read a CANMessage from the bus.
*
* @param msg A CANMessage to read to.
* @param handle message filter handle (0 for any message)
*
* @returns
* 0 if no message arrived,
* 1 if message arrived
*/
int read(CANMessage &msg, int handle = 0);
};
} //namespace mbed
#endif
#endif //RAWCAN_H

41
drivers/source/RawCAN.cpp Normal file
View File

@ -0,0 +1,41 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2019 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "drivers/RawCan.h"
#if DEVICE_CAN
#include "platform/mbed_power_mgmt.h"
namespace mbed {
RawCAN::RawCAN(PinName rd, PinName td): CAN(rd, td) {}
RawCAN::RawCAN(PinName rd, PinName td, int hz): CAN(rd, td, hz) {}
/* There are situations where the RX interrupt of CAN are cleared only by
* CAN read operations and locks are not allowed in ISR context in mbed
* hence this provides an unlocked read to resolve such problem without
* any effect on the performance. This will work only in case of a single
* thread accessing a CAN instance, multiple threads will lead to race conditions
*/
int RawCAN::read(CANMessage &msg, int handle){
int ret = can_read(&_can, &msg, handle);
return ret;
}
} // namespace
#endif //DEVICE_CAN

1
mbed.h
View File

@ -68,6 +68,7 @@
#include "drivers/I2C.h"
#include "drivers/I2CSlave.h"
#include "drivers/CAN.h"
#include "drivers/RawCAN.h"
#include "drivers/UnbufferedSerial.h"
#include "drivers/BufferedSerial.h"
#include "drivers/FlashIAP.h"

View File

@ -152,6 +152,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -142,6 +142,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -151,6 +151,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -139,6 +139,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -154,6 +154,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -163,6 +163,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -153,6 +153,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -153,6 +153,7 @@ struct can_s {
CAN_HandleTypeDef CanHandle;
int index;
int hz;
int rxIrqStatus;
};
#endif

View File

@ -651,7 +651,6 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
static uint32_t can_irq_ids[CAN_NUM] = {0};
static can_irq_handler irq_handler;
static uint32_t rx_irq_status = DISABLED;
static void can_registers_init(can_t *obj)
{
@ -762,6 +761,7 @@ void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id)
{
irq_handler = handler;
can_irq_ids[obj->index] = id;
obj->rxIrqStatus = false;
}
void can_irq_free(can_t *obj)
@ -771,7 +771,7 @@ void can_irq_free(can_t *obj)
can->IER &= ~(CAN_IT_FMP0 | CAN_IT_FMP1 | CAN_IT_TME | \
CAN_IT_ERR | CAN_IT_EPV | CAN_IT_BOF);
can_irq_ids[obj->index] = 0;
rx_irq_status = DISABLED;
obj->rxIrqStatus = DISABLED;
}
void can_free(can_t *obj)
@ -1003,7 +1003,7 @@ int can_read(can_t *obj, CAN_Message *msg, int handle)
can->RF1R |= CAN_RF1R_RFOM1;
}
if(rx_irq_status == ENABLED) {
if(obj->rxIrqStatus == ENABLED) {
__HAL_CAN_ENABLE_IT(&obj->CanHandle, CAN_IT_FMP0);
}
@ -1020,7 +1020,7 @@ void can_reset(can_t *obj)
/* restore registers state as saved in obj context */
can_registers_init(obj);
rx_irq_status = DISABLED;
obj->rxIrqStatus = DISABLED;
}
unsigned char can_rderror(can_t *obj)
@ -1276,7 +1276,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
ier = CAN_IT_FMP0;
irq_n = CAN1_IRQ_RX_IRQN;
vector = (uint32_t)&CAN1_IRQ_RX_VECT;
rx_irq_status = ENABLED;
obj->rxIrqStatus = ENABLED;
break;
case IRQ_TX:
ier = CAN_IT_TME;
@ -1309,7 +1309,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
ier = CAN_IT_FMP0;
irq_n = CAN2_IRQ_RX_IRQN;
vector = (uint32_t)&CAN2_IRQ_RX_VECT;
rx_irq_status = ENABLED;
obj->rxIrqStatus = ENABLED;
break;
case IRQ_TX:
ier = CAN_IT_TME;
@ -1343,7 +1343,7 @@ void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable)
ier = CAN_IT_FMP0;
irq_n = CAN3_IRQ_RX_IRQN;
vector = (uint32_t)&CAN3_IRQ_RX_VECT;
rx_irq_status = ENABLED;
obj->rxIrqStatus = ENABLED;
break;
case IRQ_TX:
ier = CAN_IT_TME;