SAMV71 Xplained Ultra Software Package 1.3

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, 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 usart_lon USART LON example with DMA
00032  *
00033  *  This example demonstrates the LON mode provided by the USART peripherals on
00034  *  SAMV7 Microcontrollers.
00035  *
00036  *  \section Requirements
00037  *
00038  *  This example can be used on SAM V71 Xplained Ultra board. Before running, 
00039  *  make sure to connect two boards with RS485 lines. The rs485 adapt board
00040  *  (ADM3485ARZ) for this purpose.
00041  *  Match each paired pins of two boards respectively with A to A,
00042  *  B to B and FGND to FGND(the central pin of J3).
00043  *  this part is connect with EK and ADM3485ARZ
00044  *   - <b>Board 1                             Board 2</b>
00045  *   -  TXD1(J507 pin28, D47) <->DI       TXD1(J507 pin28, D47) <->DI
00046  *   -  RXD1(J507 pin27, D46) <->RO       RXD1(J507 pin27, D46) <->RO
00047  *   -  RTS1(J507 pin26, D45) <->DE       RTS1(J507 pin26, D45) <->DE
00048  *   -  CTS1(J507 pin25, D44) <->RE       CTS1(J507 pin25, D44) <->RE
00049  *   -  3.3v                                   3.3v
00050  *   -  GND                                    GND
00051  *  this part is connect with 2 ADM3485ARZ
00052  *      A              <-------------------->  A
00053  *      B              <-------------------->  B
00054  *      PGND           <-------------------->  PGND
00055  *
00056  *  \section Description
00057  *
00058  *  This example connects two boards through RS485 interface to show how to
00059  *  use USART in LON (local operating network) mode. One of the board acts
00060  *  as the transmitter and the other one as the receiver. It is determined by
00061  *  the sequence the two applications started.
00062  *
00063  * \section Usage
00064  *
00065  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. Please
00066  *     refer to the Getting Started with SAM V71 Microcontrollers.pdf
00067  *  -# Connect a serial cable to the UART4 port (J505 Pin3 D18 and Pin4 D19) on the evaluation kit.
00068  *  -# On the computer, open and configure a terminal application for each board (e.g.
00069  *     HyperTerminal on Microsoft Windows) with these settings:
00070  *        - 115200 bauds
00071  *        - 8 data bits
00072  *        - No parity
00073  *        - 1 stop bit
00074  *        - No flow control
00075  *  -# Start application from two boards in sequence. Make sure the second board
00076  *     should NOT be started unless the first board had run to wait for the
00077  *     synchronizing character. The output message in later section would
00078  *     describe this.
00079  *
00080  *  -# In the terminal  window, the
00081  *     following text should appear (values depend on the board and chip used):
00082  *     \code
00083  *     -- USART LON Mode Example xxx --
00084  *     -- SAMxxxxx-xx
00085  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00086  *     \endcode
00087  *
00088  *  \section References
00089  *  - usart_lon/main.c
00090  *  - pio.h
00091  *  - usart.h
00092  */
00093 
00094 /** \file
00095  *
00096  *  This file contains all the specific code for the usart_rs485 example.
00097  */
00098 
00099 /*----------------------------------------------------------------------------
00100  *        Headers
00101  *----------------------------------------------------------------------------*/
00102 
00103 #include "board.h"
00104 
00105 #include <stdbool.h>
00106 #include <stdio.h>
00107 #include <string.h>
00108 
00109 /*----------------------------------------------------------------------------
00110  *        Local definitions
00111  *----------------------------------------------------------------------------*/
00112 
00113 /** size of the receive buffer used by the DMA, in bytes.*/
00114 #define BUFFER_SIZE     256
00115 
00116 /** baud rate */
00117 #define BAUDRATE  256000
00118 
00119 /** Register base for USART */
00120 #define USART           USART1
00121 #define ID_USART        ID_USART1
00122 
00123 /*----------------------------------------------------------------------------
00124  *        Local variables
00125  *----------------------------------------------------------------------------*/
00126 /** Global DMA driver for all transfer */
00127 static sXdmad dmad;
00128 
00129 static uint32_t usartDmaRxChannel;
00130 static uint32_t usartDmaTxChannel;
00131 
00132 /** RE for LON */
00133 #define PIN_USART1_CTS_IOR {PIO_PA25A_CTS1, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
00134 
00135 /**  Pins to configure for the application.*/
00136 const Pin pins[] = { PIN_USART1_RXD, PIN_USART1_TXD, PIN_USART1_CTS_IOR, PIN_USART1_RTS };
00137 
00138 /** Transmit buffer. resver 2 bytes for DATAL and L2HDR*/
00139 char palette[BUFFER_SIZE-2]=
00140 "#*************************************************************************\n\r\
00141  *  This application gives an example of how to use USART in LON mode.\n\r\
00142  *  The LON mode provides connectivity to the local operating network (LON).\n\r\
00143  *                      .\n\r\
00144  ";
00145 
00146 /** Transmit buffer. */
00147 COMPILER_ALIGNED(8) static char Buffer[BUFFER_SIZE];
00148 
00149 /** buffer for receiving */
00150 COMPILER_ALIGNED(8) static char pRecvBufferUSART[BUFFER_SIZE];
00151 
00152 /** reception done*/
00153 static volatile uint8_t recvDone = 0;
00154 
00155 /** sending done*/
00156 static volatile uint8_t transDone = 0;
00157 
00158 /*----------------------------------------------------------------------------
00159  *        Local functions
00160  *----------------------------------------------------------------------------*/
00161 
00162 /**
00163  * \brief Configures USART in LON mode
00164  */
00165 static void _ConfigureUsart( void )
00166 {
00167     /* Initialization for Sending/Receiving A LON Frame */
00168 
00169     uint32_t mode;
00170     Usart *pUsart = USART;
00171 
00172     /* 1. Write TXEN and RXEN in US_CR to enable both the transmitter and the 
00173           receiver.                                                           */
00174     /* Enable receiver & transmitter */
00175     USART_SetTransmitterEnabled( pUsart, 1 ) ;
00176     USART_SetReceiverEnabled( pUsart, 1 ) ;
00177 
00178     /* 2. Write USART_MODE in US_MR to select the LON mode configuration.     */
00179     /* Enable the peripheral clock in the PMC */
00180     PMC_EnablePeripheral( ID_USART ) ;
00181 
00182     mode = US_MR_USART_MODE_LON | US_MR_USCLKS_MCK
00183                     | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT
00184                     | US_MR_CHMODE_NORMAL
00185                     //| US_MR_CHMODE_LOCAL_LOOPBACK //US_MR_CHMODE_NORMAL
00186                     | US_MR_MAN;
00187 
00188     pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX
00189                     | US_CR_RXDIS | US_CR_TXDIS | US_CR_RSTSTA;
00190     pUsart->US_IDR = 0xFFFFFFFF;
00191 
00192     pUsart->US_MR = mode;
00193 
00194     /* 3. Write CD and FP in US_BRGR to configure the baud rate.              */
00195     USART_SetBaudrate(pUsart, 0, BAUDRATE, BOARD_MCK);
00196 
00197     /* 4. Write COMMT, COLDET, TCOL, CDTAIL, RDMNBM and DMAM in US_LONMR to 
00198           configure the LON operating mode.                                   */
00199     pUsart->US_LONMR = US_LONMR_COMMT /* LON comm_type = 2 mode */
00200                     | US_LONMR_COLDET /* LON collision detection feature enabled */
00201                     | US_LONMR_DMAM   /* The LON data length register US_LONDL is written by the DMA */
00202                     | US_LONMR_LCDS   /* LON collision detection source is internal. */
00203                     | US_LONMR_EOFS(1);
00204 
00205     /* 5. Write BETA2, BETA1TX, BETA1RX, PCYCLE, PSNB, NPS, IDTTX and ITDRX 
00206           respectively in US_FIDI, US_LONB1TX, US_LONB1RX, US_TTGR, US_LONPRIO, 
00207           US_LONIDTTX and US_LONIDTRX to set the LON network configuration.   */
00208     pUsart->US_FIDI    = 5; /* LON BETA2 length */
00209     pUsart->US_LONB1TX = 5; /* LON Beta1 Tx     */
00210     pUsart->US_LONB1RX = 5; /* LON Beta1 Rx     */
00211     pUsart->US_TTGR    = US_TTGR_PCYCLE(5);  /* package cycle timer value */
00212     pUsart->US_LONPRIO = US_LONPRIO_PSNB(5)  /* Number of priority slots  */
00213                         | US_LONPRIO_NPS(5); /* Node priority slot        */
00214 
00215     /* Set LON Indeterminate Time after Transmission or Reception 
00216      * (comm_type = 1 mode only) */
00217     if ( 0 == (pUsart->US_LONMR & US_LONMR_COMMT) )
00218     {
00219         pUsart->US_IDTTX   = US_IDTTX_IDTTX(3);
00220         pUsart->US_IDTRX   = US_IDTRX_IDTRX(3);
00221     }
00222 
00223     /* (TX) 6. Write TX_PL in US_MAN to select the preamble pattern to use.   */
00224     /* (RX) 6. Write RXIDLEV and RX_PL in US_MAN to indicate the receiver line
00225                value and select the preamble pattern to use.                  */
00226     // preamble pattern
00227     pUsart->US_MAN =  US_MAN_TX_PL(5) | US_MAN_TX_PP_ALL_ONE 
00228                     | US_MAN_RX_PL(5) | US_MAN_RX_PP_ALL_ONE 
00229                     | US_MAN_ONE | US_MAN_DRIFT;
00230 
00231     pUsart->US_LONPR = US_LONPR_LONPL(5);
00232 
00233     /* proceed by a software reset of the transmitter and the receiver and 
00234     followed by a transmitter/receiver enable to avoid unpredictable behavior */
00235     pUsart->US_CR = US_CR_RSTRX | US_CR_RSTTX;
00236     pUsart->US_CR = US_CR_RXEN | US_CR_TXEN;
00237 }
00238 
00239 /**
00240  * ISR for DMA interrupt
00241  */
00242 void XDMAC_Handler(void)
00243 {
00244     XDMAD_Handler(&dmad);
00245 }
00246 
00247 /**
00248  *  \brief Callback function for DMA receiving.
00249  */
00250 static void _DmaRxCallback( uint8_t status, void* pArg )
00251 {
00252     status = status;
00253     pArg = pArg;
00254     recvDone = 1;
00255 }
00256 
00257 /**
00258  *  \brief Callback function for DMA transmitting.
00259  */
00260 static void _DmaTxCallback( uint8_t status, void* pArg )
00261 {
00262     status = status;
00263     pArg = pArg;
00264     transDone = 1;
00265 }
00266 
00267 /**
00268  *  \brief Start USART sending data.
00269  */
00270 static void _DmaUsartTx( void )
00271 {
00272     sXdmadCfg xdmadCfg;
00273     xdmadCfg.mbr_ubc = BUFFER_SIZE;
00274     xdmadCfg.mbr_sa = (uint32_t)Buffer;
00275     xdmadCfg.mbr_da = (uint32_t)&USART->US_THR;
00276     xdmadCfg.mbr_cfg = 
00277             XDMAC_CC_TYPE_PER_TRAN |
00278             XDMAC_CC_MBSIZE_SINGLE |
00279             XDMAC_CC_DSYNC_MEM2PER |
00280             XDMAC_CC_CSIZE_CHK_1 |
00281             XDMAC_CC_DWIDTH_BYTE |
00282             XDMAC_CC_SIF_AHB_IF0 |
00283             XDMAC_CC_DIF_AHB_IF1 |
00284             XDMAC_CC_SAM_INCREMENTED_AM |
00285             XDMAC_CC_DAM_FIXED_AM |
00286             XDMAC_CC_PERID(
00287                 XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_TX)
00288                 );
00289 
00290     xdmadCfg.mbr_bc  = 0;
00291     xdmadCfg.mbr_ds  = 0;
00292     xdmadCfg.mbr_sus = 0;
00293     xdmadCfg.mbr_dus = 0; 
00294     XDMAD_ConfigureTransfer(
00295             &dmad, usartDmaTxChannel, &xdmadCfg, 0, 0,
00296             XDMAC_CIE_BIE |
00297             XDMAC_CIE_DIE |
00298             XDMAC_CIE_FIE |
00299             XDMAC_CIE_RBIE |
00300             XDMAC_CIE_WBIE |
00301             XDMAC_CIE_ROIE);
00302             XDMAD_StartTransfer( &dmad, usartDmaTxChannel);
00303 }
00304 
00305 /**
00306  *  \brief Start USART waiting data.
00307  */
00308 static void _DmaUsartRx( void )
00309 {
00310     uint32_t status; 
00311     /* Read USART status */
00312     status = USART->US_CSR;
00313     if ((status & US_CSR_RXRDY) == US_CSR_RXRDY ) 
00314     {
00315         status = USART->US_RHR; /* clear the US_CSR_RXRDY*/
00316     }
00317     sXdmadCfg xdmadCfg;
00318     xdmadCfg.mbr_ubc = BUFFER_SIZE - 1;
00319     xdmadCfg.mbr_sa = (uint32_t)&USART->US_RHR;
00320     xdmadCfg.mbr_da = (uint32_t)pRecvBufferUSART;
00321     xdmadCfg.mbr_cfg = 
00322             XDMAC_CC_TYPE_PER_TRAN |
00323             XDMAC_CC_MBSIZE_SINGLE |
00324             XDMAC_CC_DSYNC_PER2MEM |
00325             XDMAC_CC_CSIZE_CHK_1 |
00326             XDMAC_CC_DWIDTH_BYTE |
00327             XDMAC_CC_SIF_AHB_IF1 |
00328             XDMAC_CC_DIF_AHB_IF0 |
00329             XDMAC_CC_SAM_FIXED_AM |
00330             XDMAC_CC_DAM_INCREMENTED_AM |
00331             XDMAC_CC_PERID(
00332                 XDMAIF_Get_ChannelNumber(ID_USART, XDMAD_TRANSFER_RX)
00333                 );
00334   
00335     xdmadCfg.mbr_bc  = 0;
00336     xdmadCfg.mbr_ds  = 0;
00337     xdmadCfg.mbr_sus = 0;
00338     xdmadCfg.mbr_dus = 0; 
00339     XDMAD_ConfigureTransfer(
00340             &dmad, usartDmaRxChannel, &xdmadCfg, 0, 0,
00341             XDMAC_CIE_BIE |
00342             XDMAC_CIE_DIE |
00343             XDMAC_CIE_FIE |
00344             XDMAC_CIE_RBIE |
00345             XDMAC_CIE_WBIE |
00346             XDMAC_CIE_ROIE);
00347     XDMAD_StartTransfer( &dmad, usartDmaRxChannel);
00348 }
00349 
00350 
00351 /*
00352  *  \brief DMA driver configuration
00353  */
00354 static void _ConfigureDma( void )
00355 {
00356     /* Driver initialize */
00357     XDMAD_Initialize( &dmad, 0 );
00358 
00359     /* Allocate XDMA channels for USART */
00360     usartDmaTxChannel = XDMAD_AllocateChannel( &dmad, XDMAD_TRANSFER_MEMORY, ID_USART);
00361     usartDmaRxChannel = XDMAD_AllocateChannel( &dmad, ID_USART, XDMAD_TRANSFER_MEMORY);
00362     if ( usartDmaTxChannel == XDMAD_ALLOC_FAILED || usartDmaRxChannel == XDMAD_ALLOC_FAILED )
00363     {
00364         printf("XDMA channel allocat failed!\n\r");
00365         while(1);
00366     }
00367 
00368     /* Set RX callback */
00369     XDMAD_SetCallback(&dmad, usartDmaRxChannel,(XdmadTransferCallback)_DmaRxCallback, 0);
00370     /* Set TX callback */
00371     XDMAD_SetCallback(&dmad, usartDmaTxChannel,(XdmadTransferCallback)_DmaTxCallback, 0);
00372     XDMAD_PrepareChannel( &dmad, usartDmaRxChannel );
00373     XDMAD_PrepareChannel( &dmad, usartDmaTxChannel);
00374 
00375 }
00376 
00377 /**
00378  * \brief Display menu.
00379  */
00380 static void _DisplayMenu( void )
00381 {
00382     printf("Menu :\n\r");
00383     printf("------\n\r");
00384     printf(" - t: Transmit pattern to LON\n\r");
00385     printf(" - r: Receive data from LON \n\r");
00386     printf(" - m: Display menu \n\r");
00387 }
00388 
00389 /**
00390  * \brief Dump buffer to DBGU
00391  *
00392  */
00393 static void _DumpInfo( char *buf, uint32_t size )
00394 {
00395     uint32_t i = 0 ;
00396 
00397     while ( (i < size) && (buf[i] != 0) )
00398     {
00399         printf( "%c", buf[i++] ) ;
00400     }
00401 }
00402 
00403 /*----------------------------------------------------------------------------
00404  *        Exported functions
00405  *----------------------------------------------------------------------------*/
00406 /**
00407  *  \brief Application entry point.
00408  *
00409  *  \return Unused (ANSI-C compatibility).
00410  */
00411 extern int main( void )
00412 {
00413     uint8_t ucKey;
00414 
00415     /* Disable watchdog */
00416     WDT_Disable( WDT ) ;
00417 
00418     SCB_EnableICache();
00419     SCB_EnableDCache();
00420 
00421     /* Output example information */
00422     printf( "-- USART LON Example %s --\n\r", SOFTPACK_VERSION ) ;
00423     printf( "-- %s\n\r", BOARD_NAME ) ;
00424     printf( "-- Compiled: %s %s  With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00425 
00426     /* Configure pins */
00427     PIO_Configure( pins, PIO_LISTSIZE( pins ) ) ;
00428     /* PB4 function selected */
00429     MATRIX->MATRIX_WPMR  = MATRIX_WPMR_WPKEY_PASSWD;
00430     MATRIX->CCFG_SYSIO |= CCFG_SYSIO_SYSIO4;
00431 
00432     /* Display menu */
00433     _DisplayMenu() ;
00434 
00435     /* Configure DMA with IRQ */
00436     _ConfigureDma();
00437 
00438     Buffer[0] = sizeof(palette) - 1; /* LON Data Length:  */
00439     Buffer[1] = US_LONL2HDR_BLI(2);
00440     memcpy(&Buffer[2], palette, sizeof(palette));
00441     SCB_CleanDCache();
00442 
00443     /* configure USART in LON mode*/
00444     _ConfigureUsart();
00445 
00446     NVIC_EnableIRQ(XDMAC_IRQn);
00447 
00448     while ( 1 )
00449     {
00450         ucKey = DBG_GetChar() ;
00451         switch ( ucKey )
00452         {
00453             case 't': case 'T':
00454             {
00455                 printf("-I- LON Transmitting ... \n\r");
00456                 USART->US_CR = US_CR_RSTSTA;    /* Reset Status Bits */
00457                 _DmaUsartTx();
00458                 while(!transDone);
00459                 printf("-I- LON Transmitting completed \n\r");
00460                 transDone = 0;
00461                 break;
00462             }
00463             case 'r': case 'R':
00464             {
00465                 printf("-I- LON receiving ... \n\r");
00466 
00467                 SCB_CleanInvalidateDCache();
00468                 USART->US_CR = US_CR_RSTSTA;    /* Reset Status Bits */
00469                 recvDone = 0;
00470 
00471                 _DmaUsartRx();
00472                 while(!recvDone);
00473                 /* successfully received */
00474                 _DumpInfo(pRecvBufferUSART, BUFFER_SIZE-1);
00475                 printf("\n\r-I- LON Receiving completed \n\r");
00476                 memset(pRecvBufferUSART, 0, sizeof(pRecvBufferUSART));
00477                 break;
00478             }
00479             case 'm': case 'M':
00480             {
00481                 _DisplayMenu() ;
00482                 break;
00483             }
00484         }
00485     }    
00486 }
00487 
00488 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines