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

📄 sl811.c

📁 基于ARM7的直流电机的驱动,还有FLASH驱动,LCD驱动等
💻 C
📖 第 1 页 / 共 3 页
字号:
	DISABLE;
	
	// 读中断状态寄存器
	st = hc_read(hc, SL_ISTATUS);

	DoScript = FALSE;

	// 命令完成中断
	if(st & SL_INTEN_DONE_A) {
		hc->DoneInts++;
		urb = hc->CurURB;
		if(urb != NULL) {

			// 执行USB请求的下一步骤
			r = (*AllScripts[urb->NextStep].End)(hc, urb);
			if(r == ISR_CONTINUE) {
				urb->NextStep++;
				DoScript = TRUE;
			} else if(r == ISR_SUSPEND) {
				/* Wait until the next SOF, the device is not ready (NAK)
                 * The toggle bit stays with the packet.
                 */
				goto sus; // ****DON'T FORGET ACK INTR****
			} else if(r != ISR_REPEAT) {
				urb->Flags |= URB_FLAG_COMPLETE;
				
				/* If there was an error the packet *is* complete
                 */
                if (r != ISR_DONE)
                    urb->Flags |= URB_FLAG_ERROR;
				hc->CurURB = NULL;
				sm_v(hc->sm);
				
				goto ret;
			} else {
				
				DoScript = TRUE;
			}
		}
	}
	
	// USB设备插入或拔出中断
	if(st & SL_INTEN_Insert) {
		hc->InsRmvInts++;
		hc->reset = TRUE;
		hc->PrevURB = NULL;
		
		if(smSL811 == 0)
			goto ret;
		
		// 唤醒USB任务
		sm_v(smSL811);

		// 撤销当前USB请求
		if(hc->CurURB != NULL) {
			hc->CurURB->Flags |= URB_FLAG_ERROR;
			hc->CurURB = NULL;
			sm_v(hc->sm);
			DoScript = FALSE;
			
			goto ret;
		}
	}
	// SOF被关闭,功能未用
	if(st & SL_INTEN_SOF) {
		hc->SofInts++;
		hc_write(hc, SL_INTEN, INTS);
		
		if(!DoScript) {
			//
			// SL_INTEN_SOF set always
			//
			
			urb = hc->PrevURB;
			if(urb != NULL) {
			
				hc->PrevURB = NULL;
				hc->CurURB = urb;
				DoScript = TRUE;
			}
		}
	}
	
	//执行脚本
	if (DoScript)
	{
        /* Execute the start action.  It might tell us that there is not enough
         * time left in the current frame, or that all is fine (ISR_CONTINUE).
         */
		r = (*AllScripts[urb->NextStep].Start)(hc, urb);
		if (r != ISR_CONTINUE) {
sus:		hc->SusCnt++;
			hc->PrevURB = urb;
			hc->CurURB = NULL;

			hc_write(hc, SL_INTEN, INTS | SL_INTEN_SOF);
		}
	}
ret:
	/* Ack the interrrupt
     */
	hc_write(hc, SL_ISTATUS, 0xFF);

	rI_ISPC = BIT_SL811;
	
	ENABLE;
}

////////////////////////////////////////////////////////
// 启动USB请求
//
// hc: 主控制器
// urb: USB请求
//
int
SL_Start(HC *hc, URB *urb) {
	PSW
	
	//DBG1("NextStep = %u\n", urb->NextStep);
	ASSERT(urb->NextStep <= 9);
	
	DISABLE;
	
	// 启动第一个阶段。。。
	//
	sm_init(hc->sm);
	hc->CurURB = urb;
	(*AllScripts[urb->NextStep].Start)(hc, urb);
	
	ENABLE;
	
	// 等待USB请求结束
	sm_p(hc->sm, FOREVER);
	
	if(urb->Flags & URB_FLAG_ERROR)
		return ISR_ERROR;
	return ISR_DONE;
}

