⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 upsd 3200序列的usb驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
    uchar index;

    // If this is data coming in (not a new command) ...
    if (rcvReport.u.cmd == 0)
    {
        // Process the incoming data based on the current command
        switch (currentCmd.u.cmd)
        {
        case CMD_WRITE:

            // Skip over command byte in first packet
            if (rcvIndex == 0)
            {
                if (cbReceived <= 1)
                {
                    // Error
                    return;
                }

                cbData = min(currentCmd.u.rw.nBytes, cbReceived - 1);
                index = rcvIndex + 1;
            }
            else
            {
                cbData = min(currentCmd.u.rw.nBytes, cbReceived);
                index = rcvIndex;
            }

            WriteBufferToFlash(
                currentCmd.u.rw.flash,
                currentCmd.u.rw.address,
                rcvReport.u.buffer + index,
                cbData);

            currentCmd.u.rw.address += cbData;
            currentCmd.u.rw.nBytes -= cbData;
            if (currentCmd.u.rw.nBytes == 0)
            {
                // All done
                currentCmd.u.cmd = 0;

                if (currentCmd.u.rw.flash == PRIMARY_FLASH)
                {
                    flash_reset();
                }
                else
                {
                    flash_boot_reset();
                }
            }
            
            break;

        default:

            break;
        }
    }
}

/////////////////// OnReportReceived()
//
// Called after all segments of a report have been received.

static void OnReportReceived()
{
    // If this is a new command coming in ...
    if (rcvReport.u.cmd)
    {
        if (rcvReport.u.cmd == CMD_STATUS)
        {
            // For CMD_GET_STATUS, don't overwrite current cmd we're working on
            returnStatus = TRUE;
        }
        else
        {
            // Copy into 'current command' global variable
            memcpy(currentCmd.u.buffer, rcvReport.u.buffer, sizeof(rcvReport));
            memset((uchar*)&status, 0, sizeof(status));

            g_debug1 = currentCmd.u.cmd;
        }

        // Some commands are processed at this point
        switch (rcvReport.u.cmd)
        {
        case CMD_RESET:
            WDKEY=0; // watchdog will trigger reset in a second
            currentCmd.u.cmd = 0;
            break;
        case CMD_SET_PAGE:
            UPSD_xreg.PAGE = rcvReport.u.setRegs.page;
            currentCmd.u.cmd = 0;
            break;
        case CMD_SET_VM:
            UPSD_xreg.VM = rcvReport.u.setRegs.vm;
            currentCmd.u.cmd = 0;
            break;
        case CMD_SET_REGS:
            UPSD_xreg.PAGE = rcvReport.u.setRegs.page;
            UPSD_xreg.VM = rcvReport.u.setRegs.vm;
            currentCmd.u.cmd = 0;
            break;
        default:
            // Prepare first segment of any response to go back to host
            PrepareTransmitSegment(0);
            break;
        }
    }
}

/////////////////// OnReportTransmitted()
//
// A complete feature report has been successfully transmitted.

static void OnReportTransmitted()
{
    if (returnStatus)
    {
        returnStatus = FALSE;
    }

    // If there's more data to go ...
    if (currentCmd.u.cmd)
    {
        // Prepare first segment of next report
        PrepareTransmitSegment(0);
    }
}

/////////////////// HandleReport()
//
// Handles HID Get_Report and Set_Report SETUP packets.
//
// Returns TRUE if the SETUP packet is a Get_Report or Set_Report
// request; else returns FALSE.

static BOOL HandleReport()
{
    // If it is a HID Set_Report request...
    if ((setupPacket.bmRequestType == CLASS_INTERFACE_TO_DEVICE)
        && (setupPacket.bRequest == HID_SET_REPORT))
    {
        // Prepare to receive report
        rcvIndex = 0;
        return TRUE;
    }
    // Else if it is a HID Get_Report request ...
    else if ((setupPacket.bmRequestType == CLASS_INTERFACE_TO_HOST)
        && (setupPacket.bRequest == HID_GET_REPORT))
    {
        // Transmit first segment of response (should be already prepared)
        UCON0 &= ~uTSEQ0;
        TransmitDataEP0(txReport.u.buffer, EP0_SIZE);

        // Prepare next segment while first one is going out
        txIndex = EP0_SIZE;
        PrepareTransmitSegment(txIndex);
        return TRUE;
    }

    return FALSE;
}

