Example #1
0
/******************************************************************************
 * Function:        byte USBGenRead(byte *buffer, byte len)
 *
 * PreCondition:    Value of input argument 'len' should be smaller than the
 *                  maximum endpoint size responsible for receiving report
 *                  data from USB host for HID class.
 *                  Input argument 'buffer' should point to a buffer area that
 *                  is bigger or equal to the size specified by 'len'.
 *
 * Input:           buffer  : Pointer to where received bytes are to be stored
 *                  len     : The number of bytes expected.
 *
 * Output:          The number of bytes copied to buffer.
 *
 * Side Effects:    Publicly accessible variable usbgen_rx_len is updated
 *                  with the number of bytes copied to buffer.
 *                  Once USBGenRead is called, subsequent retrieval of
 *                  usbgen_rx_len can be done by calling macro
 *                  mUSBGenGetRxLength().
 *
 * Overview:        USBGenRead copies a string of bytes received through
 *                  the OUT endpoint to a user's specified location. 
 *                  It is a non-blocking function. It does not wait
 *                  for data if there is no data available. Instead it returns
 *                  '0' to notify the caller that there is no data available.
 *
 * Note:            If the actual number of bytes received is larger than the
 *                  number of bytes expected (len), only the expected number
 *                  of bytes specified will be copied to buffer.
 *                  If the actual number of bytes received is smaller than the
 *                  number of bytes expected (len), only the actual number
 *                  of bytes received will be copied to buffer.
 *****************************************************************************/
byte USBGenRead(byte *buffer, byte len)
{
    usbgen_rx_len = 0;
    
    if(!mUSBGenRxIsBusy())
    {
        /*
         * Adjust the expected number of bytes to equal
         * the actual number of bytes received.
         */
        if(len > USBGEN_BD_OUT.Cnt)
            len = USBGEN_BD_OUT.Cnt;
        
        /*
         * Copy data from dual-ram buffer to user's buffer
         */
        for(usbgen_rx_len = 0; usbgen_rx_len < len; usbgen_rx_len++)
            buffer[usbgen_rx_len] = usbgen_out[usbgen_rx_len];

        /*
         * Prepare dual-ram buffer for next OUT transaction
         */
        USBGEN_BD_OUT.Cnt = sizeof(usbgen_out);
        mUSBBufferReady(USBGEN_BD_OUT);
    }//end if
    
    return usbgen_rx_len;
    
}//end USBGenRead
Example #2
0
/******************************************************************************
 * Function:        byte HIDRxReport(char *buffer, byte len)
 *
 * PreCondition:    Value of input argument 'len' should be smaller than the
 *                  maximum endpoint size responsible for receiving report
 *                  data from USB host for HID class.
 *                  Input argument 'buffer' should point to a buffer area that
 *                  is bigger or equal to the size specified by 'len'.
 *
 * Input:           buffer  : Pointer to where received bytes are to be stored
 *                  len     : The number of bytes expected.
 *
 * Output:          The number of bytes copied to buffer.
 *
 * Side Effects:    Publicly accessible variable hid_rpt_rx_len is updated
 *                  with the number of bytes copied to buffer.
 *                  Once HIDRxReport is called, subsequent retrieval of
 *                  hid_rpt_rx_len can be done by calling macro
 *                  mHIDGetRptRxLength().
 *
 * Overview:        HIDRxReport copies a string of bytes received through
 *                  USB HID OUT endpoint to a user's specified location.
 *                  It is a non-blocking function. It does not wait
 *                  for data if there is no data available. Instead it returns
 *                  '0' to notify the caller that there is no data available.
 *
 * Note:            If the actual number of bytes received is larger than the
 *                  number of bytes expected (len), only the expected number
 *                  of bytes specified will be copied to buffer.
 *                  If the actual number of bytes received is smaller than the
 *                  number of bytes expected (len), only the actual number
 *                  of bytes received will be copied to buffer.
 *****************************************************************************/