//
// 获取设备的设备描述符
//
int
GetDevDesc(MASS_STOR *ms) {
	HC	*hc = ms->hc;
	int	r;
	URB	urb;
	struct usb_ctrlrequest req;
	
	//DBG("GET_DEVICE_DESCRIPTOR...\n");
	req.bRequestType = USB_DIR_IN;
	req.bRequest = USB_REQ_GET_DESCRIPTOR;
	req.wValue = USB_DT_DEVICE << 8;
	req.wIndex = 0;
	req.wLength = USB_DT_DEVICE_SIZE;
	
	urb.Ep = &ms->hc->ep0;
	urb.Flags = URB_FLAG_IN | URB_FLAG_CONTROL;
	urb.Data = (UCHAR *)&hc->dev;
	urb.ExpectedDataLength = sizeof(hc->dev);
	urb.ActualDataLength = 0;
	urb.SetupLength = 8;
	urb.SetupData = (void *)&req;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = ControlReadScript;
	
	r = SL_Start(hc, &urb);
	hc->ep0.Payload = hc->dev.bMaxPacketSize0;
	if(r != ISR_DONE)
		return FALSE;
	return TRUE;
}

//
// 设置USB设备地址
//
int
SetAddress(MASS_STOR *ms) {
	int	r;
	URB	urb;
	struct usb_ctrlrequest req;
	
	// SET_ADDRESS
	req.bRequestType = USB_DIR_OUT;
	req.bRequest = USB_REQ_SET_ADDRESS;
	req.wValue = USB_ADDR;
	req.wIndex = 0;
	req.wLength = 0;
	
	urb.Ep = &ms->hc->ep0;
	urb.Flags = URB_FLAG_OUT | URB_FLAG_CONTROL;
	urb.Data = NULL;
	urb.ExpectedDataLength = 0;
	urb.ActualDataLength = 0;
	urb.SetupLength = 8;
	urb.SetupData = (void *)&req;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = NoDataControlScript;
	
	r = SL_Start(ms->hc, &urb);
	if(r != ISR_DONE)
		return FALSE;
	return TRUE;
}

//
// 检测USB海量存储设备
//
int
UsbMassDetect(MASS_STOR *ms) {
	HC *hc = ms->hc;
	int	r;
	URB	urb;
	UCHAR	in, out;
	struct usb_ctrlrequest req;
	UCHAR	buf[128];
	
	// 获取配置
	
	// GET_CONFIGURATION *HEADER*
	//DBG("GET_CONFIGURATION *HEADER*...\n");
	req.bRequestType = USB_DIR_IN;
	req.bRequest = USB_REQ_GET_DESCRIPTOR;
	req.wValue = __le16(USB_DT_CONFIG << 8);
	req.wLength = __le16(USB_DT_CONFIG_SIZE);
	
	urb.Ep = &ms->hc->ep0;
	urb.Flags = URB_FLAG_IN | URB_FLAG_CONTROL;
	urb.Data = (void *)hc->conf;
	urb.ExpectedDataLength = USB_DT_CONFIG_SIZE;
	urb.ActualDataLength = 0;
	urb.SetupLength = 8;
	urb.SetupData = (void *)&req;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = ControlReadScript;
	
	r = SL_Start(hc, &urb);
	if(r != ISR_DONE)
		return FALSE;

	//
	// 获取配置、接口、端点描述
	//
	////GET_CONFIGURATION *HEADER + INTERFACE + ENDPOINTS*
	//DBG("GET_CONFIGURATION *HEADER + INTERFACE + ENDPOINTS*...\n");
	req.bRequestType = USB_DIR_IN;
	req.bRequest = USB_REQ_GET_DESCRIPTOR;
	req.wValue = __le16(USB_DT_CONFIG << 8);
	req.wLength = __le16(hc->conf[0].wTotalLength);
	
	urb.Flags = URB_FLAG_IN | URB_FLAG_CONTROL;
	urb.Data = buf;
	urb.ExpectedDataLength = __le16(hc->conf[0].wTotalLength);
	urb.ActualDataLength = 0;
	urb.SetupLength = 8;
	urb.SetupData = (void *)&req;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = ControlReadScript;
	
	r = SL_Start(hc, &urb);
	if(r != ISR_DONE)
		return FALSE;
	
	// copy interface descriptors
	Memcpy((void *)hc->intf,
		buf + USB_DT_CONFIG_SIZE,
		1 * USB_DT_INTERFACE_SIZE);

	// 复制端点描述符
	for(r = 0; r < hc->intf[0].bNumEndpoints; r++)
		Memcpy((void *)&hc->ep[r],
			buf + USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE +
				r * USB_DT_ENDPOINT_SIZE,
			USB_DT_ENDPOINT_SIZE);

	// 获取设备输入、输出端点地址
	if(hc->ep[0].bEndpointAddress & 0x80) {
		in = 0;
		out = 1;
	}
	else {
		out = 0;
		in = 1;
	}
	
	ms->In.Payload = hc->ep[in].wMaxPacketSize;
	ms->In.Endpoint = hc->ep[in].bEndpointAddress & 0xF;
	ms->Out.Payload = hc->ep[out].wMaxPacketSize;
	ms->Out.Endpoint = hc->ep[out].bEndpointAddress & 0xF;
	ms->In.Toggle = 0;
	ms->Out.Toggle = 0;
	
	//
	// 设置配置
	//
	// SET_CONFIGURATION
	//DBG("SET_CONFIGURATION...\n");
	req.bRequestType = USB_DIR_OUT;
	req.bRequest = USB_REQ_SET_CONFIGURATION;
	req.wValue = 1;
	req.wIndex = 0;
	req.wLength = 0;
	
	urb.Flags = URB_FLAG_OUT | URB_FLAG_CONTROL;
	urb.Data = NULL;
	urb.ExpectedDataLength = 0;
	urb.ActualDataLength = 0;
	urb.SetupLength = 8;
	urb.SetupData = (void *)&req;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = NoDataControlScript;
	
	r = SL_Start(hc, &urb);
	if(r != ISR_DONE)
		return FALSE;
	
	hc->devfound = TRUE;
	return TRUE;
}

