├── src ├── fccf.c ├── fccf_encoder.c ├── fccf_encoder.h ├── crc.h ├── fccf.h ├── fccf_decoder.h ├── fccf_def.h ├── crc.c └── fccf_decoder.c ├── .gitignore └── test ├── makefile ├── crc_test.c └── test.h /src/fccf.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/fccf_encoder.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/fccf_encoder.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.out 2 | *.gch -------------------------------------------------------------------------------- /test/makefile: -------------------------------------------------------------------------------- 1 | 2 | src:= ../src/ 3 | 4 | test: 5 | gcc crc_test.c test.h $(src)crc.c $(src)crc.h -------------------------------------------------------------------------------- /src/crc.h: -------------------------------------------------------------------------------- 1 | #ifndef __CRC_H__ 2 | #define __CRC_H__ 3 | 4 | #include 5 | 6 | uint16_t ModBusCRC16(uint8_t *puchMsg, uint32_t usDataLen); 7 | 8 | #endif -------------------------------------------------------------------------------- /test/crc_test.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include "../src/crc.h" 3 | 4 | uint8_t test_data[] = {0,0,0,0,0}; 5 | 6 | int main(){ 7 | // printf("%x\n", ModBusCRC16(test_data, 5)); 8 | TEST(ModBusCRC16(test_data, 5) == 0x2400) 9 | } -------------------------------------------------------------------------------- /test/test.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST_H__ 2 | #define __TEST_H__ 3 | 4 | #include 5 | #include 6 | 7 | #define TEST(code) \ 8 | if(code){ \ 9 | printf("[ok] %s\n", #code);\ 10 | }else{\ 11 | printf("[no] %s\n", #code);\ 12 | } 13 | 14 | #endif -------------------------------------------------------------------------------- /src/fccf.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | enum FCCF_SLAVE_STATE{ 5 | 6 | }; 7 | 8 | typedef struct fccf_slave 9 | { 10 | FccfBuff rx_fifo; 11 | FccfPkg rx_pkg; 12 | FccfBuff tx_buff; 13 | FccfPkg tx_pkg; 14 | union fccf_ctrl_frame ctrl_frame; 15 | 16 | uint32_t slave_addr; 17 | 18 | FccfCb *cb; 19 | }FccfSlave; 20 | 21 | typedef FccfSlave* FccfSlave_t; 22 | 23 | 24 | struct fccf_buff FccfBuff_create(uint8_t *buf, uint32_t len); 25 | 26 | void FccfSlave_init (FccfSlave_t fccf, uint32_t addr, struct fccf_buff rx_buff, struct fccf_buff tx_buff); 27 | void FccfSlave_setCb (FccfSlave_t fccf, FccfCb*); 28 | int FccfSlave_recWrite (FccfSlave_t fccf, uint8_t *data, uint32_t len); 29 | int FccfSlave_recPush (FccfSlave_t fccf, uint8_t frame); 30 | int FccfSlave_handler (FccfSlave_t fccf); 31 | -------------------------------------------------------------------------------- /src/fccf_decoder.h: -------------------------------------------------------------------------------- 1 | #include "fccf_def.h" 2 | 3 | enum FCCF_DECODER_STATE{ 4 | FCCF_DECODER_STATE_HEAD, 5 | FCCF_DECODER_STATE_CREL, 6 | FCCF_DECODER_STATE_REMOTE, 7 | FCCF_DECODER_STATE_HOST, 8 | FCCF_DECODER_STATE_USER, 9 | FCCF_DECODER_STATE_DATA_SIZE, 10 | FCCF_DECODER_STATE_HEAD_CRC, 11 | FCCF_DECODER_STATE_DATA, 12 | FCCF_DECODER_STATE_DATA_CRC, 13 | FCCF_DECODER_STATE_FINISH, 14 | FCCF_DECODER_STATE_ERROR 15 | }; 16 | 17 | typedef struct fccf_decoder 18 | { 19 | FccfBuff buff; 20 | uint32_t buff_count; 21 | FccfPkg pkg; 22 | union fccf_head *head; 23 | fccf_crc_fun crc_fun; 24 | enum FCCF_DECODER_STATE state; 25 | int count; 26 | }FccfDecoder; 27 | 28 | void FccfDecoder_init (FccfDecoder *decoder, fccf_crc_fun crc_fun, uint8_t *buf, uint32_t len); 29 | int FccfDecoder_push (FccfDecoder *decoder, uint8_t frame); 30 | int FccfDecoder_write (FccfDecoder *decoder, uint8_t *data, uint32_t len); 31 | FccfPkg FccfDecoder_getPkg (FccfDecoder *decoder); 32 | int FccfDecoder_reset (FccfDecoder *decoder); -------------------------------------------------------------------------------- /src/fccf_def.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define FCCF_HEAD_FLAG 0xAF 4 | 5 | typedef uint16_t (*fccf_crc_fun)(uint8_t *data, uint32_t len); 6 | 7 | typedef struct fccf_buff 8 | { 9 | uint8_t *ptr; 10 | uint32_t len; 11 | }FccfBuff; 12 | 13 | 14 | union fccf_ctrl_frame 15 | { 16 | uint8_t val; 17 | struct{ 18 | uint8_t m_s_flag:1; 19 | uint8_t crc_flag:1; 20 | uint8_t addr_size:2; 21 | uint8_t user_code_size:2; 22 | uint8_t data_len_size:2; 23 | } context; 24 | }; 25 | 26 | union fccf_head 27 | { 28 | uint8_t buf[2]; 29 | struct{ 30 | uint8_t begin; 31 | union fccf_ctrl_frame ctrl; 32 | } context; 33 | }; 34 | 35 | typedef struct fccf_pkg 36 | { 37 | uint32_t remote_addr; 38 | uint32_t host_addr; 39 | uint32_t user_code; 40 | struct fccf_buff data; 41 | }FccfPkg; 42 | 43 | typedef void(*Fccf_ReceiveCb)(FccfPkg *receive_pkg, FccfPkg *send_pkg); 44 | typedef void(*Fccf_SendFinishCb)(); 45 | 46 | typedef struct fccf_cb 47 | { 48 | Fccf_ReceiveCb receive; 49 | Fccf_SendFinishCb send_finish; 50 | }FccfCb; -------------------------------------------------------------------------------- /src/crc.c: -------------------------------------------------------------------------------- 1 | #include "crc.h" 2 | 3 | const unsigned char auchCRCHi[] = { 4 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 5 | 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 6 | 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 7 | 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 8 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 9 | 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 10 | 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 11 | 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 12 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 13 | 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 14 | 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 15 | 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 16 | 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 17 | 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 18 | 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 19 | 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 20 | 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 21 | 0x40}; 22 | 23 | 24 | const unsigned char auchCRCLo[] = { 25 | 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 26 | 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 27 | 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 28 | 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 29 | 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 30 | 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 31 | 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 32 | 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 33 | 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 34 | 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 35 | 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 36 | 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 37 | 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 38 | 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 39 | 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 40 | 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 41 | 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 42 | 0x40}; 43 | 44 | uint16_t ModBusCRC16(uint8_t *puchMsg, uint32_t usDataLen) 45 | { 46 | unsigned char uchCRCHi = 0xFF; /* high byte of CRC initialized */ 47 | unsigned char uchCRCLo = 0xFF; /* low byte of CRC initialized */ 48 | unsigned uIndex; /* will index into CRC lookup table */ 49 | while (usDataLen--) /* pass through message buffer */ 50 | { 51 | uIndex = uchCRCHi ^ *puchMsg++; /* calculate the CRC */ 52 | uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex]; 53 | uchCRCLo = auchCRCLo[uIndex]; 54 | } 55 | return (uchCRCHi << 8 | uchCRCLo); 56 | } -------------------------------------------------------------------------------- /src/fccf_decoder.c: -------------------------------------------------------------------------------- 1 | #include "fccf_decoder.h" 2 | 3 | static enum FCCF_DECODER_STATE FccfDecoder_ctrlAnalyze( 4 | union fccf_ctrl_frame *ctrl, 5 | enum FCCF_DECODER_STATE state) 6 | { 7 | enum FCCF_DECODER_STATE ret = FCCF_DECODER_STATE_ERROR; 8 | switch (state) 9 | { 10 | case FCCF_DECODER_STATE_HEAD: 11 | case FCCF_DECODER_STATE_DATA_CRC: 12 | case FCCF_DECODER_STATE_FINISH: 13 | case FCCF_DECODER_STATE_ERROR: 14 | break; 15 | 16 | case FCCF_DECODER_STATE_CREL: 17 | if (ctrl->context.addr_size != 0) 18 | { 19 | ret = ctrl->context.m_s_flag ? FCCF_DECODER_STATE_REMOTE : FCCF_DECODER_STATE_HOST; 20 | break; 21 | } 22 | 23 | case FCCF_DECODER_STATE_REMOTE: 24 | if (ctrl->context.addr_size != 0) 25 | { 26 | ret = FCCF_DECODER_STATE_HOST; 27 | break; 28 | } 29 | 30 | case FCCF_DECODER_STATE_HOST: 31 | if (ctrl->context.user_code_size != 0) 32 | { 33 | ret = FCCF_DECODER_STATE_USER; 34 | break; 35 | } 36 | 37 | case FCCF_DECODER_STATE_USER: 38 | if (ctrl->context.data_len_size != 0) 39 | { 40 | ret = FCCF_DECODER_STATE_DATA_SIZE; 41 | break; 42 | } 43 | 44 | case FCCF_DECODER_STATE_DATA_SIZE: 45 | if (ctrl->context.crc_flag) 46 | { 47 | ret = FCCF_DECODER_STATE_HEAD_CRC; 48 | break; 49 | } 50 | 51 | case FCCF_DECODER_STATE_HEAD_CRC: 52 | if (ctrl->context.data_len_size != 0) 53 | { 54 | ret = FCCF_DECODER_STATE_DATA; 55 | break; 56 | } 57 | 58 | case FCCF_DECODER_STATE_DATA: 59 | if (ctrl->context.data_len_size != 0 && ctrl->context.crc_flag) 60 | { 61 | ret = FCCF_DECODER_STATE_DATA_CRC; 62 | break; 63 | } 64 | } 65 | 66 | return ret; 67 | } 68 | 69 | void FccfDecoder_init( 70 | FccfDecoder *decoder, 71 | fccf_crc_fun crc_fun, 72 | uint8_t *buf, 73 | uint32_t len) 74 | { 75 | decoder->buff.ptr = buf; 76 | decoder->buff.len = len; 77 | decoder->buff_count = 0; 78 | decoder->head = buf; 79 | decoder->crc_fun = crc_fun; 80 | decoder->state = FCCF_DECODER_STATE_HEAD; 81 | decoder->count = 0; 82 | decoder->pkg.data.len = 0; 83 | decoder->pkg.host_addr = 0; 84 | decoder->pkg.remote_addr = 0; 85 | decoder->pkg.user_code = 0; 86 | } 87 | 88 | int FccfDecoder_push(FccfDecoder *decoder, uint8_t frame) 89 | { 90 | int ret = 1; 91 | decoder->buff.ptr[decoder->buff_count] = frame; 92 | 93 | const union fccf_ctrl_frame *ctrl = &decoder->head->context.ctrl; 94 | 95 | switch (decoder->state) 96 | { 97 | case FCCF_DECODER_STATE_HEAD: 98 | if (decoder->head->context.begin == FCCF_HEAD_FLAG) 99 | { 100 | decoder->buff_count++; 101 | decoder->state = FCCF_DECODER_STATE_CREL; 102 | } 103 | break; 104 | 105 | case FCCF_DECODER_STATE_CREL: 106 | decoder->state = FccfDecoder_ctrlAnalyze(ctrl, decoder->state); 107 | break; 108 | 109 | case FCCF_DECODER_STATE_REMOTE: 110 | if(ctrl->context.addr_size == 1 && ) 111 | break; 112 | 113 | case FCCF_DECODER_STATE_HOST: 114 | break; 115 | 116 | case FCCF_DECODER_STATE_USER: 117 | break; 118 | 119 | case FCCF_DECODER_STATE_DATA_SIZE: 120 | break; 121 | 122 | case FCCF_DECODER_STATE_HEAD_CRC: 123 | break; 124 | 125 | case FCCF_DECODER_STATE_DATA: 126 | break; 127 | 128 | case FCCF_DECODER_STATE_DATA_CRC: 129 | break; 130 | 131 | default: 132 | break; 133 | } 134 | 135 | if(decoder->state == FCCF_DECODER_STATE_ERROR){ 136 | ret = -1; 137 | } 138 | if(decoder->state == FCCF_DECODER_STATE_FINISH){ 139 | ret = 0; 140 | } 141 | 142 | return ret; 143 | } 144 | 145 | int FccfDecoder_write(FccfDecoder *decoder, uint8_t *data, uint32_t len) 146 | { 147 | } 148 | 149 | FccfPkg FccfDecoder_getPkg(FccfDecoder *decoder) 150 | { 151 | } 152 | 153 | int FccfDecoder_clear(FccfDecoder *decoder) 154 | { 155 | } --------------------------------------------------------------------------------