📄 sl811hst.c
字号:
/**
* sl811.c
* 倀俽俛儂僗僩僠僢僾僪儔僀僶
* 僒僀僾儗僗俽俴俉侾侾俫俽
*
* Copyright (c)2004 Junichi Tomaru
*/
#include "h8hst.h"
#define USB_ACK 1
#define USB_NAK 2
#define USB_STALL 4
/**
* 巜掕儗僕僗僞偺僨乕僞撉傓
*/
byte sl_read( char addr )
{
SL811ADDR = addr; /* 傾僪儗僗僙僢僩 */
return SL811DATA; /* 僨乕僞撉傒弌偟 */
}
/**
* 巜掕儗僕僗僞偵僨乕僞彂偔
*/
void sl_write( char addr, byte data )
{
SL811ADDR = addr; /* 傾僪儗僗僙僢僩 */
SL811DATA = data; /* 僨乕僞彂偒崬傒 */
}
/**
* 巜掕傾僪儗僗傛傝楢懕僨乕僞撉傓
* 傾僪儗僗偼俬俠懁偱僆乕僩僀儞僋儕儊儞僩
*/
void sl_burstread( char addr, char *buf, int size )
{
int i;
if( size <= 0 ){
return;
}
SL811ADDR = addr; /* 愭摢傾僪儗僗僙僢僩 */
for( i = 0; i < size; i++ ){
*( buf + i ) = SL811DATA;
}
}
/**
* 巜掕傾僪儗僗傛傝楢懕僨乕僞彂偔
* 傾僪儗僗偼俬俠懁偱僆乕僩僀儞僋儕儊儞僩
*/
void sl_burstwrite( char addr, char *buf, int size )
{
int i;
if( size <= 0 ){
return;
}
SL811ADDR = addr; /* 愭摢傾僪儗僗僙僢僩 */
for( i = 0; i < size; i++ ){ /* 僨乕僞偺彂偒崬傒 */
SL811DATA = *( buf + i );
}
}
/**
* 俽俴俉侾侾俫俽弶婜壔
*/
void sl_init( void )
{
usbspeed = NOSPEED;
P9DR &= 0xef;
wait10us( ); /* 倀俽俛僠僢僾儕僙僢僩僷儖僗 */
P9DR |= 0x10;
waitms( 1 );
sl_write( SL_CTRLREG2, 0xae ); /* 儅僗僞儌乕僪,嬌惈愗傝懼偊側偟亄僇僂儞僞俀俤俫 */
}
/**
* 俽俤俿倀俹僷働僢僩彂偒崬傒
* ret:俙俠俲乛俶俙俲乛俽俿俙俴俴
*/
int send_setup( char *data )
{
byte sts, ret;
sl_burstwrite( 0x10, data, 8 ); /* 僨乕僞揮憲 */
sl_write( SL_BASEADDRA, 0x10 ); /* 揮憲奐巒傾僪儗僗 */
sl_write( SL_BASELENA, 8 ); /* 僨乕僞挿偝 */
sl_write( SL_DEVADDRA, info.addr ); /* 捠怣憡庤偺僨僶僀僗傾僪儗僗 */
sl_write( SL_PIDDEVEPA, PID_SETUP + 0 );/* 僙僢僩傾僢僾僷働僢僩 */
sl_write( SL_HOSTCTRLA, ARM + ENABLE + DIRECTION ); /* 僨乕僞侽偱憲怣 */
wait100us( );
wait100us( );
while(( sl_read( SL_INTSTATUS ) & INT_USBADONE ) == 0 ){ /* 憲怣廔椆懸偪 */
}
sts = sl_read( SL_USBSTSA );
ret = 0;
if(( sts & ACK ) == ACK ){
ret |= USB_ACK;
}
if(( sts & NAK ) == NAK ){
ret |= USB_NAK;
}
if(( sts & STALL ) == STALL ){
ret |= USB_STALL;
}
return ret;
}
/**
* 俽俴俉侾侾俫俽偵僨乕僞彂偒崬傓
*/
int sl_writedata( char *data, int size )
{
byte sts, tgl, ret;
if( size < 2 ){
return 0;
}
sl_burstwrite( 0x10, data + 2, size - 2 );
sl_write( SL_BASEADDRA, 0x10 );
sl_write( SL_BASELENA, size - 2 );
sl_write( SL_DEVADDRA, info.addr );
sl_write( SL_PIDDEVEPA, PID_OUT | info.txep );
tgl = ARM + ENABLE + DIRECTION;
if( info.tgl == 1 ){
tgl += DATATGL;
}
sl_write( SL_HOSTCTRLA, tgl );
wait100us( );
wait100us( );
while(( sl_read( SL_INTSTATUS ) & INT_USBADONE ) == 0 ){ /* 憲怣姰椆懸偪 */
}
sts = sl_read( SL_USBSTSA );
ret = 0;
if(( sts & ACK ) == ACK ){
ret |= USB_ACK;
}
if(( sts & NAK ) == NAK ){
ret |= USB_NAK;
}
if(( sts & STALL ) == STALL ){
ret |= USB_STALL;
}
return ret;
}
/**
* 俽俴俉侾侾俫俽傛傝僨乕僞撉傒弌偡
*/
int sl_readdata( char *data, int size )
{
byte sts, tgl, ret;
int i;
if( size < 0 ){
return 0;
}
sl_write( SL_BASEADDRA, 0x10 );
sl_write( SL_BASELENA, size );
sl_write( SL_DEVADDRA, info.addr ); /* 懳徾僨僶僀僗傾僪儗僗 */
sl_write( SL_PIDDEVEPA, PID_IN + info.txep ); /* 俬俶僷働僢僩 */
tgl = ARM + ENABLE;
if( info.tgl == 1 ){
tgl += DATATGL;
}
for( i = 0; i < 200; i++ ){
sl_write( SL_HOSTCTRLA, tgl );
wait100us( );
wait100us( );
while(( sl_read( SL_INTSTATUS ) & INT_USBADONE ) == 0 ){ /* 憲怣廔椆懸偪 */
}
sts = sl_read( SL_USBSTSA );
if(( sts & NAK ) == 0 ){ /* 俶俙俲偱側偗傟偽敳偗傞 */
break;
}
}
ret = 0;
if(( sts & ACK ) == ACK ){
sl_burstread( 0x10, data, size );
ret |= USB_ACK;
}
if(( sts & NAK ) == NAK ){
ret |= USB_NAK;
}
if(( sts & STALL ) == STALL ){
ret |= USB_STALL;
}
return ret;
}
/**
* 僨僶僀僗僠僃僢僋
*/
bool checkdevice( void )
{
byte sts;
bool ret;
sl_write( SL_INTSTATUS, 0xff ); /* 偡傋偰偺妱傝崬傒價僢僩僋儕傾 */
sts = sl_read( SL_INTSTATUS );
if(( sts & 0x40 ) == 0x40 ){ /* 價僢僩偑棫偭偰偄傞偲僨僶僀僗側偟 */
return FALSE;
}
else{
if(( sts & 0x80 ) == 0x80 ){ /* 僼儖僗僺乕僪 */
usbspeed = FULLSPEED;
dispmessage( 7 );
}
else{
usbspeed = LOWSPEED;
dispmessage( 8 );
}
}
return TRUE;
}
/**
* 僨僶僀僗専弌仺僾儔僌仌僾儗僀
*/
bool plugnplay( void )
{
byte sts, tp;
byte buf[10];
char i, tmp[4];
const char getdesc[8] = {
DEV2HOST + TYPESTD + RXDEVICE, /* bmRequestType */
GET_DESCRIPTOR, /* bRequest */
0, DEVICE, /* wValue */
0, 0, /* wIndex */
8, 0 /* Data */
};
const char setaddr[8] = {
HOST2DEV + TYPESTD + RXDEVICE, /* bmRequestType */
SET_ADDRESS, /* bRequest */
2, 0, /* wValue */
0, 0, /* wIndex */
0, 0 /* Data */
};
waitms( 100 ); /* 僨僶僀僗敪尒仺侾侽侽倣倱僨傿儗僀 */
info.addr = info.txep = info.rxep = 0;
info.tgl = 1;
sl_write( SL_CTRLREG2, 0xae ); /* 儅僗僞儌乕僪,嬌惈愗傝懼偊側偟亄僇僂儞僞俀俤俫 */
sl_write( SL_SOFCNTLOW, 0xe0 );
sl_write( SL_CTRLREG1, 0x8 ); /* 僶僗儕僙僢僩 */
waitms( 20 ); /* 俵俬俶侾侽倣倱 */
if( usbspeed == FULLSPEED ){ /* 僼儖僗僺乕僪 */
sl_write( SL_CTRLREG2, 0xae ); /* 僨乕僞斀揮側偟 */
sl_write( SL_CTRLREG1, 0x1 ); /* 傎傫偲偼俆丠 */
}
else{ /* 儘乕僗僺乕僪 */
sl_write( SL_CTRLREG2, 0xee ); /* 僨乕僞斀揮偁傝 */
sl_write( SL_CTRLREG1, 0x21 );
}
sl_write( SL_PIDDEVEPA, 0x50 );
sl_write( SL_DEVADDRA, 0x00 ); /* 憡庤僨僶僀僗偼侽 *//* 1偱側偄丠 */
sl_write( SL_IER, INT_USBADONE + INT_USBBDONE + INT_SOFTIM + INT_INSREM );/* 妱傝崬傒僙僢僩 */
sl_write( SL_HOSTCTRLA, 1 ); /* SOF僀僱乕僽儖 */
waitms( 30 );
sl_write( SL_INTSTATUS, 0xff );
if(( send_setup( (char *)getdesc ) & USB_ACK ) == 0 ){ /* 僨僶僀僗僨傿僗僋儕僾僞 */
return FALSE;
}
if(( sl_readdata( buf, 8 ) & USB_ACK ) == 0 ){ /* 僨僶僀僗僨傿僗僋儕僾僞庴怣 */
return FALSE;
}
devdesc.length = buf[0];
devdesc.type = buf[1];
devdesc.usbver = (((int)buf[3] << 8 ) & 0xff00 );
devdesc.usbver |= ( (int)buf[2] & 0x00ff );
devdesc.class = buf[4];
devdesc.subclass = buf[5];
devdesc.protocol = buf[6];
devdesc.maxsize = buf[7];
/**/ lcdlocate( 12, 0 );
/**/ lcdputch( 'v' );
/**/ lcdputch( buf[3] + 0x30 );
/**/ lcdputch( '.' );
/**/ lcdputch( ((( buf[2] >> 4 ) & 0xf ) + 0x30 ));
/**/ for( i = 0; i < 8; i++ ){
/**/ lcdprint( i*2, 1, uctoahz( buf[i], tmp ) );
/**/ }
if(( send_setup( (char *)setaddr ) & USB_ACK ) == 0 ){ /* 僙僢僩傾僪儗僗 */
return FALSE;
}
info.addr = 2;
return TRUE;
}
/* end of sl811hst.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -