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

📄 at91samxusb.c

📁 基于AT91SAM7S64单片机的USB鼠标的实现。
💻 C
字号:
/******************************************************************
   本程序只供学习使用,未经作者许可,不得用于其它任何用途

        欢迎访问我的USB专区:http://group.ednchina.com/93/
        欢迎访问我的blog:   http://www.ednchina.com/blog/computer00
                             http://computer00.21ic.org

AT91SAMxUSB.C  file

作者:电脑圈圈
建立日期: 2008.06.27
修改日期: 2009.03.08
版本:V1.1
版权所有,盗版必究。
Copyright(C) 电脑圈圈 2008-2018
All rights reserved            
*******************************************************************/

#include <AT91SAM7S64.H>
#include "MyType.h"
#include "AT91SAMxUSB.H"
#include "config.h"
#include "UART.h"
#include "Led.h"
#include "UsbCore.h"

unsigned char CurrentBank[4];  //保存当前读的是哪个bank的数据

/********************************************************************
函数功能:USB断开连接函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbDisconnect(void)
{
#ifdef DEBUG0
 Prints("断开USB连接。\r\n");
#endif
 *AT91C_PIOA_SODR=(1<<16); //Disconnect pull-up resistor
 DelayXms(1000);  //延迟1秒
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:USB连接函数。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbConnect(void)
{
#ifdef DEBUG0
 Prints("连接USB。\r\n");
#endif
 *AT91C_PIOA_CODR=(1<<16); //Connect pull-up resistor
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:USB芯片初始化。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipInit(void)
{
 *AT91C_UDP_TXVC=0; //enable the transceiver
 *AT91C_UDP_IDR=0xFFFFFFFF; //disable all USB interrupts
 
 *AT91C_PIOA_PER=(1<<16);  //Enable PA16
 *AT91C_PIOA_OER=(1<<16);  //Output Enable PA16
 
 ConfigValue=0; //配置值初始化为0 
 
 UsbDisconnect();  //先断开USB连接
 UsbConnect();     //将USB连接上
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
函数功能:USB端点复位。
入口参数:无。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipResetEndpoint(void)
{
 *AT91C_UDP_RSTEP=0x0E;  //复位端点
 *AT91C_UDP_RSTEP=0x00;  //复位端点完成
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
函数功能:设置芯片配置状态
入口参数:Value:配置值。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipSetConfig(uint8 Value)
{
 if(Value==0)
 {
  *AT91C_UDP_GLBSTATE&=~(1<<1);  //配置值为0,清除配置
 }
 else
 {
  *AT91C_UDP_GLBSTATE|=(1<<1);   //配置值非0,设置配置
 }
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
函数功能:设置芯片进入设置地址状态
入口参数:Value:地址状态,非0为设置地址,0为未设置地址。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipSetAddressStatus(uint8 Value)
{
 if(Value==0)
 {
  *AT91C_UDP_GLBSTATE&=~(1<<0);  //默认状态
 }
 else
 {
  *AT91C_UDP_GLBSTATE|=(1<<0);  //进入到设置地址阶段
 }
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
函数功能:设置USB芯片功能地址函数。
入口参数:Addr:要设置的地址值。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipWriteAddress(uint8 Addr)
{
 //等待前一个数据包(实际上是状态阶段)发送完毕
 //等待中断产生
 while(1)
 {
  if((*AT91C_UDP_ISR)&(1<<0))break; //发送完毕
  if((*AT91C_UDP_ISR)&((1<<8)|(1<<12)))return; //如果产生复位、挂起则直接返回
 }

 *AT91C_UDP_FADDR=(1<<8)|Addr;  //使能功能端点并设置地址
 if(Addr!=0)  //如果地址非0
 {
  UsbChipSetAddressStatus(1); //设置进入到设置地址阶段
 }
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:使能端点函数。
入口参数:Enable: 是否使能。0值为不使能,非0值为使能。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipSetEndpointEnable(uint8 Enable)
{
 if(Enable!=0)
 {
  AT91C_UDP_CSR[1]|=(7<<8)|(1<<15); //使能端点1,并设置为中断IN端点
  while((AT91C_UDP_CSR[1]&((7<<8)|(1<<15)))!=((7<<8)|(1<<15)));  //等待设置好
 
  AT91C_UDP_CSR[2]|=(3<<8)|(1<<15); //使能端点2,并设置为中断OUT端点
  while((AT91C_UDP_CSR[2]&((3<<8)|(1<<15)))!=((3<<8)|(1<<15)));  //等待设置好
 }
 else
 {
 }
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:判断是否是SETUP包。
入口参数:无。
返    回:0:不是SETUP;非0:是SETUP。
备    注:无。
********************************************************************/
int UsbChipIsSetup(uint8 Endp)
{
 if((AT91C_UDP_CSR[Endp])&(1<<2))
 {
  return 0xFF;  //是setup包,返回非0
 }
 else
 {
  return 0;
 }
}
/////////////////////////End of function/////////////////////////////

