コード例 #1
0
ファイル: cs8900a.c プロジェクト: HITEG/TenByTen6410_MLC
//------------------------------------------------------------------------------
//
//  Function:  CS8900AGetFrame
//
UINT16 CS8900AGetFrame(UINT8 *pData, UINT16 *pLength)
{
    UINT16 isq, length, status, count, data;

    OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
        L"+CS8900AGetFrame(0x%08x, %d)\r\n", pData, *pLength
    ));

    length = 0;
    isq = INPORT16(&g_pCS8900->ISQ);
    if ((isq & ISQ_ID_MASK) == RX_EVENT_ID && (isq & RX_EVENT_RX_OK) != 0) {

        // Get RxStatus and length
        status = INPORT16(&g_pCS8900->DATA0);
        length = INPORT16(&g_pCS8900->DATA0);

        if (length > *pLength) {
            // If packet doesn't fit in buffer, skip it
            data = ReadPacketPage(RX_CFG);
            WritePacketPage(RX_CFG, data | RX_CFG_SKIP_1);
            length = 0;
        } else {
            // Read packet data
            count = length;
            while (count > 1) {
                data = INPORT16(&g_pCS8900->DATA0);
                *(UINT16*)pData = data;
                pData += sizeof(UINT16);
                count -= sizeof(UINT16);
            }

            // Read last one byte
            if (count > 0) {
                data = INPORT16(&g_pCS8900->DATA0);
                *pData = (UINT8)data;
            }
        }
    }

    // Return packet size
    *pLength = length;

    OALMSGS(OAL_ETHER&&OAL_VERBOSE, (
        L"-CS8900AGetFrame(length = %d)\r\n", length
    ));
    return length;
}
コード例 #2
0
ファイル: cs8900a.c プロジェクト: Phong005/aeroboot
//------------------------------------------------------------------------------
//
//  Function:  CS8900AGetFrame
//
UINT16
CS8900AGetFrame(UINT8 *pData, UINT16 *pLength)
{
    UINT16 isq, length, status, count, data;
    UINT16 DeviceInterrupt;
    BOOL   GlobalInterrupt;

    OALMSGS(OAL_ETHER && OAL_VERBOSE, (
        L"+CS8900AGetFrame(0x%08x, %d)\r\n", pData, *pLength
    ));

    //
    // This routine could be interrupt driven, or polled.
    // When polled, it keeps the emulator so busy that it
    // starves other threads. The emulator already has the
    // ability to recognize the polling in the bootloader
    // by noting whether the interrupt for this device is
    // disabled. In order to make the emulator recognize it
    // here as well, we need to detect the polling by noting
    // that *global* interrupts are disabled, then disable at
    // the device level as well if so.
    //
    GlobalInterrupt = INTERRUPTS_ENABLE(FALSE);	// Disable to obtain state
    INTERRUPTS_ENABLE(GlobalInterrupt);          // Immediately restore it.

    // Mimic the global interrupt state at the device level too.
    if (!GlobalInterrupt)	// If polled
    {
        // Disable at the device level too so the emulator knows we're polling.
        // Now it can yeild to other threads on the host side.
        DeviceInterrupt = ReadPacketPage(BUS_CTL);
        WritePacketPage(BUS_CTL, DeviceInterrupt & ~BUS_CTL_ENABLE_IRQ);
        DeviceInterrupt &= BUS_CTL_ENABLE_IRQ;
    }
        
    length = 0;
    isq = INPORT16(&g_pCS8900->ISQ);

    if ((isq & ISQ_ID_MASK) == RX_EVENT_ID
    &&  (isq & RX_EVENT_RX_OK) != 0)
    {
        // Get RxStatus and length
        status = INPORT16(&g_pCS8900->DATA0);
        length = INPORT16(&g_pCS8900->DATA0);

        if (length > *pLength)
        {
            // If packet doesn't fit in buffer, skip it
            data = ReadPacketPage(RX_CFG);
            WritePacketPage(RX_CFG, data | RX_CFG_SKIP_1);
            length = 0;
        } else {
            // Read packet data
            count = length;
            while (count > 1)
            {
                data = INPORT16(&g_pCS8900->DATA0);
                *(UINT16*)pData = data;
                pData += sizeof *(UINT16*)pData;
                count -= sizeof *(UINT16*)pData;
            }

            // Read last one byte
            if (count > 0)
            {
                data = INPORT16(&g_pCS8900->DATA0);
                *pData = (UINT8)data;
            }
        }
    }

    if (!GlobalInterrupt)	// If polled
    {
        if (DeviceInterrupt)    // If it was enabled at the device level,
        {
            // Re-enable at the device level.
            CS8900AEnableInts();
        }
    }

    // Return packet size
    *pLength = length;

    OALMSGS(OAL_ETHER && OAL_VERBOSE, (
        L"-CS8900AGetFrame(length = %d)\r\n", length
    ));

    return (length);
}