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

📄 usbn960x.c

📁 TI公司的CCS一些常用的函数库
💻 C
📖 第 1 页 / 共 4 页
字号:
   status=usbn_read(USBN_TXEV) & USBN_TXMSK_ENABLES;

   debug(debug_txb,"T %X ",status);

   if (status & 0xF0) {
      //TODO: not used by CCS
   }
   if (bit_test(status,0)) {  //sent data out of EP0
      txs=usbn_read(USBN_TXS0);
      debug(debug_txb,"%X ",txs);
      if (bit_test(txs,6)) {
         if (USB_dev_req != NONE) { //if we are processing a report then send the next part
            usb_isr_tok_in_dne(0);
         }
         else {
            usbn_write(USBN_TXC0, 0x08);  //flush TX FIFO, disable TX_EN
            usbn_write(USBN_RXC0, 0x08);  //flush RX FIFO
            usbn_write(USBN_RXC0, 0x01);  //enable reception
         }
      }
      else {
         usbn_write(USBN_RXC0, 0x01);
      }
      usb_clear_ep0_buffer();
   }
   if (bit_test(status,1)) {
      txs=usbn_read(USBN_TXS1);
      usb_isr_tok_in_dne(usb_epc_in_address[1]);
   }
   if (bit_test(status,2)) {
      txs=usbn_read(USBN_TXS2);
      usb_isr_tok_in_dne(usb_epc_in_address[2]);
   }
   if (bit_test(status,3)) {
      txs=usbn_read(USBN_TXS3);
      usb_isr_tok_in_dne(usb_epc_in_address[3]);
   }
}

/*******************************************************************************
/* usb_check_rxev()
/*
/* Summary: Handles the RX interrupt.  This happens when an OUT/SETUP token has happened (HOST -> PIC)
/*          and there is data in the RX buffers.
/*
/*          If there is data in the EP0 buffer and it is a SETUP token, it is processed by the
/*          SETUP token handler.  The SETUP token handler is the bulk of this code.
/*
/*          If there is data in the EP1-3 buffers then data is placed into RAM on the PIC.
/*          (See usb_isr_tok_out_dne(endpoint)).
/*
/*          TODO: Not provided by CCS - handle non SETUP data on EP0.
/*
/********************************************************************************/
void usb_check_rxev(void) {
   int8 status, rxstatus, len;

   status=usbn_read(USBN_RXEV) & USBN_RXMSK_ENABLES;

   debug(debug_txb,"R %X ",status);

   if (status & 0xF0) {
      debug(debug_txb,"O ");      //TODO: not used by CCS
   }

   if (bit_test(status,0)) {
      rxstatus=usbn_read(USBN_RXS0);
      debug(debug_txb,"%X ",rxstatus);
      len=rxstatus & 0x0F;

      if ( (len==0) && (bit_test(rxstatus,4)) ) {  //skip the zero len packet, get the next one
      //I have noticed that if you wait to long to get a packet from the buffer that the USBN960x device
      //fails and kills the buffer.  The USBN960x crashes the buffer until a reset, and the
      //USBN960x then thinks there is a 0 length packet.  Sometimes
      //it may even think it has a 0 length setup packet (which is not possible).  When this starts
      //happening the only way I found around the problem was to turn off debugging.  Although the
      //debugging was coded in a way that it should not interfere with the USB interrupt, sometimes it still
      //would.  I did not have such a problem with debugging output on the PIC16C7x5 USB part.
      }

      else if (bit_test(rxstatus,6)) {   //setup
         usbn_write(USBN_EPC0, usbn_read(USBN_EPC0) & 0x7F); //clear STALL

         if (len==USB_MAX_EP0_PACKET_LENGTH) {
            usb_get_packet(0, usb_ep0_rx_buffer, len);   //should always be a length of 8, but just in case
            usbn_write(USBN_TXC0, 0x08);  //flush TX FIFO
            usb_isr_tok_setup_dne();
         }
         else {
            usbn_write(USBN_RXC0, 0x01);  //flush RX FIFO
         }
         usb_clear_ep0_buffer();
      }
      else {
            //TODO: handle OUT tokens to EP0.  CCS only handles SETUP tokens.
            usbn_write(USBN_RXC0, 0x08);  //flush RX buffer.
            usbn_write(USBN_RXC0, 0x01);  //re-enable reception
      }
   }
   if (bit_test(status,1)) {usb_isr_tok_out_dne(usb_epc_out_address[1]);}
   if (bit_test(status,2)) {usb_isr_tok_out_dne(usb_epc_out_address[2]);}
   if (bit_test(status,3)) {usb_isr_tok_out_dne(usb_epc_out_address[3]);}
}

/// END USB Interrupt Service Routine


/// BEGIN USBN960x Functions only used in this File

