diff --git a/drivers/include/drivers/RawCAN.h b/drivers/include/drivers/RawCAN.h new file mode 100644 index 0000000..9a1ed64 --- /dev/null +++ b/drivers/include/drivers/RawCAN.h @@ -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 \ No newline at end of file diff --git a/drivers/source/RawCAN.cpp b/drivers/source/RawCAN.cpp new file mode 100644 index 0000000..89ea776 --- /dev/null +++ b/drivers/source/RawCAN.cpp @@ -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 \ No newline at end of file diff --git a/mbed.h b/mbed.h index dc20a69..896000a 100644 --- a/mbed.h +++ b/mbed.h @@ -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" diff --git a/targets/TARGET_STM/TARGET_STM32F0/objects.h b/targets/TARGET_STM/TARGET_STM32F0/objects.h index 08c0e50..f6c0820 100644 --- a/targets/TARGET_STM/TARGET_STM32F0/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F0/objects.h @@ -152,6 +152,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/objects.h b/targets/TARGET_STM/TARGET_STM32F1/objects.h index a85c815..5c2108c 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F1/objects.h @@ -142,6 +142,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/objects.h b/targets/TARGET_STM/TARGET_STM32F2/objects.h index 98eb64d..fefdfec 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F2/objects.h @@ -151,6 +151,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/objects.h b/targets/TARGET_STM/TARGET_STM32F3/objects.h index 088aa8b..a5489d0 100644 --- a/targets/TARGET_STM/TARGET_STM32F3/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F3/objects.h @@ -139,6 +139,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/objects.h b/targets/TARGET_STM/TARGET_STM32F4/objects.h index 6042c82..73eb6e6 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/objects.h @@ -154,6 +154,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/objects.h b/targets/TARGET_STM/TARGET_STM32F7/objects.h index 3e485fb..006e4f3 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F7/objects.h @@ -163,6 +163,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/objects.h b/targets/TARGET_STM/TARGET_STM32L4/objects.h index 1644691..eab7c05 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L4/objects.h @@ -153,6 +153,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/TARGET_STM32L5/objects.h b/targets/TARGET_STM/TARGET_STM32L5/objects.h index 195fcc2..fb8af8d 100644 --- a/targets/TARGET_STM/TARGET_STM32L5/objects.h +++ b/targets/TARGET_STM/TARGET_STM32L5/objects.h @@ -153,6 +153,7 @@ CAN_HandleTypeDef CanHandle; int index; int hz; + int rxIrqStatus; }; #endif diff --git a/targets/TARGET_STM/can_api.c b/targets/TARGET_STM/can_api.c index 0843ba8..3893735 100644 --- a/targets/TARGET_STM/can_api.c +++ b/targets/TARGET_STM/can_api.c @@ -651,7 +651,6 @@ 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 @@ { irq_handler = handler; can_irq_ids[obj->index] = id; + obj->rxIrqStatus = false; } void can_irq_free(can_t *obj) @@ -771,7 +771,7 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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;