2022-02-11 11:20:53 +01:00

275 lines
6.3 KiB
C

/* the radian_trx SW shall not be distributed nor used for commercial product*/
/* it is exposed just to demonstrate CC1101 capability to reader water meter indexes */
/* there is no Warranty on radian_trx SW */
void show_in_hex(uint8_t* buffer, size_t len)
{
int i=0;
for (i=0 ; i<len ; i++) {
if (!(i % 16))
puts("");
printf("%02X ", buffer[i]);
}
printf("\n");
}
void show_in_hex_array(uint8_t* buffer, size_t len)
{
int i=0;
for (i=0 ; i<len ; i++) {
if (!(i % 16))printf("\r\n");
printf("0x%02X,", buffer[i]);
}
printf("\n");
}
void show_in_hex_one_line(uint8_t* buffer, size_t len)
{
int i=0;
for (i=0 ; i<len ; i++) {
printf("%02X ", buffer[i]);
}
}
void show_in_hex_one_line_GET(uint8_t* buffer, size_t len)
{
int i=0;
for (i=0 ; i<len ; i++) {
printf("%02XS", buffer[i]);
}
}
void show_in_bin(uint8_t* buffer, size_t len)
{
const uint8_t *ptr;
uint8_t mask;
for ( ptr = buffer; len--; ptr++ )
{
for ( mask = 0x80 ; mask ; mask >>= 1 )
{
(mask & *ptr) > 0 ? printf("1") : printf("0");
}
printf(" ");
}
printf("\n");
}
void echo_debug(T_BOOL l_flag,char *fmt, ...)
{
if (l_flag)
{
va_list args;
va_start (args, fmt);
vprintf (fmt, args);
fflush(stdout);
}
}
void print_time(void)
{/*
time_t mytime;
mytime = time(NULL);
printf(ctime(&mytime));*/
time_t rawtime;
struct tm * timeinfo;
char buffer [80];
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buffer,80,"%d/%m/%Y %X",timeinfo);
printf("%s",buffer);
}
/*----------------------------------------------------------------------------*/
#define CRC_START_KERMIT 0x0000
#define CRC_POLY_KERMIT 0x8408
static uint8_t crc_tab_init = 0;
static uint16_t crc_tab[256];
/*----------------------------------------------------------------------------*/
/* https://www.libcrc.org/
* static void init_crc_tab( void );
*
* For optimal performance, the CRC Kermit routine uses a lookup table with
* values that can be used directly in the XOR arithmetic in the algorithm.
* This lookup table is calculated by the init_crc_tab() routine, the first
* time the CRC function is called.
*/
static void init_crc_tab( void ) {
uint16_t i;
uint16_t j;
uint16_t crc;
uint16_t c;
for (i=0; i<256; i++) {
crc = 0;
c = i;
for (j=0; j<8; j++) {
if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ CRC_POLY_KERMIT;
else crc = crc >> 1;
c = c >> 1;
}
crc_tab[i] = crc;
}
crc_tab_init = 1;
} /* init_crc_tab */
/* https://www.libcrc.org/
* uint16_t crc_kermit( const unsigned char *input_str, size_t num_bytes );
*
* The function crc_kermit() calculates the 16 bits Kermit CRC in one pass for
* a byte string of which the beginning has been passed to the function. The
* number of bytes to check is also a parameter.
*/
uint16_t crc_kermit( const unsigned char *input_ptr, size_t num_bytes ) {
uint16_t crc;
uint16_t tmp;
uint16_t short_c;
uint16_t low_byte;
uint16_t high_byte;
const unsigned char *ptr;
size_t a;
if ( ! crc_tab_init ) init_crc_tab();
crc = CRC_START_KERMIT;
ptr = input_ptr;
for (a=0; a<num_bytes; a++) {
short_c = 0x00ff & (uint16_t) *ptr;
tmp = crc ^ short_c;
crc = (crc >> 8) ^ crc_tab[ tmp & 0xff ];
ptr++;
}
low_byte = (crc & 0xff00) >> 8;
high_byte = (crc & 0x00ff) << 8;
crc = low_byte | high_byte;
return crc;
} /* crc_kermit */
/*----------------------------------------------------------------------------*/
/**
* Reverses the bit order of the input data and adds a start bit before and a stop bit
* after each byte.
*
* @param inputBuffer Points to the unencoded data.
* @param inputBufferLen Number of bytes of unencoded data.
* @param outputBuffer Points to the encoded data.
* @param outputBufferLen Number of bytes of encoded data.
*/
int encode2serial_1_3(uint8_t *inputBuffer, int inputBufferLen, uint8_t *outputBuffer) {
// Adds a start and stop bit and reverses the bit order.
// 76543210 76543210 76543210 76543210
// is encoded to:
// #0123456 7###0123 4567###0 1234567# ##012345 6s7# (# -> Start/Stop bit)
int bytepos;
int bitpos;
int i;
int j = 0;
for (i=0 ; i < (inputBufferLen * 8) ; i++) {
//printf("\r\ni=%u",i);
if (i % 8 == 0) {
if (i > 0) {
//printf(" j=%u stopBIT",j);
// Insert stop bit (3)
bytepos = j / 8;
bitpos = j % 8;
outputBuffer[bytepos] |= 1 << (7 - bitpos);
j++;
bytepos = j / 8;
bitpos = j % 8;
outputBuffer[bytepos] |= 1 << (7 - bitpos);
j++;
bytepos = j / 8;
bitpos = j % 8;
outputBuffer[bytepos] |= 1 << (7 - bitpos);
j++;
} //stop bit
// Insert start bit (0)
bytepos = j / 8;
bitpos = j % 8;
//printf(" j=%u startBIT",j);
outputBuffer[bytepos] &= ~(1 << (7 - bitpos));
j++;
}// start stop bit
bytepos = i / 8;
bitpos = i % 8;
uint8_t mask = 1 << bitpos;
if ((inputBuffer[bytepos] & mask) > 0) {
bytepos = j / 8;
bitpos = 7 - (j % 8);
outputBuffer[bytepos] |= 1 << bitpos;
} else {
bytepos = j / 8;
bitpos = 7 - (j % 8);
outputBuffer[bytepos] &= ~(1 << bitpos);
}
j++;
}//for
//insert additional stop bit until end of byte
while (j%8 > 0)
{
bytepos = j / 8;
bitpos = 7 - (j % 8);
outputBuffer[bytepos] |= 1 << bitpos;
j++;
}
outputBuffer[bytepos+1] = 0xFF;
return bytepos+2;
}
int Make_Radian_Master_req(uint8_t *outputBuffer,uint8_t year,uint32_t serial)
{
uint16_t crc;
uint8_t to_encode[] ={0x13,0x10,0x00,0x45,0xFF,0xFF,0xFF,0xFF,0x00,0x45,0x20,0x0A,0x50,0x14,0x00,0x0A,0x40,0xFF,0xFF}; //les 2 derniers octet sont en reserve pour le CKS ainsi que le serial number
uint8_t synch_pattern[] ={0x50,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF};
uint8_t TS_len_u8;
to_encode[4] = year;
to_encode[5] = (uint8_t)((serial&0x00FF0000)>>16);
to_encode[6] = (uint8_t)((serial&0x0000FF00)>>8);
to_encode[7] = (uint8_t) (serial&0x000000FF);
crc = crc_kermit(to_encode,sizeof(to_encode)-2);
//printf("crc:%x\r\n",crc);
to_encode[sizeof(to_encode)-2]=(uint8_t)((crc&0xFF00)>>8);
to_encode[sizeof(to_encode)-1]=(uint8_t)(crc&0x00FF);
//show_in_hex_one_line(to_encode,sizeof(to_encode));
memcpy(outputBuffer,synch_pattern,sizeof(synch_pattern));
TS_len_u8=encode2serial_1_3(to_encode,sizeof(to_encode),&outputBuffer[sizeof(synch_pattern)]);
return TS_len_u8+sizeof(synch_pattern);
}