fix for mbed lib issue 3 (i2c problem) see also https://mbed.org/users/mbed_official/code/mbed/issues/3 affected implementations: LPC812, LPC11U24, LPC1768, LPC2368, LPC4088

Fork of mbed-src by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CAN.cpp Source File

CAN.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #include "CAN.h"
00017 
00018 #if DEVICE_CAN
00019 
00020 #include "cmsis.h"
00021 
00022 namespace mbed {
00023 
00024 CAN::CAN(PinName rd, PinName td) {
00025     can_init(&_can, rd, td);
00026 }
00027 
00028 CAN::~CAN() {
00029     can_free(&_can);
00030 }
00031 
00032 int CAN::frequency(int f) {
00033     return can_frequency(&_can, f);
00034 }
00035 
00036 int CAN::write(CANMessage msg) {
00037     return can_write(&_can, msg, 0);
00038 }
00039 
00040 int CAN::read(CANMessage &msg) {
00041     return can_read(&_can, &msg);
00042 }
00043 
00044 void CAN::reset() {
00045     can_reset(&_can);
00046 }
00047 
00048 unsigned char CAN::rderror() {
00049     return can_rderror(&_can);
00050 }
00051 
00052 unsigned char CAN::tderror() {
00053     return can_tderror(&_can);
00054 }
00055 
00056 void CAN::monitor(bool silent) {
00057     can_monitor(&_can, (silent) ? 1 : 0);
00058 }
00059 
00060 static FunctionPointer* can_obj[2] = { NULL };
00061 
00062 // Have to check that the CAN block is active before reading the Interrupt
00063 // Control Register, or the mbed hangs
00064 void can_irq(void) {
00065     uint32_t icr;
00066 
00067     if(LPC_SC->PCONP & (1 << 13)) {
00068         icr = LPC_CAN1->ICR;
00069 
00070         if(icr && (can_obj[0] != NULL)) {
00071             can_obj[0]->call();
00072         }
00073     }
00074 
00075     if(LPC_SC->PCONP & (1 << 14)) {
00076         icr = LPC_CAN2->ICR;
00077         if(icr && (can_obj[1] != NULL)) {
00078             can_obj[1]->call();
00079         }
00080     }
00081 
00082 }
00083 
00084 void CAN::setup_interrupt(void) {
00085     switch ((int)_can.dev) {
00086         case CAN_1: can_obj[0] = &_rxirq; break;
00087         case CAN_2: can_obj[1] = &_rxirq; break;
00088     }
00089     _can.dev->MOD |= 1;
00090     _can.dev->IER |= 1;
00091     _can.dev->MOD &= ~1;
00092     NVIC_SetVector(CAN_IRQn , (uint32_t) &can_irq);
00093     NVIC_EnableIRQ(CAN_IRQn );
00094 }
00095 
00096 void CAN::remove_interrupt(void) {
00097     switch ((int)_can.dev) {
00098         case CAN_1: can_obj[0] = NULL; break;
00099         case CAN_2: can_obj[1] = NULL; break;
00100     }
00101 
00102     _can.dev->IER &= ~(1);
00103     if ((can_obj[0] == NULL) && (can_obj[1] == NULL)) {
00104         NVIC_DisableIRQ(CAN_IRQn );
00105     }
00106 }
00107 
00108 void CAN::attach(void (*fptr)(void)) {
00109     if (fptr != NULL) {
00110         _rxirq.attach(fptr);
00111         setup_interrupt();
00112     } else {
00113         remove_interrupt();
00114     }
00115 }
00116 
00117 } // namespace mbed
00118 
00119 #endif