//
// 批量输入
//
// ms: 海量存储设备
// buf:数据指针
// len:数据长度
//
static int
BulkIn(MASS_STOR *ms, UCHAR *buf, UINT len) {
	int	r;
	URB	urb;
	
	urb.Ep = &ms->In;
	urb.Flags = URB_FLAG_IN;
	urb.Data = buf;
	urb.ExpectedDataLength = len;
	urb.ActualDataLength = 0;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = ReadScript;
	
	r = SL_Start(ms->hc, &urb);
	if(r != ISR_DONE)
		return FALSE;
	return TRUE;
}

//
// 批量输出
//
// ms: 海量存储设备
// buf:数据指针
// len:数据长度
//
static int
BulkOut(MASS_STOR *ms, UCHAR *buf, UINT len) {
	int	r;
	URB	urb;
	
	urb.Ep = &ms->Out;
	urb.Flags = URB_FLAG_OUT;
	urb.Data = buf;
	urb.ExpectedDataLength = len;
	urb.ActualDataLength = 0;
	urb.FinalStatus = 0;
	urb.DeviceAddress = ms->DeviceAddress;
	urb.NextStep = WriteScript;
	
	r = SL_Start(ms->hc, &urb);
	if(r != ISR_DONE)
		return FALSE;
	return TRUE;
}

//
// 质询设备
//
static int
Inquiry(MASS_STOR *ms) {
	struct us_cbw	cbw;
	struct us_csw	csw;
	UCHAR			buf[36];
	
	//DBG("INQUIRY...\n");
	
	// 组"SCSI质询"命令包
	cbw.dSignature = CBW_SIGNATURE;
	cbw.dTag = 0x60a624de;
	cbw.dXferLength = __le16(36);
	cbw.bFlags = 0x80;
	cbw.bLUN = 0;
	
	cbw.bCBDLength = 6;
	cbw.aCmd[0] = 0x12;
	cbw.aCmd[1] = 0;
	cbw.aCmd[2] = 0;
	cbw.aCmd[3] = 0;
	cbw.aCmd[4] = 36;
	cbw.aCmd[5] = 0;

	////////////////////////////////
	// 下发"SCSI质询"命令包
	if(BulkOut(ms, (UCHAR *)&cbw, sizeof(cbw)) != TRUE)
		return FALSE;
	
	// 读出质询结果
	if(BulkIn(ms, buf, 36) != TRUE)
		return FALSE;
	
	// 读出命令操作状态
	if(BulkIn(ms, (UCHAR *)&csw, sizeof(csw)) != TRUE)
		return FALSE;
	
	if(csw.bStatus != CSW_STATUS_OK) {
		return FALSE;
	}
	return TRUE;
}

// 从指定地址取一个小端序列长字
__inline static ULONG
makelong(UCHAR *p) {
	return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}

