etisserant@375: /* etisserant@375: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@375: etisserant@375: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@375: AVR Port: Andreas GLAUSER and Peter CHRISTEN etisserant@375: etisserant@375: See COPYING file for copyrights details. etisserant@375: etisserant@375: This library is free software; you can redistribute it and/or etisserant@375: modify it under the terms of the GNU Lesser General Public etisserant@375: License as published by the Free Software Foundation; either etisserant@375: version 2.1 of the License, or (at your option) any later version. etisserant@375: etisserant@375: This library is distributed in the hope that it will be useful, etisserant@375: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@375: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@375: Lesser General Public License for more details. etisserant@375: etisserant@375: You should have received a copy of the GNU Lesser General Public etisserant@375: License along with this library; if not, write to the Free Software etisserant@375: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@375: */ etisserant@375: etisserant@375: //#define DEBUG_WAR_CONSOLE_ON etisserant@375: //#define DEBUG_ERR_CONSOLE_ON etisserant@375: etisserant@375: #include "can_AVR.h" etisserant@375: #include "canfestival.h" etisserant@375: etisserant@375: volatile unsigned char msg_received = 0; etisserant@375: etisserant@375: unsigned char canInit(unsigned int bitrate) etisserant@375: /****************************************************************************** etisserant@375: Initialize the hardware to receive CAN messages and start the timer for the etisserant@375: CANopen stack. etisserant@375: INPUT bitrate bitrate in kilobit etisserant@375: OUTPUT 1 if successful etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: unsigned char i,k; etisserant@375: //- Pull-up on TxCAN & RxCAN one by one to use bit-addressing etisserant@375: CAN_PORT_DIR &= ~(1< CAN frame etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: unsigned char i; etisserant@375: etisserant@375: for (i = START_TX_MOB; i < NB_MOB; i++) // Search the first free MOb etisserant@375: { etisserant@375: Can_set_mob(i); // Change to MOb etisserant@375: if ((CANCDMOB & CONMOB_MSK) == 0) // MOb disabled = free etisserant@375: { etisserant@375: break; etisserant@375: } etisserant@375: } etisserant@375: if (i < NB_MOB) // free MOb found etisserant@375: { etisserant@375: Can_set_mob(i); // Switch to the sending messagebox etisserant@375: Can_set_std_id(m->cob_id); // Set cob id etisserant@375: if (m->rtr) // Set remote transmission request etisserant@375: Can_set_rtr(); etisserant@375: Can_set_dlc(m->len); // Set data lenght code etisserant@375: etisserant@375: for (i= 0; i < (m->len); i++) // Add data bytes to the MOb etisserant@375: CANMSG = m->data[i]; etisserant@375: // Start sending by writing the MB configuration register to transmit etisserant@375: Can_config_tx(); // Set the last MOb to transmit mode etisserant@375: return 1; // succesful etisserant@375: } etisserant@375: else etisserant@375: return 0; // not succesful etisserant@375: } etisserant@375: etisserant@375: unsigned char canReceive(Message *m) etisserant@375: /****************************************************************************** etisserant@375: The driver pass a received CAN message to the stack etisserant@375: INPUT Message *m pointer to received CAN message etisserant@375: OUTPUT 1 if a message received etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: unsigned char i; etisserant@375: etisserant@375: if (msg_received == 0) etisserant@375: return 0; // Nothing received etisserant@375: etisserant@375: for (i = 0; i < NB_RX_MOB; i++) // Search the first MOb received etisserant@375: { etisserant@375: Can_set_mob(i); // Change to MOb etisserant@375: if ((CANCDMOB & CONMOB_MSK) == 0) // MOb disabled = received etisserant@375: { etisserant@375: msg_received--; etisserant@375: break; etisserant@375: } etisserant@375: } etisserant@375: if (i < NB_RX_MOB) // message found etisserant@375: { etisserant@375: Can_get_std_id(m->cob_id); // Get cob id etisserant@375: m->rtr = Can_get_rtr(); // Get remote transmission request etisserant@375: m->len = Can_get_dlc(); // Get data lenght code etisserant@375: for (i= 0; i < (m->len); i++) // get data bytes from the MOb etisserant@375: m->data[i] = CANMSG; etisserant@375: Can_config_rx_buffer(); // reset the MOb for receive etisserant@375: return 1; // message received etisserant@375: } etisserant@375: else // no message found etisserant@375: { etisserant@375: msg_received = 0; // reset counter etisserant@375: return 0; // no message received etisserant@375: } etisserant@375: } etisserant@375: groke6@384: /***************************************************************************/ groke6@384: unsigned char canChangeBaudRate_driver( CAN_HANDLE fd, char* baud) groke6@384: { groke6@384: groke6@384: return 0; groke6@384: } groke6@384: etisserant@375: #ifdef __IAR_SYSTEMS_ICC__ etisserant@375: #pragma type_attribute = __interrupt etisserant@375: #pragma vector=CANIT_vect etisserant@375: void CANIT_interrupt(void) etisserant@375: #else // GCC etisserant@375: ISR(CANIT_vect) etisserant@375: #endif // GCC etisserant@375: /****************************************************************************** etisserant@375: CAN Interrupt etisserant@375: ******************************************************************************/ etisserant@375: { edouard@601: unsigned char saved_page = CANPAGE; etisserant@375: unsigned char i; etisserant@375: etisserant@375: if (CANGIT & (1 << CANIT)) // is a messagebox interrupt etisserant@375: { etisserant@375: if ((CANSIT1 & TX_INT_MSK) == 0) // is a Rx interrupt etisserant@375: { etisserant@375: for (i = 0; (i < NB_RX_MOB) && (CANGIT & (1 << CANIT)); i++) // Search the first MOb received etisserant@375: { etisserant@375: Can_set_mob(i); // Change to MOb etisserant@375: if (CANSTMOB & MOB_RX_COMPLETED) // receive ok etisserant@375: { etisserant@375: Can_clear_status_mob(); // Clear status register etisserant@375: Can_mob_abort(); // disable the MOb = received etisserant@375: msg_received++; etisserant@375: } etisserant@375: else if (CANSTMOB & ~MOB_RX_COMPLETED) // error etisserant@375: { etisserant@375: Can_clear_status_mob(); // Clear status register etisserant@375: Can_config_rx_buffer(); // reconfigure as receive buffer etisserant@375: } etisserant@375: } etisserant@375: } etisserant@375: else // is a Tx interrupt etisserant@375: { etisserant@375: for (i = NB_RX_MOB; i < NB_MOB; i++) // Search the first MOb transmitted etisserant@375: { etisserant@375: Can_set_mob(i); // change to MOb etisserant@375: if (CANSTMOB) // transmission ok or error etisserant@375: { etisserant@375: Can_clear_status_mob(); // clear status register etisserant@375: CANCDMOB = 0; // disable the MOb etisserant@375: break; etisserant@375: } etisserant@375: } etisserant@375: } etisserant@375: } etisserant@375: edouard@601: CANPAGE = saved_page; edouard@601: etisserant@375: // Bus Off Interrupt Flag etisserant@375: if (CANGIT & (1 << BOFFIT)) // Finaly clear the interrupt status register etisserant@375: { etisserant@375: CANGIT |= (1 << BOFFIT); // Clear the interrupt flag etisserant@375: } etisserant@375: else etisserant@375: CANGIT |= (1 << BXOK) | (1 << SERG) | (1 << CERG) | (1 << FERG) | (1 << AERG);// Finaly clear other interrupts etisserant@375: } etisserant@375: etisserant@375: #ifdef __IAR_SYSTEMS_ICC__ etisserant@375: #pragma type_attribute = __interrupt etisserant@375: #pragma vector=OVRIT_vect etisserant@375: void OVRIT_interrupt(void) etisserant@375: #else // GCC etisserant@375: ISR(OVRIT_vect) etisserant@375: #endif // GCC etisserant@375: /****************************************************************************** etisserant@375: CAN Timer Interrupt etisserant@375: ******************************************************************************/ etisserant@375: { etisserant@375: CANGIT |= (1 << OVRTIM); etisserant@375: } etisserant@375: