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) 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_rs485 USART RS485 example with DMA
00032  *
00033  *  This example demonstrates the RS485 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, make sure to connect
00039  *  two boards with RS485 lines. The rs485 adapt board(ADM3485ARZ) for this purpose.
00040  *  Match each paired pins of two boards respectively with A to A,
00041  *  B to B and FGND to FGND(the central pin of J3).
00042  *  this part is connect with EK and ADM3485ARZ
00043  *   - <b>Board 1                             Board 2</b>
00044  *   -  TXD0(EXT1 pin14) <->DI            TXD0(EXT1 pin14) <->DI
00045  *   -  RXD0(EXT1 pin13) <->RO            RXD0(EXT1 pin13) <->RO
00046  *   -  RTS0(EXT1 pin5 ) <->DE            RTS0(EXT1 pin5 ) <->DE
00047  *   -  CTS0(EXT1 pin6 ) <->RE            CTS0(EXT1 pin6 ) <->RE
00048  *   -  3.3v                                   3.3v
00049  *   -  GND                                    GND
00050  *  this part is connect with 2 ADM3485ARZ
00051  *      A              <-------------------->  A
00052  *      B              <-------------------->  B
00053  *      PGND           <-------------------->  PGND
00054  *
00055  *  \section Description
00056  *
00057  *  This example connects two boards through RS485 interface. One board acts
00058  *  as the transmitter and the other one as the receiver. It is determined by
00059  *  the sequence the two applications started.
00060  *
00061  * \section Usage
00062  *
00063  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. Please
00064  *     refer to the Getting Started with SAM V71 Microcontrollers.pdf
00065  *  -# Connect a serial cable to the DBGU port on the evaluation kit.
00066  *  -# On the computer, open and configure a terminal application for each board (e.g.
00067  *     HyperTerminal on Microsoft Windows) with these settings:
00068  *        - 115200 bauds
00069  *        - 8 data bits
00070  *        - No parity
00071  *        - 1 stop bit
00072  *        - No flow control
00073  *  -# Start application from two boards in sequence. Make sure the second board
00074  *     should NOT be started unless the first board had run to wait for the
00075  *     synchronizing character. The output message in later section would
00076  *     describe this.
00077  *
00078  *  -# In the terminal  window, the
00079  *     following text should appear (values depend on the board and chip used):
00080  *     \code
00081  *     -- USART RS485 Mode Example xxx --
00082  *     -- SAMxxxxx-xx
00083  *     -- Compiled: xxx xx xxxx xx:xx:xx --
00084  *     \endcode
00085  *
00086  *  \section References
00087  *  - usart_rs485/main.c
00088  *  - pio.h
00089  *  - usart.h
00090  */
00091 
00092 /** \file
00093  *
00094  *  This file contains all the specific code for the usart_rs485 example.
00095  */
00096 
00097 /*----------------------------------------------------------------------------
00098  *        Headers
00099  *----------------------------------------------------------------------------*/
00100 
00101 #include "board.h"
00102 
00103 #include <stdbool.h>
00104 #include <stdio.h>
00105 #include <string.h>
00106 
00107 /*----------------------------------------------------------------------------
00108  *        Local definitions
00109  *----------------------------------------------------------------------------*/
00110 
00111 /** size of the receive buffer used by the DMA, in bytes.*/
00112 #define BUFFER_SIZE     1000
00113 
00114 /** baud rate */
00115 #define BAUDRATE_RS485  256000
00116 
00117 /** Register base for USART */
00118 #define USART           USART0
00119 #define ID_USART        ID_USART0
00120 
00121 /*----------------------------------------------------------------------------
00122  *        Local variables
00123  *----------------------------------------------------------------------------*/
00124 /** Global DMA driver for all transfer */
00125 static sXdmad dmad;
00126 
00127 static uint32_t usartDmaRxChannel;
00128 static uint32_t usartDmaTxChannel;
00129 
00130 /** RE for RS485 */
00131 #define PIN_USART0_CTS_IOR {PIO_PB2C_CTS0, PIOB, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT}
00132 
00133 /**  Pins to configure for the application.*/
00134 const Pin pins[] = { PIN_USART0_RXD, PIN_USART0_TXD, PIN_USART0_CTS_IOR, PIN_USART0_RTS };
00135 
00136 /** Transmit buffer. */
00137 char palette[BUFFER_SIZE]=
00138  "**************************************************************************\n\r\
00139  *  This application gives an example of how to use USART in RS485 mode.\n\r\
00140  *  The USART features the RS485 mode to enable line driver control.\n\r\
00141  *  While operating in RS485 mode, the USART behaves as though in asynchronous \n\r\
00142  *  or synchronous mode and configuration of all the parameters is possible \n\r\
00143  *  \n\r\
00144  *  The difference is that the RTS pin is driven high when the transmitter\n\r\
00145  *  is operating. The behavior of the RTS pin is controlled by the TXEMPTY bit.\n\r\
00146  *  \n\r\
00147  **************************************************************************\n\r\
00148  ";
00149 
00150 /** Transmit buffer. */
00151 COMPILER_ALIGNED(8) static char Buffer[BUFFER_SIZE];
00152 
00153 /** buffer for receiving */
00154 COMPILER_ALIGNED(8) static char pRecvBufferUSART[BUFFER_SIZE];
00155 
00156 /** reception done*/
00157 static volatile uint8_t recvDone = 0;
00158 
00159 /** sending done*/
00160 static volatile uint8_t transDone = 0;
00161 
00162 /*----------------------------------------------------------------------------
00163  *        Local functions
00164  *----------------------------------------------------------------------------*/
00165 
00166 /**
00167  * \brief Configures USART in rs485 mode
00168  */
00169 static void _ConfigureUsart( void )
00170 {
00171     uint32_t mode = US_MR_USART_MODE_RS485 | US_MR_USCLKS_MCK
00172                     | US_MR_CHRL_8_BIT | US_MR_PAR_NO | US_MR_NBSTOP_1_BIT
00173                     | US_MR_CHMODE_NORMAL;
00174 
00175     /* Enable the peripheral clock in the PMC */
00176     PMC_EnablePeripheral( ID_USART ) ;
00177 
00178     /* Configure the USART in the desired mode @USART_SPI_CLK bauds*/
00179     USART_Configure( USART, mode, BAUDRATE_RS485, BOARD_MCK ) ;
00180 
00181     /* Enable receiver & transmitter */
00182     USART_SetTransmitterEnabled( USART, 1 ) ;
00183     USART_SetReceiverEnabled( USART, 1 ) ;
00184 }
00185 
00186 /**
00187  * ISR for DMA interrupt
00188  */
00189 void XDMAC_Handler(void)
00190 {
00191     XDMAD_Handler(&dmad);
00192 }
00193 
00194 /**
00195  *  \brief Callback function for DMA receiving.
00196  */
00197 static void _DmaRxCallback( uint32_t channel, void* pArg )
00198 {
00199     channel = channel;
00200     pArg = pArg;
00201     recvDone = 1;
00202 }
00203 
00204 /**
00205  *  \brief Callback function for DMA transmitting.
00206  */
00207 static void _DmaTxCallback( uint32_t channel, void* pArg )
00208 {
00209     channel = channel;
00210     pArg = pArg;
00211     transDone = 1;
00212 }
00213 
00214 /**
00215  *  \brief Start USART sending data.
00216  */
00217 static void _DmaUsartTx( void )
00218 {
00219     sXdmadCfg xdmadCfg;
00220     xdmadCfg.mbr_ubc = BUFFER_SIZE;
00221     xdmadCfg.mbr_sa = (uint32_t)Buffer;
00222     xdmadCfg.mbr_da = (uint32_t)&USART->US_THR;
00223     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00224                     XDMAC_CC_MBSIZE_SINGLE |
00225                     XDMAC_CC_DSYNC_MEM2PER |
00226                     XDMAC_CC_CSIZE_CHK_1 |
00227                     XDMAC_CC_DWIDTH_BYTE |
00228                     XDMAC_CC_SIF_AHB_IF0 |
00229                     XDMAC_CC_DIF_AHB_IF1 |
00230                     XDMAC_CC_SAM_INCREMENTED_AM |
00231                     XDMAC_CC_DAM_FIXED_AM |
00232                     XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_USART, XDMAD_TRANSFER_TX ));
00233   
00234     xdmadCfg.mbr_bc =  0;
00235     xdmadCfg.mbr_ds =  0;
00236     xdmadCfg.mbr_sus = 0;
00237     xdmadCfg.mbr_dus = 0; 
00238     XDMAD_ConfigureTransfer( &dmad, usartDmaTxChannel, &xdmadCfg, 0, 0,
00239                             XDMAC_CIE_BIE |
00240                             XDMAC_CIE_DIE |
00241                             XDMAC_CIE_FIE |
00242                             XDMAC_CIE_RBIE |
00243                             XDMAC_CIE_WBIE |
00244                             XDMAC_CIE_ROIE);
00245     XDMAD_StartTransfer( &dmad, usartDmaTxChannel);
00246 }
00247 
00248 /**
00249  *  \brief Start USART waiting data.
00250  */
00251 static void _DmaUsartRx( void )
00252 {
00253     uint32_t status; 
00254     /* Read USART status */
00255     status = USART->US_CSR;
00256     if ((status & US_CSR_RXRDY) == US_CSR_RXRDY ) 
00257     {
00258         status = USART->US_RHR; /* clear the US_CSR_RXRDY*/
00259     }
00260     sXdmadCfg xdmadCfg;
00261     xdmadCfg.mbr_ubc = BUFFER_SIZE;
00262     xdmadCfg.mbr_sa = (uint32_t)&USART->US_RHR;
00263     xdmadCfg.mbr_da = (uint32_t)pRecvBufferUSART;
00264     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN |
00265                        XDMAC_CC_MBSIZE_SINGLE |
00266                        XDMAC_CC_DSYNC_PER2MEM |
00267                        XDMAC_CC_CSIZE_CHK_1 |
00268                        XDMAC_CC_DWIDTH_BYTE |
00269                        XDMAC_CC_SIF_AHB_IF1 |
00270                        XDMAC_CC_DIF_AHB_IF0 |
00271                        XDMAC_CC_SAM_FIXED_AM |
00272                        XDMAC_CC_DAM_INCREMENTED_AM |
00273                        XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_USART, XDMAD_TRANSFER_RX ));
00274   
00275     xdmadCfg.mbr_bc =  0;
00276     xdmadCfg.mbr_ds =  0;
00277     xdmadCfg.mbr_sus = 0;
00278     xdmadCfg.mbr_dus = 0; 
00279     XDMAD_ConfigureTransfer( &dmad, usartDmaRxChannel, &xdmadCfg, 0, 0,
00280                              XDMAC_CIE_BIE |
00281                              XDMAC_CIE_DIE |
00282                              XDMAC_CIE_FIE |
00283                              XDMAC_CIE_RBIE |
00284                              XDMAC_CIE_WBIE |
00285                              XDMAC_CIE_ROIE);
00286     XDMAD_StartTransfer( &dmad, usartDmaRxChannel);
00287 }
00288 
00289 
00290 /*
00291  *  \brief DMA driver configuration
00292  */
00293 static void _ConfigureDma( void )
00294 {
00295     /* Driver initialize */
00296     XDMAD_Initialize( &dmad, 0 );
00297 
00298     /* Allocate XDMA channels for USART */
00299     usartDmaTxChannel = XDMAD_AllocateChannel( &dmad, XDMAD_TRANSFER_MEMORY, ID_USART);
00300     usartDmaRxChannel = XDMAD_AllocateChannel( &dmad, ID_USART, XDMAD_TRANSFER_MEMORY);
00301     if ( usartDmaTxChannel == XDMAD_ALLOC_FAILED || usartDmaRxChannel == XDMAD_ALLOC_FAILED )
00302     {
00303         printf("XDMA channel allocat failed!\n\r");
00304         while(1);
00305     }
00306 
00307     /* Set RX callback */
00308     XDMAD_SetCallback(&dmad, usartDmaRxChannel,(XdmadTransferCallback)_DmaRxCallback, 0);
00309     /* Set TX callback */
00310     XDMAD_SetCallback(&dmad, usartDmaTxChannel,(XdmadTransferCallback)_DmaTxCallback, 0);
00311     XDMAD_PrepareChannel( &dmad, usartDmaRxChannel );
00312     XDMAD_PrepareChannel( &dmad, usartDmaTxChannel);
00313 
00314 }
00315 
00316 /**
00317  * \brief Display menu.
00318  */
00319 static void _DisplayMenu( void )
00320 {
00321     printf("Menu :\n\r");
00322     printf("------\n\r");
00323     printf(" - t: Transmit pattern to RS485\n\r");
00324     printf(" - r: Receive data from RS485 \n\r");
00325     printf(" - m: Display menu \n\r");
00326 }
00327 
00328 /**
00329  * \brief Dump buffer to DBGU
00330  *
00331  */
00332 static void _DumpInfo( char *buf, uint32_t size )
00333 {
00334     uint32_t i = 0 ;
00335 
00336     while ( (i < size) && (buf[i] != 0) )
00337     {
00338         printf( "%c", buf[i++] ) ;
00339     }
00340 }
00341 
00342 /*----------------------------------------------------------------------------
00343  *        Exported functions
00344  *----------------------------------------------------------------------------*/
00345 /**
00346  *  \brief Application entry point.
00347  *
00348  *  \return Unused (ANSI-C compatibility).
00349  */
00350 extern int main( void )
00351 {
00352     uint8_t ucKey;
00353 
00354     /* Disable watchdog */
00355     WDT_Disable( WDT ) ;
00356 
00357     SCB_EnableICache();
00358     SCB_EnableDCache();
00359 
00360     /* Output example information */
00361     printf( "-- USART RS485 Example %s --\n\r", SOFTPACK_VERSION ) ;
00362     printf( "-- %s\n\r", BOARD_NAME ) ;
00363     printf( "-- Compiled: %s %s  With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00364 
00365     /* Configure pins*/
00366     PIO_Configure( pins, PIO_LISTSIZE( pins ) ) ;
00367 
00368     /* Display menu */
00369     _DisplayMenu() ;
00370 
00371     /* Configure DMA with IRQ */
00372     _ConfigureDma();
00373 
00374     memcpy(Buffer, palette, BUFFER_SIZE);
00375     SCB_CleanDCache();
00376 
00377     /* configure USART in RS485 mode*/
00378     _ConfigureUsart();
00379 
00380     NVIC_EnableIRQ(XDMAC_IRQn);
00381 
00382     while ( 1 )
00383     {
00384         ucKey = DBG_GetChar() ;
00385         switch ( ucKey )
00386         {
00387             case 't': case 'T':
00388             {
00389                 printf("-I- RS485 Transmitting ... \n\r");
00390                 _DmaUsartTx();
00391                 while(!transDone);
00392                 printf("-I- RS485 Transmitting completed \n\r");
00393                 transDone = 0;
00394                 break;
00395             }
00396             case 'r': case 'R':
00397             {
00398                 printf("-I- RS485 receiving ... \n\r");
00399                 SCB_CleanInvalidateDCache();
00400                 recvDone = 0;
00401                 _DmaUsartRx();
00402                 while(!recvDone);
00403                 /* successfully received */
00404                 _DumpInfo(pRecvBufferUSART, BUFFER_SIZE);
00405                 printf("-I- RS485 Receiving completed \n\r");
00406                 memset(pRecvBufferUSART, 0, sizeof(pRecvBufferUSART));
00407                 break;
00408             }
00409             case 'm': case 'M':
00410             {
00411                 _DisplayMenu() ;
00412                 break;
00413             }
00414         }
00415     }    
00416 }
00417 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines