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

📄 periph.c

📁 This Program uses the 2131 dev board s push buttons and seven-segment LED for limited keyboard funct
💻 C
字号:
#pragma NOIV          // Do not generate interrupt vectors
//-----------------------------------------------------------------------------
//  File:    periph.c
//  Contents:  Hooks required to implement USB peripheral function.
//
//   Copyright (c) 2001 Cypress Semiconductor All rights reserved
//-----------------------------------------------------------------------------
#include "ezusb.h"
#include "ezregs.h"
#include "Fx.h"
#include "intrins.h"

extern BOOL GotSUD;             // Received setup data flag
extern BOOL Sleep;
extern BOOL Rwuen;
extern BOOL Selfpwr;

BYTE  Configuration;            // Current configuration
BYTE  AlternateSetting;         // Alternate settings

void TD_Poll( void );

// 0xFFFF - 0x9C40 = 0x63BF (don't forget it's an upcounter, rollover at 0xFFFF
#define T2AUTOH 0x63    // so, 10msec/250nsec = 40,000 tic's
#define T2AUTOL 0xBF    // 40,000 tic's = 0x9C40 for auto-reload value

// TODO: check to see that this matrix maps properly to your connections...
// ...firmware is flexible, <smile>...
const BYTE code kpd_mat[ 4 ][ 4 ] =
{ // ...standard 4x4 keypad matrix...
  {'A', '3', '2', '1'},         // alt: {'D', 'C', 'B', 'A'}, etc...
  {'B', '6', '5', '4'},         //      {'#', '9', '6', '3'},
  {'C', '9', '8', '7'},         //      {'0', '8', '5', '2'},
  {'D', '#', '0', '*'}          //      {'*', '7', '4', '1'} 
};

// Rev. D FX DK board, addr decode (movx reads only) via CPLD
xdata volatile const unsigned char LED0_ON  _at_ 0x8000;
xdata volatile const unsigned char LED0_OFF _at_ 0x8100;
xdata volatile const unsigned char LED1_ON  _at_ 0x9000;
xdata volatile const unsigned char LED1_OFF _at_ 0x9100;
xdata volatile const unsigned char LED2_ON  _at_ 0xA000;
xdata volatile const unsigned char LED2_OFF _at_ 0xA100;
xdata volatile const unsigned char LED3_ON  _at_ 0xB000;
xdata volatile const unsigned char LED3_OFF _at_ 0xB100;
// it may be worth noting that by default the Keil mon-51
// ...utility loads at 0xE000 and above

// use this global (periph.c) variable when (de)asserting debug LEDs...
BYTE ledX_rdvar = 0x00;

#define NOKEY 0xFF
#define DEQUEUE 0x00
#define ENQUEUE 0x01
#define BYTECNT 0x02
#define FLUSHDQ 0x03
#define AOKAY 0
#define ERROR 1

