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

📄 filetransfer.c

📁 8051试验程序 基础教材
💻 C
字号:
/*--[ FileTransfer.c ]---------------------------------------------------------
Author   DM  DATE 4-4-03
Modified CS  DATE 8-25-03
Modified PKC DATE 1-24-06  (changed 'F320.h to 'F340.h)
Modified PKC DATE 10-11-06 (changed USBXpress API interrupt to 17)

This example illustrates usage of the USB_API.lib

DO NOT locate code segments at 0x1400 to 0x4000
These are used for non-voltile storage for transmitted data.
------------------------------------------------------------------------------*/

/*--[ Include files ]---------------------------------------------------------*/

#include <stddef.h>         /* Used for NULL pointer definition */
#include "MCU_SELECT.h" /* Header file for SiLabs c8051f34x */
#include "USB_API.h"    /* Header file for USB_API.lib */

/*--[ Bit Definitions ]-------------------------------------------------------*/

#define Led1 P2_bit.P22   /* LED='1' means ON */
#define Led2 P2_bit.P23   /* These blink to indicate data transmission */

/*--[ Constants Definitions ]-------------------------------------------------*/

/* Total number of flash pages to be used for file storage */
#define NUM_STG_PAGES 20

/* Use the maximum read block size of 64 bytes */
#define MAX_BLOCK_SIZE_READ 64

/* Use the maximum write block size of 4096 bytes */
#define MAX_BLOCK_SIZE_WRITE 4096

/* Size of each flash page */
#define FLASH_PAGE_SIZE 512

#define BLOCKS_PR_PAGE FLASH_PAGE_SIZE/MAX_BLOCK_SIZE_READ
#define MAX_NUM_BYTES   FLASH_PAGE_SIZE*NUM_STG_PAGES
#define MAX_NUM_BLOCKS  BLOCKS_PR_PAGE*NUM_STG_PAGES

/* Message Types for communication with host */
#define READ_MSG  0x00
#define WRITE_MSG 0x01
#define SIZE_MSG  0x02
#define DELAYED_READ_MSG 0x05

/* Machine States */
#define ST_WAIT_DEV 0x01 /* Wait for application to open a device instance */
#define ST_IDLE_DEV 0x02 /* Device is open, wait for Setup Message from host */
#define ST_RX_SETUP 0x04 /* Received Setup Message, decode and wait for data */
#define ST_RX_FILE  0x08 /* Receive file data from host */
#define ST_TX_FILE  0x10 /* Transmit file data to host */
#define ST_TX_ACK   0x20 /* Transmit ACK 0xFF back to host after every 8
                            packets */
#define ST_ERROR    0x80 /* Error state */

/* Structure definition of a block of data */
typedef struct {
   BYTE  Piece[MAX_BLOCK_SIZE_READ];
}  BLOCK;

/* Structure definition of a flash memory page */
typedef struct {
   BYTE  FlashPage[FLASH_PAGE_SIZE];
}  PAGE;

/*--[ Constants ]-------------------------------------------------------------*/

/* Temporary storage of between flash writes */
__xdata BLOCK TempStorage[BLOCKS_PR_PAGE];

__data BYTE __code *PageIndices[20]={
  (BYTE __code *)0x2200, (BYTE __code *)0x2400, (BYTE __code *)0x2600,
  (BYTE __code *)0x2800, (BYTE __code *)0x2A00, (BYTE __code *)0x2C00,
  (BYTE __code *)0x2E00, (BYTE __code *)0x3000, (BYTE __code *)0x3200,
  (BYTE __code *)0x3400, (BYTE __code *)0x3600, (BYTE __code *)0x3800,
  (BYTE __code *)0x3A00, (BYTE __code *)0x3C00, (BYTE __code *)0x3E00,
  (BYTE __code *)0x4000, (BYTE __code *)0x4200, (BYTE __code *)0x4400,
  (BYTE __code *)0x4600
};

__data BYTE  Buffer[3];         /* buffer for setup messages */
__data BYTE *ReadIndex;
__data UINT  BytesToRead, WriteStageLength, ReadStageLength, NumBytes,
             BytesRead, BytesToWrite, BytesWrote;
__data BYTE  M_State, BlockIndex, PageIndex, BlocksWrote, NumBlocks;

__code const BYTE LengthFile[3] @ 0x2000;

/*--[ USB Descriptor Information ]--------------------------------------------*/

__code const UINT USB_VID          = 0x10C4;
__code const UINT USB_PID          = 0xEA61;
__code const BYTE USB_MaxPower     = 15;      /* Max current = 30 mA (15 * 2) */
__code const UINT USB_bcdDevice    = 0x0100;  /* Device release number 1.00 */
__code const BYTE USB_PwAttributes = 0x80;    /* Bus-powered,
                                                 remote wakeup not supported */

