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

📄 level4.c

📁 EM推出的可读写卡片EM4469
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*-------------------------------------------------------------------------------
*--  RCSId: $Id: level4.c,v 0.17 2003-10-10 10:55:39+02 mjg Exp mjg $
*--         $Name:  $
*-------------------------------------------------------------------------------
*-- level4.c - UART Communication Routines 
*-------------------------------------------------------------------------------
*-- $Log: level4.c,v $
*-- Revision 0.17  2003-10-10 10:55:39+02  mjg
*-- *** empty log message ***
*--
*-- Revision 0.16  2003-08-21 16:00:21+02  mjg
*-- RTF capture problem
*--
*-- Revision 0.15  2003-08-20 10:53:20+02  mjg
*-- to redesign SearchPattern
*--
*-- Revision 0.14  2003-08-20 10:00:46+02  mjg
*-- to add debug features
*--
*-- Revision 0.13  2003-08-07 08:01:29+02  mjg
*-- *** empty log message ***
*--
*-- Revision 0.11  2003-07-22 13:27:42+02  mjg
*-- cloned firmware
*--
*-------------------------------------------------------------------------------
*/

#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdio.h>

#include "level4.h"
#include "level2.h"
#include "level1.h"

//--------------------------------------------------------------
//global declarations


uint8_t volatile uart_command;          // command handshake value
                                        // set by UART RECV
                                        // reset by main() when done

uint8_t read_tag_memory_word_address;   // address of Read cmd
uint16_t read_tag_memory_word_low;      // Read Cmd content low
uint16_t read_tag_memory_word_hi;       // Read Cmd content hi

uint16_t write_tag_memory_word_address; // address of Write Tag cmd
uint16_t write_tag_memory_word_low;     // low word of Write Tag cmd
uint16_t write_tag_memory_word_hi;      // hi word of Write Tag cmd

uint16_t write_tag_memory_login_low;    // low word of Login cmd
uint16_t write_tag_memory_login_hi;     // hi word of Login cmd

uint8_t write_tag_memory_forward_link;  // forward item of Forward link cmd

uint16_t read_only_word_low;            // Read Only Cmd content low
uint16_t read_only_word_hi;             // Read Only Cmd content hi


uint8_t switch_coil_byte;               // switch item of Set Coil cmd

uint8_t config_data_rate;               // see EM4469 spec
uint8_t config_encoder;                 // see EM4469 spec
uint8_t config_psk_carrier;             // see EM4469 spec
uint8_t config_delayed;                 // see EM4469 spec
uint8_t config_lwr;                     // see EM4469 spec
uint8_t config_raw;                     // see EM4469 spec
uint8_t config_forward_link;            // 0=4050 type, 1=other
uint8_t config_write_conf;              // 1=write this configuration into the EEPROM

uint8_t * read_ptr;                     //debug capture pulse lengths uart data pointer
uint8_t volatile read_pos;              //debug capture pulse lengths uart read counter

uint8_t fwd_set_0;                      // forwadlink pulse length values to be set
uint8_t fwd_set_A;
uint8_t fwd_set_B;
uint8_t fwd_set_C;
uint8_t fwd_set_D;
uint8_t fwd_set_E;
uint8_t fwd_set_F;

uint8_t debug_mode;

//--------------------------------------------------------------
//local declarations

#define UART_IN_BUFFER_SIZE 32             // incoming data uart buffer reserved size
#define UART_OUT_BUFFER_SIZE 250           // outgoing data uart buffer reserved size

uint8_t volatile uart_in_buffer[UART_IN_BUFFER_SIZE]; // input cyclic buffer
uint8_t volatile uart_in_read;                        // input read index
uint8_t volatile uart_in_end;                         // input message read index
uint8_t volatile uart_in_write;                       // input write index
uint8_t volatile uart_in_overflow;                    // input buffer overflow
uint8_t volatile uart_in_error;                       // input buffer parity error, ...

uint8_t volatile uart_out_buffer[UART_OUT_BUFFER_SIZE];   // output buffer
uint8_t volatile uart_out_read;                       // output read index
uint8_t volatile uart_out_write;                      // output write index
uint8_t volatile uart_out_end;                        // last output write index

uint8_t volatile uart_read_bytes;       // number of bytes to read before parsing
uint8_t volatile uart_read_msg_bytes;   // actual number of bytes (msg position no.2)

//UART_STATE - enum is errorneous in gcc+sim/debug
#define UART_EMPTY           1          // no bytes are pending
#define UART_READ_SIZE       2          // try to analyze incoming message size from pending bytes
#define UART_READ_BYTES      3          // try to analyze body and ETX of message from pending bytes
#define UART_WAIT_ERROR_SENT 4          // something is wrong within analysed pending bytes
#define UART_VALID           5          // known message format was detected, rest is still pending

uint8_t uart_state;                     // current state of incoming message analysis

// ==================================================================

void IncWriteOutIndex(void);
uint8_t ParseMessage(void);
void FormatResponse_ReadTagMemory(uint8_t ack);
void FormatResponse_ReadOnly(uint8_t ack);
void FormatResponse_Status(uint8_t ack);
 

// ==================================================================
// uart byte receive interrupt

SIGNAL (SIG_UART_RECV)
{
  uart_in_buffer[uart_in_write++] = UDR;               //store byte into cyclic buffer

  if (uart_in_write == UART_IN_BUFFER_SIZE)
    uart_in_write = 0;

  if (uart_in_write == uart_in_read) {  
    uart_in_overflow = 1;                              //set flag in overflow
    //block reception until some bytes are parsed out
  }

  if ((UCSRA & ((1<<FE)|(1<<DOR)|(1<<PE))) != 0) {     //frame error, data overrun or parity error
    uart_in_error = 1;                                 //set flag in error
  };

}

// ==================================================================
// uart byte transmission

SIGNAL(SIG_UART_DATA)
{
  if (uart_out_end != uart_out_read) {                 //if current message is being sent
    UDR = uart_out_buffer[uart_out_read++];            //send next byte
    if (uart_out_read == UART_OUT_BUFFER_SIZE)
      uart_out_read = 0;
  } else {
    cbi(UCSRB, UDRIE);                                 //else stop
  }
}

// ==================================================================
// uart init routine

void UARTIni(void) {

   // UCSRA is not necessary to set up, using initial valuses         
   // no double transmission speed, no multi-processor mode           

   UCSRB  = (1<<RXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN); 
                       // set up : RXCIE, UDRIE, RXEN, TXEN           
                       // (interrupt enable from receiver,            
                       // UART receiver enable, UART transmit enable) 

   UCSRC = (1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0); 
                       // asynchronous operation, 8 data bits,        
                       // no parity, 1 stop bit                       

   UBRRL = 103;        // baud rate - see UBRR register setting table 
                       //             in AVR ATmega8 specification    
                       // UBRRH - using initial values                
                       // UBRRL - 51 for frequency f=8 MHz            
                       //       - 103 for frequency f=16 MHz          
                       // (using SINGLE transmission speed)           

  uart_in_read = uart_in_write = uart_in_end = 0;
  uart_out_read = uart_out_write = uart_out_end = 0;
  uart_state = UART_EMPTY; 
}

// ==================================================================
// increase uart_out_write pointer by 1 
// (to consider which one has better space/speed trade-off)

void IncWriteOut(uint8_t x) {
  uart_out_buffer[uart_out_write++] = x;
  if (uart_out_write == UART_OUT_BUFFER_SIZE)
    uart_out_write = 0;
}

// ==================================================================
// parsing procedures
// ==================================================================

// ==================================================================
// checks pending bytes in uart buffer to find known message format
// if already received bytes form incomplete known message, UART_MESSAGE_OK is returned
// if any chaos bytes are detected, appropriate error is returned
// if complete known message is detected and parsed ok, command type is returned,
//    uart_read_msg_bytes size is set and command respective values are parsed

uint8_t CheckIncommingMessage(void) {

uint8_t ptr = uart_in_read;
uint8_t result = UART_MESSAGE_OK;
uint8_t c;

  if (uart_in_overflow != 0) {
    uart_in_overflow = 0;              //buffer is dropped
    uart_in_read = uart_in_write;      //=async
    return ERR_UART_OVERFLOW;
  }
  if (uart_in_error != 0) {
    uart_in_error = 0;                 //buffer is dropped
    uart_in_read = uart_in_write;      //=async
    return ERR_UART_ERROR_FLAG;
  }

  if (uart_in_read == uart_in_write) {
    return UART_MESSAGE_OK;
  }

  uart_state = UART_EMPTY;
  result = UART_MESSAGE_OK;

  while ((ptr != uart_in_write) && (uart_state != UART_WAIT_ERROR_SENT) && (uart_state != UART_VALID)) {

    c = uart_in_buffer[ptr];

    //positive branches inside each case are usually written first 

    switch (uart_state) {
    case UART_EMPTY :                //detect STX
      if (c == 0x00) {               //zero byte is ignored
      } else 
      if (c == 0x02) {             
        uart_state = UART_READ_SIZE;
      } else {

        uart_state = UART_WAIT_ERROR_SENT;
        result = ERR_UART_ERROR_FLAG;
      }
      break;

    case UART_READ_SIZE :            //capture size byte
      if ((c >= 3) || (c <= 9)) {
        uart_read_bytes = c;
        uart_read_msg_bytes = c;
        uart_state = UART_READ_BYTES;
      } else {
        result = ERR_UART_INTERBYTE_ERR;
        uart_state = UART_WAIT_ERROR_SENT;
      }
      break;

    case UART_READ_BYTES :           //read specified size bytes to allow 

      if (--uart_read_bytes == 0) {  //last byte - ETX expected
        //check ETX
        if (c == 0x03) {
          result = UART_MESSAGE_OK;
          uart_state = UART_VALID;
          uart_in_end = ptr;
        } else {
          result = ERR_UART_NO_ETX;
          uart_state = UART_WAIT_ERROR_SENT;
        }
      }
      break;
    };

    if(++ptr == UART_IN_BUFFER_SIZE)
      ptr = 0;
  }

⌨️ 快捷键说明

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