亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專(zhuān)輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? hal_usb.c

?? 非常全的nrf2401設(shè)計(jì)資料
?? C
?? 第 1 頁(yè) / 共 2 頁(yè)
字號(hào):
/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRENTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 * $LastChangedRevision: 2290 $
 */ 

/** @file
 * Implementaion of the USB HAL
 * @author Ken A. Redergaard
 */

#include <intrins.h>
#include <stdint.h>

#include "nordic_common.h"
#include "hal_usb_desc.h"
#include "usb.h"

#include <Nordic\reg24lu1.h>

// Define formulas for jumping in the usb registry map based upon the endpoint number

// Calculate control and status register location in USB-controller
#define CALCULATE_CS_IN_PTR(ep) (uint8_t*)(&(i_usb.map->in1cs) + 2 * (  ( ep & 0x7f ) - 1 ))
#define CALCULATE_CS_OUT_PTR(ep) (uint8_t*)(&(i_usb.map->out1cs) + 2 * (  ( ep & 0x7f ) - 1 ))

// Calculate byte count register location in USB-controller
#define CALCULATE_BC_OUT_PTR(ep) (uint8_t*)(&(i_usb.map->out0bc) + ( ( ep ) * 2 ))
#define CALCULATE_BC_IN_PTR(ep) (uint8_t*)(&(i_usb.map->in0bc) + ( ( ep & 0x7f ) * 2 ))

// Calculate buffer location in USB-controller
#define CALCULATE_BUF_IN_PTR(ep) (uint8_t*)(i_usb.map->in0buf - ( ( ep & 0x7f ) * 128 ))
#define CALCULATE_BUF_OUT_PTR(ep) (uint8_t*)(i_usb.map->out0buf - ( ep * 128 ))

static xdata usb_t i_usb;
static hal_usb_device_req req;
hal_usb_t g_hal_usb;

static void packetize(uint8_t* data_ptr, uint8_t data_size, uint8_t pkt_size);
static void packetizer_isr_ep0_in();
static void usb_process_dev_req_cb_response(hal_usb_dev_req_resp_t ret, hal_usb_device_req* req, uint8_t* data_ptr, uint16_t size);
static void usb_process_get_status(hal_usb_device_req* req);
static void usb_process_get_descriptor(hal_usb_device_req* req);

static void isr_sudav();
static void isr_sof();
static void isr_sutok();
static void isr_suspend();
static void isr_usbreset();
static void isr_ep0out();

static void usb_process_ep_response(uint8_t ret, uint8_t* cs_ptr, uint8_t* bc_ptr);
static void delay_ms(uint8_t ms);

void hal_usb_init(
    bool usb_disconnect,
    hal_usb_cb_device_req_t device_req,
    hal_usb_cb_reset_t     reset,
    hal_usb_cb_resume_t    resume,
    hal_usb_cb_suspend_t   suspend)
{
     // Setup the USB struct.
    i_usb.map = (usb_map_t xdata*)0;

    // Setup descriptors
    g_hal_usb.descs.dev = &g_usb_dev_desc;
    g_hal_usb.descs.dev = &g_usb_dev_desc;
    g_hal_usb.descs.conf = &g_usb_conf_desc;
    g_hal_usb.descs.string = &g_usb_string_desc;

    // This is for setting language American English (String descriptor 0 is an array of supported languages)
    g_hal_usb.descs.string_zero[0] = 0x04;
    g_hal_usb.descs.string_zero[1] = 0x03;
    g_hal_usb.descs.string_zero[2] = 0x09;
    g_hal_usb.descs.string_zero[3] = 0x04;

    // Setup state information
    g_hal_usb.state = DEFAULT;
    g_hal_usb.bm_state = 0;

    // Setconfig configuration information
    g_hal_usb.current_config = 0;
    g_hal_usb.current_alt_interface = 0;
    
    // Setup callbacks
    g_hal_usb.device_req = device_req;
    g_hal_usb.reset = reset;
    g_hal_usb.resume = resume;
    g_hal_usb.suspend = suspend;

    // Disconnect from USB-bus if we are in this routine from a power on and not a soft reset
    if(usb_disconnect)
    {
        i_usb.map->usbcs |= 0x08; // disconnect
        delay_ms(50);
        i_usb.map->usbcs &= ~(0x08); // connect
    }

    // Setup interrupts
    USBWU = 1; // USBWU is mapped to IEN1.3
    USB = 1; // USBIRQ is mapped to IEN1.4

    i_usb.map->usbien = 0x1d; // ibnie -5 4 - uresir 3 - suspir, 0 - sudavir

    i_usb.map->in_ien = 0x01;
    i_usb.map->in_irq = 0x1f;
    i_usb.map->out_ien = 0x01;
    i_usb.map->out_irq = 0x1f;

    // Setup the USB RAM with some OK default values. Note that isochronos is not set up yet.
    i_usb.map->bout1addr = 16;
    i_usb.map->bout2addr = 32;
    i_usb.map->bout3addr = 48;
    i_usb.map->bout4addr = 64;
    i_usb.map->bout5addr = 80;

    i_usb.map->binstaddr = 0xc0;
    i_usb.map->bin1addr = 16;
    i_usb.map->bin2addr = 32;
    i_usb.map->bin3addr = 48;
    i_usb.map->bin4addr = 64;
    i_usb.map->bin5addr = 80;

    // Set all endpoints to not valid (except EP0IN and EP0OUT)
    i_usb.map->inbulkval = 0x01;
    i_usb.map->outbulkval = 0x01;
    i_usb.map->inisoval = 0x00;
    i_usb.map->outisoval = 0x00;
}

