Lancaster University's (short term!) clone of mbed-src for micro:bit. This is a copy of the github branch https://github.com/lancaster-university/mbed-classic

Fork of mbed-src by mbed official

Committer:
emilmont
Date:
Fri Jun 14 17:49:17 2013 +0100
Revision:
10:3bc89ef62ce7
Parent:
9:0ce32e54c9a7
Child:
13:0645d8841f51
Unify mbed library sources

Who changed what in which revision?

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