mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Added Raw CAN (unlocked can read api) and updated the code for the
rxInterrupt to work for all CAN instancespull/14688/head
							parent
							
								
									033b08de19
								
							
						
					
					
						commit
						1a2d624828
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
								
								
								
								
							
							
						
						
									
										1
									
								
								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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -152,6 +152,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -142,6 +142,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,6 +151,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,6 +139,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,6 +154,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,6 +163,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,6 +153,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,6 +153,7 @@ struct can_s {
 | 
			
		|||
    CAN_HandleTypeDef CanHandle;
 | 
			
		||||
    int index;
 | 
			
		||||
    int hz;
 | 
			
		||||
    int rxIrqStatus;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue