📄 level4.c
字号:
/*
*-------------------------------------------------------------------------------
*-- RCSId: $Id: level4.c,v 1.50 2005-04-12 14:54:27+02 mjg Exp mjg $
*-- $Name: $
*-------------------------------------------------------------------------------
*-- level4.c - UART Communication Routines
*-------------------------------------------------------------------------------
*-- $Log: level4.c,v $
*-- Revision 1.50 2005-04-12 14:54:27+02 mjg
*-- switch to normal mode
*--
*-- Revision 1.49 2005-03-21 17:01:05+01 mjg
*-- Uplink timing tuned
*--
*-- Revision 1.47 2005-02-28 13:35:30+01 mjg
*-- EM4006 uid crc check
*--
*-- Revision 1.46 2005-02-25 11:23:13+01 mjg
*-- EM4006 extraction routine, no crc check
*--
*-- Revision 1.44 2005-02-25 09:12:50+01 mjg
*-- EM4006 decode mode
*--
*-- Revision 1.43 2005-02-23 16:04:15+01 mjg
*-- EM4006 raw mode, not tested
*--
*-- Revision 1.42 2005-02-21 18:13:55+01 mjg
*-- hubneme IV
*--
*-- Revision 1.41 2005-02-21 10:56:31+01 mjg
*-- hubneme III
*--
*-- Revision 1.40 2005-02-21 10:47:42+01 mjg
*-- hubneme III
*--
*-- Revision 1.38 2005-01-19 15:53:52+01 mjg
*-- EM4034 EAS off support corrected
*--
*-- Revision 1.37 2004-12-13 08:49:33+01 mjg
*-- compiler sensitive code in HWTransaction
*--
*-- Revision 1.36 2004-12-07 17:22:17+01 mjg
*-- version 4 of 1TS ready
*--
*-- Revision 1.35 2004-12-07 15:22:21+01 mjg
*-- 1.33 strikes back!
*--
*-- Revision 1.33 2004-06-30 12:47:41+02 mjg
*-- key selection extension
*--
*-- Revision 1.32 2004-05-31 16:41:51+02 mjg
*-- single carrier too slow caused CRC errors, speeded up
*--
*-- Revision 1.31 2004-05-21 09:29:37+02 mjg
*-- startup inventory, to toggle EAS off for EM4034
*--
*-- Revision 1.30 2004-05-10 09:23:28+02 mjg
*-- to toggle EAS off
*--
*-- Revision 1.29 2004-05-07 08:10:25+02 mjg
*-- HW auth passed
*--
*-- Revision 1.28 2004-04-27 17:05:44+02 mjg
*-- to better test the design
*--
*-- Revision 1.27 2004-04-21 15:48:47+02 mjg
*-- FSK low data rate support
*--
*-- Revision 1.26 2004-04-21 13:05:21+02 mjg
*-- EOF ignored because of FSK and 4034 support
*--
*-- Revision 1.25 2004-04-13 11:21:39+02 mjg
*-- sync
*--
*-- Revision 1.24 2004-03-25 16:09:19+01 mjg
*-- to add delayed EOF feature
*--
*-- Revision 1.23 2004-03-25 15:13:23+01 mjg
*-- to add delayed EOF feature
*--
*-- Revision 1.22 2004-03-24 13:35:36+01 mjg
*-- error msg needs better handling
*--
*-- Revision 1.21 2004-03-15 16:59:06+01 mjg
*-- to check SPI
*--
*-- Revision 1.20 2004-02-16 08:04:12+01 mjg
*-- preliminary CD
*--
*-- Revision 1.18 2004-02-10 19:24:41+01 mjg
*-- FSK to add valid bits
*--
*-- Revision 1.17 2004-02-10 18:30:46+01 mjg
*-- dual carrier raw, decoded 1st try
*--
*-- Revision 1.16 2004-02-09 18:03:33+01 mjg
*-- raw dual carrier capture
*--
*-- Revision 1.15 2004-02-08 12:30:53+01 mjg
*-- Decode var removed, FSK polling added
*--
*-- Revision 1.14 2004-02-07 14:59:47+01 mjg
*-- Response parsing correction
*--
*-- Revision 1.13 2004-02-03 08:42:52+01 mjg
*-- hubneme II
*--
*-- Revision 1.12 2004-02-03 07:24:37+01 mjg
*-- fwd debug implemented and removed from being compiled
*--
*-- Revision 1.11 2004-01-19 14:08:05+01 mjg
*-- hubneme I
*--
*-- Revision 1.10 2004-01-14 14:57:35+01 mjg
*-- to Invenotry version 2
*--
*-- Revision 1.9 2003-12-11 17:37:20+01 mjg
*-- yes
*--
*-- Revision 1.8 2003-12-11 16:33:41+01 mjg
*-- 1TS gives too much responses, stayquiet ?
*--
*-- Revision 1.7 2003-12-10 08:15:48+01 mjg
*-- to add dbg code
*--
*-- Revision 1.6 2003-12-09 12:43:01+01 mjg
*-- to 1TS inventory
*--
*-- Revision 1.5 2003-12-09 12:42:44+01 mjg
*-- to 1TS inventory
*--
*-- Revision 1.4 2003-12-05 13:37:15+01 mjg
*-- Reset2Ready, GetSystemInfo
*--
*-- Revision 1.3 2003-12-05 08:38:56+01 mjg
*-- write update
*--
*-- Revision 1.2 2003-12-04 15:58:09+01 mjg
*-- to write
*--
*-- Revision 1.1 2003-12-01 08:18:04+01 mjg
*-- single carrier low drate level1 ok
*--
*-- Revision 1.0 2003-11-26 09:01:03+01 mjg
*-- Initial revision
*--
*-------------------------------------------------------------------------------
*/
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include "level4.h"
#include "level3.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 cmd_message[32]; // maximum
uint8_t cmd_message_len; // length of current cmd_message
uint8_t message_flags; // current message flags
uint8_t expectedResponseLen; // expected number of response bits
uint8_t read_tag_memory_word_flags; // first byte of message
uint8_t read_tag_memory_word_address; // address of Read cmd
uint8_t read_tag_memory_word_blocks; // number of blocks to send
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_delay; // time delay before eof/response
uint16_t write_tag_memory_login_low; // low word of Login cmd
uint16_t write_tag_memory_login_hi; // hi word of Login cmd
uint16_t read_only_word_low; // Read Only Cmd content low
uint16_t read_only_word_hi; // Read Only Cmd content hi
uint16_t write_4094_low; // low word of SPI configuration word
uint16_t write_4094_hi; // hi word of SPI configuration word
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 debug_mode;
//--------------------------------------------------------------
//local declarations
register uint8_t captured_byte asm ("r6"); //store_bit current capture bits
register uint8_t captured_valid asm ("r7"); //store_bit current capture valid bits
register uint8_t capture_cnt asm ("r8"); //store_bit current capture byte index
register uint8_t captured_bit_count asm ("r9"); //store_bit current capture bit counter
#define UART_IN_BUFFER_SIZE 32 // incoming data uart buffer reserved size
const uint8_t VERSION[4] = {
READER_RELEASE,
READER_DATE | ((READER_MONTH & 0x07) << 5),
(READER_MONTH >> 3) | (READER_YEAR << 1),
(READER_FAMILY)
};
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_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
uint8_t temp_buffer[UART_IN_BUFFER_SIZE];
//--------------------------------------------------------------
uint8_t ParseMessage(void);
// ==================================================================
// 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 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 = 25; // baud rate - see UBRR register setting table
// in AVR ATmega8 specification
// UBRRH - using initial values
// UBRRL - 25 for 38k4Bd and frequency f=16 MHz
// (using SINGLE transmission speed)
uart_in_read = uart_in_write = uart_in_end = 0;
uart_state = UART_EMPTY;
}
// ==================================================================
// 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -