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

📄 radioclient.c

📁 simulink real-time workshop for dragon12 development board from
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
 * Code to manage the client's radio transceiver.
 * See main.c for a simple example of a basic client application.
 *
 * Read README for further documentation.
 *
 * Use at own risk, etc. Feel free to modify and distribute.
 *
 * @author Stephen Craig, 07/08/2006
 */

/* System macros (EXT_MODE, etc.) -- generated by 'gen_cpp_req_defines_h.tlc' */
#include "cpp_req_defines.h"

/* HAS_RFCOMMS:  '0' : no RF communications, '1' : server, '2' : client, '3' : 'both' */
#if ((HAS_RFCOMMS == 2) | (HAS_RFCOMMS == 3))

/* ensure that SPI support is enabled */
#ifndef HAS_SPI
#define HAS_SPI	1
#endif

#include <mc9s12dp256.h>        /* derivative information */
#include "radioClient.h"        /* various macros etc */
//#include "sci0.h"               /* support for SCI0 */
#include "rb_.h"                /* ring buffer implementation */
#include "mc_timer.h"           /* included for TIMER_PRESCALER */

/* define a macro to set the current module state */
#define setState(s) tickCounter = 0, moduleState = s

 /* RF baud rate macro.
    Include the macro for 1 MBits (may be necessary for large ranges)
    Remove macro for 2 MBits */
    
// #define SLOW_RF_BAUD_RATE 

#define CE              PTM_PTM7   /* chip enable */
#define CE_DDR          DDRM_DDRM7 /* chip enable data direction */

/* macro used to print out some debug info */
// #define TO_DEBUG
// #define TO_DEBUG_ERROR_CONDITIONS

#ifdef TO_DEBUG
  #define TO_DEBUG_ERROR_CONDITIONS
#endif

#ifdef TO_DEBUG

/* when debugging, make the whole thing run as slow as possible */
#define TICK_PRESCALAR              0xffff
#define WAIT_FOR_ACK_TICK_COUNT     17

#else
#ifdef SLOW_RF_BAUD_RATE 
/* For 1MBits, nominal time between T~ and ACK is given by
    128 + 5 + 128 + 5 + 2*(33 + 33 + 4*(5 + 2 + PAYLOAD_LEN)) = 710us */
  #define TICK_PRESCALAR   (24*712/TIMER_PRESCALER)

/* If every packet fails, then MAX_RT will occur in
    (250*1 + 8*(5+2+PAYLOAD_LEN) + 138.5)*16 = 12712us = 16 ticks
   Make it 17 to be conservative */
  #define WAIT_FOR_ACK_TICK_COUNT     (17)

#else
/* For 2MBits, nominal time between T~ and ACK is given by
    128 + 5 + 128 + 5 + 1*(33 + 33 + 4*(5 + 2 + PAYLOAD_LEN)) = 488us */
  #define TICK_PRESCALAR   (24*490/TIMER_PRESCALER)

/* If every packet fails, then MAX_RT will occur in
    (250*1 + 4*(5+2+PAYLOAD_LEN) + 138.5)*16 = 8712us = 18 ticks
    Make it 19 to be conservative */ 
  #define WAIT_FOR_ACK_TICK_COUNT     (19)
#endif
#endif

#define TIME_OUT_TICK_COUNT          (255)

#define TICK_REGISTER   TC0
#define TICK_ENABLE     TIE_C0I
#define TICK_INTERRUPT  TFLG1_C0F
// RadioClient_OnTick

/* a delay is required for the client to enter receive mode */
#define WAIT_FOR_SERVER_TICK_COUNT     1

#define ADDRESS_LENGTH       5  /* Address length (should be 5) */

/* define useful mnemonics */
/* these are all reads */
#define R_CONFIG          0x00     // Configuration Register
#define R_EN_AA           0x01     // Enable Auto Acknowledge
#define R_EN_RXADDR       0x02     // Enable RX Addresses
#define R_SETUP_AW        0x03     // Setup of Address Widths
#define R_SETUP_RETR      0x04     // Setup of Automatic Retransmission
#define R_RF_CH           0x05     // RF Channel
#define R_RF_SETUP        0x06     // RF Setup
#define R_STATUS          0x07     // Status
#define R_OBSERVE_TX      0x08     // Transmit Observe register
#define R_CD              0x09     // Carrier Detect
#define R_RX_ADDR_P0      0x0a     // Receive address data pipe 0
#define R_RX_ADDR_P1      0x0b     // Receive address data pipe 1
#define R_RX_ADDR_P2      0x0c     // Receive address data pipe 2
#define R_RX_ADDR_P3      0x0d     // Receive address data pipe 3
#define R_RX_ADDR_P4      0x0e     // Receive address data pipe 4
#define R_RX_ADDR_P5      0x0f     // Receive address data pipe 5
#define R_TX_ADDR         0x10     // Transmit address
#define R_RX_PW_0         0x11     // Number of bytes in RX payload for pipe 0
#define R_RX_PW_1         0x12     // Number of bytes in RX payload for pipe 1
#define R_RX_PW_2         0x13     // Number of bytes in RX payload for pipe 2
#define R_RX_PW_3         0x14     // Number of bytes in RX payload for pipe 3
#define R_RW_PW_4         0x15     // Number of bytes in RX payload for pipe 4
#define R_RW_PW_5         0x16     // Number of bytes in RX payload for pipe 5
#define R_FIFO_STATUS     0x17     // FIFO Status register

