This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570 MCU Development Kit

Other Parts Discussed in Thread: OMAP-L137, HALCOGEN, SYSBIOS

I have several question regarding the TMS570 development board which I purchased from TI.

1. According to the Keil website, the development kit comes preprogrammed with the board confidence test and demo application which is available on the DVD that comes in the kit. Is this application available to those of us that purchased the board from TI instead of Keil? This would be a good example of how to interface to the touch screen. If not, is there any thing else that can help explain how to use the touchscreen?

2. Are there any example programs or documentation on how to use the ethernet and usb ports which I believe are handled by an omap device on the cpu board.

3. Are there any example programs or documentation on how to use the FRAM device or SD card.

The TMS570 Safety MCU Demos program that comes with the TI kit does not address any of these needs.

-Walt

  • Hi Walt,

    If you read the response to my post (http://e2e.ti.com/support/microcontrollers/tms570/f/312/t/59501.aspx) it appears that the only solution at present is to download uVision from the Keil website and look at the Blinky source code. Of course this will then need porting to CCS but it should give you enough information to see how to access the touchscreen.

    I will leave it to the TI guys to provide information about the other peripherals although note that schematics are available here:

    http://processors.wiki.ti.com/index.php/TMS570_MDK_Kit#MDK_Board_Schematic 

    and you could look up the data sheets.

    Regards,

    Richard

  • Hi Richard,

    I did read your post before I posted my questions but I missed that the blinky program used the touch screen. Thanks that will be helpful.

    I should be able to figure out the FRAM and SD card from the schematics and data sheets. I'm not too worried about those right now but if there are examples available, they would be helpful.

    I am really interested in the ethernet port connected to the omap. I assume there is support software programmed in the omap but I cannot find any documentation on the communication protocol between the TMS570 and the omap. I hope I don't need to learn to develop code for omap to get the ethernet port and USB working.

    -Walt

     

     

  • Walt,

    I did some checkout of the MDK's Ethernet and USB ports the following way:

      - From the OMAP-L137 I checked out the connection from ports to connectors by programming a U-Boot image into the OMAP-L137 serial eeprom.    This has capability to do basic Ethernet and USB communication; but is all code that runs on the OMAP-L137.  (i.e. I had to connect a JTAG emulator to the L137 to do this).

     - From the TMS570 side, I was able to confirm that we can read and write to the on chip memory, USB, and Ethernet peripherals of the OMAP chip through the TMS570.  These are mapped to the TMS570 external memory interface through the OMAP's UHPI port.   

    As an example,  the code to check that we could read the peripheral ID from the OMAP-L137's Ethernet module (base address 0x01E220000) looked like:

     

    /* EMAC CTRL */

     

    while ((uhpiHpicRead() & UHPI_HPIC_NRDY_HPIA_WR) != 0);

    uhpiHpiaWrite(0x01E22000);

    uhpiHpicWrite(UHPI_HPIC_FETCH);

     

    while ((uhpiHpicRead() & UHPI_HPIC_NRDY_HPID_RD) != 0);

    data = uhpiHpidIncRead();

    printf (

    "Reading EMAC Control Peripheral ID %x Should be %x \n", data, 0x4ec80100);

     

    The above should probably be refined a little more - with the read and write steps written as functions;  for example reading involves these steps:

     - Check that the OMAP-L137 UHPI is able to accept a new HPIA write

     - Write address to read (0x01E220000) into the HPIA register

     - Set the Prefetch bit in the UHPI HPIC control register - which causes the UHPI to fetch the data from address 0x01E220000 into it's local FIFO

    - Check that the OMAP-L137 UHPI has data available in it's fifo to read

    - Finally, read that data from the HPID register

     

    Hopefully that gives you a flavor of what is involved in accessing the OMAP peripherals from the TMS570. 

    The above is not enough to send data over ethernet or access a USB peripheral, but is more a starting point for an OS / Middleware vendor to begin a porting process.

    As far as learning to program the OMAP-L137 goes - the answer is no, you don't need ot program the L137.  But you do need at the moment to consult the OMAP-L137 reference manuals to get the details on how to program the Ethernet and USB ports.   There are code examples avaialble as well that can be taken from the L137 world.

    Best Regards,

    Anthony

  • Hi,

    Is there an application note or example code describing in more detail how to use the ethernet on the MCBTMS570 dev board? If not, can someone please expand on the last post in this thread giving more detail on how to set up the TMS570 external memory controller to be able to interface with the HPI on the OMAP chip?

    Thanks,

    Charlie.

  • Hi Charlie,

    You can download a uVision evaluation version for the TMS570 from the Keil website that contains the source code for the dev board. Unfortunately, you cannot directly compile the Keil source code in CCS but it should give you an idea of how to drive some of the peripherals. What's more, although you can build the code, you can't actually link it due to the size limitations on the evaluation version of uVision.

    Hope this helps.

    Regards,

    Richard

  • Hi Richard,

    Thanks for the reply. I have the uVision example code (and the CCS equivalent) and can see that the EMIF is used there to control the LCD and external RAM, but I can't figure out how to extend this to interface with the OMAP.

    The earlier posts to this thread make sense, but until I work out the detail behind the "uhpiHpicRead()" function etc, I can't move forward.

    Regards,

    Charlie.

  • The MDK Confidence Test & Demo Application source code for CCSv4.x may be downloaded from the MDK TMS570 WIKI page.

    http://processors.wiki.ti.com/images/c/c1/ConfidenceTest_CCSv4.zip 

     

  • Hi Charlie,

    Here are a couple of the key files from the project that I used to checkout the UHPI interface to the OMAP-L137.

    These are files for the TMS570 side program.   The rest of the program was built out of HalCoGen; except for the async EMIF and MPU settings.


    What I don't know at the moment is whether the MDKs ship with code in the serial EEPROM to enable the UHPI on the OMAP-L137, and also to enable the etherenet and usb modules on those devices.   When I did my testing, I used a larger EEPROM and put a full U-Boot image into the OMAP-L137 serial flash;  I modified this image to enable UHPI, Etherent, and USB.  U-Boot was useful on the OMAP-L137 because you could check out etherent and USB functionality from the OMAP-L137 itself, and also peek/poke memory to confirm UHPI writes from 570 were happening.

    If the MDK doesn't ship with the appropriate code in EEPROM, first step might be to either reprogram the EEPROM or alternatively to change the OMAP-L137 boot resistors to select UHPI boot and feed the data in from the TMS570.

    3731.uhpi.h5228.uhpi.c1513.sys_main.c

  • Hi Anthony,

    Thanks for your reply. I had managed to get the UHPI interface to the OMAP working before I saw your response, but I have a few key differences that I wondered if you were able to consider.

    The first stumbling point for me was which addresses to use for reading/writing. The schematic shows EMIF_ADD15, 16 & 17 connected to UHPL_HRW, CNTL0, CNTL1 respectively and EMIF_BADD1 connected to UHPI_HHWIL. Although several reference manuals referred to the address pins EMIF_ADD15 - EMIF_ADD0 and the bank address pins EMIF_BADD1, EMIF_BADD0 being combined to create the actual address used for reading/writing through the EMIF, none of them explained how this was done. It took some experimentation to determine that the bank address pins represent the 2 least significant bits of the address, and so in order to set EMIF_ADD15 high, I needed to set bit 17 in the address - i.e. to read the UHPI Control register, I needed to read from address 0x6C020000.

    The next issue was that I was unable to write to the UHPI registers using 32 bit data types - these only resulted in the 1st half word being set in the registers. I found that instead I needed to write 2 16-bit words, i.e. to write the UHPI Address register, I had to write the 1st half word to address 0x6C080000 and the 2nd half word to address 0x6C080002. The same principle held for the UHPI Control register, even though it is effectively a 16-bit register and (according to the data sheet) should be accessible using a single 16-bit write command, I have to write 2 16-bit commands for the register to be set reliably. Perversely, 32-bit read commands always succeed for all registers.

    My final comments/questions relate to the bits in the UHPI Control register. The code you posted treated bits 12-15 as 'NRDY' flags, but the data sheets for the OMAP-L137 that I have seen show these bits as being reserved. In any case, they always read as 0 for me. I'm also confused by the 'FETCH' bit in the register - the code you posted indicated that, after a write to the UHPI Address register, the FETCH bit must be set before reading the content of the UHPI Data register, however I have found that this step seems to be unnecessary. At least in my limited testing, simply writing the UHPI Address register and then immediately reading the UHPI Data register always returns the expected values.

    Thanks again for your help,

    Charlie.

  • Hi Charlie,

    Great that you've gotten UHPI communication working!   This means that there is at least enough code in the OMAP-L137 serial EEPROM to enable the UHPI, which confirms what my colleague who works on the MDK told me yesterday.  We're not quite sure whether it goes as far as enabling the clocks and releasing reset to the USB and Ethernet peripherals; so if you are trying to get to these you might try checking whether you can read out the Peripheral revision ID (I had the code to do this in the sys_main.c I posted along with the expected values).   If you can read the peripheral ID that means the peripheral is powered on;  and you should be able to make use of it.   If not then I think you may need to inject some code into the OMAP-L137's processors to turn these peripherals on. 

    I think your understanding of the use of the bank addresses is correct.  There is an explanation of this in the TMS570 Technical Reference Manual, (TI Literature Number SPNU489B) In section 10.2.5.1;  if you want to see the details.

    If you are only successful using two 16 bit word accesses then I think you probably have the TMS570 EMIF chip select 3 (which connects to the OMAP-L137) configured for a 32-bit async memory.   In the testing that I did, I configured it for as a 16-bit memory.   If you tell the EMIF module that the memory is 16 bits wide and then you do a 32-bit read, it will automatically break this up into two separate 16-bit accesses for you.  This will be a little faster too, because the two accesses are created on the fly inside the EMIF;  no need to execute two separate CPU instructions.

    The 'NRDY' flags are a new feature in the OMAP-L137 and the user's guides may not have caught up with this.  I'll post something on the OMAP-L137 forum so the team is aware.  

    Essentially, if you read through the UHPI manuals for older processors like the C6727 DSP, you'll see a lot of warnings about the need to keep the UHPI HCS\ asserted until the UHPI comes back with UHPI_HRDY indicating 'ready'.    Now, sometimes the UHPI will come back 'ready' right away.  This is probably what's happening in your testing and why it works fine for you.    But as the actiivty inside the OMAP-L137 increases you might find that something like a DMA transaction from the Ethernet to RAM takes priority over the UHPI transaction to RAM, and causes a delay in the UHPI being able to complete the access.   In this case the UHPI would assert 'not ready' and the TMS570 is not supposed to release the chip select until this happens.

    Now, the TMS570 EMIF doesn't include the WAIT\ signal, so there is no hardware mechanism that will allow the OMAP-L137 to insert extra wait states when UHPI is not ready.   Even if the 570 did have a WAIT\ input as some other processors do, you may not want to make the host processor external bus wait for an indefinite amount of time until UHPI comes back ready.

    For these reasons, there is an alternative offered which is to check the ready state of the UHPI by polling bits in the UHPI HPIC register.   Actually this isn't a completely new feature, but on older devices like the C6727 we had a single bit indicating ready status - which turned out to be unreliable - so the feature wasn't documented.

    The reason a single bit is unreliable is that you don't know what resource the external host is going to access next, so you can't really tell it whether that particular resource is ready or not.   By resource I mean HPIC, HPIA, HPID, HPID++.    What causes these resources to be busy or not is kind of complex to explain in a forum post like this, but we have the scenarios documented in the  UHPI user's guide (TI Lit# sprufm7d Section 2.6.9).  The same scenarios that would cause the UHPI_HRDY pin to be indicating 'not ready' also would be reflected in the new bits in the UHPI HPIC register.

    While you might find the code you have working with a relatively lightly loaded OMAPL137 - it might actually fail as you do things that increase the speed of the TMS570 EMIF to OMAP-L137 link (like, programming the 570 EMIF for 16-bit mode, or reducing the number of wait states that the 570 EMIF inserts to the minimum required).   Also, as you start making the OMAP-L137 more active - ie. if you get USB and Ethernet transactions to on-chip RAM going;  you might find that the UHPI starts indicating not-ready.  Then you will actually need to poll the HPIC NRDY bits to make operation reliable.   So I think it's a good idea to build this handshaking into your application from the start, but this is just my opinion.

    The FETCH is related to the previous paragraph's discussion point.   Once the activity gets to the point where the UHPI comes back not-ready, you will need to start using the pre-fetch capability of the UHPI to read from the OMAP-L137 memory & peripherals.   What the FETCH does is allow you to tell the UHPI to go off and perform a read, storing the results into the UHPI FIFO.   Once the read data reaches the UHPI FIFO, it can be read out of the UHPI by the external host without worrying about wait states inserted due to on-chip bus traffic.    So if your host processor doesn't have a WAIT\ input on its external memory interface (like the TMS570) the only really safe way to read from on-chip memory is to use the FETCH mechanism.

    BTW - Here are the settings that I used for EMIF Async Chip Select 3 on TMS570 to configure it for x16-bit accesses to UHPI:

    /*-------------------------------------------------------------*

    *                                                              *

    *  HPI                                                         *

    *--------------------------------------------------------------*/

        Uint32 acs3cr = 0

            | ( 0x1  << 31 )  // Select Strobe    [Normal]

            | ( 0xf  << 26 )  // writeSetup       [  0]

            | ( 0x3f << 20 )  // writeStrobe      [ 35]

            | ( 0x7  << 17 )  // writeHold        [  0]

            | ( 0xf  << 13 )  // readSetup        [  0]

            | ( 0x3f << 7 )   // readStrobe       [110]

            | ( 0x7  << 4 )   // readHold         [  0]

            | ( 0x3  << 2 )   // readHold         [  0]

            | ( 0x1  << 0 );  // asyncSize        [16-bit] bus

     

            EMIF_ACS3CR = acs3cr;  // HPI

     

  • Hi Anthony,

    Thanks for the latest information.

    The difference in my configuration of the EMIF_ACS3CR register turned out to be the "Select Strobe" bit - I had Normal Mode enabled, whereas your code has Select Strobe Mode enabled. With this configuration, I can also now write 32 bit values.

    Thanks for the information on the NRDY bits. I've added this as well as the FETCH mechanism. When using the FETCH mechanism, reading the data using the HPID read address fails (it always returns 0), but using the HPID Read with Increment address, the read is successful - what is the reason for this?

    Can you also confirm the meaning of bits 5 and 6 in the HPIC register? From SPRUFM7D, I understood that these bits were reserved and should have the value 2h - your code writes 0 to these bits which seems to be accepted. Are these bits really reserved or do they have another function?

    I am able to read and write various EMAC registers. I've got as far as confirming that the PINMUX9 and PCS1 registers are automatically configured correctly (presumably by whatever code is running in the OMAP). So it seems I just need to climb the steep learning curve for ethernet.....

    Thanks again for your help.

    Charlie.

  • Hi Charlie,

    Super - more good progress it sounds like!  Excited to hear that you're so close to getting the EMAC communicating.

    Regarding the question about why the HPID read fails but HPID read with autoincrement (I personally call this reg HPID++ as a shortcut); the reason has to do with the UHPI FIFO.   Section 2.6.10.3 talks about conditions that flush the UHPI's FIFO;  one is an HPID read  (without auto-increment).   So by using that register, you'd be flushing the data that was prefetched, and fetching new data again from memory.   That can be useful sometimes - but in this case you don't have a WAIT\ input on the TMS570 so it's not 100% safe to read HPID (potential problems discussed in previous post on this thread).

    Bits 5 and 6 of HPIA are truly not useful on the OMAP-L137 - I would just write the value '2' back to them.  On other devices, one of these bits might allow you to actually reset the device (ie. the OMAP) through the HPI - but the L137 integrates it's own host ARM 926 CPU so this option didn't make sense to implement.  The other bit is used on some devices when there is a bigger mismatch than 2:1 between the internal address bus width and external;  but in this case the internal address space is 32-bit and the UHPI only goes down to 16-bit - so this feature isn't needed (two halfword writes are enough to specify a full 32 bit address).

    Regarding the EMAC - there is some very simple code in the LSP for OMAP-L137 that you might want to check out.   I think in the source tree for U-Boot, there's just enough code to send a packet out of the MAC.   This could be one good starting point for you.

    Another might be to look at the TI NDK which supports the OMAP-L137.

     

  • Sorry to ask silly questions, but what are the "LSP for OMAP-L137", "source tree for U-Boot" and the "TI NDK for MAP-L137"? Where can I access these resources?

    Thanks.

  • Hi Charlie,

    Sorry - my fault for using so many acronyms.

    If haven't already seen the TI Embedded Processor WIKI - there is a ton of good information there:

      - http://processors.wiki.ti.com/index.php/Main_Page

    The LSP is a 'Linux Support Package'  - it's down a couple levels under the "Operating Systems" heading on the top page.

    This is a direct link to the LSP page:  http://processors.wiki.ti.com/index.php/Linux_Support_Package

    The NDK is basically a TCP/IP stack that works with TI SYSBIOS.   

    http://processors.wiki.ti.com/index.php/Category:NDK

    Best Regards,

    Anthony 

  • Anthony,

    The information you've posted so far has been very helpful in my own attempts to port an Ethernet stack to the MDK, however I feel I have a long way to go still.

    The EMIF and UHPI interfaces are both quite new to me, so I am still dedicating a lot of my time to learning them.  In your post earlier with the sample code you said that it was without the EMIF and MPU settings.  I assume these are in the nonincluded tms570_emif.h and uhpi.h files?  Could you elaborate on how you created these?

  • Hi Bart,

    You should be able to start with the EMIF configuration files that are part of the board confidence test;

    In my post from Feb 9th I have at the bottom the settings for the ASYNC control register 3.  This controls the timings of chip select that UHPI is tied to.

    I think the confidence test leaves out configuration of async control register 3 completely but does configure other async control registers.  So you can just follow the template for the other async control registers in the confidence test code, but use the values from the feb 9th post.

    Those values also may be pretty conservative;  with a very long STROBE duraton.  Most likely this could be sped up by studying the UHPI timings from the OMAP-L137 and the EMIF timings from the TMS570 datasheets.  I haven't done this though.

    Regarding the MPU settings - the default memory map for the Cortex R4F MPU (See ARM DDI 0363E table 7.1)  has the address range from 0x6000 0000 to 0x7FFF FFFF as Normal, Non-Cacheable, Shared type.   For EMIF>UHPI, Device or Strongly Ordered are appropriate.  I picked Strongly Ordered for my testing, just to keep it simple at first.  However performance might be improved by using Device.  In any case I'd recommend you start with strongly ordered.

    There is a release of HalCoGen in the works that has MPU support, but in the meantime I'm adding a few files to this post that worked for me;  I think these came from the HalCoGen team so maybe the final product will be similar.  

    Should note a couple things:

      - once you enable the MPU - the default memory map 'goes away'.  So you need to make sure that you are configuring the MPU not only for the EMIF, but for all the OTHER regions like Flash, SRAM, on-chip peripherals.

    -  the MPU registers live in CP15 - a coprocessor.  you have to be in a priv. mode to write to them; and there are some specific assembly instructions that are required. (There may be C compiler intrinsics by now for this purpose, but the code here uses assembly to get the job done.)

    Hope this helps.   Good luck with your project.

     

    6765.EMIF_Config.c

    5008.R4_MPU_Config.asm

     

  • Anthony,

    Your information helped out immensely.  Once I re-flashed the OMAP to it's original state I was able to get the communication working.

    I was curious however if you knew where the memory maps lined up?  The EMIF block on the TMS570 should start at 0x60000000 like the tech reference says, but where does that line up in the OMAP's memory?  I feel like I would be going in blind if I made any assumptions about it.

  • Hi Bart,

    Great to hear this. 

    The OMAP address space is not mapped into the TMS570's address space - in the sense that there isn't any region  (start address to end address) that you can display in a debugger window which will result in reading or writing from the OMAP-L137.

    Instead, the OMAP-L137's UHPI interface is mapped to several addresses in the TMS570 space, as defined in the header file uhpi.h.

    I'm referring to these addresses: UHPI_HPIC_RD, UHPI_HPIC_WR, UHPI_HPIA_RD, UHPI_HPI_WR, UHPI_HPID_RD, UHPI_HPID_WR, UHPI_HPID_INC_RD, and UHPI_HPID_INC_WR which are all in the range of 0x6Cxx xxxx of the TMS570 address space.

    So the view OMAP-L137 from the TMS570 is one of a memory mapped device, like a UART or SPI port. You need to write a device driver that reads and writes from addresses in the OMAP-L137 space through the UHPI port.  Some of the very primitive building blocks for this driver are the functions like uhpiHpicRead().

    To give an analogy you're probably more familiar with - think about a SPI Serial Flash device.  This could contain several megabytes of memory - but you don't 'see' this memory directly in the TMS570 memory map.  Instead, you have to send commands through SPI to access it.  You might have to first send a command saying 'read' then followed by several bytes of address - and then finally shift in some number of bytes that will start from the address you shifted in, but then this address keeps incrementing automatically inside the serial flash;  so that the serial flash gives you a block of it's memory contents through SPI ... as many bytes as you shift before issuing a new command.

    The UHPI port almost works the same way - except it's more parallel (16-bits wide instead of 1 bit wide for SPI).  And it has several addresses which you could think of as a SPI device that had a chip select for setting up a command, a second chip select for setting up the start address and finally another chip select for reading data.   I don't think there are any SPI serial flash devices that actually work this way - but if there were one that would be similar to the HCNTL[1:0] inputs on the UHPI which you can think of as chip selects for the HPIC, HPIA, HPID, and HPID with auto-increment registers.

    Hope that helps understand a little better;  you can almost pretend you have only a SPI port into the OMAP-L137 and think about how you would arrange your code for it - then the difference between SPI and UHPI is mainly the improved speed and the fact that you don't need any software running on OMAP-L137 to process UHPI commands - the processing is done in hardware.

    Given the above explanation of how the TMS570 'sees' the OMAP-L137 memory map through the UHPI device (almost like a 'peephole') - let's change gears completely and consider how the OMAP-L137 etherent and USB peripherals will operate.   These peripherals include bus mastering DMA controllers, and as far as I know you really have to enable the DMA controllers to get them operating;  with the exception of the USB OTG controller.  But for the OHCI USB controller, you have to build tables of EP and TD descriptors in the on-chip OMAP-L137 RAM and then have the OHCI USB port operate on that RAM.   For ethernet, you have to build packets up in the OMAP-L137 RAM and then submit a 16-byte (I think) descriptor to the DMA that is built into the Ethernet controller to tell it where to find the packet.

    The good news is that you just use the OMAP-L137 memory map for this.  You can find the OMAP-L137 memory map in it's datasheet on this page: to http://focus.ti.com/docs/prod/folders/print/omap-l137.html.   The memory areas that would be best to use for setting up ethernet packets and USB descriptors are: "Shared RAM" 0x8000 0000 - 0x8001 FFFF and DSP L2 RAM 0x1180 0000 - 0x1183 FFFF.   There's a total of 384K bytes of RAM on chip so that's probably enough to do quite a lot with.   If you need more RAM than this you could try the SDRAM on the OMAP-L137 EMIF;  I believe there is SDRAM populated there on the MDK.  But I wouldn't start with this because it's more complex.. you might run into EMIF configuraiton issues.

    So to summarize, when you write the packet of data to the OMAP L137's RAM, you will need to use the protocol of UHPI and first write the address (for example, 0x8000 0000) into the HPIA register first.  Then you need to access HPID - of course polling HPIC between each access to make sure you don't access when the UHPI isn't ready.   The same thing happens when you write the descriptor to the Ethernet CPPI RAM - you'll have to setup the address of the descriptor in HPIA first, then actually write the descriptor data.    These steps will result in memory mapped accesses from the TMS570 in the 0x6Cxx xxxx range - or in other words accesses to HPIA, HPIC, HPID, and HPID with auto-increment.

    However, when you get to the point where you are issuing HPID writes to the CPPI RAM on the Ethernet controller - and you are ready to write the address of the packet into the Ethernet controller's descriptor area - you need to use the address from the perspective of the Ethernet controller.  This would be an address in the 0x8000 0000 range - wherevever you put the packet in the OMAP L137's "Shared RAM"  (just an example).

    One last point - it will take some additional work to generate an interrupt from the OMAP-L137 back to the TMS570.  So what I would recommend doing to start with is writing your ethernet ISR such that it is triggered by an RTI compare event on the TMS570.  Then just poll the OMAP-L137's etherent inside that ISR to see if any events are really pending.     Once you get something working with this sort of scheme, you might consider putting some helper code inside the OMAP-L137 that checks the Etherent interrupt and generates an HINT\ interrupt back to the TMS570.  But this is kind of advanced and I wouldn't start with this.