// ...only kpd_mat[][] char(s) are valid as data to enqueue/dequeue...
BYTE queue( BYTE qflg, BYTE qkey )
{ // ...this is a simple queue...
  static BYTE kqueue[ 4 ];      // circular buffer
  static BYTE qtail = 0x00;     // enqueued keys here
  static BYTE qhead = 0x00;     // dequeued keys here
  static BYTE qbc = 0x00;       // number of keys in queue
  
  switch( qflg )
  {
    case DEQUEUE:
    { // ...dequeue user entry
      if( qbc )
      { // there are keys in the queue...notify user - "not full"...
        ledX_rdvar = LED1_OFF;  
        qbc--;
        
        if( qbc )
        { // notify user - "not empty"...
          ledX_rdvar = LED0_ON; 
        }
        else
        { // notify user - "empty"
          ledX_rdvar = LED0_OFF;
        }
        
        qhead = ( qhead + 1 ) % sizeof( kqueue );
        return( kqueue[ qhead ] );
      }
      else
      { // notify user - "empty"
        ledX_rdvar = LED0_OFF;  
        return( NOKEY );
      }
      break;
    }
    case ENQUEUE:
    { // ...enqueue user entry      
      if( qbc < sizeof( kqueue ) )
      { // notify user - "not empty"...
        ledX_rdvar = LED0_ON;   
        qbc++;
        
        if( qbc == sizeof( kqueue ) )
        { // notify user  - "full"...
          ledX_rdvar = LED1_ON; 
        }
        else
        { // notify user - "not full"...
          ledX_rdvar = LED1_OFF;
        }
        
        qtail = ( qtail + 1 ) % sizeof( kqueue );
        kqueue[ qtail ] = qkey;
        return( AOKAY );
      }
      else
      { // notify user  - "full"...
        ledX_rdvar = LED1_ON;   
        return( ERROR );
      }
      break;
    }
    case BYTECNT:
    { // ...return current byte count
      return( qbc );
    }
    
    case FLUSHDQ:
    { // ...flush queue
      qbc = qtail = qhead = 0x00;
      ledX_rdvar = LED1_OFF;    // notify user, "not full"
      ledX_rdvar = LED0_OFF;    // notify user, "empty"
      return( AOKAY );
    }  
    
    default :
    {
      return( ERROR );
    }
  } // ...end "switch"  
      
  return( ERROR );
}  

// 4x4 kpd lines tied to PORTD
// ...PD[7:4] are output col(s)
// ...PD[3:0] are input row(s) - need pull-ups

void getkey( void )
{ // this is a simple 4x4 keypad scan routine, stuffs entry into queue...
  static BYTE lastkey = 0xFF;
  static BYTE thiskey = 0xFF;
  static BYTE cas = 0x7F;       // col assert
  static BOOL qd = 0;
  BYTE icol = 0x00;             // represents PD[7:4], outputs
  BYTE zbit = 0x00;
  BYTE zrow = 0x00;             // represents PD[3:0], inputs
  BYTE drow = 0x00;
  
  if( TR2 )
  {                             // ...still processing software debounce
    return;                     // ...continue to TD_Poll( );
  }
  
  thiskey = 0xFF;
  OUTD = cas = 0x7F;             // "prime-the-pump", assert col - PD7
  zrow = drow = 0x00;
    
  for( icol = 0; icol < 4; icol++ )
  {
    _nop_( );                   // wait, 83nsec
    _nop_( );                   // wait, 167nsec
    _nop_( );                   // wait, 250nsec
    _nop_( );                   // wait, 333nsec
    _nop_( );                   // wait, 416nsec
    _nop_( );                   // wait, 499nsec
    _nop_( );                   // wait, 
    _nop_( );                   // wait, 
    _nop_( );                   // wait, 
    _nop_( );                   // wait, 
    _nop_( );                   // wait, 
    _nop_( );                   // wait, 1usec

    drow = ( PINSD & 0x0F );    
    if( drow != 0x0F )
    { // ...one of the rows detected lo
      zbit = ( drow | 0xF0 );   // snap shot of row(s)
      while( zbit & 1 )
      {                         // search through, find which row is lo
        zbit >>= 1;
        zrow++;                 // used in array lookup below
        if( zrow > 3 )
        { // test for overflow
          break;                // ...out of while loop
        }
      }
      // ...found match, do lookup
      thiskey = kpd_mat[ zrow ][ icol ];
      break;                    // ...out of for loop
    }
    else
    { 
    
    }
    
    // ...try next col...
    cas =  _cror_( cas, 1 );
    OUTD = cas;                 // 0111 1111  - assert col PD7
                                // 1011 1111  - assert col PD6
                                // 1101 1111  - assert col PD5
                                // 1110 1111  - assert col PD4
  }
  OUTD = 0xF0;
  
  if( thiskey != 0xFF )
  { // ...potential key pressed
    ledX_rdvar = LED3_ON;       // ...is "ON" while key is being held
    if( thiskey == lastkey )
    { // ...debounce passed, valid entry
      if( !qd )
      { // ...put key into queue
        lastkey = 0xFF;
        queue( ENQUEUE, thiskey );
        qd = 1;
      }
      else
      { // ...
        
      }
    }
    else
    { // ...new input detected first go 'round
      lastkey = thiskey;        // ...save entry
    }
    TR2 = 1;                    // ...start timer2(T2CON.2=1)
  }
  else
  { // ...
    ledX_rdvar = LED3_OFF;      // ...lastkey depressed
    qd = 0;  
  }
}  