void hal_usb_endpoint_stall(uint8_t ep_num, bool stall)
{
    uint8_t temp;
    uint8_t* cs_ptr;

    temp = ep_num & 0x7f;

    // Calculate register address
    if( ( ep_num & 0x80 ) == 0x80 ) // IN endpoints
    {
        // Calculate control and status register for IN endpoint
        cs_ptr = (uint8_t*)(&(i_usb.map->in1cs) + 2 * ( temp - 1 ));
    }
    else // OUT endpoints
    {
        // Calculate control and status register for OUT endpoint
        cs_ptr = (uint8_t*)(&(i_usb.map->out1cs) + 2 * ( temp - 1 ));
    }

    if( stall == true )
    {
        // Set the stall bit
        *cs_ptr = 0x01;
    }
    else
    {
        // Clear the stall bit
        *cs_ptr = 0x00;
    }
}

uint8_t hal_usb_get_address()
{
    return i_usb.map->fnaddr;
}

void hal_usb_endpoint_config(uint8_t ep_num, uint8_t ep_size, hal_usb_cb_endpoint_t endpoint_isr)
{
    /// @todo Create a function that setup the usbram correctly
    xdata uint8_t *bc_ptr;
    uint8_t temp = ep_num & 0x7f;

    // Dummy use of variable to get rid of warning
    ep_size = 0;

    if( ( ep_num & 0x80 ) == 0x80 ) // MSB set indicates IN endpoint
    {
        if( endpoint_isr != NULL )
        {
            // Add the callback, enable the interrupt and validate the endpoint
            i_usb.endpoint_in_isr[temp - 1] = endpoint_isr;
            i_usb.map->in_ien |= ( 1 << temp ); 
            i_usb.map->inbulkval |= (1 << temp );
        }
        else
        {
            //lint --e{502}

            // Remove the callback, disable the interrupt and invalidate the endpoint
            i_usb.endpoint_in_isr[temp - 1] = NULL;
            i_usb.map->in_ien &= ~( 1 << temp );
            i_usb.map->inbulkval &= ~(1 << temp );
        }
    }
    else // OUT endpoint
    {
        if( endpoint_isr != NULL )
        {
            // Add the callback, enable the interrupt and validate the endpoint
            i_usb.endpoint_out_isr[temp - 1] = endpoint_isr;
            i_usb.map->out_ien |= ( 1 << temp );
            i_usb.map->outbulkval |= (1 << temp );

            // Have to write a dummy value to the OUTxBC register to get interrupts
            bc_ptr = CALCULATE_BC_OUT_PTR(ep_num);
            *bc_ptr = 0xff;
        }
        else
        {
            //lint --e{502}

            // Remove the callback, disable the interrupt and invalidate the endpoint

            i_usb.endpoint_out_isr[temp - 1] = NULL;
            i_usb.map->out_ien &= ~( 1 << temp );
            i_usb.map->outbulkval &= ~(1 << temp );
        }
    }
}

void hal_usb_wakeup()
{
    // We can only issue a wakeup if the host has allowed us to do so
    if( ( g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP )
    {
        USBCON = 0x40;  // Wakeup the USB controller via remote pin
        delay_ms(1);    // Wait until the USB clock starts
        USBCON = 0x00;
    }
}

void hal_usb_reset()
{
    SWRST = 1;  // Perform a hardware reset of the USB controller
}

hal_usb_state_t hal_usb_get_state()
{
    return g_hal_usb.state;
}

void hal_usb_send_data(uint8_t ep_num, uint8_t* array, uint8_t count)
{
    uint8_t i;

    xdata uint8_t *buf_ptr;
    xdata uint8_t *bc_ptr;

    // Calculate the buffer pointer and byte count pointer
    buf_ptr = CALCULATE_BUF_IN_PTR(ep_num);
    bc_ptr = CALCULATE_BC_IN_PTR(ep_num);

    // Copy the data into the USB controller
    for( i = 0; i < count; i++ )
    {
        buf_ptr[i] = array[i];
    }
    
    // Set the number of bytes we want to send to USB-host. This also trigger sending of data to USB-host.
    *bc_ptr = count;
}

void hal_usb_bus_disconnect()
{
    i_usb.map->usbcs |= 0x08; // disconnect
}

void hal_usb_bus_connect()
{
    i_usb.map->usbcs &= ~(0x08); // connect
}

void hal_usb_sleep()
{
    USBSLP=1;
}
 
static void packetize(uint8_t* data_ptr, uint8_t data_size, uint8_t pkt_size)
{
     i_usb.packetizer.data_ptr = data_ptr;
     i_usb.packetizer.data_size = data_size;
     i_usb.packetizer.pkt_size = pkt_size;
}

// This routine is called by functions that shall send their first packet and when the EP0IN interrupt is set
static void packetizer_isr_ep0_in() 
{
    uint16_t size, i;

    // We are getting a ep0in interupt when the host send ACK and do not have any more data to send
    if( i_usb.packetizer.data_size == 0 )
    {
        i_usb.map->in0bc = 0;
        USB_EP0_HSNAK();

        //USB_EP0_DSTALL();
        return;
    }

    size = MIN(i_usb.packetizer.data_size, i_usb.packetizer.pkt_size);

    // Copy data to the USB-controller buffer
    for( i = 0; i < size; i++ )
    {
        i_usb.map->in0buf[i] = i_usb.packetizer.data_ptr[i];
    }

    // Tell the USB-controller how many bytes to send
    // If a IN is received from host after this the USB-controller will send the data
    i_usb.map->in0bc = size;

    // Update the packetizer data
    i_usb.packetizer.data_ptr += size;
    i_usb.packetizer.data_size -= size;

    return;
}

/** This function processes the response from the callback */
static void usb_process_dev_req_cb_response(hal_usb_dev_req_resp_t ret, hal_usb_device_req* req, uint8_t* data_ptr, uint16_t size)
{
    switch( ret )
    {
    case STALL:
        USB_EP0_STALL();
        break;
    case DATA:
        packetize(data_ptr, MIN(LSB(req->wLength), size), g_hal_usb.descs.dev->bMaxPacketSize0);
        packetizer_isr_ep0_in();
        break;
    case NO_RESPONSE:
        break;
    case EMPTY_RESPONSE:
        USB_EP0_HSNAK();
        break;
    case NAK:
        USB_EP0_HSNAK();
        break;
    case ACK:
        i_usb.map->out0bc = 0xff;
        break;
    default:
        USB_EP0_STALL();
        break;
    }
}

static void usb_process_get_status(hal_usb_device_req* req)
{
    uint8_t* ptr;

    if( g_hal_usb.state == ADDRESSED )
    {
        if( LSB(req->wIndex) != 0x00 )
        {
            USB_EP0_STALL();
        }
        else
        {
            i_usb.map->in0buf[0] = i_usb.map->in0buf[1] = 
                ((g_hal_usb.descs.conf->conf.bmAttributes & 0x40 ) >> 6); // D0 - 0: bus powered, 1: self powered
            i_usb.map->in0bc = 0x02;
        }
    }
    else if( g_hal_usb.state == CONFIGURED )
    {
        switch(req->bmRequestType)
        {
            case 0x80: // Device
                if( ( g_hal_usb.bm_state & USB_BM_STATE_ALLOW_REMOTE_WAKEUP ) == USB_BM_STATE_ALLOW_REMOTE_WAKEUP )
                {
                    i_usb.map->in0buf[0] = 0x02;
                }
                else
                {
                    i_usb.map->in0buf[0] = 0x00;
                }

                i_usb.map->in0buf[0] |= ((g_hal_usb.descs.conf->conf.bmAttributes & 0x40 ) >> 6); // D0 - 0: bus powered, 1: self powered
                i_usb.map->in0buf[1] = 0x00; // Reserved (Reset to zero)
                i_usb.map->in0bc = 0x02;
                break;
            case 0x81: // Interface
                i_usb.map->in0buf[0] = i_usb.map->in0buf[1] = 0x00;
                i_usb.map->in0bc = 0x02;
                break;
            case 0x82: // Endpoint
                if( ( LSB(req->wIndex) & 0x80 ) == 0x80 ) // IN endpoints
                {
                    ptr = CALCULATE_CS_IN_PTR(req->wIndex);
                }
                else
                {
                    ptr = CALCULATE_CS_OUT_PTR(req->wIndex);
                }

                i_usb.map->in0buf[0] = *ptr & 0x01;
                i_usb.map->in0buf[1] = 0x00;
                i_usb.map->in0bc = 0x02;
                break;
            default:
                USB_EP0_STALL();
                break;
        } // switch(req.bmRequestType) --end--
    }
    else
    {
        // We should not be in this state
        USB_EP0_STALL();
    }
}

static void usb_process_get_descriptor(hal_usb_device_req* req)
{
    hal_usb_dev_req_resp_t ret;
    uint8_t* data_ptr;
    uint16_t data_size;

    // Switch on descriptor type
    switch( MSB(req->wValue) )
    {
        case USB_DESC_DEVICE:
            packetize((uint8_t*)g_hal_usb.descs.dev,
            MIN(req->wLength, sizeof(hal_usb_dev_desc_t)),
            g_hal_usb.descs.dev->bMaxPacketSize0);
            packetizer_isr_ep0_in();
            break;
        case USB_DESC_CONFIGURATION:
            // For now we just support one configuration. The asked configuration is stored in LSB(wValue).
            packetize((uint8_t*)g_hal_usb.descs.conf,
                MIN(LSB(req->wLength), sizeof(usb_conf_desc_templ_t)),
                g_hal_usb.descs.dev->bMaxPacketSize0);
                packetizer_isr_ep0_in();
            break;
        case USB_DESC_STRING:
            // For now we just support english as string descriptor language.

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人国产精品免费网站| 91在线国内视频| 色一区在线观看| 精品久久一区二区| 亚洲福利视频三区| www.日韩在线| 精品久久久久一区二区国产| 亚洲精品视频在线看| 国产精品18久久久久久vr| 欧美性受xxxx| 一区免费观看视频| 国产乱人伦偷精品视频免下载| 制服丝袜日韩国产| 亚洲综合免费观看高清完整版在线| 国产福利视频一区二区三区| 日韩欧美自拍偷拍| 午夜一区二区三区视频| 色吧成人激情小说| 欧美经典一区二区三区| 激情六月婷婷久久| 日韩一级免费一区| 亚洲综合丝袜美腿| 91亚洲国产成人精品一区二三| 国产性做久久久久久| 久久99久久99| 欧美一区二区三区的| 午夜亚洲国产au精品一区二区| 欧美主播一区二区三区| 亚洲男女一区二区三区| 99国产一区二区三精品乱码| 日本一区二区三区免费乱视频| 国产精品99久久久久久久女警 | 久久精品国产99国产| 欧美日本视频在线| 亚洲福利一二三区| 欧美唯美清纯偷拍| 亚洲国产aⅴ成人精品无吗| 色婷婷av一区二区三区gif| 国产精品丝袜久久久久久app| 国产美女av一区二区三区| 精品国产制服丝袜高跟| 久久精品国产免费| 精品国产百合女同互慰| 久久99热狠狠色一区二区| 欧美大片在线观看一区| 久久精品国产亚洲高清剧情介绍 | 国产精品亚洲一区二区三区在线| 欧美tickling挠脚心丨vk| 久久国产精品色婷婷| 久久久亚洲精华液精华液精华液| 国产精品一区二区三区四区| 国产视频不卡一区| www.亚洲精品| 亚洲免费高清视频在线| 欧美视频精品在线观看| 三级一区在线视频先锋 | 色88888久久久久久影院野外| 亚洲乱码日产精品bd| 欧洲生活片亚洲生活在线观看| 亚洲3atv精品一区二区三区| 欧美一级理论片| 国产综合色在线| 国产精品色哟哟| 91高清视频在线| 三级久久三级久久久| 欧美精品一区二区三区蜜桃视频| 国产成人午夜99999| 亚洲色欲色欲www在线观看| 欧美日韩在线播放一区| 麻豆国产精品一区二区三区| 久久精品综合网| 色婷婷久久一区二区三区麻豆| 亚洲高清免费观看高清完整版在线观看| 欧美一区二区三区在线观看视频| 国产精品自拍在线| 亚洲六月丁香色婷婷综合久久 | 欧美视频在线观看一区| 日本亚洲免费观看| 国产日本欧洲亚洲| 欧美一a一片一级一片| 久久se这里有精品| 国产精品天天看| 欧美日韩一区二区在线观看视频| 麻豆一区二区在线| 中文字幕一区二区三区视频| 欧美日韩一区二区在线观看视频 | 91日韩一区二区三区| 日韩美女精品在线| 69成人精品免费视频| 国产美女一区二区三区| 亚洲六月丁香色婷婷综合久久| 国产精品美女久久福利网站| 色天天综合久久久久综合片| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产视频911| 欧美久久高跟鞋激| 国产精品911| 首页综合国产亚洲丝袜| 久久精品视频一区二区三区| 在线观看国产精品网站| 国产一区二区三区免费| 亚洲在线成人精品| 中文字幕在线不卡一区二区三区| 91浏览器在线视频| 麻豆精品蜜桃视频网站| 亚洲精品国产a| 久久综合色鬼综合色| 欧美午夜影院一区| 大胆欧美人体老妇| 日本aⅴ精品一区二区三区| 亚洲桃色在线一区| 2023国产精品| 欧洲国产伦久久久久久久| 国产精品亚洲第一区在线暖暖韩国| 亚洲第一成人在线| 国产精品久久福利| 精品三级在线观看| 欧美日韩国产综合一区二区三区| 夫妻av一区二区| 麻豆精品国产传媒mv男同| 亚洲无人区一区| 中文字幕一区二区三区色视频| 精品国产一区二区亚洲人成毛片| 欧美日韩一区不卡| 91老师片黄在线观看| 国产大片一区二区| 久久国产精品99久久久久久老狼 | 久久亚洲综合色一区二区三区| 欧美日韩一区在线| 91麻豆国产自产在线观看| 国产suv精品一区二区883| 久久国产精品区| 日本不卡一二三区黄网| 亚洲va国产天堂va久久en| 亚洲色欲色欲www| 国产精品日产欧美久久久久| 26uuu精品一区二区三区四区在线| 56国语精品自产拍在线观看| 色综合久久天天综合网| av午夜一区麻豆| 国产99精品国产| 国产成人综合在线观看| 国内精品久久久久影院色| 美女网站色91| 久久国产视频网| 久久99精品国产麻豆婷婷| 日韩和欧美一区二区| 视频在线观看一区二区三区| 亚洲成人黄色影院| 亚洲一区二区三区四区不卡| 亚洲精品videosex极品| 亚洲欧美一区二区三区孕妇| 国产精品久久久99| 一区视频在线播放| 亚洲人成小说网站色在线 | 制服丝袜中文字幕一区| 777奇米四色成人影色区| 欧美一区二区三区四区五区| 欧美熟乱第一页| 欧美精品在线观看播放| 91麻豆精品国产91久久久| 337p亚洲精品色噜噜狠狠| 日韩午夜中文字幕| 精品福利视频一区二区三区| 精品国产网站在线观看| 精品国产1区二区| 久久久精品日韩欧美| 日本一区二区久久| 国产精品国产馆在线真实露脸| 国产精品美女一区二区三区 | 精品日韩在线一区| 欧美sm美女调教| 久久亚洲综合av| 国产精品三级av| 亚洲色图清纯唯美| 亚洲影院免费观看| 婷婷综合久久一区二区三区| 视频一区欧美精品| 精品系列免费在线观看| 国产精品影音先锋| 粉嫩av亚洲一区二区图片| 成人av第一页| 欧美自拍偷拍一区| 欧美一区二区三区在线视频| 久久这里只有精品6| 欧美韩国日本不卡| 亚洲蜜臀av乱码久久精品| 亚洲无人区一区| 麻豆精品一区二区综合av| 国产久卡久卡久卡久卡视频精品| 成人h动漫精品| 欧洲日韩一区二区三区| 欧美一级黄色大片| 中文字幕欧美三区| 亚洲一区二区三区美女| 蜜桃av噜噜一区| 不卡影院免费观看| 欧美欧美欧美欧美| 久久精品一区四区| 一区二区三区在线视频观看|