// 取2的近似对数
UINT
mylog2(ULONG x) {
	UINT	i;
	
	i = 0;
	while((1 << i) < x)
		i++;
	return i;
}

//
// 获取设备参数
//
// ms: 海量存储设备
//
static int
ReadCapacity(MASS_STOR *ms) {
	struct us_cbw	cbw;
	struct us_csw	csw;
	UCHAR			buf[16];
	
	//DBG("ReadCapacity...\n");
	
	// 组"SCSI读参数"命令包
	cbw.dSignature = CBW_SIGNATURE;
	cbw.dTag = 0x60a624de;
	cbw.dXferLength = 8;
	cbw.bFlags = 0x80;
	cbw.bLUN = 0;
	cbw.bCBDLength = 10;
	
	/////////////////////////////////
	cbw.aCmd[0] = 0x25;	// operation code
	cbw.aCmd[9] = 0;	// Control = 00h
	
	////////////////////////////////
	// 下发"SCSI读参数"命令包
	if(BulkOut(ms, (UCHAR *)&cbw, sizeof(cbw)) != TRUE)
		return FALSE;
	
	// 读出参数
	if(BulkIn(ms, buf, 8) != TRUE)
		return FALSE;
	
	// 读出命令操作状态
	if(BulkIn(ms, (UCHAR *)&csw, sizeof(csw)) != TRUE)
		return FALSE;
	
	if(csw.bStatus != CSW_STATUS_OK) {
		return FALSE;
	}
	
	// U盘块数
	ms->BlockNumber = makelong(buf) + 1;
	
	// 块大小,一般为512
	ms->BlockSize = makelong(buf + 4);
	if(ms->BlockSize > 1024)
		DBG("*******注意********\nUSB盘块大小 > 1K字节!\n");

	//
	// BlockSize = 1 << BlockSizeShift
	//
	ms->BlockSizeShift = mylog2(ms->BlockSize);
//	ms->DiskSize = (unsigned long long)ms->BlockNumber
//		* (unsigned long long)ms->BlockSize;
	DBG1("%u Bytes/Block\n", ms->BlockSize);

//	DBG3("USB盘 %luMB, %lu 块, %lu 字节每块\n",
//		(ULONG)((ms->DiskSize + 1024*1024-1)/1024/1024), ms->BlockNumber, ms->BlockSize);
	return TRUE;
}

//
// 写海量存储设备扇区
//
// ms: 海量存储设备
// lba:扇区号
// buf:数据指针
//

int
__usbWriteBlock(MASS_STOR *ms, ULONG lba, void *buf) {
	struct us_cbw	cbw;
	struct us_csw	csw;
	
	//DBG2("usbWriteBlock(%u, %08X)...\n", lba, buf);
	
	// 组"SCSI写扇区"命令包
	cbw.dSignature = CBW_SIGNATURE;
	cbw.dTag = 0x60a624de;
	cbw.dXferLength = ms->BlockSize;
	cbw.bFlags = 0x0;
	cbw.bLUN = 0;
	cbw.bCBDLength = 10;
	
	/////////////////////////////////
	cbw.aCmd[0] = 0x2a;	// operation code
	cbw.aCmd[1] = 0;
	// LBA
	cbw.aCmd[2] = lba >> 24;
	cbw.aCmd[3] = lba >> 16;
	cbw.aCmd[4] = lba >> 8;
	cbw.aCmd[5] = lba;
	// Transfer Length
	cbw.aCmd[7] = 0;
	cbw.aCmd[8] = 1;
	cbw.aCmd[9] = 0;	// Control = 00h

	////////////////////////////////
	// 下发"SCSI写扇区"命令包
	if(BulkOut(ms, (UCHAR *)&cbw, sizeof(cbw)) != TRUE)
		return FALSE;

	//tm_delay(5);
	
	// 发送数据
	if(BulkOut(ms, buf, ms->BlockSize) != TRUE)
		return FALSE;
	
	// 读出命令操作状态
	if(BulkIn(ms, (UCHAR *)&csw, sizeof(csw)) != TRUE)
		return FALSE;
	
	if(csw.bStatus != CSW_STATUS_OK)
		return FALSE;
	return TRUE;
}

//
// 缓冲区定义

⌨️ 快捷键说明

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