//-----------------------------------------------------------------------------
// Task Dispatcher hooks
//  The following hooks are called by the task dispatcher.
//-----------------------------------------------------------------------------

void TD_Init( void )         
{ // Called once at startup
  
  CPUCS &= 0xFD;                // don't drive CLKOUT (CLKOE=0)

  IFCONFIG = 0x00;              // ports mode
  OED = 0xF0;                   // setup PD[7:4] as outputs, PD[3:0] as inputs

  IN07VAL = 0x04;               // enable endp 2 IN
  OUT07VAL = 0x04;              // enable endp 2 OUT
  USBPAIR = 0x09;               // enable 2x buffering on both endp's

  BPADDR = ( WORD )TD_Poll;     // set breakpoint to trigger on TD_Poll()
  USBBAV |= 0x02;               // BPEN=1, enable breakpoint feature
  USBBAV &= 0xFB;               // BPPULSE=0, disable breakpoint pulse mode

  Rwuen = TRUE;                 // enable remote-wakeup
  
  // using on-chip 16-bit timer2 with auto-reload feature at 10msec tic's...
  // Timer2 runs only in 16-bit mode
  // we'll want to use 16-bit auto-reload timer feature
  CKCON &= 0xDF;      // bit5 controls the base unit timer clock rate for Timer2
                      // bit5=0, Timer2 uses CLK24/12 (used in this example)
                      // bit5=1, Timer2 uses CLK24/4
  
  RCAP2H = TH2 = T2AUTOH;       // see top of this file for #define
  RCAP2L = TL2 = T2AUTOL;

  ET2 = 1;                      // ...don't forget to enable this interrupt

  // turn debug LED[3:0] off...
  ledX_rdvar = LED0_OFF;
  ledX_rdvar = LED1_OFF;
  ledX_rdvar = LED2_OFF;
  ledX_rdvar = LED3_OFF;
  
}

void TD_Poll( void )
{ // Called repeatedly while the device is idle
  BYTE entry = 0x00;

  getkey( );                    // ...scan kpd matix, if found then queue...
  
  if( !( IN2CS & 0x02 ) )
  { // IN2BUSY=0 when buffer available...dequeue users inputs...
    entry = queue( DEQUEUE, NOKEY );   
    if(  entry != 0xFF )
    { // ...valid key closure
      IN2BUF[ 0 ] = entry;
      IN2BC = 1;                // arm endp, 1 key at a time...
    }
    else
    { // ...
  
    }
  }
  else
  {
    
  }
  
  USBBAV |= 0x08;               // turn off breakpoint LED
}

BOOL TD_Suspend(void)       // Called before the device goes into suspend mode
{
  return(TRUE);
}

BOOL TD_Resume(void)       // Called after the device resumes
{
  return(TRUE);
}

//-----------------------------------------------------------------------------
// Device Request hooks
//  The following hooks are called by the end point 0 device request parser.
//-----------------------------------------------------------------------------

BOOL DR_GetDescriptor(void)
{
  return(TRUE);
}

BOOL DR_SetConfiguration(void)  // Called when a Set Configuration command is received
{
  Configuration = SETUPDAT[2];
  return(TRUE);        // Handled by user code
}

BOOL DR_GetConfiguration(void)  // Called when a Get Configuration command is received
{
  IN0BUF[0] = Configuration;
  EZUSB_SET_EP_BYTES(IN0BUF_ID,1);
  return(TRUE);        // Handled by user code
}

BOOL DR_SetInterface(void)     // Called when a Set Interface command is received
{
  AlternateSetting = SETUPDAT[2];
  return(TRUE);        // Handled by user code
}

BOOL DR_GetInterface(void)     // Called when a Set Interface command is received
{
  IN0BUF[0] = AlternateSetting;
  EZUSB_SET_EP_BYTES(IN0BUF_ID,1);
  return(TRUE);        // Handled by user code
}

BOOL DR_GetStatus(void)
{
  return(TRUE);
}

BOOL DR_ClearFeature(void)
{
  return(TRUE);
}

BOOL DR_SetFeature(void)
{
  return(TRUE);
}

#define VX_B0 0xB0              // ...flush the queue
#define VX_B1 0xB1              // ...return number of keys in queue

BOOL DR_VendorCmnd(void)
{
  switch( SETUPDAT[ 1 ] )
  {
    case VX_B0:
    { // flush the queue
      *IN0BUF = queue( FLUSHDQ, NOKEY ); 
      IN0BC = 0x01;             // arm endp, # bytes to xfr
      EP0CS |= bmBIT1;          // ack handshake phase of device request
      break;
    }
    case VX_B1:
    { // return number of keys in queue
      *IN0BUF = queue( BYTECNT, NOKEY ); 
      IN0BC = 0x01;             // arm endp, # bytes to xfr
      EP0CS |= bmBIT1;          // ack handshake phase of device request
      break;
    }
    default:
    {
      break;
    }
  }
  return( FALSE );              // no errors, cmd handled okay
}

//-----------------------------------------------------------------------------
// USB Interrupt Handlers
//  The following functions are called by the USB interrupt jump table.
//-----------------------------------------------------------------------------

// Setup Data Available Interrupt Handler
void ISR_Sudav(void) interrupt 0
{
  GotSUD = TRUE;        // Set flag
  EZUSB_IRQ_CLEAR();
  USBIRQ = bmSUDAV;      // Clear SUDAV IRQ
}

// Setup Token Interrupt Handler
void ISR_Sutok(void) interrupt 0
{
  EZUSB_IRQ_CLEAR();
  USBIRQ = bmSUTOK;      // Clear SUTOK IRQ
}

void ISR_Sof(void) interrupt 0
{
  EZUSB_IRQ_CLEAR();
  USBIRQ = bmSOF;        // Clear SOF IRQ
}

void ISR_Ures(void) interrupt 0
{
  EZUSB_IRQ_CLEAR();
  USBIRQ = bmURES;      // Clear URES IRQ
}

void ISR_IBN(void) interrupt 0
{
}

void ISR_Susp(void) interrupt 0
{
  Sleep = TRUE;
  EZUSB_IRQ_CLEAR();
  USBIRQ = bmSUSP;
}

void ISR_Ep0in(void) interrupt 0
{
}

void ISR_Ep0out(void) interrupt 0
{
}

void ISR_Ep1in(void) interrupt 0
{
}

void ISR_Ep1out(void) interrupt 0
{
}

void ISR_Ep2in(void) interrupt 0
{
}

void ISR_Ep2out(void) interrupt 0
{
}

void ISR_Ep3in(void) interrupt 0
{
}

void ISR_Ep3out(void) interrupt 0
{
}

void ISR_Ep4in(void) interrupt 0
{
}

void ISR_Ep4out(void) interrupt 0
{
}

void ISR_Ep5in(void) interrupt 0
{
}

void ISR_Ep5out(void) interrupt 0
{
}

void ISR_Ep6in(void) interrupt 0
{
}

void ISR_Ep6out(void) interrupt 0
{
}

void ISR_Ep7in(void) interrupt 0
{
}

void ISR_Ep7out(void) interrupt 0
{
}

⌨️ 快捷键说明

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