__xdata BYTE USB_SerialStr[]  = {0x0A, 0x03, '1', 0, '2', 0, '3', 0, '4', 0};
__xdata BYTE USB_ProductStr[] =
  {0x10, 0x03, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'A', 0, 'P', 0, 'I', 0};

__xdata BYTE USB_MfrStr[] =
  {0x1A, 0x03, 'S', 0, 'i', 0, 'l', 0, 'i', 0, 'c', 0, 'o', 0, 'n', 0,
   ' ', 0, 'L', 0, 'a', 0, 'b', 0, 's', 0};

/*--[ Forward declarations ]--------------------------------------------------*/

void Port_Init(void);       /* Initialize Ports Pins and Enable Crossbar */
void State_Machine(void);   /* Determine new state and act on current state */
void Receive_Setup(void);   /* Receive and decode setup packet from host */
void Receive_File(void);    /* Receive file data from host */

void Page_Erase(BYTE __code *);    /* Erase a flash page */
void Page_Write(BYTE __code *);    /* Write a flash page */

/*--[ Code starts here ]------------------------------------------------------*/

void main(void){

  USB_Clock_Start();    /* Init USB clock *before* calling USB_Init */
  USB_Init(USB_VID, USB_PID, USB_MfrStr, USB_ProductStr, USB_SerialStr,
           USB_MaxPower, USB_PwAttributes, USB_bcdDevice);

  CLKSEL |= 0x02;
  RSTSRC   |= 0x02;

  Port_Init();          /* Initialize crossbar and GPIO */
  USB_Int_Enable();     /* Enable USB_API Interrupts */

  while (1);
}

void  Port_Init(void){

  P2MDOUT |= 0x0C;      /* Port 2 pins 0,1 set high impedence */
#ifndef _C8051F326_7_
  XBR0     = 0x00;
  XBR1     = 0x40;      /* Enable Crossbar */
#endif
}

void  Page_Erase(BYTE __code *Page_Address){
  BYTE EA_Save;
  BYTE __xdata *pwrite;

  EA_Save   = IE_bit.EA;   /* Save current EA */
  IE_bit.EA = 0;           /* Turn off interrupts */

  /* Set write pointer to Page_Address */
  pwrite = (BYTE __xdata *)(Page_Address);

  PSCTL = 0x03;            /* Enable flash erase and writes */
  FLKEY = 0xA5;            /* Write flash key sequence to FLKEY */
  FLKEY = 0xF1;

  *pwrite  =  0x00;        /* Erase flash page using a write command */
  PSCTL =  0x00;           /* Disable flash erase and writes */

  IE_bit.EA =  EA_Save;    /* Restore state of EA */
}

void  Page_Write(BYTE __code *PageAddress){

  BYTE  EA_Save;
  BYTE  __xdata *pwrite, *pread;
  UINT  x;

  pread = (BYTE __xdata *)(TempStorage);

  /* Save EA & disable interrupts */
  EA_Save = IE_bit.EA;
  IE_bit.EA = 0;

  pwrite = (BYTE __xdata *)(PageAddress);

  PSCTL  =  0x01;             // Enable flash writes

  for(x = 0;  x<FLASH_PAGE_SIZE;   x++){

     FLKEY =  0xA5;         /* Write flash key sequence */
     FLKEY =  0xF1;
     *pwrite  =  *pread;    /* Write data byte to flash */

     pread++;
     pwrite++;
  }

  /* Disable flash writes & restore EA */
  PSCTL =  0x00;
  IE_bit.EA =  EA_Save;
}

void  State_Machine(void){

  switch   (M_State){
    case  ST_RX_SETUP:    /* Receive and decode host Setup Message */
      Receive_Setup();
      break;
    case  ST_RX_FILE:     /* Receive File data from host */
      Receive_File();
      break;
    case  ST_TX_ACK:      /* Ack Transmit complete, continue RX data */
      M_State = ST_RX_FILE;
      break;
    case  ST_TX_FILE:     /* Send file data to host */
      WriteStageLength = ((BytesToWrite - BytesWrote) > MAX_BLOCK_SIZE_WRITE) ?
                           MAX_BLOCK_SIZE_WRITE : (BytesToWrite - BytesWrote);

      BytesWrote += Block_Write((BYTE __code *)(ReadIndex), WriteStageLength);
      ReadIndex  += WriteStageLength;

      if ((BlocksWrote%8) == 0)
        Led2 = ~Led2;
      if (BytesWrote == NumBytes)
        Led2 = 0;
      break;
    default:
      break;
  }
}

#if defined(_C8051F320_1_)
  #pragma vector=0x83
#elif defined(_C8051F326_7_)
  #pragma vector=0x83
#elif defined(_C8051F34X_)
  #pragma vector=0x8b
#else
  #error Invalid microcontroller choice. See MCU_SELECT.h for details.
#endif

__interrupt void  USB_API_TEST_ISR(void){

  BYTE INTVAL = Get_Interrupt_Source(); /* Determine type of API interrupts */

  if (INTVAL  &  USB_RESET)    /* Bus Reset Event, go to Wait State */
    M_State  =  ST_WAIT_DEV;

  if (INTVAL  &  DEVICE_OPEN)  /* Device opened on host, go to Idle */
    M_State  =  ST_IDLE_DEV;

  if (INTVAL  &  TX_COMPLETE){

    if (M_State == ST_RX_FILE)   /* Ack Transmit complete, go to RX state */
      M_State  =  (ST_TX_ACK);

    /* Transmit complete? Transmit the file, Idle when done */
    if (M_State == ST_TX_FILE)
      M_State  =  (BytesWrote == BytesToWrite) ? ST_IDLE_DEV :ST_TX_FILE;
  }

  if (INTVAL  &  RX_COMPLETE)  /* RX Complete? RX Setup or RX file state */
    M_State  =  (M_State == ST_IDLE_DEV) ? ST_RX_SETUP : ST_RX_FILE;

  if (INTVAL  &  DEVICE_CLOSE)  /* Device closed, wait for re-open */
    M_State  =  ST_WAIT_DEV;

  if (INTVAL  &  FIFO_PURGE)   /* Fifo purged, go to Idle State */
    M_State  =  ST_IDLE_DEV;

  State_Machine();    /* Call state machine routine */
}

void  Receive_Setup(void){

  BytesRead = Block_Read(Buffer, 3);  /* Read Setup Message */

  if (Buffer[0] == READ_MSG){         /* Check See if Read File Setup */

     PageIndex = 0;                   /* Reset Index */
     NumBlocks = LengthFile[2];       /* Read NumBlocks from flash stg */
     NumBlocks = (NumBlocks > MAX_NUM_BLOCKS) ? /* only write as many bytes */
                  MAX_NUM_BLOCKS : NumBlocks;   /* as we have space available */

     Buffer[0]    = SIZE_MSG;         /* Send host size of transfer message */
     Buffer[1]    = LengthFile[1];
     Buffer[2]    = LengthFile[0];
     BytesToWrite = Buffer[1] + 256*Buffer[2];
     BytesWrote   = Block_Write((BYTE*)Buffer, 3);
     M_State      = ST_TX_FILE;       /* Go to TX data state */
     BytesWrote   = 0;
     ReadIndex    = (BYTE *)PageIndices[0];
     Led2         = 1;
  }
  else{                               /* Otherwise assume Write Setup Packet */

    BytesToRead = Buffer[1] + 256*Buffer[2];
    NumBlocks   = (BYTE)(BytesToRead/MAX_BLOCK_SIZE_READ);  /* Find NumBlocks */

    if (BytesToRead > MAX_NUM_BYTES)  /* State Error if transfer too big */
      M_State = ST_ERROR;
    else{

      if (BytesToRead%MAX_BLOCK_SIZE_READ)
        NumBlocks++;    /* Increment NumBlocks for last partial block */

      TempStorage->Piece[0] = Buffer[2];
      TempStorage->Piece[1] = Buffer[1];
      TempStorage->Piece[2] = NumBlocks;

      /* Write Values to Flash */
      Page_Erase((BYTE __code *)0x2000);
      Page_Write((BYTE __code *)0x2000);

      PageIndex   =  0;          /* Reset Index */
      BlockIndex  =  0;
      BytesRead   =  0;
      Led1        =  1;
      M_State     = ST_RX_FILE;  /* Go to RX data state */
    }
  }
}

void Receive_File(void){

  ReadStageLength = ((BytesToRead - BytesRead) > MAX_BLOCK_SIZE_READ) ?
                      MAX_BLOCK_SIZE_READ : (BytesToRead - BytesRead);

  /* Read Block */
  BytesRead += Block_Read((BYTE*)(&TempStorage[BlockIndex]), ReadStageLength);

  BlockIndex++;

  /* If device has received as many bytes as fit on one FLASH page,
   * disable interrupts, write page to flash, reset packet index,
   * enable interrupts. Send handshake packet 0xFF to host after FLASH write
   */
  if ((BlockIndex == (BLOCKS_PR_PAGE)) || (BytesRead == BytesToRead)){
    Page_Erase((BYTE __code *)(PageIndices[PageIndex]));
    Page_Write((BYTE __code *)(PageIndices[PageIndex]));
    PageIndex++;
    Led1 = ~Led1;
    BlockIndex = 0;
    Buffer[0] = 0xFF;
    Block_Write(Buffer, 1);  /* Send handshake Acknowledge to host */
  }

  /* Go to Idle state if last packet has been received */
  if (BytesRead == BytesToRead){
    M_State = ST_IDLE_DEV;
    Led1 = 0;
  }
}

⌨️ 快捷键说明

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