/*******************************************************************************
/* usbn_write(address, data)
/*
/* Input: address - address of USBN960x register to write to
/*        data - data to write to USBN960x
/*
/* Summary: Writes a byte of memory to specified address on USBN960x
/*
/********************************************************************************/
void usbn_write(int8 address, int8 data) {
   output_high(USBN_RD);
   output_high(USBN_WR);

   usbn_bus_out(address);
   output_high(USBN_A0);
   output_low(USBN_CS);
   output_low(USBN_WR);
   output_high(USBN_WR);
   output_high(USBN_CS);
   output_float(USBN_A0);

   usbn_bus_out(data);
   output_low(USBN_A0);
   output_low(USBN_CS);
   output_low(USBN_WR);
   output_high(USBN_WR);
   output_high(USBN_CS);
   output_float(USBN_A0);
   usbn_bus_float();
}

/*******************************************************************************
/* usbn_read(address)
/*
/* Input: address - address of USBN960x register to read
/* Output: data (byte) in specified address.
/*
/* Summary: Reads a byte of memory from specified address on USBN960x
/*
/********************************************************************************/
int8 usbn_read(int8 address) {
   int8 data;

   output_high(USBN_RD);
   output_high(USBN_WR);

   usbn_bus_out(address);
   output_high(USBN_A0);
   output_low(USBN_CS);
   output_low(USBN_WR);
   output_high(USBN_WR);
   output_high(USBN_CS);
   output_float(USBN_A0);
   usbn_bus_float();

   output_low(USBN_A0);
   output_low(USBN_CS);
   output_low(USBN_RD);
   data=usbn_bus_in();
   output_high(USBN_RD);
   output_high(USBN_CS);
   output_float(USBN_A0);
   usbn_bus_float();

   return(data);
}

/*******************************************************************************
/* usb_find_epc()
/*
/* Input: endpoint - endpoint to find USBN channel number
/*        direction - direction of endpoint.  0 == OUT or CONTROL, 1 == IN
/* Output: returns the USBN960x channel number
/*
/* Summary: The USBN960x has 7 channels (EP0, EP1-3 TX, and EP1-3 RX), but
/*          EP1-3 TX/RX can be mapped to any endpoint from 1-15.  This function
/*          looks up what endpoint is mapped to what channel.  See usb_epc_out_address[]
/*          and usb_epc_in_address[] on how to map channels to endpoint.  CCS defaults to
/*          channel 1 <-> endpoint 1, channel 2 <-> endpoint 2, channel 3 <-> endpoint 3.
/*
/********************************************************************************/
int8 usb_find_epc(int8 endpoint, int1 direction) {
      int8 epc;
      int8 found=0xFF;
      for (epc=0;epc<4;epc++) {
         if (direction) {
            if (usb_epc_in_address[epc]==endpoint) {found=(epc*2); if (epc) {found--;} return(found);}   //0,1,3,5
         }
         else {
            if (usb_epc_out_address[epc]==endpoint) {found=epc*2; return(found);}   //0,2,4,6
         }
      }
      return(found);
}

/*******************************************************************************
/* usb_reset()
/*
/* Summary: Resetsthe USB token handler code, resets the USBN device (software reset, not hardware),
/*          clears all the USBN buffers, clears the local EP0 buffer, enables reception
/*          on EP0.
/*
/********************************************************************************/
void usb_reset(void) {
   usb_token_reset();

   usbn_write(USBN_FAR, 0);
   usbn_write(USBN_EPC0,0);
   usbn_write(USBN_NFSR, USBN_NFSR_RESET);

   usbn_write(USBN_TXC0, 0x08);   //flush fifos
   usbn_write(USBN_TXC1, 0x08);
   usbn_write(USBN_TXC2, 0x08);
   usbn_write(USBN_TXC3, 0x08);

   usbn_write(USBN_RXC0, 0x08);
   usbn_write(USBN_RXC1, 0x08);
   usbn_write(USBN_RXC2, 0x08);
   usbn_write(USBN_RXC3, 0x08);

   usb_clear_ep0_buffer();

   usbn_write(USBN_RXC0, 0x01);    //enable rx0
}