/////////////////// UsbIsr()
//
// USB interrupt service routine.

static void UsbIsr() interrupt USB_VECTOR
{
    uchar cb;
    uchar i;
    volatile uchar x;
    BOOL ret;
        
    // If data successfully transmitted on EP0 IN ...
    if (UISTA & uTXD0F)
    {
        // Reset transmit FIFO and clear transmit enable bit
        UCON0 |= (uRX0E | uTX0E | 8);
        UCON0 &= ~uTX0E;

        // If in the middle of transmitting a report ...
        if (txIndex < FEATURE_REPORT_SIZE)
        {
            // Transmit next segment of outgoing report
            cb = min(FEATURE_REPORT_SIZE - txIndex, EP0_SIZE);
            TransmitDataEP0(txReport.u.buffer + txIndex, cb);

            // Clear the interrupt and let the packet go out
            UISTA &= ~uTXD0F;

            if ((txIndex += cb) >= FEATURE_REPORT_SIZE)
            {
                OnReportTransmitted();
            }
            else
            {
                // Prepare the next segment while that last one is going out
                PrepareTransmitSegment(txIndex);
            }    
        }
        else
        {
            // Handle standard control requests
            BaseEp0TxHandler();

            // Clear the interrupt
            UISTA &= ~uTXD0F;
        }
    }

    // If data received on EP0 OUT ...
    if (UISTA & uRXD0F)
    {
        // If it's a SETUP packet ...
        if (USTA & uSETUP)
        {
            // Read the SETUP packet
            ret = ReadSetupPacket();

            // Clear interrupt so next packet can come in now
            UISTA &= ~uRXD0F;

            if (ret)
            {                
                // If this is not a HID report ...
                if (!HandleReport())
                {
                    // ... pass it on to the basic SETUP packet handler
                    OnSetupPacket();
                }
            }                    
        }
        else
        {
            // If in the middle of receiving a report ...
            if ((USTA & 0x0F) && (rcvIndex < OUTPUT_REPORT_SIZE))
            {
                // Read the next segment
                cb = USTA & 0x0F;
                for (i = 0; i < cb; i++)
                {
                    rcvReport.u.buffer[rcvIndex + i] = UDR0;
                }

                // Toggle data toggle bit
                USTA ^= uRSEQ;

                // Next packet can come in now
                UISTA &= ~uRXD0F;
            
                // Handle report as it comes in and/or when all done
                OnReportSegmentReceived(cb);
                if ((rcvIndex += cb) >= OUTPUT_REPORT_SIZE)
                {
                    OnReportReceived();
            
                    // Transmit 0 length ack packet
                    UCON0 = uTSEQ0 | uRX0E | uTX0E;
                }
            }
            else
            {
                // Toggle data toggle bit
                USTA ^= uRSEQ;

                // Next packet can come in now
                UISTA &= ~uRXD0F;
            }
        }
	}

    // If data transmitted on EP1 ...
    if (UISTA & uTXD1F)
    {
        // Load up next input report with LCD display data
        OnTransmitEP1();

        // Clear the interrupt
        UISTA &= ~uTXD1F;
    }

    // If there is a resume bus condition ...
    if (UISTA & uRESUMEF)
    {
        // Handle bus activity while in suspended state
        UISTA &= ~uRESUMEF;
    }

    // Handle suspend interrupt
    if (UISTA & uSUSPENDF)
    {
        UISTA &= ~uSUSPENDF;

        // Delay (from Hynix code)
        for (i = 10; i; i--)
        {
            x = i;
        }

        UCON1 |= uFRESUM;

        // Delay (from Hynix code)
        for (i = 6; i; i--)
        {
            x = i;
        }

        UCON1 &= ~uFRESUM;        
    }

    // Handle USB bus reset
    if (UISTA & uRSTF)
    {
        UISTA &= ~uRSTF;
        UsbInitialize();
    }

    // Just clear EOP interrupts
    UISTA &= ~(uEOPF);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -