📄 level1.c
字号:
/* FileName: Level1.c */
#include "io51.h"
#include "usb_def.h"
extern interrupt void T0_int(void);
extern interrupt void EX0_int(void);
/* the variable defined in level1.c */
unsigned char ep0stat;
unsigned char intstat;
unsigned char sofstat;
unsigned char blk_data_out[3];
unsigned char sof_token;
unsigned int fn;
unsigned char test,speed;
/* the function defined in level1.c */
void host_blk_write(unsigned char, unsigned char *, unsigned char);
void host_blk_read(unsigned char, unsigned char *, unsigned char);
void reset_root_hub(void);
void host_init(void);
void host_int(void);
void send_setup(unsigned char, unsigned char,unsigned char *);
void xfer_data(unsigned char, unsigned char, unsigned char,unsigned char, unsigned char);
void sof_emit(void);
unsigned char crc5(unsigned int crc_input);
/* the external function defined in level0.c */
extern void write_host_addr(unsigned char addr);
extern void write_host_data(unsigned char datum);
extern unsigned char read_host_data(void);
extern void i_write_host_addr(unsigned char addr);
extern void i_write_host_data(unsigned char datum);
extern unsigned char i_read_host_data(void);
extern void enable_tmr(void);
extern void disable_tmr(void);
extern void delay ( unsigned int cnt);
extern void i_delay ( unsigned int cnt);
/**************************************************************************
This function writes a string to SL11H.
**************************************************************************/
void host_blk_write(unsigned char addr, unsigned char *buf,unsigned char cnt)
{
write_host_addr(addr);
while (cnt--)
{
write_host_data(*buf++);
}
}
/**************************************************************************
This function reads a string from SL11H.
**************************************************************************/
void host_blk_read(unsigned char addr,unsigned char *buf,unsigned char cnt)
{
while (cnt--)
{
write_host_addr(addr);
*buf++ = read_host_data();
addr++;
}
}
/**************************************************************************
This function resets the root hub
**************************************************************************/
void reset_root_hub(void)
{
disable_tmr();
write_host_addr(USB_CTL);
write_host_data(0x08); /* USB_CTL = USB Engine reset*/
delay(5000);
write_host_addr(USB_CTL);
write_host_data(0x01); /* USB_CTL = USB enable*/
write_host_data(0x4F); /* INT_ENB = 0x40*/
write_host_addr(INT_STS);
write_host_data(0xff); /* INT_STS = 0xff*/
write_host_addr(INT_STS);
test = read_host_data(); /* INT_STS = 0xff*/
write_host_addr(INT_ENB);
test = read_host_data(); /* INT_STS = 0xff*/
enable_tmr(); /* resume EOF emission*/
}
/**************************************************************************
This function initializes the SL11H
**************************************************************************/
void host_init(void)
{
RB1=1;
P3.4=0; /* CS=0 */
PORTB &= 0x7F;
delay(10); /* reset signal*/
P3.4=0; /* CS=0 */
PORTB |= 0x80;
write_host_addr(USB_ADR);
write_host_data(0); /* USB_ADR = 0*/
write_host_addr(SOF_CTL);
write_host_data(0); /* EP0A_CTL = 0*/
write_host_addr(EP0A_STS);
write_host_data(0); /* EP0A_STS = 0*/
write_host_addr(EP1A_CTL);
write_host_data(0);
write_host_addr(EP1A_STS);
write_host_data(0);
write_host_addr(SOF_BUF);
write_host_data(PID_SOF); /* init SOF_BUF PID */
RB2 = 1; /* 1MS signal off */
RB3 = 1; /* SEND = 1 for low speed*/
RB1=1;
}
/**************************************************************************
This function handles the SL11H interrupt
**************************************************************************/
/*void host_int(void)
{
unsigned char int_flag, temp;
i_write_host_addr(INT_STS);
int_flag = i_read_host_data();
if (int_flag & 0x01)
{
intstat = 1;
i_write_host_addr(EP0A_STS);
temp = i_read_host_data();
if (temp != 0)
ep0stat = temp;
i_write_host_addr(EP0A_STS);
i_write_host_data(0);
}
i_write_host_addr(INT_STS);
i_write_host_data(0xff);
i_write_host_addr(INT_ENB);
i_write_host_data(0x4F);
}*/
/*****************************************************************************
This function sends out a SETUP packet. A SL11H ep0 done interrupt will be
generated when the xfer is finished
Input: device's address
device's endpoit
SETUP command
device speed
Return: NONE
*****************************************************************************/
void send_setup(unsigned char dev,unsigned char ep,unsigned char *buf)
{
unsigned char c;
enable_tmr();
sofstat = 0;
while(!sofstat);
disable_tmr();
/* write PID to buffer*/
write_host_addr(EP0_BUF);
write_host_data(PID_SETUP);
/* write addr, ep0, crc5*/
if (dev == 0) /* dev = 0, ep = 0*/
{ blk_data_out[0] = 0;
blk_data_out[1] = 0x10;
}
else /* dev = 2, ep = 0*/
{ blk_data_out[0] = 2;
blk_data_out[1] = 0xA8;
}
host_blk_write(EP0_BUF+1, blk_data_out, 2);
write_host_addr(EP0_BUF+3);
for (c = 0; c < 8; c++)
write_host_data(*(buf+c));
enable_tmr();
sofstat = 0;
while(!sofstat);
disable_tmr();
/* write buffer base address*/
write_host_addr(EP0A_ADR);
write_host_data(EP0_BUF);
/* buffer length*/
write_host_addr(EP0A_LEN);
write_host_data(0x0b);
/* select SL11H ep0 control register*/
RA4 = 1; /* DIR = 1, data out */
write_host_addr(EP0A_CTL);
write_host_data(EP_OUT);
}
/*****************************************************************************
This function implements a data transfer. Also used in SETUP transfer data and status stages.
Input: device's address
device's endpoit
data length
data direction
data sequence
device speed
Return: none
*****************************************************************************/
void xfer_data(unsigned char addr,unsigned char ep,unsigned char len,
unsigned char dir,unsigned char sqn)
{
unsigned char ctl; /* byte to be written to EP0A_CTL*/
enable_tmr();
sofstat = 0;
while(!sofstat);
disable_tmr();
write_host_addr(EP0_BUF); /* EP0_BUF = 0x40, EP1_BUF = 0x60*/
if(dir)
write_host_data(PID_OUT);
else
write_host_data(PID_IN);
/* write addr, ep0, crc5*/
if (addr == 0) /* addr = 0, ep = 0*/
{
blk_data_out[0] = 0x00;
blk_data_out[1] = 0x10;
}
else
if (ep == 0) /* addr = 2, ep = 0*/
{ blk_data_out[0] = 2;
blk_data_out[1] = 0xA8;
}
else
if (ep == 1) /* addr = 2, ep = 1*/
{ blk_data_out[0] = 0x82;
blk_data_out[1] = 0x18;
}
else /* addr = 2, ep = 2*/
{ blk_data_out[0] = 0x02;
blk_data_out[1] = 0x81;
}
host_blk_write(EP0_BUF+1, blk_data_out, 2);
enable_tmr();
sofstat = 0;
while(!sofstat);
disable_tmr();
write_host_addr(EP0A_ADR);
write_host_data(EP0_BUF); /* write buffer base address*/
write_host_addr(EP0A_LEN);
write_host_data(len + 3); /* buffer length*/
if(dir)
{ ctl = EP_OUT | sqn;
RA4 = 1; /* DIR = 1, data out*/
}
else
{ ctl = EP_IN | sqn;
RA4 = 0; /* DIR = 0, data in */
}
write_host_addr(EP0A_CTL);
write_host_data(ctl);
}
/********************************************************************************/
void sof_emit(void)
{
speed=0; /* speed=1 making a EOP signal */
/* By hgm : sv73002a must useing the SOF */
/* Other mode must use the EOP; thus the usbtester is not polling*/
/* or somtimes it can polling and somtimes it can not polling */
if(speed==1)
{
RB1=1;
RB1=1;
RB1=0;
RB1=0;
RB1=1;
RB1=1;
}
else
{
sof_token = fn;
RB2 = 0;
i_write_host_addr(SOF_BUF+1);
i_write_host_data(sof_token);
sof_token = (fn >> 8) & 0x07;
sof_token = sof_token + crc5(fn);
i_write_host_addr(SOF_BUF+2);
i_write_host_data(sof_token);
i_write_host_addr(SOF_ADR);
i_write_host_data(SOF_BUF);
i_write_host_addr(SOF_LEN);
i_write_host_data(3);
i_write_host_addr(SOF_CTL);
i_write_host_data(EPCTL_ARM);
i_write_host_addr(INT_ENB);
i_write_host_data(0x4F);
fn++;
fn &= 2047;
RB2 = 1;
}
sofstat = 1;
}
/************************************************************************************/
unsigned char crc5(unsigned int crc_input)
{
unsigned char crc_result, crc_shift, crc_cnt;
crc_result = 0xFF;
crc_shift = crc_input & 0x07F; /* first 7 LSB first*/
for (crc_cnt = 0; crc_cnt < 7; crc_cnt++)
{
crc_result = crc_result >> 1;
if (((crc_result >> 2) & 0x01) == (crc_shift & 0x01)) /* LSB CRC = LSB data*/
crc_result &= 0x7F;
else /* LSB CRC != LSB data*/
{
crc_result |= 0x80;
crc_result ^= 0x20;
}
crc_shift = crc_shift >> 1;
}
crc_shift = crc_input >> 7; /* last 4 bit*/
for (crc_cnt = 0; crc_cnt < 4; crc_cnt++)
{
crc_result = crc_result >> 1;
if (((crc_result >> 2) & 0x01) == (crc_shift & 0x01)) /* LSB CRC = LSB data*/
crc_result &= 0x7F;
else /* LSB CRC != LSB data*/
{
crc_result |= 0x80;
crc_result ^= 0x20;
}
crc_shift = crc_shift >> 1;
}
crc_result |= 0x07;
crc_result = ~crc_result;
return crc_result;
}
/****end*****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -