Tentative KL25Z I2C HAL fix

Fork of mbed-src by mbed official

Committer:
bogdanm
Date:
Mon Aug 05 14:12:34 2013 +0300
Revision:
13:0645d8841f51
Parent:
10:3bc89ef62ce7
Update mbed sources to revision 64

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 13:0645d8841f51 1 /* mbed Microcontroller Library
bogdanm 13:0645d8841f51 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 13:0645d8841f51 3 *
bogdanm 13:0645d8841f51 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 13:0645d8841f51 5 * you may not use this file except in compliance with the License.
bogdanm 13:0645d8841f51 6 * You may obtain a copy of the License at
bogdanm 13:0645d8841f51 7 *
bogdanm 13:0645d8841f51 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 13:0645d8841f51 9 *
bogdanm 13:0645d8841f51 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 13:0645d8841f51 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 13:0645d8841f51 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 13:0645d8841f51 13 * See the License for the specific language governing permissions and
bogdanm 13:0645d8841f51 14 * limitations under the License.
bogdanm 13:0645d8841f51 15 */
bogdanm 13:0645d8841f51 16 #include "CAN.h"
bogdanm 13:0645d8841f51 17
bogdanm 13:0645d8841f51 18 #if DEVICE_CAN
bogdanm 13:0645d8841f51 19
bogdanm 13:0645d8841f51 20 #include "cmsis.h"
bogdanm 13:0645d8841f51 21
bogdanm 13:0645d8841f51 22 namespace mbed {
bogdanm 13:0645d8841f51 23
bogdanm 13:0645d8841f51 24 CAN::CAN(PinName rd, PinName td) {
bogdanm 13:0645d8841f51 25 can_init(&_can, rd, td);
bogdanm 13:0645d8841f51 26 }
bogdanm 13:0645d8841f51 27
bogdanm 13:0645d8841f51 28 CAN::~CAN() {
bogdanm 13:0645d8841f51 29 can_free(&_can);
bogdanm 13:0645d8841f51 30 }
bogdanm 13:0645d8841f51 31
bogdanm 13:0645d8841f51 32 int CAN::frequency(int f) {
bogdanm 13:0645d8841f51 33 return can_frequency(&_can, f);
bogdanm 13:0645d8841f51 34 }
bogdanm 13:0645d8841f51 35
bogdanm 13:0645d8841f51 36 int CAN::write(CANMessage msg) {
bogdanm 13:0645d8841f51 37 return can_write(&_can, msg, 0);
bogdanm 13:0645d8841f51 38 }
bogdanm 13:0645d8841f51 39
bogdanm 13:0645d8841f51 40 int CAN::read(CANMessage &msg) {
bogdanm 13:0645d8841f51 41 return can_read(&_can, &msg);
bogdanm 13:0645d8841f51 42 }
bogdanm 13:0645d8841f51 43
bogdanm 13:0645d8841f51 44 void CAN::reset() {
bogdanm 13:0645d8841f51 45 can_reset(&_can);
bogdanm 13:0645d8841f51 46 }
bogdanm 13:0645d8841f51 47
bogdanm 13:0645d8841f51 48 unsigned char CAN::rderror() {
bogdanm 13:0645d8841f51 49 return can_rderror(&_can);
bogdanm 13:0645d8841f51 50 }
bogdanm 13:0645d8841f51 51
bogdanm 13:0645d8841f51 52 unsigned char CAN::tderror() {
bogdanm 13:0645d8841f51 53 return can_tderror(&_can);
bogdanm 13:0645d8841f51 54 }
bogdanm 13:0645d8841f51 55
bogdanm 13:0645d8841f51 56 void CAN::monitor(bool silent) {
bogdanm 13:0645d8841f51 57 can_monitor(&_can, (silent) ? 1 : 0);
bogdanm 13:0645d8841f51 58 }
bogdanm 13:0645d8841f51 59
bogdanm 13:0645d8841f51 60 static FunctionPointer* can_obj[2] = { NULL };
bogdanm 13:0645d8841f51 61
bogdanm 13:0645d8841f51 62 // Have to check that the CAN block is active before reading the Interrupt
bogdanm 13:0645d8841f51 63 // Control Register, or the mbed hangs
bogdanm 13:0645d8841f51 64 void can_irq(void) {
bogdanm 13:0645d8841f51 65 uint32_t icr;
bogdanm 13:0645d8841f51 66
bogdanm 13:0645d8841f51 67 if(LPC_SC->PCONP & (1 << 13)) {
bogdanm 13:0645d8841f51 68 icr = LPC_CAN1->ICR;
bogdanm 13:0645d8841f51 69
bogdanm 13:0645d8841f51 70 if(icr && (can_obj[0] != NULL)) {
bogdanm 13:0645d8841f51 71 can_obj[0]->call();
bogdanm 13:0645d8841f51 72 }
bogdanm 13:0645d8841f51 73 }
bogdanm 13:0645d8841f51 74
bogdanm 13:0645d8841f51 75 if(LPC_SC->PCONP & (1 << 14)) {
bogdanm 13:0645d8841f51 76 icr = LPC_CAN2->ICR;
bogdanm 13:0645d8841f51 77 if(icr && (can_obj[1] != NULL)) {
bogdanm 13:0645d8841f51 78 can_obj[1]->call();
bogdanm 13:0645d8841f51 79 }
bogdanm 13:0645d8841f51 80 }
bogdanm 13:0645d8841f51 81
bogdanm 13:0645d8841f51 82 }
bogdanm 13:0645d8841f51 83
bogdanm 13:0645d8841f51 84 void CAN::setup_interrupt(void) {
bogdanm 13:0645d8841f51 85 switch ((int)_can.dev) {
bogdanm 13:0645d8841f51 86 case CAN_1: can_obj[0] = &_rxirq; break;
bogdanm 13:0645d8841f51 87 case CAN_2: can_obj[1] = &_rxirq; break;
bogdanm 13:0645d8841f51 88 }
bogdanm 13:0645d8841f51 89 _can.dev->MOD |= 1;
bogdanm 13:0645d8841f51 90 _can.dev->IER |= 1;
bogdanm 13:0645d8841f51 91 _can.dev->MOD &= ~1;
bogdanm 13:0645d8841f51 92 NVIC_SetVector(CAN_IRQn, (uint32_t) &can_irq);
bogdanm 13:0645d8841f51 93 NVIC_EnableIRQ(CAN_IRQn);
bogdanm 13:0645d8841f51 94 }
bogdanm 13:0645d8841f51 95
bogdanm 13:0645d8841f51 96 void CAN::remove_interrupt(void) {
bogdanm 13:0645d8841f51 97 switch ((int)_can.dev) {
bogdanm 13:0645d8841f51 98 case CAN_1: can_obj[0] = NULL; break;
bogdanm 13:0645d8841f51 99 case CAN_2: can_obj[1] = NULL; break;
bogdanm 13:0645d8841f51 100 }
bogdanm 13:0645d8841f51 101
bogdanm 13:0645d8841f51 102 _can.dev->IER &= ~(1);
bogdanm 13:0645d8841f51 103 if ((can_obj[0] == NULL) && (can_obj[1] == NULL)) {
bogdanm 13:0645d8841f51 104 NVIC_DisableIRQ(CAN_IRQn);
bogdanm 13:0645d8841f51 105 }
bogdanm 13:0645d8841f51 106 }
bogdanm 13:0645d8841f51 107
bogdanm 13:0645d8841f51 108 void CAN::attach(void (*fptr)(void)) {
bogdanm 13:0645d8841f51 109 if (fptr != NULL) {
bogdanm 13:0645d8841f51 110 _rxirq.attach(fptr);
bogdanm 13:0645d8841f51 111 setup_interrupt();
bogdanm 13:0645d8841f51 112 } else {
bogdanm 13:0645d8841f51 113 remove_interrupt();
bogdanm 13:0645d8841f51 114 }
bogdanm 13:0645d8841f51 115 }
bogdanm 13:0645d8841f51 116
bogdanm 13:0645d8841f51 117 } // namespace mbed
bogdanm 13:0645d8841f51 118
bogdanm 13:0645d8841f51 119 #endif