uint8_t HIDRxReport(char *buffer, uint8_t len)
{
    hid_rpt_rx_len = 0;

    if(!mHIDRxIsBusy())
    {
        /*
         * Adjust the expected number of bytes to equal
         * the actual number of bytes received.
         */
        if(len > HID_BD_OUT.Cnt)
            len = HID_BD_OUT.Cnt;

        /*
         * Copy data from dual-ram buffer to user's buffer
         */
        for(hid_rpt_rx_len = 0; hid_rpt_rx_len < len; hid_rpt_rx_len++)
            buffer[hid_rpt_rx_len] = hid_report_out[hid_rpt_rx_len];

        /*
         * Prepare dual-ram buffer for next OUT transaction
         */
        HID_BD_OUT.Cnt = sizeof(hid_report_out);
        mUSBBufferReady(HID_BD_OUT);
    }//end if

    return hid_rpt_rx_len;

}//end HIDRxReport
Example #3
0
/******************************************************************************
 * Function:        byte getsUSBUSART(char *buffer,
 *                                    byte len)
 *
 * PreCondition:    Value of input argument 'len' should be smaller than the
 *                  maximum endpoint size responsible for receiving bulk
 *                  data from USB host for CDC class.
 *                  Input argument 'buffer' should point to a buffer area that
 *                  is bigger or equal to the size specified by 'len'.
 *
 * Input:           buffer  : Pointer to where received bytes are to be stored
 *                  len     : The number of bytes expected.
 *
 * Output:          The number of bytes copied to buffer.
 *
 * Side Effects:    Publicly accessible variable cdc_rx_len is updated with
 *                  the number of bytes copied to buffer.
 *                  Once getsUSBUSART is called, subsequent retrieval of
 *                  cdc_rx_len can be done by calling macro mCDCGetRxLength().
 *
 * Overview:        getsUSBUSART copies a string of bytes received through
 *                  USB CDC Bulk OUT endpoint to a user's specified location. 
 *                  It is a non-blocking function. It does not wait
 *                  for data if there is no data available. Instead it returns
 *                  '0' to notify the caller that there is no data available.
 *
 * Note:            If the actual number of bytes received is larger than the
 *                  number of bytes expected (len), only the expected number
 *                  of bytes specified will be copied to buffer.
 *                  If the actual number of bytes received is smaller than the
 *                  number of bytes expected (len), only the actual number
 *                  of bytes received will be copied to buffer.
 *****************************************************************************/
byte getsUSBUSART(char *buffer, byte len)
{
    cdc_rx_len = 0;
    
    if(!mCDCUsartRxIsBusy())
    {
        /*
         * Adjust the expected number of bytes to equal
         * the actual number of bytes received.
         */
        if(len > CDC_BULK_BD_OUT.Cnt)
            len = CDC_BULK_BD_OUT.Cnt;
        
        /*
         * Copy data from dual-ram buffer to user's buffer
         */
        for(cdc_rx_len = 0; cdc_rx_len < len; cdc_rx_len++)
            buffer[cdc_rx_len] = cdc_data_rx[cdc_rx_len];

        /*
         * Prepare dual-ram buffer for next OUT transaction
         */
        CDC_BULK_BD_OUT.Cnt = sizeof(cdc_data_rx);
        mUSBBufferReady(CDC_BULK_BD_OUT);
    }//end if
    
    return cdc_rx_len;
    
}//end getsUSBUSART
Example #4
0
/******************************************************************************
 * Function:        void HIDTxReport(char *buffer, byte len)
 *
 * PreCondition:    mHIDTxIsBusy() must return false.
 *
 *                  Value of 'len' must be equal to or smaller than
 *                  HID_INT_IN_EP_SIZE
 *                  For an interrupt endpoint, the largest buffer size is
 *                  64 bytes.
 *
 * Input:           buffer  : Pointer to the starting location of data bytes
 *                  len     : Number of bytes to be transferred
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Use this macro to transfer data located in data memory.
 *
 *                  Remember: mHIDTxIsBusy() must return false before user
 *                  can call this function.
 *                  Unexpected behavior will occur if this function is called
 *                  when mHIDTxIsBusy() == 0
 *
 *                  Typical Usage:
 *                  if(!mHIDTxIsBusy())
 *                      HIDTxReport(buffer, 3);
 *
 * Note:            None
 *****************************************************************************/
