42 #define TS_NOT_ASSIGNED 255 
   46 enum TS_state_t : uint8_t {
 
   55 #ifndef TS_RECEIVE_TIME 
   56 #define TS_RECEIVE_TIME 0 
   62     uint8_t buffer[PJON_PACKET_MAX_LENGTH] = {0};
 
   63     uint16_t position = 0;
 
   64     TS_state_t state = TS_WAITING;
 
   65     PJON_SERIAL_TYPE serial;
 
   69     uint32_t back_off(uint8_t attempts)
 
   71         uint32_t result = attempts;
 
   72         for(uint8_t d = 0; d < TS_BACK_OFF_DEGREE; d++) {
 
   73             result *= (uint32_t)(attempts);
 
   75         return result + PJON_RANDOM(TS_COLLISION_DELAY);
 
   82     bool begin(uint8_t did = 0)
 
   84         PJON_DELAY(PJON_RANDOM(TS_INITIAL_DELAY) + did);
 
   85         _last_reception_time = PJON_MICROS();
 
   94         PJON_DELAY_MICROSECONDS(PJON_RANDOM(TS_COLLISION_DELAY));
 
   96             (state != TS_WAITING) ||
 
   97             PJON_SERIAL_AVAILABLE(serial) ||
 
   98             ((uint32_t)(PJON_MICROS() - _last_reception_time) < TS_TIME_IN)
 
  108     uint16_t fail(TS_state_t s)
 
  111         return (uint16_t)TS_FAIL;
 
  117     static uint8_t get_max_attempts()
 
  119         return TS_MAX_ATTEMPTS;
 
  125     static uint16_t get_receive_time()
 
  127         return TS_RECEIVE_TIME;
 
  133     void handle_collision()
 
  135         PJON_DELAY_MICROSECONDS(PJON_RANDOM(TS_COLLISION_DELAY));
 
  141     int16_t receive_byte()
 
  143         int16_t value = PJON_SERIAL_READ(serial);
 
  147         _last_reception_time = PJON_MICROS();
 
  154     uint16_t receive_response()
 
  159         uint32_t time = PJON_MICROS();
 
  161         while((uint32_t)(PJON_MICROS() - time) < TS_RESPONSE_TIME_OUT) {
 
  162             if(PJON_SERIAL_AVAILABLE(serial)) {
 
  163                 int16_t read = PJON_SERIAL_READ(serial);
 
  164                 _last_reception_time = PJON_MICROS();
 
  166                     if(_response[i++] != read) {
 
  169                     if(i == TS_RESPONSE_LENGTH) {
 
  175             PJON_DELAY_MICROSECONDS(TS_RESPONSE_TIME_OUT / 10);
 
  184     uint16_t receive_frame(uint8_t *
data, uint16_t max_length)
 
  188             (uint32_t)(PJON_MICROS() - _last_call_time) < _read_interval
 
  193         _last_call_time = PJON_MICROS();
 
  197                 (state == TS_RECEIVING) ||
 
  198                 (state == TS_WAITING_END) ||
 
  199                 (state == TS_WAITING_ESCAPE)
 
  201             ((uint32_t)(PJON_MICROS() - _last_reception_time) > TS_BYTE_TIME_OUT)
 
  203             return fail(TS_WAITING);
 
  208             while(PJON_SERIAL_AVAILABLE(serial)) {
 
  209                 int16_t value = receive_byte();
 
  213                 if(value == TS_START) {
 
  215                     return fail(TS_RECEIVING);
 
  221             while(PJON_SERIAL_AVAILABLE(serial)) {
 
  222                 int16_t value = receive_byte();
 
  223                 if((value == TS_START) || (value == -1)) {
 
  224                     return fail(TS_WAITING);
 
  226                 if(value == TS_ESC) {
 
  227                     if(!PJON_SERIAL_AVAILABLE(serial)) {
 
  228                         return fail(TS_WAITING_ESCAPE);
 
  230                         value = receive_byte();
 
  232                             return fail(TS_WAITING);
 
  234                         value = value ^ TS_ESC;
 
  236                             (value != TS_START) &&
 
  240                             return fail(TS_WAITING);
 
  242                         buffer[position++] = (uint8_t)value;
 
  246                 if(max_length == 1) {
 
  247                     return fail(TS_WAITING_END);
 
  249                 if(position + 1 >= PJON_PACKET_MAX_LENGTH) {
 
  250                     return fail(TS_WAITING);
 
  252                 if(value == TS_END) {
 
  253                     return fail(TS_DONE);
 
  255                 buffer[position++] = (uint8_t)value;
 
  260         case TS_WAITING_ESCAPE: {
 
  261             if(PJON_SERIAL_AVAILABLE(serial)) {
 
  262                 int16_t value = receive_byte();
 
  264                     return fail(TS_WAITING);
 
  266                 value = value ^ TS_ESC;
 
  268                     (value != TS_START) &&
 
  272                     return fail(TS_WAITING);
 
  274                 buffer[position++] = (uint8_t)value;
 
  275                 return fail(TS_RECEIVING);
 
  280         case TS_WAITING_END: {
 
  281             if(PJON_SERIAL_AVAILABLE(serial)) {
 
  282                 int16_t value = receive_byte();
 
  284                     return fail(TS_WAITING);
 
  286                 if(value == TS_END) {
 
  287                     return fail(TS_DONE);
 
  289                     return fail(TS_WAITING);
 
  296             memcpy(&
data[0], &buffer[0], position);
 
  297             prepare_response(buffer, position);
 
  309     void send_byte(uint8_t b)
 
  311         uint32_t time = PJON_MICROS();
 
  314             ((result = PJON_SERIAL_WRITE(serial, b)) != 1) &&
 
  315             ((uint32_t)(PJON_MICROS() - time) < TS_BYTE_TIME_OUT)
 
  329     void prepare_response(
const uint8_t *buffer, uint16_t position)
 
  332         for(int8_t i = 0; i < TS_RESPONSE_LENGTH; i++) {
 
  333             raw = buffer[(position - ((TS_RESPONSE_LENGTH - 1) - i)) - 1];
 
  335                                (raw == TS_START) || (raw == TS_ESC) || (raw == TS_END)
 
  343     void send_response(uint8_t response)
 
  345         if(response == PJON_ACK) {
 
  347             wait_RS485_pin_change();
 
  348             for(uint8_t i = 0; i < TS_RESPONSE_LENGTH; i++) {
 
  349                 send_byte(_response[i]);
 
  351             PJON_SERIAL_FLUSH(serial);
 
  352             wait_RS485_pin_change();
 
  360     void send_frame(uint8_t *
data, uint16_t length)
 
  364         uint16_t overhead = 2;
 
  367         for(uint16_t b = 0; b < length; b++) {
 
  373                 (
data[b] == TS_START) ||
 
  374                 (
data[b] == TS_ESC) ||
 
  378                 send_byte(
data[b] ^ TS_ESC);
 
  387 #if defined(RPI) || defined(LINUX) 
  389             PJON_DELAY_MICROSECONDS(
 
  390                 ((1000000 / (_bd / 8)) + _flush_offset) * (overhead + length)
 
  393         PJON_SERIAL_FLUSH(serial);
 
  396         prepare_response(
data, length);
 
  402     void set_serial(PJON_SERIAL_TYPE serial_port)
 
  404         serial = serial_port;
 
  412         if(_enable_RS485_txe_pin != TS_NOT_ASSIGNED) {
 
  413             PJON_IO_WRITE(_enable_RS485_txe_pin, 
HIGH);
 
  414             if(_enable_RS485_rxe_pin != TS_NOT_ASSIGNED) {
 
  415                 PJON_IO_WRITE(_enable_RS485_rxe_pin, 
HIGH);
 
  417             wait_RS485_pin_change();
 
  423         if(_enable_RS485_txe_pin != TS_NOT_ASSIGNED) {
 
  424             wait_RS485_pin_change();
 
  425             PJON_IO_WRITE(_enable_RS485_txe_pin, 
LOW);
 
  426             if(_enable_RS485_rxe_pin != TS_NOT_ASSIGNED) {
 
  427                 PJON_IO_WRITE(_enable_RS485_rxe_pin, 
LOW);
 
  432 #if defined(RPI) || defined(LINUX) 
  436     void set_baud_rate(uint32_t baud)
 
  445     void set_flush_offset(uint16_t offset)
 
  447         _flush_offset = offset;
 
  456     uint32_t get_read_interval()
 
  458         return _read_interval;
 
  461     void set_read_interval(uint32_t t)
 
  468     void set_enable_RS485_pin(uint8_t pin)
 
  470         set_RS485_txe_pin(pin);
 
  473     void set_RS485_rxe_pin(uint8_t pin)
 
  475         _enable_RS485_rxe_pin = pin;
 
  476         PJON_IO_MODE(_enable_RS485_rxe_pin, OUTPUT);
 
  479     void set_RS485_txe_pin(uint8_t pin)
 
  481         _enable_RS485_txe_pin = pin;
 
  482         PJON_IO_MODE(_enable_RS485_txe_pin, OUTPUT);
 
  485     void wait_RS485_pin_change()
 
  487         if(_enable_RS485_txe_pin != TS_NOT_ASSIGNED) {
 
  488             PJON_DELAY(_RS485_delay);
 
  493 #if defined(RPI) || defined(LINUX) 
  494     uint16_t _flush_offset = TS_FLUSH_OFFSET;
 
  498     uint8_t  _response[TS_RESPONSE_LENGTH];
 
  499     uint32_t _last_reception_time = 0;
 
  500     uint32_t _last_call_time = 0;
 
  501     uint8_t  _enable_RS485_rxe_pin = TS_NOT_ASSIGNED;
 
  502     uint8_t  _enable_RS485_txe_pin = TS_NOT_ASSIGNED;
 
  503     uint32_t _RS485_delay = TS_RS485_DELAY;
 
  504     uint32_t _read_interval = TS_READ_INTERVAL;