Infineon XMC 4700 - lorenzo-campana/bpm GitHub Wiki

This document is a step by step documentation on how to configure a XMC 4700 relax kit. This document provides a guide for

  • DAVE Installation
  • UART Communication
  • LCD Display control
  • USB communication

Dave Installation and first steps

In order to program the XMC 4700 you need to use the DEVE IDE. You can download it from Infineon website; follow this link and submit your information to receive an email with the download link. Once downloaded, extract the DAVE-IDE-4.4.2-64Bit folder and create a desktop shortcut to the DAVE application located in the Eclipse folder. The program doesn't need an installation, just double click on the shortcut to launch it.

In order to test and upload our programs on the microcontroller we need to install SEGGER J-link debugger. Go to this link and download the latest version of the software. During the installation make sure to also install the USB Driver for the debugger. Connect the XMC 4700 from the debugger micro USB port to the PC. If the driver are installed correctly, the green LED will blink from a second and then stop.

Now we can create our first project in DAVE. Go to File -> New -> DAVE project... and enter the name of the project. Select DAVE CE Project and click Next. In the next window select your microcontroller (in our case XMC 4700 Relax kit) and tick "Add floating point support printf and scanf" at the bottom. Click Finish and you are done.

DAVE projects are based on APPs. You can add them clicking on the "Add new APP" button located on the top toolbar. APPs are used to add functionalities to your project. We will see some examples in the next sections of the documents.

On the toolbar you can find other usefull command:

  • Rebuild Active Project is used to compile your current active project. Use this command everytime you modify the main.c file.
  • Manual Resources Assignment is used to assign resources.
  • Manual Pin Allocator is used to assign a pin from the XMC 4700 header to one APP
  • Generate Code is used to generate the header files from the APP of the project. Everytime you modify one of the APP from the GUI (accessed by double clicking it from the APP dependency tab at the bottom) you need to generate a new code before building it.
  • Debugger is used to start the debugger. After clicking the button, the program will switch into the debug view; in this view you can test your code executing one command line at the time, by pressing the "Step Over" button (F6). In the top right there is the "Variables" tab, where you can check the real time value of every variables of the code. To exit the debugger view use the right part of the toolbar (DAVE CE button).

UART Communication

With this project we will set up a serial communication between the microcontroller and the computer using the UART protocol. The first thing we need is a way to test the code. Download Hterm, a virtual interface to simulate serial input and output. The program doesn't need installation, just launch the .exe file. Connect the XMC 4700 from the debugger micro USB to the PC and select the right COM port on the Hterm terminal. Then set the other parameter according to the following image:

Create a new DAVE project and add a UART[4.1.12] APP. Double click on it to open the setting panel. Under "Advanced Settings" you can change change the protocol handling for receiving and transmit. The possible choices are (from the UART APP Help page):

  • Interrupt: Data provided by the user is transmitted using interrupts. FIFO can be configured to optimize the CPU utilization. Data is loaded to the transmit buffer in interrupt service handler. A callback function can be registered in "Interrupt Settings" tab to be executed after the transmission is complete.

  • DMA: Data provided by the user is transmitted by configuring DMA memory to peripheral block transfer. FIFO cannot be used in DMA mode. A callback function can be registered in "Interrupt Settings" tab to be executed after the transmission is complete. Note: DMA option uses DMA capable service requests for establishing DMA handshake. Only 2 such service requests are available for each USIC module. So the user may not be able to select this option if the DMA capable service requests of the USIC module are already used.

  • Direct: On selecting this option, interrupt signals will be available for external connection. User can choose a way for implementing data transfer. In this mode, the APP APIs implemented using 'Interrupt' or 'DMA' mode cannot be used.

Now we need to wire the APP to the pin. Open the Manual Pin Allocator and set pin 1.4 as "Receive Pin" and pin 1.5 as "Transmit Pin" and then Save and Close. Remember to generate the code everytime you modify the APP.

After that, in the project explorer on the left, double click on main.c to open the code. Delete everything and copy this code in:

#include <DAVE.h>                 //Declarations from DAVE Code Generation (includes SFR declaration)
#include <stdio.h.>
int main(void)
{
  DAVE_STATUS_t status;
  uint8_t Send_Data[50] = "test";
  uint8_t Rec_Data[20]={'\0'};
  uint8_t index = 0;

  /*Initialize Dave (including UART) */
  status = DAVE_Init();

  if(status == DAVE_STATUS_SUCCESS)
  {
    /*Transmit the string */
    while(Send_Data[index] != 0)
      {
        UART_TransmitWord(&UART_0,Send_Data[index]);
        index++;

        /*Wait for transmit buffer interrupt to fill it again with remaining data */
        while((UART_GetTXFIFOStatus(&UART_0) & XMC_USIC_CH_TXFIFO_EVENT_STANDARD) == 0);
        UART_ClearTXFIFOStatus(&UART_0, XMC_USIC_CH_TXFIFO_EVENT_STANDARD);
      }

    /* Receive input */
    index = 0;
    while (1)
      {
        if (!UART_IsRXFIFOEmpty (&UART_0))
          {
            Rec_Data[index] = UART_GetReceivedWord(&UART_0);
            index++;
          }
        if(Rec_Data[index-1]=='\n') break;
      }

    /* Format the string */
    int int_value=0;
    char char_value='\0';
    sscanf(Rec_Data,"%s %d",&char_value, &int_value);


    /*Transmit the received data */
    index = 0;
    while(1)
      {
        UART_TransmitWord(&UART_0,Rec_Data[index]);
        index++;

        /*Wait for transmit buffer interrupt to fill it again with remaining data */
        while ((UART_GetTXFIFOStatus (&UART_0) & XMC_USIC_CH_TXFIFO_EVENT_STANDARD) == 0);
        UART_ClearTXFIFOStatus(&UART_0, XMC_USIC_CH_TXFIFO_EVENT_STANDARD);

        if(Rec_Data[index-1]=='\n') break;
      }
  }
  else
  {
    XMC_DEBUG("main: Application initialization failed");
    while(1U)
    {
    }
  }
  return 1U;
}


This code sends through UART communication the string Send_Data and then receive data until a \n comes through. At that point the program sends back the message received. The code can also formats the string sent if the string is in the format " ", saving the character in the variable char_value and the integer in int_value.

To test the program build the project and start the debugger. Then click "Resume" in the debug view toolbar. Use the Hterm terminal to send the string to the microcontroller and receive it back.

LCD Display

For this example we will use a Newhaven Dislay NHD-0420D3Z-FL-GBW-V3 in I2C mode. To enter I2C mode you need to solder a jumper across the R1 pad on the back on the display, as shown in the following image:

To control the LCD we will use the I2C_MASTER APP. Add the APP in the project and double click on it to open the configuration tab. In "General Setting" change the "Desired bus speed" to 40 KHz. Then open the manual pin allocator and link the SCL and SDA pin (for example SCL to pin 0.13 and SDA to pin 3.15), save, close and generate the code. Now connect with a wire the SCL pin to pin 6 of the display and the SDA pin to pin 5. Pin 4 must be wired to ground, while pin 3 to 5V.

Now if you power the XMC 4700, the display should light on. We can control the display sending command with the I2C_MASTER_Transmit function:

I2C_MASTER_Transmit ( 
  I2C_MASTER_t *  handle,  
  bool  send_start,  
  const uint32_t  address,  
  uint8_t *  data,  
  const uint32_t  size,  
  bool  send_stop  
 ) 
 
  • handle I2C device handle of type I2C_MASTER_t*
  • send_start The flag to indicate that the start condition need to be send.
  • address I2C slave device address.
  • data buffer containing the data to transmit.
  • size The number of bytes to be send to slave.
  • send_stop The flag to indicate that the stop condition need to be send.

For our display the default address of the slave device is 0x50. The following table contains the available commands with their corresponding address:

And finally these are some examples function that can be implemented in the code to control the display (remember to send the prefix addres before the actual command):

void clear_display (void)
{
  uint8_t clear[2]={0xfe,0x51};
  I2C_MASTER_Transmit(&I2C_MASTER_0, true, 0x50, clear, 2, false);
}

void send_text(uint8_t* text)
{
  I2C_MASTER_Transmit(&I2C_MASTER_0, true, 0x50, text, sizeof(text), false);
}

void set_position (uint8_t position)
{
  uint8_t set_position[3]={0xfe,0x45};
  // position must be an addres between 0x00 and 0x67
  set_position[2] = position;
  I2C_MASTER_Transmit(&I2C_MASTER_0, true, 0x50, set_position, 3, false);
}

USB Communication

USB ia a more simple and robust way of communicating with the XMC than UART. To configure the communication we need to add to our project the "USBD_VCOM" APP; DAVE will automatically add the "USBD" APP, that can be edited to change the settings. For this example we don't need to change anything in the setting. Generate the code, and copy the following code in the main.c file.

 #include <DAVE.h>

 int8_t rx_buffer[64] = { 0 };
 int8_t tx_buffer[64] = { 0 };

 int main(void)
 {
   DAVE_STATUS_t init_status;
   uint16_t bytes = 0;

   init_status = DAVE_Init();

   if (init_status == DAVE_STATUS_SUCCESS)
   {
     if (USBD_VCOM_Connect() != USBD_VCOM_STATUS_SUCCESS)
     {
       return -1;
     }

     while (!USBD_VCOM_IsEnumDone());

     while(1U)
     {
       bytes = USBD_VCOM_BytesReceived();

       if (bytes)
       {
         if (bytes == 1)
         {
           USBD_VCOM_ReceiveByte(&rx_buffer[0]);

           USBD_VCOM_SendByte(rx_buffer[0]);

         }
         else
         {
           USBD_VCOM_ReceiveData(rx_buffer, bytes);
           memcpy(tx_buffer, rx_buffer, bytes);
           USBD_VCOM_SendData((const int8_t *)&tx_buffer[0], bytes);
         }

       }
       CDC_Device_USBTask(&USBD_VCOM_cdc_interface);
     }
   }
   else
   {
     XMC_DEBUG("main: Application initialization failed");
     while(1U)
     {
     }
   }

   return 1U;
 }

The code is really simple: the USB communicaion is initialized in the DAVE_Init() function. After the enumeration for the USB device is done ( while(!USBD_VCOM_IsEnumDone()) ), the code will wait for at least one byte of information to come through the serial bus (if(bytes)) and then it will send it back.

Upload the code to the board using the debugger. Unfortunately we can't test the program with the debugger: the USB interface is only wired to the main micro usb port, and not to the debugger one.

Connect the XMC 4700 to the pc and refresh the Hterm port list with the "R" button on the top right. After selecting the right COM port, the communication should start.

⚠️ **GitHub.com Fallback** ⚠️