/* these are all writes */
#define W_CONFIG          0x20     // Configuration Register
#define W_EN_AA           0x21     // Enable Auto Acknowledge
#define W_EN_RXADDR       0x22     // Enable RX Addresses
#define W_SETUP_AW        0x23     // Setup of Address Widths
#define W_SETUP_RETR      0x24     // Setup of Automatic Retransmission
#define W_RF_CH           0x25     // RF Channel
#define W_RF_SETUP        0x26     // RF Setup
#define W_STATUS          0x27     // Status
#define W_OBSERVE_TX      0x28     // Transmit Observe register
#define W_RX_ADDR_P0      0x2a     // Receive address data pipe 0
#define W_RX_ADDR_P1      0x2b     // Receive address data pipe 1
#define W_RX_ADDR_P2      0x2c     // Receive address data pipe 2
#define W_RX_ADDR_P3      0x2d     // Receive address data pipe 3
#define W_RX_ADDR_P4      0x2e     // Receive address data pipe 4
#define W_RX_ADDR_P5      0x2f     // Receive address data pipe 5
#define W_TX_ADDR         0x30     // Transmit address
#define W_RX_PW_0         0x31     // Number of bytes in RX payload for pipe 0
#define W_RX_PW_1         0x32     // Number of bytes in RX payload for pipe 1
#define W_RX_PW_2         0x33     // Number of bytes in RX payload for pipe 2
#define W_RX_PW_3         0x34     // Number of bytes in RX payload for pipe 3
#define W_RX_PW_4         0x35     // Number of bytes in RX payload for pipe 4
#define W_RX_PW_5         0x36     // Number of bytes in RX payload for pipe 5

#define R_RX_PAYLOAD      0x61     // Read RX-payload
#define W_TX_PAYLOAD      0xa0     // Write TX-payload

#define FLUSH_TX          0xe1     // Flush transmit buffer
#define FLUSH_RX          0xe2     // Flush receive buffer
#define REUSE_TX_PL       0xe3     // Reuse last transmission
#define NOP               0xff     // No operation

/* Flags in STATUS */
#define RX_DR_MASK        0x40     /* Data Ready RX FIFO interrupt */
#define TX_DS_MASK        0x20     /* Data Sent TX FIFO interrupt */
#define MAX_RT_MASK       0x10     /* Max number of TX retries interrupt */
#define RX_P_NO_MASK      0x0e     /* Mask to retrieve the data pipe number */

#define RX_EMPTY_MASK     0x01     /* Flag in FIFO_STATUS register */

#define RF_CH_MASK        0x7f     /* To ensure 0 < rf_ch < 127 */

/* used to escape the characters matching the EOT token and ESCAPE */
#define RADIO_ESCAPE_CHAR           0xfe

/* end of transmission token */
#define RADIO_EOT_CHAR              0xfd

/* define states */
#define STATE_WAIT_FOR_EOT             0
#define STATE_WAIT_FOR_RECEIVE         1
#define STATE_WAIT_FOR_SERVER          2

/* First byte of every message is a header byte */

/* This flag is set if the client (or server) has been reset. */
#define HEADER_RESET_MASK           0x80
/* This flag is set if the client (or server) acknowledges reset. */
#define HEADER_ACK_RESET_MASK       0x40
/* This bit is set in the header byte if the header is to be
   interpretted as EOT */
#define HEADER_EOT_MASK             0x10

/* Last byte of client 0's address, etc 
   Must match the address specified in radioClient.c */
#define CLIENT_TAIL_0               0xc2
#define CLIENT_TAIL_1               0xc3
#define CLIENT_TAIL_2               0xc4
#define CLIENT_TAIL_3               0xc5
#define CLIENT_TAIL_4               0xc6

#define RB_TX_FULL(b) \
  ( ((unsigned char)((b)->out - (b)->in) <= PAYLOAD_LEN - 3) \
   && ((b)->in != (b)->out) \
  )

#define RB_TX_PUSH(b, v) \
	(RB_TX_FULL(b) ? 1 : \
	 ((b)->start[(b)->in++] = (v), (b)->nElements++, 0) \
	)