/********************************************************************
函数功能:清除接收端点缓冲区的函数。
入口参数:无。
返    回:无。
备    注:只有使用该函数清除端点缓冲后,该接收端点才能接收新的数据包。
********************************************************************/
void UsbChipClearBuffer(uint8 Endp)
{
 if(CurrentBank[Endp]==0) //清除BANK0
 {
  AT91C_UDP_CSR[Endp]&=~(1<<1); //将RX_DATA_BK0置0
  while(AT91C_UDP_CSR[Endp]&(1<<1));  //等待该位被置0
 }
 else
 {
  AT91C_UDP_CSR[Endp]&=~(1<<6); //将RX_DATA_BK1置0
  while(AT91C_UDP_CSR[Endp]&(1<<6));  //等待该位被置0
 }
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:应答建立包的函数。
入口参数:Endp:端点号。
返    回:无。
备    注:无。
********************************************************************/
void UsbChipAcknowledgeSetup(uint8 Endp)
{
 AT91C_UDP_CSR[Endp]|=(1<<7);  //设置DIR位
 while(!(AT91C_UDP_CSR[Endp]&(1<<7)));  //直到该位被设置
 AT91C_UDP_CSR[Endp]&=~(1<<2);  //清除RX SETUP位
 while((AT91C_UDP_CSR[Endp]&(1<<2)));  //直到该位被清除
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:读取端点缓冲区函数。
入口参数:Endp:端点号;Len:需要读取的长度;Buf:保存数据的缓冲区。
返    回:实际读到的数据长度。
备    注:无。
********************************************************************/
uint8 UsbChipReadEndpointBuffer(uint8 Endp, uint8 Len, uint8 *Buf)
{
 uint8 i,j;

#ifdef DEBUG2
 Prints("UDP_CSR");
 Printc('0'+Endp);
 Prints(" is ");
 PrintLongIntHex(AT91C_UDP_CSR[Endp]);
 Prints("\r\n");
#endif
 
 if(!UsbChipIsSetup(Endp))  //如果不是SETUP包,则要检查是哪个端点缓冲区
 {
  switch(AT91C_UDP_CSR[Endp]&((1<<1)|(1<<6)))
  {
   case ((1<<1)|(1<<6)): //两个缓冲区都满了
    if(CurrentBank[Endp]==0)  //如果前面读的是BANK0,那么本次读BANK1
    {
     CurrentBank[Endp]=1;
    }
    else   //如果前面读的是BANK1,那么本次读BANK0
    {
     CurrentBank[Endp]=0;
    }
   break;
   case (1<<1): //如果只是BANK0满,那么就读它
    CurrentBank[Endp]=0;
   break;
   case (1<<6): //如果只是BANK1满,那么就读它
    CurrentBank[Endp]=1;
   break;
   default:  //没有缓冲区有数据,则返回0,没有数据
   return 0;
  }
 }
 
 j=(AT91C_UDP_CSR[Endp])>>16; //获取数据长度
 if(j>Len) //如果要读的字节数比实际接收到的数据长
 {
  j=Len;  //则只读指定的长度数据
 }
#ifdef DEBUG1 //如果定义了DEBUG1,则需要显示调试信息
 Prints("读端点");
 PrintLongInt(Endp);
 Prints("缓冲区");
 PrintLongInt(j);      //实际读取的字节数
 Prints("字节。\r\n");
#endif
 for(i=0;i<j;i++)
 {
  *(Buf+i)=AT91C_UDP_FDR[Endp];  //从FIFO中读一字节数据
#ifdef DEBUG1
  PrintHex(*(Buf+i)); //如果需要显示调试信息,则显示读到的数据
  if(((i+1)%16)==0)Prints("\r\n"); //每16字节换行一次
#endif
 }
#ifdef DEBUG1
 if((j%16)!=0)Prints("\r\n"); //换行。
#endif
 return j; //返回实际读取的字节数。
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:使能发送端点缓冲区数据有效的函数。
入口参数:Endp: 端点号。
返    回:无。
备    注:只有使用该函数使能发送端点数据有效之后,数据才能发送出去。
********************************************************************/
void UsbChipValidateBuffer(unsigned char Endp)
{
 AT91C_UDP_CSR[Endp]|=(1<<4); //TXPKTRDY置1,使能发送数据
 while(!(AT91C_UDP_CSR[Endp]&(1<<4))); //等待该位被置1
}
////////////////////////End of function//////////////////////////////

/********************************************************************
函数功能:将数据写入端点缓冲区函数。
入口参数:Endp:端点号;Len:需要发送的长度;Buf:保存数据的缓冲区。
返    回:Len的值。
备    注:无。
********************************************************************/
uint8 UsbChipWriteEndpointBuffer(uint8 Endp,uint8 Len,uint8 * Buf)
{
 uint8 i;
 
#ifdef DEBUG1 //如果定义了DEBUG1,则需要显示调试信息
 Prints("写端点");
 PrintLongInt(Endp);
 Prints("缓冲区");
 PrintLongInt(Len);    //写入的字节数
 Prints("字节。\r\n");
#endif
 for(i=0;i<Len;i++)
 {
  AT91C_UDP_FDR[Endp]=*(Buf+i); //将数据写到FIFO中
#ifdef DEBUG1
  PrintHex(*(Buf+i));  //如果需要显示调试信息,则显示发送的数据
  if(((i+1)%16)==0)Prints("\r\n"); //每16字节换行一次
#endif
  }
#ifdef DEBUG1
 if((Len%16)!=0)Prints("\r\n"); //换行
#endif
 UsbChipValidateBuffer(Endp); //使端点数据有效
 return Len; //返回Len
}
////////////////////////End of function//////////////////////////////

⌨️ 快捷键说明

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