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

📄 sl811.c

📁 基于ARM7的直流电机的驱动,还有FLASH驱动,LCD驱动等
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "defs.h"
#include "44b0x.h"
#include "usb.h"
#include "sl811.h"
#include <avt.h>
#include <stdarg.h>

// U盘设备地址
#define	USB_ADDR		1

// 主机控制器中断允许位
#define INTS			(SL_INTEN_DONE_A | SL_INTEN_Insert/* | SL_INTEN_SOF*/)

// USB请求返回值类型
#define	ISR_CONTINUE	0 // 还有后续步骤
#define ISR_REPEAT	1 // 重复该步骤
#define ISR_ERROR	2 // 错误
#define ISR_DONE	3 // 结束本请求
#define ISR_SUSPEND	4 // 挂起

// 中断的开、关
#define PSW			int psw;
#define DISABLE			psw = interrupts_disable()
#define ENABLE			interrupts_enable(psw)

//////////////////////////////////////////////////////////
void SL811Handler(void);
void udelay(UINT us);
void mdelay(UINT ms);
void sm_init(UINT);

//////////////////////////////////////////////////////////
static HC		SL811;	  // USB主控制器
static MASS_STOR	MassStor; // U盘结构
DRIVE			UsbDsk;	  // U盘驱动器
UINT			smSL811;  // 信号量

// 调试输出
void
DbgOut(const char *fmt, ...) {
	va_list ap;
	PSW
	static char	buf[1024];
  
  	psw = interrupts_disable();
	va_start(ap, fmt);
	myvsprintf(buf, fmt, ap);
	va_end(ap);
	interrupts_enable(psw);
	
	bsp_puts(buf);
}

// 诊断失败
// f: 文件
// l: 行
// expr: 表达式
//
void
__assert(const char *f, int l, const char *expr) {

	interrupts_disable();

	DbgOut("%s:%u `%s`", f, l, expr);
	while(1);
}

///////////////////////////////////////////////////////////
// 读主控制器寄存器
//
// hc: 主控制器
// reg:寄存器
//
static UCHAR
hc_read(HC *hc, UCHAR reg) {
	outb(hc->AddrPort, reg);
	return inb(hc->DataPort);
}

// 写主控制器寄存器
//
// hc: 主控制器
// reg:寄存器
// val:值
//
static void
hc_write(HC *hc, UCHAR reg, UCHAR val) {
	outb(hc->AddrPort, reg);
	outb(hc->DataPort, val);
}

// 写连续的多个主控制器寄存器
//
// hc: 主控制器
// addr:起始寄存器
// buf: 值数组起始地址
// count: 寄存器数
//
static void
hc_write_buf(HC *hc, UCHAR addr, const UCHAR *buf, UINT count) {
	
	ASSERT(count <= 64);
	outb(hc->AddrPort, addr);
	do {
		outb(hc->DataPort, *buf++);
	} while (--count);
}

// 读连续的多个主控制器寄存器
// hc: 主控制器
// addr:起始寄存器
// buf: 值数组起始地址
// count: 寄存器数
//
static void
hc_read_buf(HC *hc, UCHAR addr, UCHAR *buf, UINT count) {
	
	ASSERT(count <= 64);
	
	outb(hc->AddrPort, addr);
	do {
		*buf++ = inb(hc->DataPort);
	} while (--count);
}

///////////////////////////////////////////////////////////////////
// SETUP阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_Setup(HC *hc, URB *urb) {
	UCHAR	ctl;
	PSW
	
	/* Build the value to stick into the ctl register
     */
    ctl = SL_HCR_Out | SL_HCR_Arm | SL_HCR_Enable;

    /* preamble?
     */
    if (urb->Flags & URB_FLAG_LOW_SPEED)
        ctl |= SL_HCR_Preamble;

	DISABLE;
	
	/* Set buffer pointer to start of usable RAM
     */
    hc_write(hc, SL_HBA_A, SL_MEM);

    /* If we got something to say
     */
    hc_write_buf(hc, SL_MEM, urb->SetupData, 8);

    /* BUGBUG check for time
     */

    /* Length
     */
    hc_write(hc,SL_HBL_A,8);

    /* Set PID, endpoint address, device address
     */
    hc_write(hc, SL_HPID_A,
               SL_MAKE_HPID(SL_HPID_SETUP, 0/*urb->Ep->Endpoint*/));
    hc_write(hc, SL_HDA_A, urb->DeviceAddress);

    /* Go
     */
    hc_write(hc, SL_ISTATUS, 0xFF);
    hc_write(hc, SL_HCR_A, ctl);
    
    urb->Ep->Toggle = SL_HCR_DToggle;
    
    ENABLE;
	return ISR_CONTINUE;
}

// 根据主控制器状态寄存器,决定本阶段结果
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_CheckErrors(HC *hc, URB *urb) {
	UCHAR Status;
	
    Status = hc_read(hc, SL_STATUS_A);

	// BUGBUG, some device response (ACK|Overflow) --YKH
	if(Status & SL_STATUS_ACK)
		return ISR_CONTINUE;

    /* Everything ok?
     */
    if (0 == (Status & (SL_STATUS_NAK |
                        SL_STATUS_Error |
                        SL_STATUS_Timeout |
                        SL_STATUS_STALL |
                        SL_STATUS_Overflow)))
    {
        return ISR_CONTINUE;
    }
    
    /* Just a glitch?
     */
    if (Status & SL_STATUS_NAK)
    {
        return ISR_SUSPEND;
    }

    /* Something serious, bail out
     * Swap STALL and Timeout to make STALL same as others
     */
#define MiStatus(s) ((UINT)((s & ~0x84) | ((s&0x80)>>5) | ((s&4)<<5)))
    urb->FinalStatus = MiStatus(Status);
    return ISR_ERROR;
}

// USB输入命令阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_In(HC *hc, URB *urb) {
	PSW
	UINT l = urb->ExpectedDataLength - urb->ActualDataLength;
    UCHAR ctl;
    
	DISABLE;
	
    /* Build the value to stick into the ctl register
     */
    ctl = urb->Ep->Toggle;
    ctl |= SL_HCR_Arm | SL_HCR_Enable;

    /* isochronous?
     */
    if (urb->Flags & URB_FLAG_ISOCHRONOUS)
        ctl |= SL_HCR_ISO;

    /* preamble?
     */
    if (urb->Flags & URB_FLAG_LOW_SPEED)
        ctl |= SL_HCR_Preamble;


	/* Set buffer pointer to start of usable RAM
     */
    hc_write(hc, SL_HBA_A, SL_MEM);
    
    /* Length
     */
    if (l > urb->Ep->Payload)
        l = urb->Ep->Payload;
    hc_write(hc, SL_HBL_A, (UCHAR)l);

    /* Set PID for IN phase, endpoint address
     */
    hc_write(hc, SL_HPID_A,
               SL_MAKE_HPID(SL_HPID_IN, urb->Ep->Endpoint));
    hc_write(hc, SL_HDA_A, urb->DeviceAddress);

    /* Go
     */
    hc_write(hc, SL_ISTATUS, 0xFF);
    hc_write(hc, SL_HCR_A, ctl);
    
    urb->Ep->Toggle ^= SL_HCR_DToggle;
    
    ENABLE;

    return ISR_CONTINUE;
}

// USB输出命令阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_Out(HC *hc, URB *urb) {
	PSW
	UINT l = urb->ExpectedDataLength - urb->ActualDataLength;
    UCHAR ctl;
    
	DISABLE;
	
	if (l > urb->Ep->Payload)
		l = urb->Ep->Payload;

    /* Build the value to stick into the ctl register
     */
    ctl = urb->Ep->Toggle;
    ctl |= SL_HCR_Arm | SL_HCR_Enable | SL_HCR_Out;

    /* isochronous?
     */
    if (urb->Flags & URB_FLAG_ISOCHRONOUS)
        ctl |= SL_HCR_ISO;

    /* preamble?
     */
    if (urb->Flags & URB_FLAG_LOW_SPEED)
        ctl |= SL_HCR_Preamble;

    /* We got something to say
     */
    if (l)
    {
    	/* Set buffer pointer to start of usable RAM
     	*/
    	hc_write(hc, SL_HBA_A, SL_MEM);
        hc_write_buf(hc, SL_MEM, urb->Data + urb->ActualDataLength, l);
    }

    /* Length
     */
    hc_write(hc, SL_HBL_A, (UCHAR)l);

    /* Set PID for OUT phase, endpoint address
     */
    hc_write(hc, SL_HPID_A,
               SL_MAKE_HPID(SL_HPID_OUT, urb->Ep->Endpoint));
    hc_write(hc, SL_HDA_A, urb->DeviceAddress);

    /* Go
     */
    hc_write(hc, SL_ISTATUS, 0xFF);
    hc_write(hc, SL_HCR_A, ctl);
    
    urb->Ep->Toggle ^= SL_HCR_DToggle;
    
    ENABLE;

    return ISR_CONTINUE;
}

// USB输出阶段(延时)
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_Out2(HC *hc, URB *urb) {
	
	 /* No idea why this should be necessary.
     * Minimum value seems to be around 86-90us.
     */
    udelay(100);
    return SA_Out(hc, urb);
}