typedef struct {
  /* the index of the state in the commStates array */
  unsigned char id;

  /* memory for outgoing data, has to be 256 bytes */
  unsigned char outBuf[256];

  /* memory for incoming data, has to be 256 bytes */
  unsigned char inBuf[256];

  /* declare pointers to rb data structures */
  rbType outRB;
  rbType inRB;

  /* store the last tID sent here */
  unsigned char lastTID;

  /* flags to store reset status */
  unsigned char reset;

  unsigned short failureCount;

} commStateType;

commStateType commState;
commStateType *cc = NULL;

/* store the current state */
unsigned char moduleState;

/* incremented every time there is a tick */
unsigned char tickCounter;

/* 
  Transmit() is a private procedure that is only called when the
  client is in possession of the EOT token.
*/
void RadioClient_Transmit() {
unsigned char i, haveSentEOT, header, data;
  
#ifdef TO_DEBUG
  SCI0_OutString("T\r\n"); /* enter Transmit */
#endif
  
  /* can only re-configure if in stand-by mode */
  CE = 0;

  /* a good idea to clear all interrupts and flush buffers first */
  SPI_OutChar(FLUSH_TX);
  SPI_OutChar(FLUSH_RX);
  
  /* clears all interrupts */
  SPI_OutChar2(W_STATUS, RX_DR_MASK | TX_DS_MASK | MAX_RT_MASK);

  /*
    bit  CONFIG Register
      7  0  Reserved
      6  1  MASK_RX_DR  : Don't reflect RX_DR on IRQ pin
      5  1  MASK_TX_DS  : Don't reflect TX_DS on IRQ pin
      4  1  MASK_MAX_RT : Don't reflect MAX_RT on IRQ pin
      3  1  EN_CRC      : Enable CRC
      2  1  CRCO        : 2 byte CRC
      1  1  PWR_UP      : Power Up
      0  0  PRIM_RX     : PTX
      
      Enter transmit mode
  */
  SPI_OutChar2(W_CONFIG, 0x7e);

  /* download the next segment */

  while(SPI0SR_SPTEF == 0) {}

  /* begin SPI segment */
  CSN = 0;

  /* output the write transmit buffer command */
  SPI0DR = W_TX_PAYLOAD;
  SPI_Pause();

  /* Determine what the header byte should be */
  header = cc->reset;
  
  if(header & HEADER_RESET_MASK) {
    /* if we've reset recently, make sure we start transmitting
       from the start of the transmit buffer */
    RB_SET_OUT(&cc->outRB, 0); 
    header |= HEADER_EOT_MASK;
  }

  /* determine whether we should send EOT in header byte */
  if(RB_EMPTY(&cc->outRB)) {
    header |= HEADER_EOT_MASK;
  }
  
  /* output the header byte */
  while(SPI0SR_SPTEF == 0) {}
  SPI0DR = header;
  SPI_Pause();

  /* work out if EOT was set in header */
  haveSentEOT = (header & HEADER_EOT_MASK) != 0;

  /* output the rID */
  while(SPI0SR_SPTEF == 0) {}
  SPI0DR = cc->inRB.in;
  SPI_Pause();

  /* output the tID */
  while(SPI0SR_SPTEF == 0) {}
  SPI0DR = cc->outRB.out;
  SPI_Pause();

  /* store what the last tID sent was */
  cc->lastTID = cc->outRB.out;
  
  /* fill the remaining 31 bytes */
  for(i=3; i<PAYLOAD_LEN; i++) {

    while(SPI0SR_SPTEF == 0) {}
  
      if(haveSentEOT == 0) {

        if(RB_EMPTY(&cc->outRB)) {
          /* if there's no more data to be sent, then EOT */

          SPI0DR = RADIO_EOT_CHAR;
          haveSentEOT = 1;

        } else {
        
          /* check what the next byte is to send */
          RB_PEEK(&cc->outRB, &data);

          if(data != RADIO_ESCAPE_CHAR
             && data != RADIO_EOT_CHAR) {

            /* the byte is not a special token, transmit it */
            RB_POP(&cc->outRB, &SPI0DR);
            
          } else {
            /* the data to be sent matches a special token, need to
               escape the data to be sent so it doesn't get
               misinterpretted */
            if(i == PAYLOAD_LEN - 1) {
              /* there's not enough space for the ESCAPE token and
                 the escaped char in this segment,
                 => EOT, send the character next time */
              SPI0DR = RADIO_EOT_CHAR;
              haveSentEOT = 1;
              
            } else {
              /* there is space for the ESCAPE token and the escaped
                 char */
              SPI0DR = RADIO_ESCAPE_CHAR;
              SPI_Pause();
              
              while(SPI0SR_SPTEF == 0) {}
              RB_POP(&cc->outRB, &SPI0DR);
              
              i++;
            }
          }
        }
      } else {
        /* we have sent EOT, but still need to fill tx_payload */
        /* fill the rest of the transmit buffer with \0 */
        SPI0DR = 0x00;
      }

    SPI_Pause();
  }
  
  /* end SPI packet */

⌨️ 快捷键说明

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