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

📄 usb.c

📁 本程序是基于USBN9602芯片的硬件驱动程序 详细请看软件的说明
💻 C
📖 第 1 页 / 共 5 页
字号:
            TXEN3_PID_NO_TGL;               /*enable TX, choose PID   */
          }
  }

/**********************************************************************/
/* This subroutine handles USB 'alternate' events.                    */
/**********************************************************************/
void usb_alt(void)
  {
        evnt = read_usb(ALTEV);             /*check the events        */
    
        if(evnt & RESET_A)                  /*reset event             */
          {
            write_usb(NFSR,RST_ST);         /*enter reset state       */
            write_usb(FAR,AD_EN+0);         /*set default address     */
            write_usb(EPC0, 0x00);          /*enable EP0 only         */
            FLUSHTX0;                       /*flush TX0 and disable   */
            write_usb(RXC0,RX_EN);          /*enable the receiver     */

          /*adjusting ints is nec. here in case we were in suspend    */
            write_usb(ALTMSK,NORMAL_ALTMSK);/*adjust interrupts       */
            write_usb(NFSR,OPR_ST);         /*go operational          */
          }

        else if(evnt & RESUME_A)            /*resume  event           */
          {
            write_usb(ALTMSK,NORMAL_ALTMSK);/*adjust interrupts       */
            write_usb(NFSR,OPR_ST);         /*go operational          */
          }

        else if((evnt & SD3)&&(suscntr==0)) /*suspend event           */
          {
            write_usb(ALTMSK,SUSPND_ALTMSK);/*adj interrupts          */
            write_usb(NFSR,SUS_ST);         /*enter suspend state     */
            deep_sleep();                   /*reduce power cons.      */
            suscntr=SUSPND_TO;              /*start suspend cntr      */
          }

        else                                /*spurious alt. event!    */
          {
          }
  }

/**********************************************************************/
/* This is the interrupt service routine for USB operations           */
/**********************************************************************/
void usb_isr(void)
  {
        evnt = read_usb(MAEV);              /*check the events        */

        USB_LED_ON;                         /*turn on  intr. LED      */

        if (evnt & RX_EV)
          {
            evnt=read_usb(RXEV);            /*check the RX events     */

            if      (evnt&RXFIFO0) rx_0();  /*endpoint 0              */
            else if (evnt&RXFIFO1) rx_1();  /*endpoint 2              */
            else if (evnt&RXFIFO2) rx_2();  /*endpoint 4              */
            else if (evnt&RXFIFO3) rx_3();  /*endpoint 6              */
            else                            /*some other RX event     */
              {
              }
          }

        else if (evnt & TX_EV)
          {
            evnt=read_usb(TXEV);            /*check the TX events     */
            if      (evnt&TXFIFO0) tx_0();  /*endpoint 0              */
            else if (evnt&TXFIFO1) tx_1();  /*endpoint 1              */
            else if (evnt&TXFIFO2) tx_2();  /*endpoint 3              */
            else if (evnt&TXFIFO3) tx_3();  /*endpoint 5              */
            else                            /*some other TX event     */
              {
              }
          }

        else if (evnt & ALT) usb_alt();     /*alternate event?        */
        
      /*NAKs can come so fast and furious (especially with OHCI hosts)*/
      /*that they MUST have a lower priority than the other events. If*/
      /*they did not, the other events could get starved out.         */
        else if (evnt & NAK)
          {
            evnt=read_usb(NAKEV);           /*check the NAK events    */
            if      (evnt&NAK_O0) onak0();  /*endpoint 0              */
            else if (evnt&NAK_O1) onak1();  /*endpoint 2              */
            else if (evnt&NAK_O2) onak2();  /*endpoint 4              */
            else if (evnt&NAK_I3) inak3();  /*endpoint 5              */
            else                            /*some other NAK event    */
              {
              }
          }

        else                                /*spurious event!         */
          {
          }

      /*the 9602 produces interrupt LEVELS, the COP looks for edges.  */
      /*So we have to fool the 9602 into producing new edges for us   */
      /*when we are ready to look for them.  We do this by temporarily*/
      /*disabling the interrupts, then re-enabling them.              */
        evnt=read_usb(MAMSK);               /*save old mask contents  */
        write_usb(MAMSK,0);                 /*disable interrupts      */
        write_usb(MAMSK,evnt);              /*re-enable interrupts    */

        USB_LED_OFF;                        /*turn off intr. LED      */
  }

/**********************************************************************/
/* This subroutine updates the given a/d report variable as necessary.*/
/**********************************************************************/
void update(byte chnl, byte near *val)
  {
        chnl = A2D_conv(chnl);              /*convert the channel     */
        
        if (chnl<MINJOY) chnl=MINJOY;       /*check and fix the limits*/
        if (chnl>MAXJOY) chnl=MAXJOY;
        chnl-=MINJOY;                       /*adjust for offset       */
        chnl=JOY_DATA[chnl];                /*linearize result        */
        if(chnl!=*val)                      /*if value is different   */
          {
            *val=chnl;                      /*store the new value     */
            SETBIT(status,RPTCHNG);         /*flag the value change   */
          }
  }