void HIDTxReport(char *buffer, uint8_t len)
{
    uint8_t i;

    /*
     * Value of len should be equal to or smaller than HID_INT_IN_EP_SIZE.
     * This check forces the value of len to meet the precondition.
     */
    if(len > HID_INT_IN_EP_SIZE)
        len = HID_INT_IN_EP_SIZE;

    /*
     * Copy data from user's buffer to a USB module accessible RAM packet buffer
     */
    for (i = 0; i < len; i++)
        hid_report_in[i] = buffer[i];

    HID_BD_IN.Cnt = len;
    mUSBBufferReady(HID_BD_IN);

}//end HIDTxReport
Example #5
0
/******************************************************************************
 * Function:        void USBGenWrite(byte *buffer, byte len)
 *
 * PreCondition:    mUSBGenTxIsBusy() must return false.
 *
 *                  Value of 'len' must be equal to or smaller than
 *                  USBGEN_EP_SIZE
 *                  For an interrupt/bulk endpoint, the largest buffer size is
 *                  64 bytes.
 *
 * Input:           buffer  : Pointer to the starting location of data bytes
 *                  len     : Number of bytes to be transferred
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Use this macro to transfer data located in data memory.
 *
 *                  Remember: mUSBGenTxIsBusy() must return false before user
 *                  can call this function.
 *                  Unexpected behavior will occur if this function is called
 *                  when mUSBGenTxIsBusy() != 0
 *
 *                  Typical Usage:
 *                  if(!mUSBGenTxIsBusy())
 *                      USBGenWrite(buffer, 3);
 *
 * Note:            None
 *****************************************************************************/
