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.

OMAP L-138 Communication from EMIF to HPI

Hello *.*,

we want to establish a fast communication between two OMAP L138 ARM-CPUs.

The best seems to be a connection EMIF to HPI. We couldn't find any description or examples for such a connection.

So we read a lot of docu and get a theoretical solution. Can anybody confirm the following Pin Connections:

Nr.
HPI EMIF A
1
HHWIL
BA[1]
Half-Word identification
2
HCTL[0]
A0
HPI Access type
3
HCTL[1]
A1
HPI Access type
4
HINT
any GPIO Pin
5
HR/W WE
differ read and write
6
HRDY WAIT[0]
async ready input
7
HCS
CS[2]
Chip select
8
HDS1

tied to HCS
9
HDS2

static high
10
HD[15:0]
ED[15:0]

 

 

 

 

 

 

 

 

 

 

We are also wondering about timings:

For HPI there is a time tw (HSTBH) "UHPI_STROBE inactive high between consecutive accesses" in Document  SPRS586A needed between any two half-words!?

But EMIF (used in "Normal Mode") inserts a "Turnaround period" only when it switches between read and write operations but not between consecutive read or write operations! Do we have to pause the EMIF manually?

Do you have any other hints for timing configuration?

 

Many thanks for your help

Rolf

 

 

 

  • Hi Rolf,

    Have you checked out this app note:

    www.ti.com/lit/an/spra536b/spra536b.pdf

    Let me know if this answers your questions.  If not, I can run some answers down for you.

    -Brad

  • Hi Brad,

    I have read this document and it help to find our Omap L138 pinning solution. But EMIF and HPI referenced in this document  have some differences to to the Omap.

    I'm not sure if our EMIF to HPI pinning fits. We can not test this combination on Evalboards and an error will cost us some weeks building a new CPU-Board.

    So I would appreciate any help from you. :-)

    Rolf

     

     

     

  • Rolf,

    Here are my comments on the hookup based on SPRA536:

    -          UHPI_HRWn should instead be connected to EMA_A_RWn

    -          Any EMA_A pins can be used for HCNTL0/1 and HHWIL.  The exact selection simply determines which address the host should write to - for a specific HPI action (described in Table 1 of SPRA536.

    -          HDS1n should be connected to EMA_WEn

    -          HDS2n should be connected to EMA_OEn

    Also, UHPI_STROBEn  is defined in the datasheet as [NOT(UHPI_HDS1 XOR UHPI_HDS2)] OR UHPI_HCS.  With the above hookup, UHPI_STROBEn should be be logic 1 during the setup/hold cycles.

    Regards,

     

    Brad

  • Also, you might look into using uPP-to-uPP as the communication link.  I belive the bandwidth is greater:

    http://processors.wiki.ti.com/index.php/Device:OMAP-L138:Device_Evaluation#Peripheral_Throughput_and_Optimizations

    -Brad

  • It has been a long time since you posted this, but we have a similar need.  We want to connect two C6746 DSPs together with the HPI and EMIF ports.  Since these come from the same family as the OMAP parts, the same approach should work.


    My question is the mention of the strobe line being a logic 1 during the setup/hold cycles.  Can it be a logic 1 all of the time?  We intended to pull it to VCC.

    Bob

  • Hi Rolf,

    Did you succeed with these connections? We are planning to mimic them on two C6746 DSPs and would like to know if it worked and what problems you may have had to overcome.
  • Hello Bob,
    yes its a long time and today I do not remember if or which changes we have done to get the HPI-EMIF communication running but it is working for us since then :-)
    After a short view I found:
    HPI-HCNTL0 -> EMIF-A2
    HPI-HCNTL1 -> EMIF-A3
    HPI-HCS -> EMIF-CS[2]
    HPI-HAS high for boot
    HPI-HINT -> A4 (GPIO5[4])
    But for the moment I have no deeper knowledge, if this are real differences to the table above.

    I also didn't find any handling of the strobe line in the firmware while reading or writing hpi:

    void Hpi::write( void* const dest, const void* const source, const uint32_t size ) const
    {
    if( ((size & 3U) != 0U) || ((reinterpret_cast<uint32_t>( dest ) & 3U) != 0U) )
    {
    PRJ_THROW( 0x000001dcU, "Size for hpi write!" );
    }
    m_host->hpiCtrl = (CSL_HPI_HPIC_HPIASEL_WRITE << CSL_HPI_HPIC_HPIASEL_SHIFT) // select write address register
    | (CSL_HPI_HPIC_DUALHPIA_ENABLE << CSL_HPI_HPIC_DUALHPIA_SHIFT) // seperate address register for read and write
    | CSL_HPI_HPIC_HWOB_LS; // first halfword is least significant
    m_host->hpiAddr = reinterpret_cast<uint32_t>( dest );
    const uint32_t* write32 = reinterpret_cast<const uint32_t*>( source );
    for( uint32_t i = 0U; i < (size >> 2U); ++i )
    {
    m_host->hpiDataInc = *write32;
    write32++;
    }
    }

    void Hpi::read( void* const dest, const void* const source, const uint32_t size ) const
    {
    if( ((size & 3U) != 0U) || ((reinterpret_cast<uint32_t>( dest ) & 3U) != 0U) )
    {
    PRJ_THROW( 0x000001ddU, "Size for hpi read!" );
    }
    m_host->hpiCtrl = (CSL_HPI_HPIC_HPIASEL_READ << CSL_HPI_HPIC_HPIASEL_SHIFT) // select read address register
    | (CSL_HPI_HPIC_DUALHPIA_ENABLE << CSL_HPI_HPIC_DUALHPIA_SHIFT) // seperate address register for read and write
    | CSL_HPI_HPIC_HWOB_LS; // first halfword is least significant
    m_host->hpiAddr = reinterpret_cast<uint32_t>( source );
    uint32_t* read32 = reinterpret_cast<uint32_t*>( dest );
    for( uint32_t i = 0U; i < (size >> 2U); ++i )
    {
    *read32 = m_host->hpiDataInc;
    read32++;
    }
    }