/**********************************************************************/
/* This subroutine queues changes, if anyreport variable as necessary.*/
/**********************************************************************/
void queue_chngs(void)
  {
      /*This procedure uses the microwire port, which is also used by */
      /*the interrupt routines.  Since this procedure is called from  */
      /*the main loop, we must temporarily disable interrupts to en-  */
      /*sure that we don't step on ourselves.                         */

      /*if there is new data to report and the xmitter is not loaded  */
        if((TSTBIT(status,RPTCHNG)) && (!TSTBIT(status,RPTBUSY)))
          {
            INTSOFF;                        /*dsable global interrupt */
            queue_rpt(TXD3);                /*queue a report          */
            TXEN3_PID_NO_TGL;               /*enable TX, choose PID   */
            INTSON;                         /*enable global interrupt */
          }
  }

/**********************************************************************/
/* This is the handler for keeping track of the real time.  This proc.*/
/* is called every 0.5 seconds.                                       */
/**********************************************************************/
void trktim(void)
  {
        HEARTBEAT;                          /*heartbeat (1 Hz flash)  */
        SETBIT(status,RPTCHNG);             /*do regular report       */
        if(suscntr>0) suscntr--;            /*decriment until 0       */
  }

/**********************************************************************/
/* This is the handler for the RS232 port.                            */
/**********************************************************************/
void rcveih(void)
  {
        rsnc=rcmd;                          /*slide buffer content up */
        rcmd=rdta;
        rdta=radh;
        radh=radl;
        radl=rcks;

        GET_RX(rcks);                       /*rcks = rx data          */
        
        if (rsnc==SYNCBYT)                  /*if sync code is valid   */
          {
            if (rcks==(unsigned char)(rsnc+rcmd+rdta+radh+radl))
              do_cmd();                     /*do the cmd              */
          }

  }

/**********************************************************************/
/* This is the handler for the RS232 port.                            */
/**********************************************************************/
void xmitih(void)
  {
    byte i;
        if(outq_idx>0)
          {
            PUT_TX(outq[0]);                /*transmit top of queue   */
            for(i=0; i<outq_idx; i++) outq[i]=outq[i+1];  /*move queue*/
            outq_idx--;                     /*decriment index         */
          }

        if(outq_idx==0) TXINTOFF;           /*turn off int if done    */
  }

/**********************************************************************/
/* This subroutine sends a character through the UART transmitter or  */
/* The usb interface, depending on the mode.                          */
/**********************************************************************/
void xmit(char c)
  {
      /*USB mode: move character to endpoint 1 FIFO *******************/
        if(TSTBIT(status,USB_CMD))
          {
            write_usb(TXD1,c);              /*send data to the FIFO   */
          }

      /*UART mode: move character to UART queue ***********************/
        else
          {
            while (outq_idx>=OUTQLEN)       /*wait for room in queue  */
              if (TX_EMPTY) xmitih();       /*or make it if we can    */
            outq[outq_idx++]=c;             /*post character          */
            TXINTON;                        /*turn on interrupt       */
            if (TX_EMPTY) xmitih();         /*start xmission if ready */
          }
  }

/**********************************************************************/
/* This subroutine parses commands received through the cmd channel:  */
/**********************************************************************/
void do_cmd(void)
  {
        byte *radr;                         /*pointer for memory ops  */

#ifdef  COP8
        radr= (byte *) radl;                /*setup pointer           */
#else
        radr= (byte *)(256*radh+radl);      /*setup pointer           */
#endif

        switch (rcmd)
          {
            case 'b':                       /*look for EE bulk erase  */
#ifdef EEPROM
              eebulk();                     /*bulk erase the EEPROM   */
#endif
              xmit('b');                    /*send back dummy code    */
              break;

            case 'd':                       /*look for 'debug' toggle */
              TGLBIT(status,DEBUG);         /*flip the bit            */
              if(TSTBIT(status,DEBUG))      /*send back conf. code    */
                xmit(0xFF);
              else
                xmit(0x00);
              break;

            case 'e':                       /*look for EE reg  erase  */
#ifdef EEPROM
              eerase(radl);                 /*erase the EEPROM reg    */
#endif
              xmit('e');                    /*send back dummy code    */
              break;

            case 'g':                       /*look for 9602 get (read)*/
              xmit(read_usb(radl));         /*read  the spec. 9602 reg*/
              break;

            case 'p':                       /*look for 9602 prog (wr) */
              write_usb(radl,rdta);         /*write the spec. 9602 reg*/
              xmit(rdta);                   /*send it back to confirm */
              break;

            case 'i':                       /*look for init USB cmd   */
              init_usb();                   /*initialize the 9602     */
              xmit('i');                    /*send back dummy code    */
              break;

            case 'l':                       /*look for EE reg  load   */
#ifdef EEPROM
              eergrd(radl);                 /*load  the EEPROM reg    */
              xmit(eebufl);                 /*send back low byte      */
#else
              xmit('l');                    /*send back dummy code    */
#endif
              break;

            case 'q':                       /*look for Query op       */
              xmit(VID);                    /*send Vendor ID          */
              xmit(MAJREV);                 /*send Major Revision     */
              xmit(MINREV);                 /*send Minor Revision     */
            /*the (unsigned char) typecast is used here because the   */
            /*BYTECRAFT C compiler can't properly handle the (byte)   */
            /*variant.                                                */
              rdta=(unsigned

⌨️ 快捷键说明

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