📄 ubcsp.cpp
字号:
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/** **/
/** ubcsp,c **/
/** **/
/** MicroBCSP - a very low cost implementation of the BCSP protocol **/
/** **/
/*****************************************************************************/
/* Int'l Corp. 2005
$Modifier sign Description
==========================================================================================
Jonathan First Version release : 12/08/2005
Jonathan Jonathan1223 Fix "Warm Reset" Command can not stop issue
*/
#include "ubcsp.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <dbgmsg.h>//jack
#if SHOW_PACKET_ERRORS || SHOW_LE_STATES
#include <stdio.h>
#include <windows.h>
#endif
#define BT_DBGMSG NKDbgPrintfW
#define BCSP_DBG FALSE
BOOL gbReset = FALSE;
static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc);
static uint16 ubcsp_crc_reverse (uint16);
/*****************************************************************************/
/** **/
/** Constant Data - ROM **/
/** **/
/*****************************************************************************/
/* This is the storage for the link establishment messages */
static const uint8 ubcsp_le_buffer[4][4] =
{
0xDA, 0xDC, 0xED, 0xED,
0xAC, 0xAF, 0xEF, 0xEE,
0xAD, 0xEF, 0xAC, 0xED,
0xDE, 0xAD, 0xD0, 0xD0
};
/* These are the link establishment headers */
/* The two version are for the CRC and non-CRC varients */
#if UBCSP_CRC
static const uint8 ubcsp_send_le_header[4] =
{
0x40, 0x41, 0x00, 0x7E
};
#else
static const uint8 ubcsp_send_le_header[4] =
{
0x00, 0x41, 0x00, 0xBE
};
#endif
/*****************************************************************************/
/** **/
/** Static Data - RAM **/
/** **/
/*****************************************************************************/
/* This is the storage for all state data for ubcsp */
struct ubcsp_configuration ubcsp_config;
/* This is the ACK packet header - this will be overwritten when
we create an ack packet */
static uint8 ubcsp_send_ack_header[4] =
{
0x00, 0x00, 0x00, 0x00
};
/* This is the deslip lookup table */
static const ubcsp_deslip[2] =
{
SLIP_FRAME, SLIP_ESCAPE,
};
/* This is a state machine table for link establishment */
static uint8 next_le_packet[16] =
{
ubcsp_le_sync, // uninit
ubcsp_le_conf, // init
ubcsp_le_none, // active
ubcsp_le_none,
ubcsp_le_sync_resp, // sync_resp
ubcsp_le_sync_resp,
ubcsp_le_none,
ubcsp_le_none,
ubcsp_le_none, // conf_resp
ubcsp_le_conf_resp,
ubcsp_le_conf_resp,
ubcsp_le_none,
};
/* This is the storage required for building send and crc data */
static uint8 ubcsp_send_header[4];
static uint8 ubcsp_send_crc[2];
/* This is where the receive header is stored before the payload arrives */
static uint8 ubcsp_receive_header[4];
/*****************************************************************************/
/** **/
/** Code - ROM or RAM **/
/** **/
/*****************************************************************************/
/*****************************************************************************/
/** **/
/** ubcsp_initialize **/
/** **/
/** This initializes the state of the ubcsp engine to a known values **/
/** **/
/*****************************************************************************/
void ubcsp_initialize (void)
{
//RETAILMSG(1,(TEXT("ubcsp_initialize+++\n")));
ubcsp_config.ack_number = 0;
ubcsp_config.sequence_number = 0;
ubcsp_config.send_ptr = 0;
ubcsp_config.send_size = 0;
ubcsp_config.receive_index = -4;
ubcsp_config.delay = 0;
#if SHOW_LE_STATES
printf ("Hello Link Uninitialized\n");
#endif
ubcsp_config.link_establishment_state = ubcsp_le_uninitialized;
ubcsp_config.link_establishment_packet = ubcsp_le_sync;
//RETAILMSG(1,(TEXT("ubcsp_initialize---\n")));
}
/*****************************************************************************/
/** **/
/** ubcsp_send_packet **/
/** **/
/** This sends a packet structure for sending to the ubcsp engine **/
/** This can only be called when the activity indication from ubcsp_poll **/
/** indicates that a packet can be sent with UBCSP_PACKET_SENT **/
/** **/
/*****************************************************************************/
void ubcsp_send_packet (struct ubcsp_packet *send_packet)
{
/* Initialize the send data to the packet we want to send */
//RETAILMSG(1,(TEXT("ubcsp_send_packet+++\n")));
ubcsp_config.send_packet = send_packet;
/* we cannot send the packet at the moment
when we can at the moment, just set things to 0 */
ubcsp_config.send_size = 0;
ubcsp_config.send_ptr = 0;
}
/*****************************************************************************/
/** **/
/** ubcsp_receive_packet **/
/** **/
/** This sends a packet structure for receiving to the ubcsp engine **/
/** This can only be called when the activity indication from ubcsp_poll **/
/** indicates that a packet can be sent with UBCSP_PACKET_RECEIVED **/
/** **/
/*****************************************************************************/
void ubcsp_receive_packet (struct ubcsp_packet *receive_packet)
{
/* Initialize the receive data to the packet we want to receive */
RETAILMSG(BCSP_DBG,(TEXT("ubcsp_receive_packet+++\n")));
ubcsp_config.receive_packet = receive_packet;
/* setup to receive the header first */
ubcsp_config.receive_index = -4;
}
/*****************************************************************************/
/** **/
/** ubcsp_calc_crc **/
/** **/
/** Takes the next 8 bit value ch, and updates the crc with this value **/
/** **/
/*****************************************************************************/
#ifdef UBCSP_CRC
static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc)
{
/* Calculate the CRC using the above 16 entry lookup table */
static const uint16 crc_table[] =
{
0x0000, 0x1081, 0x2102, 0x3183,
0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xa50a, 0xb58b,
0xc60c, 0xd68d, 0xe70e, 0xf78f
};
/* Do this four bits at a time - more code, less space */
crc = (crc >> 4) ^ crc_table[(crc ^ ch) & 0x000f];
crc = (crc >> 4) ^ crc_table[(crc ^ (ch >> 4)) & 0x000f];
return crc;
}
/*****************************************************************************/
/** **/
/** ubcsp_crc_reverse **/
/** **/
/** Reserves the bits in crc and returns the new value **/
/** **/
/*****************************************************************************/
static uint16 ubcsp_crc_reverse (uint16 crc)
{
int32
b,
rev;
/* Reserse the bits to compute the actual CRC value */
for (b = 0, rev=0; b < 16; b++)
{
rev = rev << 1;
rev |= (crc & 1);
crc = crc >> 1;
}
return rev;
}
#endif
/*****************************************************************************/
/** **/
/** ubcsp_put_slip_uart **/
/** **/
/** Outputs a single octet to the uart **/
/** If the octet needs to be escaped, then output the escape value **/
/** and then store the second octet to be output later **/
/** **/
/*****************************************************************************/
static void ubcsp_put_slip_uart (uint8 ch)
{
/* output a single UART octet */
/* If it needs to be escaped, then output the escape octet
and set the send_slip_escape so that the next time we
output the second octet for the escape correctly.
This is done right at the top of ubcsp_poll */
////RETAILMSG(1,(TEXT("ubcsp_put_slip_uart+++\n")));
if (ch == SLIP_FRAME)
{
put_uart (SLIP_ESCAPE);
ubcsp_config.send_slip_escape = SLIP_ESCAPE_FRAME;
RETAILMSG(BCSP_DBG,(TEXT("SLIP_ESCAPE_FRAME\n")));
}
else if (ch == SLIP_ESCAPE)
{
put_uart (SLIP_ESCAPE);
ubcsp_config.send_slip_escape = SLIP_ESCAPE_ESCAPE;
RETAILMSG(BCSP_DBG,(TEXT("SLIP_ESCAPE_ESCAPE\n")));
}
else
{
/* Not escaped, so just output octet */
put_uart (ch);
}
}
/*****************************************************************************/
/** **/
/** ubcsp_which_le_payload **/
/** **/
/** Check the payload of this packet, and determine which of the four **/
/** link establishment packets this was. **/
/** Can return 5 if it is not a valid link establishment packet **/
/** **/
/*****************************************************************************/
static uint32 ubcsp_which_le_payload (const uint8 *payload)
{
static int32
octet,
loop;
/* Search through the various link establishment payloads to find
which one we have received */
for (loop = 0; loop < 4; loop ++)
{
for (octet = 0; octet < 4; octet ++)
{
if (payload[octet] != ubcsp_le_buffer[loop][octet])
{
/* Bad match, just to loop again */
goto bad_match_loop;
}
}
/* All the octets matched, return the value */
return loop;
/* Jumps out of octet loop if we got a bad match */
bad_match_loop:
{}
}
/* Non of the link establishment payloads matched - return invalid value */
return 5;
}
/*****************************************************************************/
/** **/
/** ubcsp_recevied_packet **/
/** **/
/** This function is called when we have a SLIP END octet and a full **/
/** packet header and possibly data in the receive packet **/
/** **/
/*****************************************************************************/
static uint8 ubcsp_recevied_packet (void)
{
static uint8
receive_crc,
receive_seq,
receive_ack,
activity;
#if UBCSP_CRC
static int32
loop;
static uint16
crc;
#endif
static uint16
length;
RETAILMSG(BCSP_DBG,(TEXT("ubcsp_recevied_packet+++\n")));
/* Keep track of what activity this received packet will cause */
activity = 0;
/*** Do all error checks that we can ***/
/* First check the header checksum */
if (((ubcsp_receive_header[0] + ubcsp_receive_header[1] + ubcsp_receive_header[2] + ubcsp_receive_header[3]) & 0xff) != 0xff)
{
/* Header Checksum Error */
#if SHOW_PACKET_ERRORS
printf ("\n######################## Header Checksum Error %02X %02X %02X %02X\n",
ubcsp_receive_header[0],
ubcsp_receive_header[1],
ubcsp_receive_header[2],
ubcsp_receive_header[3]);
#endif
/* If we have a header checksum error, send an ack in return
this gets a packet to be resent as quickly as possible */
ubcsp_config.send_ack = 1;
////RETAILMSG(1,(TEXT("ubcsp_recevied_packet+++1\n")));
return activity;
}
/* Decode the received packets header */
ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7;
receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6;
receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3;
receive_seq = (ubcsp_receive_header[0] & 0x07);
ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f);
length =
((ubcsp_receive_header[1] & 0xf0) >> 4) |
(ubcsp_receive_header[2] << 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -