SAMV71 Xplained Ultra Software Package 1.4

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2015, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 /**
00031  *  \page mcan Controller Area Network (CAN) Example using MCAN
00032  *
00033  *  \section Purpose
00034  *
00035  *  The Controller Area Network (CAN) Example will help new users get familiar 
00036  *  with the MCAN peripheral used in Atmel's Samv7 family of microcontrollers. 
00037  *
00038  *  \section Requirements
00039  *
00040  *  This package can be used with SAMV7-Xplained Ultra.
00041  *
00042  *  \section Description
00043  *
00044  *  The demonstration program periodically transmits several different CAN
00045  *  messages.  The program enables CAN loopback mode so that the transmitted 
00046  *  messages are reflected back as received messages as well.  LED #0 is toggled
00047  *  on a successful transmission of one of the messages & LED #1 is toggles on a  
00048  *  successful reception of the same message.  Message transmission is stopped
00049  *  while SWITCH #0 is held depressed, which in turns means that both LED's 
00050  *  should stop blinking.  Depressing SWITCH #1 alternates between standard CAN
00051  *  operation and CAN-FD operation with bit rate switching. 
00052  *
00053  *  \section Usage
00054  *
00055  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00056  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00057  *  -# On the computer, open and configure a terminal application
00058  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00059  *    - 115200 bauds
00060  *    - 8 bits of data
00061  *    - No parity
00062  *    - 1 stop bit
00063  *    - No flow control
00064  *  -# Start the application.
00065  *  -# Two LEDs should start blinking on the board. In the terminal window, the
00066  *     following text should appear (values depend on the board and chip used):
00067  *     \code
00068  *      -- Controller Area Network (CAN) Example %s --\n\r", SOFTPACK_VERSION );
00069  *      -- xxxxxx-xx
00070  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00071  *      -- LED0 toggles on CAN message reception
00072  *      -- LED1 toggles on CAN message transmission
00073  *      -- CAN message transmission stopped while SW0 is pushed
00074  *      -- SW1 pushes alternate between standard CAN and CAN-FD
00075  *     \endcode
00076  * -# Both LEDs should stop blinking while Button #0 is held depressed.
00077  *
00078  *  \section References
00079  *  - main.c
00080  *  - pio.h
00081  *  - pio_it.h
00082  *  - led.h
00083  *  - trace.h
00084  */
00085 
00086 /** \file
00087  *
00088  *  This file contains all the specific code for the CAN example.
00089  *
00090  */
00091 
00092 /*----------------------------------------------------------------------------
00093  *        Headers
00094  *----------------------------------------------------------------------------*/
00095 
00096 #include "board.h"
00097 
00098 #include <stdbool.h>
00099 #include <stdio.h>
00100 
00101 /*----------------------------------------------------------------------------
00102  *        Local definitions
00103  *----------------------------------------------------------------------------*/
00104 
00105 #define MSG_ID_0           0x555       // standard ID
00106 #define MSG_ID_0_DATA1     0x81        // 1 byte message
00107 #define MSG_ID_1           0x11111111  // extended ID
00108 #define MSG_ID_1_DATA1_4   0x55555555  // 8 byte message
00109 #define MSG_ID_1_DATA5_8   0x00FF00FF     
00110 #define MSG_ID_2           0x444       // standard ID
00111 #define MSG_ID_2_MASK      0x7FC       // bits 0 & 1 are don't care
00112 #define TX_BUFFER_0        0
00113 #define TX_BUFFER_1        1
00114 #define RX_BUFFER_0        0
00115 #define RX_BUFFER_1        1
00116 #define FILTER_0           0
00117 #define FILTER_1           1
00118 
00119 #define BUTTON_NOT_PUSHED  1
00120 #define BUTTON_PUSHED      0
00121 
00122 #define CAN_STANDARD       0
00123 #define CAN_FD             1
00124 
00125 /*----------------------------------------------------------------------------
00126  *        Local variables
00127  *----------------------------------------------------------------------------*/
00128 
00129 static const Pin pushbutton[] = { PIN_PUSHBUTTON_0, PIN_PUSHBUTTON_1 };
00130 
00131 volatile uint8_t tick = 0;
00132 
00133 uint32_t       txdCntr;
00134 uint32_t       rxdCntr;
00135 uint32_t       rxFifoCntr;
00136 uint32_t     * txMailbox0;
00137 uint32_t     * txMailbox1;
00138 Mailbox8Type   rxMailbox0;
00139 Mailbox8Type   rxMailbox1;
00140 Mailbox8Type   rxMailbox2;
00141 uint8_t        txData[8];
00142 
00143 /*----------------------------------------------------------------------------
00144  *        Local functions
00145  *----------------------------------------------------------------------------*/
00146 
00147 /* Handler for MCAN0, Line 0 */
00148 void MCAN0_Handler(void)
00149 {
00150 }
00151 
00152 /* Handler for MCAN0, Line 1 */
00153 void MCAN0_Line1_Handler(void)
00154 {
00155 }
00156 
00157 /* Handler for MCAN1, Line 0 */
00158 void MCAN1_Handler(void)
00159 {
00160 }
00161 
00162 /* Handler for MCAN1, Line 1 */
00163 void MCAN1_Line1_Handler(void)
00164 {
00165     if ( MCAN_IsMessageStoredToRxDedBuffer( &mcan1Config ) ) {
00166         MCAN_ClearMessageStoredToRxBuffer( &mcan1Config );
00167         if ( MCAN_IsNewDataInRxDedBuffer( &mcan1Config, RX_BUFFER_0 ) ) {
00168             MCAN_GetRxDedBuffer( &mcan1Config, RX_BUFFER_0, (Mailbox64Type *) 
00169                 &rxMailbox0 );
00170         // verify data
00171             if ( rxMailbox0.data[0] == MSG_ID_0_DATA1 ) {
00172                 // Toggle LED #0 To Indicate New Message Received in Interrupt
00173                 LED_Toggle( 0 );
00174                 rxdCntr++;
00175             }
00176         }
00177         if ( MCAN_IsNewDataInRxDedBuffer( &mcan1Config, RX_BUFFER_1 ) ) {
00178             MCAN_GetRxDedBuffer( &mcan1Config, RX_BUFFER_1, (Mailbox64Type *)
00179                 &rxMailbox1 );
00180         rxdCntr++;
00181         }
00182     }
00183 }
00184 
00185 /**
00186  *  Interrupt handler for TC0 interrupt. Toggles the state of LED\#2.
00187  */
00188 void TC0_Handler(void)
00189 {
00190     volatile uint32_t dummy;
00191     /* Clear status bit to acknowledge interrupt */
00192     dummy = TC0->TC_CHANNEL[ 0 ].TC_SR;
00193     tick = 1;
00194 }
00195 
00196 /**
00197  *  Configure Timer Counter 0 to generate an interrupt every 250ms.
00198  */
00199 static void _ConfigureTc(void)
00200 {
00201     uint32_t div;
00202     uint32_t tcclks;
00203 
00204     /** Enable peripheral clock. */
00205     PMC_EnablePeripheral(ID_TC0);
00206     /** Configure TC for a 4Hz frequency and trigger on RC compare. */
00207     TC_FindMckDivisor( 4, BOARD_MCK, &div, &tcclks, BOARD_MCK );  
00208 
00209     TC_Configure( TC0, 0, tcclks | TC_CMR_CPCTRG );
00210     TC0->TC_CHANNEL[ 0 ].TC_RC = ( BOARD_MCK / div ) / 4;
00211 
00212     /* Configure and enable interrupt on RC compare */
00213     NVIC_ClearPendingIRQ(TC0_IRQn);
00214     NVIC_EnableIRQ(TC0_IRQn);
00215 
00216     TC0->TC_CHANNEL[ 0 ].TC_IER = TC_IER_CPCS ;
00217 
00218     /** Start the counter */
00219     TC_Start( TC0, 0 );
00220 }
00221 
00222 /*----------------------------------------------------------------------------
00223  *        Exported functions
00224  *----------------------------------------------------------------------------*/
00225 /**
00226  *  \brief getting-started Application entry point.
00227  *
00228  *  \return Unused (ANSI-C compatibility).
00229  */
00230 extern int main( void )
00231 {
00232     uint32_t id_offset = 0;
00233     uint32_t fifo_entries;
00234     uint32_t button_state = BUTTON_PUSHED;
00235     uint32_t button_state2 = BUTTON_NOT_PUSHED;
00236     uint32_t can_mode = CAN_STANDARD;
00237     
00238 #if 0
00239     uint32_t keyboard;
00240     uint32_t loopback = 1;  // default to loop-back ON
00241 #endif
00242     
00243     /* Disable watchdog */
00244     WDT_Disable( WDT ) ;
00245 
00246     /* Output example information */
00247     printf( "\n\r-- Controller Area Network (CAN) Example %s --\n\r",
00248             SOFTPACK_VERSION );
00249     printf( "-- %s\n\r", BOARD_NAME );
00250     printf( "-- Compiled: %s %s --\n\r\n\r", __DATE__, __TIME__ );
00251     printf( "-- LED0 toggles on CAN message reception\n\r" );
00252     printf( "-- LED1 toggles on CAN message transmission\n\r" );
00253     printf( "-- CAN message transmission stopped while SW0 is pushed\n\r" );
00254     printf( "-- SW1 pushes alternate between standard CAN and CAN-FD\n\r" );
00255     //printf( "-- Enter 'L' or 'l' to disable / enable loop-back mode\n\r" );
00256     
00257     SCB_EnableICache();
00258     SCB_EnableDCache();
00259 
00260     /* Configure systick for 1 ms. */
00261     TimeTick_Configure ();
00262     
00263     /* Configure Board LED's */
00264     LED_Configure( 0 ) ;
00265     LED_Configure( 1 ) ;
00266 
00267     /* Configure Timer/Counter for 250msec Tick */
00268     _ConfigureTc() ;
00269 
00270     /* Configure Board Push-buttons */
00271     // SW1 is a ERASE system function, switch it to port function
00272     MATRIX->CCFG_SYSIO |= (1u << 12);
00273     /* have to disable the pull down on PB12 for SW1 before the pull up can be 
00274         enabled */
00275     PIOB->PIO_PPDDR = 1 << 12;
00276     PIO_Configure( pushbutton, PIO_LISTSIZE( pushbutton ) );
00277     /* Adjust pio denounce filter parameters, uses 10 Hz filter. */
00278     PIO_SetDebounceFilter( &pushbutton[0], 10 ) ;
00279     PIO_SetDebounceFilter( &pushbutton[1], 10000 ) ;
00280 
00281     SystemCoreClockUpdate();
00282 
00283     MCAN_Init( &mcan1Config );
00284     //MCAN_InitFdEnable( &mcan1Config );
00285     MCAN_InitFdBitRateSwitchEnable( &mcan1Config );
00286     MCAN_InitTxQueue( &mcan1Config );
00287     MCAN_InitLoopback( &mcan1Config );  // remove to disable loop back mode
00288     MCAN_Enable( &mcan1Config );
00289 
00290     MCAN_IEnableMessageStoredToRxDedBuffer( &mcan1Config, CAN_INTR_LINE_1 );
00291     
00292     txMailbox0 = (uint32_t *) MCAN_ConfigTxDedBuffer( &mcan1Config, TX_BUFFER_0, 
00293             MSG_ID_0, CAN_STD_ID, CAN_DLC_1 );
00294     txMailbox1 = (uint32_t *) MCAN_ConfigTxDedBuffer( &mcan1Config, TX_BUFFER_1, 
00295             MSG_ID_1, CAN_EXT_ID, CAN_DLC_8 );
00296     MCAN_ConfigRxBufferFilter( &mcan1Config, RX_BUFFER_0, FILTER_0, MSG_ID_0, 
00297             CAN_STD_ID );
00298     MCAN_ConfigRxBufferFilter( &mcan1Config, RX_BUFFER_1, FILTER_0, MSG_ID_1, 
00299             CAN_EXT_ID );
00300     MCAN_ConfigRxClassicFilter( &mcan1Config, CAN_FIFO_0, FILTER_1, MSG_ID_2, 
00301             CAN_STD_ID, MSG_ID_2_MASK );
00302 
00303     while ( 1 ) {
00304          if ( tick ) {
00305             tick = 0 ;
00306             if ( PIO_Get( &pushbutton[0] ) == BUTTON_NOT_PUSHED ) {
00307                 if (button_state2 == BUTTON_NOT_PUSHED) {
00308                     /* periodically transmit messages while SW0 is not pushed */
00309                     // send standard ID from a dedicated buffer
00310                     *txMailbox0 = MSG_ID_0_DATA1;  // write data into CAN mailbox
00311                     MCAN_SendTxDedBuffer( &mcan1Config, TX_BUFFER_0 );  // send data
00312                     txdCntr++;
00313                     // send extended ID from a dedicated buffer
00314                     *txMailbox1 = MSG_ID_1_DATA1_4;  // write data into CAN mailbox
00315                     *(txMailbox1 + 1) = MSG_ID_1_DATA5_8; // write data into CAN mailbox
00316                     MCAN_SendTxDedBuffer( &mcan1Config, TX_BUFFER_1 ); // send the data
00317                     txdCntr++;
00318                     // send from Tx Queue
00319                     MCAN_AddToTxFifoQ( &mcan1Config, MSG_ID_2 + id_offset, CAN_STD_ID, 
00320                             CAN_DLC_1, &txData[0] );
00321                     txdCntr++;
00322                     // increment the offset so we send different ID's within the 
00323                     // range defined by the mask
00324                     id_offset = ( id_offset + 1 ) & (uint32_t) ~MSG_ID_2_MASK;
00325                     // update data being sent for next time
00326                     txData[0]++;
00327                     button_state2 = BUTTON_NOT_PUSHED;
00328                 }
00329             } else {
00330                 if(button_state2 == BUTTON_NOT_PUSHED) 
00331                     button_state2 = BUTTON_PUSHED;
00332                 else 
00333                     button_state2 = BUTTON_NOT_PUSHED;
00334             }
00335         }
00336         /* poll for TX'd message complete */
00337          if ( MCAN_IsTxComplete( &mcan1Config ) ) {
00338             MCAN_ClearTxComplete( &mcan1Config );
00339             if ( MCAN_IsBufferTxd( &mcan1Config, TX_BUFFER_0 ) ) {
00340                   LED_Toggle( 1 );
00341             }
00342         }
00343         /* Poll for new CAN messages in RX FIFO */
00344         do {
00345             fifo_entries = MCAN_GetRxFifoBuffer( &mcan1Config, CAN_FIFO_0, 
00346                     (Mailbox64Type *) &rxMailbox2 );
00347             if ( fifo_entries > 0 ) rxdCntr++;
00348         } while ( fifo_entries > 1 );
00349          
00350         /* SW1 used to alternate between standard CAN and CAN-FD operation */
00351         if ( PIO_Get( &pushbutton[1] ) == BUTTON_NOT_PUSHED ) {
00352              button_state = BUTTON_NOT_PUSHED;
00353         } else {
00354             if ( button_state == BUTTON_NOT_PUSHED ) {
00355                 // Switch on a NOT PUSHED to PUSHED edge
00356                 button_state = BUTTON_PUSHED;
00357                 if ( can_mode == CAN_STANDARD ) {
00358                     can_mode = CAN_FD;
00359                     MCAN_RequestFdBitRateSwitch( &mcan1Config );
00360                 }else {
00361                     can_mode = CAN_STANDARD;
00362                     MCAN_RequestIso11898_1( &mcan1Config );
00363                 }
00364             }
00365         }
00366 #if 0
00367     /* poll for keyboard entry */
00368     if ( DBG_IsRxReady( ) ) {
00369         keyboard = DBG_GetChar( );
00370         if (( (char) keyboard == 'L' ) || ( (char) keyboard == 'l' )) {
00371             if ( loopback == 1 ) {
00372                 MCAN_LoopbackOff( &mcan1Config );
00373                 loopback = 0;
00374             } else {
00375                 MCAN_LoopbackOn( &mcan1Config );
00376                 loopback = 1;
00377             }
00378         }
00379     }
00380 #endif
00381     }
00382 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines