Example – Writing to and Reading from FPGA Register via serial port. This is an example program which shows how to read and write values to and from the FPGA register via the serial port on your EVM. This example project will flash each LED ON and OFF for 1 second while simultaneously writing LED # ON and LED # OFF to both the UART and the CCS console. It will then read and write to the FPGA register via the serial port. 1. The first step is to create a new CCS project, an empty RTSC. Open CCS File Æ New Æ CCS Project and in the name field enter FPGA_register, Under Project templates and examples select Empty RTSC Project In Family select the family of your DSP and under variant select the same Then click Next Select the applicable platform and hit finish 2. Create a new RTSC configuration file FileÆNewÆ RTSC configuration file In Filename type FPGA_Register.cfg Click Finish 3. Now we will create source file that will use the MCSDK library to a) load the necessary libraries, b) prepare the environment c) blink the LEDs on and off while simultaneously writing to the serial port and UART, and finally d) read and write to the FPGA registers. To create the source file: go to File Æ New Æ Source File name the source file FPGA_Register.C Select Default C Source Template And click Finish Finally paste the following code into the source file /* * main.c */ #include <cerrno> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ti\platform\platform.h> #include <ti\platform\resource_mgr.h> #include <ti\platform\evmc6678l\platform_lib\include\evmc66x_fpga.h> /* note that the evmc66x_fpga.h file will need to be specified depending on which platform * the user is developing on. In this example the 6678l platform is being used. Change the * above path to suit your needs. */ typedef struct test_config { uint8_t print_info; uint8_t print_current_core_id; uint8_t print_switch_state; uint8_t test_eeprom; uint8_t test_nand; uint8_t test_nor; uint8_t test_led; uint8_t test_uart; uint8_t test_external_mem; uint8_t test_internal_mem; uint32_t init_config_pll1_pllm; uint32_t init_config_uart_baudrate; uint32_t nand_test_block_number; uint32_t nor_test_sector_number; uint32_t eeprom_test_slave_address; uint32_t led_test_loop_count; uint32_t led_test_loop_delay; uint32_t ext_mem_test_base_addr; uint32_t ext_mem_test_length; uint32_t int_mem_test_core_id; } test_config; void setup_args(platform_init_flags *flags, test_config *args) { /* should always be 1 */ flags->pll = 1; /* to init DDR3 */ flags->ddr = 1; flags->tcsl = 1; flags->phy = 0; flags->ecc = 0; args->print_info = args->print_current_core_id args->print_switch_state args->test_eeprom = args->test_nand = 1; args->test_nor = 1; args->test_led = 1; args->test_uart = 1; args->test_external_mem = args->test_internal_mem = 1; = = 1; 0; 1; 1; 1; args->init_config_pll1_pllm = 20; args->init_config_uart_baudrate = 19200; args->nand_test_block_number = 510; args->nor_test_sector_number = 10; args->eeprom_test_slave_address = 0; args->led_test_loop_count = 1; args->led_test_loop_delay = 2000000; args->ext_mem_test_base_addr= 0x80000000; args->ext_mem_test_length = 0x1fffffff; args->int_mem_test_core_id = 1; } /* OSAL functions for Platform Library */ uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment) { return malloc(num_bytes); } void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes) { /* Free up the memory */ if (dataPtr) { free(dataPtr); } } void Osal_platformSpiCsEnter(void) { /* Get the hardware semaphore. * * Acquire Multi core CPPI synchronization lock */ while ((CSL_semAcquireDirect (PLATFORM_SPI_HW_SEM)) == 0); return; } void Osal_platformSpiCsExit (void) { /* Release the hardware semaphore * * Release multi-core lock. */ CSL_semReleaseSemaphore (PLATFORM_SPI_HW_SEM); return; } void main(void) { platform_init_flags init_flags; platform_init_config init_config; platform_info p_info; test_config args; uint8_t uchValue = 0; /* Default value */ volatile uint8_t temp; volatile uint32_t ret; /* Set default values */ int32_t i,j; memset(&args, 0x01, sizeof(test_config)); memset(&init_flags, 0x01, sizeof(platform_init_flags)); setup_args(&init_flags, &args); init_config.pllm = args.init_config_pll1_pllm; if (platform_init(&init_flags, &init_config) != Platform_EOK) { printf("Platform failed to initialize, errno = 0x%x \n", platform_errno); } platform_write_configure(PLATFORM_WRITE_ALL); ret = fpgaReadConfigurationRegister(FPGA_DBG_LED_OFFSET, &uchValue); ret = fpgaReadConfigurationRegister(0x0C, &uchValue); for (j = PLATFORM_USER_LED_CLASS; j < PLATFORM_END_LED_CLASS; j++) { for (i = 0; i < 3; i++) { platform_write("LED %d ON\n", i); platform_led(i, PLATFORM_LED_ON, (LED_CLASS_E)j); platform_delay(10000000); platform_write("LED %d OFF\n", i); platform_led(i, PLATFORM_LED_OFF, (LED_CLASS_E) j); platform_delay(10000000); platform_write("LED %d ON\n", i); platform_led(i, PLATFORM_LED_ON, (LED_CLASS_E)j); } } /*Read FPGA Register*/ ret = fpgaReadConfigurationRegister(0x0C, &uchValue); printf("Register value is %d\n",uchValue); /*Write FPGA Register*/ uchValue = uchValue | 0x03; ret = fpgaWriteConfigurationRegister(0x0c, uchValue); /*Read back the written values from FPGA Register*/ fpgaReadConfigurationRegister(0x0C, &uchValue); printf("Register value is %d\n",uchValue); } /***************************************************************************************************** ****** * END FPGA_REGISTERS_EXAMPLE ****************************************************************************************************** ** ****************************************************************************************************** ***/ NOTE: First ensure that the required platform header files are available. These files are part of the MCSDK install (http://software-dl.ti.com/sdoemb/sdoemb_public_sw/bios_mcsdk/latest/index_FDS.html) and the evmc66x_fpga.h is dependent on the specific platform in use. As an example here, we point to the 6678l platform, where the installation path would be: C:\TI\pdk_C6678_1_0_0_21\packages Specify including these headers via the following code. #include <ti\platform\platform.h> #include <ti\platform\resource_mgr.h> #include <ti\platform\evmc6678l\platform_lib\include\evmc66x_fpga.h> NOTE: To have the project only write the LED status to UART or only to CCS console the argument passed to platform_write_configure( ) ; should be changed to PLATFORM_WRITE_UART and PLATFORM_WRITE_PRINTF respectively. The default for the example project is PLATFORM_WRITE_ALL. After flashing the LEDs the code reads the FPGA configuration register writes a value to it and reads the value written to the FPGA register /*Read FPGA Register*/ ret = fpgaReadConfigurationRegister(0x0C, &uchValue); printf("Register value is %d\n",uchValue); /*Write FPGA Register*/ uchValue = uchValue | 0x03; ret = fpgaWriteConfigurationRegister(0x0c, uchValue); /*Read back the written values from FPGA Register*/ fpgaReadConfigurationRegister(0x0C, &uchValue); printf("Register value is %d\n",uchValue); 4. Our project now needs a linker command script. The linker command script defines the memory map for the platform. Select FileÆ New Æ File from Template, Enter File Name as link.cmd and click Finish. It should open link.cmd file in the editor. Within the editor, erase any text that may be in the link.cmd file, and paste the following code instead. SECTIONS { platform_lib > L2SRAM } 5. Setup CCS to point to the platform header files and platform library. FileÆ Properties Add the appropriate path to the compiler include options. (Example: C:\TI\pdk_C6678_1_0_0_21\packages) Add the appropriate library and library path to the linker file search path. (Example: ti.platform.evm6678l.ae66) 6. Now select Project Æ Build Project to build the project This should result in an executable, likely built as a Debug, as this is the default option. Use the following steps to load and run this example Select View->Target Configurations to open target configuration tab in the left pane (this step assumes you have followed Getting Started Guide to create target configuration for your setup). Right click on the configurations file (######.ccxml) and select Launch Selected Configuration. It should change the CCS prospective to Debug. After launch is complete select core 0 (e.g. C66XX_0). Select Run->Connect Target to connect to the core. After core 0 is connected, select Run->Load->Load Program, then hit Browse Project.... It should open Select program to load dialog, then select FPGA_Register.out[....] and hit OK and another OK to load the program to core 0. After loading completes, select Target->Run to run the application. The application should print to UART and CCS console window : [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] [C66xx_0] LED 0 ON LED 0 OFF LED 0 ON LED 1 ON LED 1 OFF LED 1 ON LED 2 ON LED 2 OFF LED 2 ON LED 0 ON LED 0 OFF LED 0 ON LED 1 ON LED 1 OFF LED 1 ON LED 2 ON LED 2 OFF LED 2 ON Register value is 28 Register value is 28 UART should be connected to the board at 115200 baud rate. Each LED will flash in sequence