void USBGenWrite(byte *buffer, byte len)
{
	byte i;
	
    /*
     * Value of len should be equal to or smaller than USBGEN_EP_SIZE.
     * This check forces the value of len to meet the precondition.
     */
	if(len > USBGEN_EP_SIZE)
	    len = USBGEN_EP_SIZE;

   /*
    * Copy data from user's buffer to dual-ram buffer
    */
    for (i = 0; i < len; i++)
    	usbgen_in[i] = buffer[i];

    USBGEN_BD_IN.Cnt = len;
    mUSBBufferReady(USBGEN_BD_IN);

}//end USBGenWrite
Example #6
0
void BootService(void)
{
    BlinkUSBStatus();
    if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
    
    if(trf_state == SENDING_RESP)
    {
        if(!mBootTxIsBusy())
        {
            BOOT_BD_OUT.Cnt = sizeof(dataPacket);
            mUSBBufferReady(BOOT_BD_OUT);
            trf_state = WAIT_FOR_CMD;
        }//end if
        return;
    }//end if
    
    if(!mBootRxIsBusy())
    {
        counter = 0;
        switch(dataPacket.CMD)
        {
            case READ_VERSION:
                ReadVersion();
                counter=0x04;
                break;

            case READ_FLASH:
            case READ_CONFIG:
                ReadProgMem();
                counter+=0x05;
                break;

            case WRITE_FLASH:
                WriteProgMem();
                counter=0x01;
                break;

            case ERASE_FLASH:
                EraseProgMem();
                counter=0x01;
                break;

            case READ_EEDATA:
                ReadEE();
                counter+=0x05;
                break;

            case WRITE_EEDATA:
                WriteEE();
                counter=0x01;
                break;

            case WRITE_CONFIG:
                WriteConfig();
                counter=0x01;
                break;
            
            case RESET:
                //When resetting, make sure to drop the device off the bus
                //for a period of time. Helps when the device is suspended.
                UCONbits.USBEN = 0;
                big_counter = 0;
                while(--big_counter);
                
                Reset();
                break;
            
            case UPDATE_LED:
                if(dataPacket.led_num == 3)
                {
                    mLED_3 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                if(dataPacket.led_num == 4)
                {
                    mLED_4 = dataPacket.led_status;
                    counter = 0x01;
                }//end if
                break;
                
            default:
                break;
        }//end switch()
        trf_state = SENDING_RESP;
        if(counter != 0)
        {
            BOOT_BD_IN.Cnt = counter;
            mUSBBufferReady(BOOT_BD_IN);
        }//end if
    }//end if
}//end BootService
Example #7
0
/******************************************************************************
 * Function:        void CDCTxService(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        CDCTxService handles device-to-host transaction(s).
 *                  This function should be called once per Main Program loop.
 *
 * Note:            None
 *****************************************************************************/
void CDCTxService(void)
{
    byte byte_to_send;
    
    if(mCDCUsartTxIsBusy()) return;
    /*
     * Completing stage is necessary while [ mCDCUSartTxIsBusy()==1 ].
     * By having this stage, user can always check cdc_trf_state,
     * and not having to call mCDCUsartTxIsBusy() directly.
     */
    if(cdc_trf_state == CDC_TX_COMPLETING)
        cdc_trf_state = CDC_TX_READY;
    
    /*
     * If CDC_TX_READY state, nothing to do, just return.
     */
    if(cdc_trf_state == CDC_TX_READY) return;
    
    /*
     * If CDC_TX_BUSY_ZLP state, send zero length packet
     */
    if(cdc_trf_state == CDC_TX_BUSY_ZLP)
    {
        CDC_BULK_BD_IN.Cnt = 0;
        cdc_trf_state = CDC_TX_COMPLETING;
    }
    else if(cdc_trf_state == CDC_TX_BUSY)
    {
        /*
         * First, have to figure out how many byte of data to send.
         */
    	if(cdc_tx_len > sizeof(cdc_data_tx))
    	    byte_to_send = sizeof(cdc_data_tx);
    	else
    	    byte_to_send = cdc_tx_len;

        /*
         * Next, load the number of bytes to send to Cnt in buffer descriptor
         */
        CDC_BULK_BD_IN.Cnt = byte_to_send;

        /*
         * Subtract the number of bytes just about to be sent from the total.
         */
    	cdc_tx_len = cdc_tx_len - byte_to_send;
    	        
        pCDCDst.bRam = (byte*)&cdc_data_tx; // Set destination pointer
        
        if(cdc_mem_type == _ROM)            // Determine type of memory source
        {
            while(byte_to_send)
            {
                *pCDCDst.bRam = *pCDCSrc.bRom;
                pCDCDst.bRam++;
                pCDCSrc.bRom++;
                byte_to_send--;
            }//end while(byte_to_send)
        }
        else // _RAM
        {
            while(byte_to_send)
            {
                *pCDCDst.bRam = *pCDCSrc.bRam;
                pCDCDst.bRam++;
                pCDCSrc.bRam++;
                byte_to_send--;
            }//end while(byte_to_send._word)
        }//end if(cdc_mem_type...)
        
        /*
         * Lastly, determine if a zero length packet state is necessary.
         * See explanation in USB Specification 2.0: Section 5.8.3
         */
        if(cdc_tx_len == 0)
        {
            if(CDC_BULK_BD_IN.Cnt == sizeof(cdc_data_tx))
                cdc_trf_state = CDC_TX_BUSY_ZLP;
            else
                cdc_trf_state = CDC_TX_COMPLETING;
        }//end if(cdc_tx_len...)
            
    }//end if(cdc_tx_sate == CDC_TX_BUSY)
    
    /*
     * Both CDC_TX_BUSY and CDC_TX_BUSY_ZLP states use the following macro
     */
    mUSBBufferReady(CDC_BULK_BD_IN);

}//end CDCTxService