// USB输入数据阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_InBytes(HC *hc, URB *urb) {
	UINT Length;
    UINT Bytes2Go = 0;
    
    if(!(hc_read(hc, SL_STATUS_A) & SL_STATUS_ACK)) {
    	return SA_CheckErrors(hc, urb);
    }

    Length = hc_read(hc, SL_HBL_A) - hc_read(hc, SL_TC_A);
    /* BUGBUG Shakey h/w ...
     */
    Length &= 0xff;
    
    if (Length)
    {
        hc_read_buf(hc, SL_MEM, urb->Data + urb->ActualDataLength, Length);
        urb->ActualDataLength += (USHORT)Length;

        Bytes2Go = urb->ExpectedDataLength - urb->ActualDataLength;
        /* But not if we did not get a full packet */
        if (Length < urb->Ep->Payload)
            Bytes2Go = 0;
    }
    
    /* Ask for more iff...
     */
    if (Bytes2Go &&
        Length)
    {
        return ISR_REPEAT;
    }

    /* Only go to status for SETUPs
     */
    if (!(urb->Flags & URB_FLAG_CONTROL))
        return ISR_DONE;

    return ISR_CONTINUE;
}

// USB输出数据阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_OutBytes(HC *hc, URB *urb) {
	UINT Length;
    UINT Bytes2Go;
    int r;
    
    r = SA_CheckErrors(hc, urb);
    if (r != ISR_CONTINUE)
        return r;

    Length = hc_read(hc, SL_HBL_A) - hc_read(hc, SL_TC_A);
    
    urb->ActualDataLength += (USHORT)Length;
    Bytes2Go = urb->ExpectedDataLength - urb->ActualDataLength;

    if (Bytes2Go)
    {
        return ISR_REPEAT;
    }

    /* Only go to status for SETUPs
     */
    if (!(urb->Flags & URB_FLAG_CONTROL))
        return ISR_DONE;

    return ISR_CONTINUE;
}


// USB输入状态阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_StatusIn(HC *hc, URB *urb) {
	UCHAR	ctl;
	
    /* Build the value to stick into the ctl register
       */
    ctl = SL_HCR_Arm | SL_HCR_Enable | SL_HCR_DToggle;

    /* preamble?
     */
    if (urb->Flags & URB_FLAG_LOW_SPEED)
        ctl |= SL_HCR_Preamble;

    /* Length
     */
    hc_write(hc, SL_HBL_A, 0);

    /* Set PID for IN phase, endpoint address
     */
    hc_write(hc, SL_HPID_A,
               SL_MAKE_HPID(SL_HPID_IN, urb->Ep->Endpoint));
    hc_write(hc, SL_HDA_A, urb->DeviceAddress);

    /* Go
     */
    hc_write(hc, SL_ISTATUS, 0xFF);
    hc_write(hc, SL_HCR_A, ctl);
    
	return ISR_CONTINUE;
}


// USB输出状态(ACK)阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_StatusOut(HC *hc, URB *urb) {
	UCHAR	ctl;
	
    /* Build the value to stick into the ctl register
     */
    ctl = SL_HCR_Arm | SL_HCR_Enable | SL_HCR_Out | SL_HCR_DToggle;

    /* preamble?
     */
    if (urb->Flags & URB_FLAG_LOW_SPEED)
        ctl |= SL_HCR_Preamble;


    /* Length
     */
    hc_write(hc, SL_HBL_A, 0);

    /* Set PID for IN phase, endpoint address
     */
    hc_write(hc, SL_HPID_A,
               SL_MAKE_HPID(SL_HPID_OUT, urb->Ep->Endpoint));
    hc_write(hc, SL_HDA_A, urb->DeviceAddress);

    /* Go
     */
    hc_write(hc, SL_ISTATUS, 0xFF);
    hc_write(hc, SL_HCR_A, ctl);

    return ISR_CONTINUE;
}

// USB结束阶段
//
// hc: 主控制器
// urb: USB请求
//
static int
SA_ControlDone(HC *hc, URB *urb) {
	int r;
	
    r = SA_CheckErrors(hc, urb);
    if (r != ISR_CONTINUE)
        return r;

    return ISR_DONE;
}

//
// USB请求脚本
//
static SCRIPT	AllScripts[] = {
#define NoDataControlScript	0		// 无数据控制写
	{ SA_Setup, SA_CheckErrors},
    { SA_StatusIn, SA_ControlDone},

#define ControlReadScript   2		// 控制读
	{ SA_Setup, SA_CheckErrors},
    { SA_In, SA_InBytes},
    { SA_StatusOut, SA_ControlDone},

#define ControlWriteScript  5		// 控制写
    { SA_Setup, SA_CheckErrors},
    { SA_Out2, SA_OutBytes},
    { SA_StatusIn, SA_ControlDone},

#define ReadScript          8		// 读
    { SA_In, SA_InBytes},

#define WriteScript         9		// 写
    { SA_Out, SA_OutBytes}
};

/////////////////////////////////////////////////////
// SL811HS中断处理程序
//
void
SL811Isr(void) {
	PSW
	URB		*urb;
	HC		*hc = &SL811;
	int		r;
	UCHAR	st;
	UCHAR	DoScript;

⌨️ 快捷键说明

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