/*******************************************************************************
/* usb_enable_endpoint()
/*
/* Input: endpoint - endpoint to enable
/*        direction - direction of endpoint.  0 == OUT or CONTROL, 1 == IN
/*        iso - TRUE if the endpoint is isochronous, FALSE if it is a bulk/interrupt endpoint.
/*
/* Summary: Enables endpoint for receiving / transmitting.
/*
/********************************************************************************/
void usb_enable_endpoint(int8 endpoint, int1 direction, int1 iso) {
   int8 epc, address, value;
      if ((endpoint < 16)&&(endpoint)) {
      epc=usb_find_epc(endpoint,direction);
      if (epc!=0xFF) {
         address=USBN_EPCx[epc];
         value= epc_to_epadd[epc] | 0x10;
         if (iso) {value |= 0x20;}
         usbn_write(address,value);
         if (!direction) {
            address=USBN_RX_FIFOx[epc] + 2;
            value=usbn_read(address);
            value |= 1; //enable reception
            usbn_write(address, value);
           #if USB_EP1_RX_SIZE
            if (endpoint == 1) {
               usb_ep1_rx_status.rx = 0;
               usb_ep1_rx_status.ov = 0;
            }
           #endif
           #if USB_EP2_RX_SIZE
            if (endpoint == 2) {
               usb_ep2_rx_status.rx = 0;
               usb_ep2_rx_status.ov = 0;
            }
           #endif
           #if USB_EP3_RX_SIZE
            if (endpoint == 3) {
               usb_ep3_rx_status.rx = 0;
               usb_ep3_rx_status.ov = 0;
            }
           #endif
           #if USB_EP4_RX_SIZE
            if (endpoint == 4) {
               usb_ep4_rx_status.rx = 0;
               usb_ep4_rx_status.ov = 0;
            }
           #endif
           #if USB_EP5_RX_SIZE
            if (endpoint == 5) {
               usb_ep5_rx_status.rx = 0;
               usb_ep5_rx_status.ov = 0;
            }
           #endif
           #if USB_EP6_RX_SIZE
            if (endpoint == 6) {
               usb_ep6_rx_status.rx = 0;
               usb_ep6_rx_status.ov = 0;
            }
           #endif
           #if USB_EP7_RX_SIZE
            if (endpoint == 7) {
               usb_ep7_rx_status.rx = 0;
               usb_ep7_rx_status.ov = 0;
            }
           #endif
           #if USB_EP8_RX_SIZE
            if (endpoint == 8) {
               usb_ep8_rx_status.rx = 0;
               usb_ep8_rx_status.ov = 0;
            }
           #endif
           #if USB_EP9_RX_SIZE
            if (endpoint == 9) {
               usb_ep9_rx_status.rx = 0;
               usb_ep9_rx_status.ov = 0;
            }
           #endif
           #if USB_EP10_RX_SIZE
            if (endpoint == 10) {
               usb_ep10_rx_status.rx = 0;
               usb_ep10_rx_status.ov = 0;
            }
           #endif
           #if USB_EP11_RX_SIZE
            if (endpoint == 11) {
               usb_ep11_rx_status.rx = 0;
               usb_ep11_rx_status.ov = 0;
            }
           #endif
           #if USB_EP12_RX_SIZE
            if (endpoint == 12) {
               usb_ep12_rx_status.rx = 0;
               usb_ep12_rx_status.ov = 0;
            }
           #endif
           #if USB_EP13_RX_SIZE
            if (endpoint == 13) {
               usb_ep13_rx_status.rx = 0;
               usb_ep13_rx_status.ov = 0;
            }
           #endif
           #if USB_EP14_RX_SIZE
            if (endpoint == 14) {
               usb_ep14_rx_status.rx = 0;
               usb_ep14_rx_status.ov = 0;
            }
           #endif
           #if USB_EP15_RX_SIZE
            if (endpoint == 15) {
               usb_ep15_rx_status.rx = 0;
               usb_ep15_rx_status.ov = 0;
            }
           #endif
         }
      }
   }
}

/*******************************************************************************
/* usb_disable_endpoint()
/*
/* Input: endpoint - endpoint to enable
/*        direction - direction of endpoint.  0 == OUT or CONTROL, 1 == IN
/*
/* Summary: Disables endpoint.  A disabled interrupt does not respond to tokens.
/*
/********************************************************************************/
void usb_disable_endpoint(int8 endpoint, int1 direction) {
   int8 epc, address, value;
   if ((endpoint != 0)&&(endpoint < 16)) {
      epc=usb_find_epc(endpoint,direction);
      if (epc!=0xFF) {
         address=USBN_EPCx[epc];
         value=usbn_read(address);
         value &= 0xEF;
         usbn_write(address,value);

         if (direction) {address=USBN_TX_FIFOx[epc];} else {address=USBN_RX_FIFOx[epc];}
         address+=2;
         value=usbn_read(address);
         value &= 0xFE; //disable TX_EN or RX_EN
         usbn_write(address,value);
      }
   }
}

void usb_clear_ep0_buffer(void) {
   int8 i;

   for (i=0;i<USB_MAX_EP0_PACKET_LENGTH;i++) {
      usb_ep0_rx_buffer[i]=0;
   }
}

/// END USBN960x Functions only used in this File

#ENDIF

⌨️ 快捷键说明

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