Esempio n. 1
0
uint8_t serial_receive(uint8_t* returnBuf, uint8_t size, uint8_t* stream, uint8_t streamSize){

  uint8_t buf[size];
  uint8_t index = 0;
  uint8_t rxByte = 1;

  if((streamSize - counter) >= 2){ //need at least 2 bytes to start receiving
    buf[0] = stream_read(stream);
    if(buf[0] == 0){ //caught the end of a previous frame
      printf("   Buf[0] was 0\n");
      return 0;
    }
   printf("   Buf[0] = %d\n", buf[0]);
        
    do{ //read until next 0 or we reach max length
      buf[++index] = stream_read(stream);
      printf("   Read %d\n", buf[index]);
    }while((buf[index] != 0) && (index < size-1));
    
    if(buf[index] != 0){ //ran out of space for a frame
      do{
        rxByte = stream_read(stream);
      }while(rxByte != 0); //get rest of frame out of buffer
      printf("   Ran out of space\n");
      return 0;
    }else{//got a full frame
      printf("   Got full frame. Index = %d\n", index);
      index = cobs_decode(buf, index, returnBuf);
      printf("   Bytes unstuffed = %d\n", index);
      return index; //represents number of bytes decoded
    }
  }
   printf("Nothing to read\n");
}
Esempio n. 2
0
int cobs_decode_empty(void) {
  uint8_t cobs_out[1];
  cobs_out[0] = 0xAA;

  size_t out_len = cobs_decode(cobs_out, NULL, 0);

  if (cobs_out[0] != 0xAA) return 1;
  if (out_len != 0) return 1;
  return 0;
}
Esempio n. 3
0
int cobs_decode_emptyout(void) {
  uint8_t cobs_in[] = {0x01};
  size_t in_len = sizeof(cobs_in);
  uint8_t cobs_out[in_len];
  cobs_out[in_len - 1] = 0xAA;

  size_t out_len = cobs_decode(cobs_out, cobs_in, in_len);

  if (cobs_out[in_len - 1] != 0xAA) return 1;
  if (out_len != in_len - 1) return 1;
  return 0;
}
Esempio n. 4
0
int cobs_decode_multizero(void) {
  uint8_t cobs_in[] = {0x02, 0x11, 0x01, 0x02, 0x33};
  size_t in_len = sizeof(cobs_in);
  uint8_t cobs_out[in_len];
  cobs_out[in_len - 1] = 0xAA;
  uint8_t cobs_out_correct[] = {0x11, 0x00, 0x00, 0x33};

  size_t out_len = cobs_decode(cobs_out, cobs_in, in_len);

  if (cobs_out[in_len - 1] != 0xAA) return 1;
  if (out_len != in_len - 1) return 1;
  return memcmp(cobs_out, cobs_out_correct, out_len);
}
Esempio n. 5
0
void ssMainUpdate() {
    if (activeSendFlag) {
        uint8_t pacLen = 0;
        uint8_t inband = 0;
        ssActiveSend(decodedBuffer, &pacLen, &inband);
        // Send reply active packet
        if (pacLen > 0 && pacLen <= ACTIVE_PACKET_MAX_LEN) {
            encodedBuffer[0] = 0x00;
            encodedBuffer[1] = packetType;
            encodedBuffer[2] = ((!!inband) << 7) | (pacLen+4);
            cobs_encode(encodedBuffer+3, decodedBuffer, pacLen);
            serialPrint(encodedBuffer, pacLen+4);
        }
        activeSendFlag = 0;
    }
    if (rxBufferFlag == RX_FLAG_DATA_AVAILABLE) {  // if done receiving
        rxBufferFlag = RX_FLAG_DATA_IN_USE;
        if (dataLen >= 1) {
            cobs_decode(decodedBuffer, rxBuffer, dataLen);
        }
        if (packetType < 0x80) {
            // Read game mode from 0th channel
            if (decodedBuffer[0] <= MAX_MODE) gameMode = decodedBuffer[0];
            // Read other channels
            ssActiveInRec(decodedBuffer+1, dataLen-2, in_band_sigFlag);
        } else if (packetType <= 0xFD && packetType >= 0xF0) {
            enumerationPacket(packetType, decodedBuffer, dataLen-1);
        } else {
            uint8_t pacLen = 0;
            maintenancePacket(packetType, decodedBuffer, dataLen-1,
                              decodedBuffer, &pacLen);
            // Send reply maintenance packet
            if (pacLen > 0 && pacLen <= 0xFF-4) {
                encodedBuffer[0] = 0x00;
                encodedBuffer[1] = packetType;  // Respond with same type as sent.
                encodedBuffer[2] = pacLen+4;
                cobs_encode(encodedBuffer+3, decodedBuffer, pacLen);
                serialPrint(encodedBuffer, pacLen+4);
            }
        }
        rxBufferFlag = RX_FLAG_READY;  // should be below if statement
    }
}
Esempio n. 6
0
portTASK_FUNCTION_PROTO(smartSensorTX, pvParameters) {
  (void) pvParameters;

  // TODO(cduck): Get bus num from pvParameters.
  uint8_t busNum = 0;
  uart_serial_module *bus = ssBusses[busNum];
  while (1) {
    vTaskDelay(200 / portTICK_RATE_MS);  // Wait for smart sensors to boot.

    while (busState == SS_BUS_ENUMERATION) {
      led_driver_set_mode(PATTERN_ENUMERATING);

      KnownIDs enumIDs = {
        .arr = pvPortMalloc(SS_MAX_SENSORS_PER_BUS * sizeof(SSState*)),
        .len = 0,
        .maxLen = SS_MAX_SENSORS_PER_BUS,
      };

      if (enumerateSensors(&enumIDs, bus, busNum)) {
      } else {
        enumIDs.len = 0;  // Ignore sensors from failed attempt.
      }

      size_t index = ss_add_sensors(&enumIDs);

      // Bandwidth allocation and assignment
      // TODO(cduck): Better bandwidth allocation (only allocates first 6)
      for (int i = 0; i < SS_NUM_FRAMES && i < enumIDs.len; ++i) {
        SSState *sensor = enumIDs.arr[i];

        uint8_t a = 0x1D;
        ss_uart_serial_send_and_finish_data(smartsensor_1, &a, 1);  // Debug

        ss_uart_serial_send_and_finish_data(smartsensor_4, &a, 1);
        ss_uart_serial_send_and_finish_data(smartsensor_1, sensor->id,
          SMART_ID_LEN);  // Debug

        // Assign bandwidth to sensor
        uint8_t data[SMART_ID_LEN+2];
        data[SMART_ID_LEN] = 0xFF;
        data[SMART_ID_LEN+1] = (uint8_t)(i+SS_FIRST_FRAME);
        memcpy(data, sensor->id, SMART_ID_LEN);
        ss_send_maintenance(bus, 0xD0, data, SMART_ID_LEN+2);
        ss_select_delay();

        // Store bandwidth assignment
        for (int s = 0; s < SS_NUM_SAMPLES; ++s) {
          sensorMapping[s][i] = index+i;
        }

        ss_select_delay();  // Debug
      }

      led_driver_set_mode(PATTERN_JUST_RED);
      led_driver_set_fixed(enumIDs.len, 0b111);

      vPortFree(enumIDs.arr);

      busState = SS_BUS_ACTIVE;  // //////////
    }

    vTaskDelay(1000 / portTICK_RATE_MS);  // ///////

    while (busState == SS_BUS_MAINTAINANCE) {
      uint8_t d1_len = 7;
      uint8_t d1[] = {0x11, 0x22, 0x33, 0x44, 0x88, 0xCC, 0xFF};
      uint8_t d2_len = 100;
      uint8_t d2[251];
      for (int i = 0; i < 251; ++i) {
        d2[i] = i;
      }
      for (int i = 0; i < numSensors; ++i) {
        ss_send_ping_pong(sensorArr[i], d1, d1_len);
        vTaskDelay(2 / portTICK_RATE_MS);
      }

      busState = SS_BUS_ACTIVE;
    }

    while (busState == SS_BUS_ACTIVE) {
      // At the beginning of each subchunk, the master sends the following
      // header:
      // |----------------------------------------
      // | 0x00 | has payload  sample#  subchunk#
      // |----------------------------------------
      //   ---------------------------------------------|
      //   | <in-band signalling>  <length> | <payload> |
      //   ---------------------------------------------|

      // size_t len = 16*6+4;
      // Bit format:
      // {0, 0b0xyyzzzz, 0bslllllll, p, p, p, p, p, p, p, p, p, p, p, p, p}
      // x=has payload, y=sample # (mod 4 (was 8)) (0-indexed),
      // z=subchunk # (1-indexed)
      // s=in-band signalling, l=length of payload, p=payload (only when s=1)
      uint8_t data_len = 100;
      uint8_t data[] =
         {0, 0b00000001, 0b00000101, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0b00000010, 0b00000011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0b00000011, 0b00000011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0b00000100, 0b00000011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0b00000101, 0b00000011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0b00000110, 0b00000011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
          0, 0, 0, 0  // Timing bytes
         };

      unsigned int sampleNumber = 0;
      uint8_t frameNumber = SS_FIRST_FRAME;
      unsigned int sampleNumberLast = sampleNumber;
      uint8_t frameNumberLast = frameNumber;

      // Recieve
      size_t recLen = 0;

      transmit_allocations allocs = {.txn = NULL, .data = NULL};
      transmit_allocations allocsOld = {.txn = NULL, .data = NULL};

      // Clear missed packets
      // while (uart_serial_receive_packet(bus, &recLen, 0)) {}

      // TODO(cduck): Better timing
      while (1) {
        // Send entire sample (about 1ms for 100 bytes)

        // Clear missed packets
        // while (uart_serial_receive_packet(bus, &recLen, 0)) {}

        uint8_t isOutgoing = 0;
        int16_t sensorIndex =
          sensorMapping[sampleNumber%SS_NUM_SAMPLES]
                       [frameNumber-SS_FIRST_FRAME];
        SSState *sensor;
        if (sensorIndex >= 0 && numSensors > sensorIndex) {
          uint8_t button = button_driver_get_button_state(sensorIndex%2);
          sensor = sensorArr[sensorIndex];
          if (xSemaphoreTake(sensor->outLock, SENSOR_WAIT_TIME) == pdTRUE) {
            if (checkOutgoingBytes(sensor, 1)) {
              sensor->outgoingBytes[0] ^= ((0xFF*(!!button)) << 1);
              isOutgoing = 1;
              allocs = ss_send_active(bus, 0, sampleNumber, frameNumber,
                sensor->outgoingBytes, sensor->outgoingLen);
            } else {
              allocs = ss_send_active(bus, 0, sampleNumber, frameNumber,
                NULL, 0);
            }

            // Wait until the previous packet sent
            ss_wait_until_done(bus, allocs);
            // Clean up the after sending the previous packet
            ss_send_finish(bus, allocs);

            xSemaphoreGive(sensor->outLock);
          }
        }

        // //////////////////////Send
        // Queue the current packet for sending
        // Send active frame (non-blocking)
        /* if (isOutgoing) {

          xSemaphoreGive(sensor->outLock);
        } else {
          allocs = ss_send_active(bus, 0, sampleNumber, frameNumber,
            NULL, 0);
        }
        if (allocs.txn) {
          // Wait until the previous packet sent
          ss_wait_until_done(bus, allocs);
          // Clean up the after sending the previous packet
          ss_send_finish(bus, allocs);
        }
        allocsOld = allocs;*/

        vTaskDelay(1 / portTICK_RATE_MS);
/*
        // Recieve the response to the packet
        {
          // 1 means wait for packet
          uint8_t *data = uart_serial_receive_packet(bus, &recLen, 0);

          if (data) {
            if (recLen > 2) {
              uint8_t prefixLen = 3;
              uint8_t decodeLen = recLen-prefixLen-1;
              uint8_t *data_decode = pvPortMalloc(decodeLen);
              uint8_t freeData = 1;
              cobs_decode(data_decode, data+prefixLen, decodeLen+1);

              int16_t sensorIndex =
                sensorMapping[sampleNumber%SS_NUM_SAMPLES]
                             [frameNumber-SS_FIRST_FRAME];
              if (sensorIndex >= 0 && numSensors > sensorIndex) {
                SSState *sensor = sensorArr[sensorIndex];
                ss_recieved_data_for_sensor(sensor, data_decode, decodeLen, 0);
              }

              // Only free if not assigned to a sensor.
              if (data_decode && freeData) vPortFree(data_decode);
            }
            vPortFree(data);
          }
        }
*/

        // Update sample and frame numbers
        frameNumberLast = frameNumber;
        sampleNumberLast = sampleNumber;

        ++frameNumber;
        if (frameNumber >= SS_NUM_FRAMES+SS_FIRST_FRAME) {
          frameNumber = SS_FIRST_FRAME;
          ++sampleNumber;
        }
      }
    }
  }
}

portTASK_FUNCTION_PROTO(smartSensorRX, pvParameters) {
  (void) pvParameters;

  // TODO(cduck): Get bus num from pvParameters.
  uint8_t busNum = 0;
  uart_serial_module *bus = ssBusses[busNum];

  // Recieve
  size_t recLen = 0;

  while (1) {
    while (busState != SS_BUS_ACTIVE) {}

    while (busState == SS_BUS_ACTIVE) {
      // Recieve the response to the packet
      // 1 means wait for packet
      uint8_t *data = uart_serial_receive_packet(bus, &recLen, 0);

      if (busState != SS_BUS_ACTIVE) break;

      if (data) {
        uint8_t prefixLen = 3;
        if (recLen > prefixLen) {
          uint8_t sampleNumber = (data[1] >> 3) & 0b111;
          // Zero indexed
          uint8_t frameNumber = (data[1] & 0b111) - SS_FIRST_FRAME;
          uint8_t inband = data[1] >> 7;
          uint8_t decodeLen = recLen-prefixLen-1;
          uint8_t *data_decode = pvPortMalloc(decodeLen);
          cobs_decode(data_decode, data+prefixLen, decodeLen+1);

          // led_driver_set_mode(PATTERN_JUST_RED);
          // led_driver_set_fixed(sampleNumber, 0b111);

          if (frameNumber < SS_NUM_FRAMES && sampleNumber < SS_NUM_SAMPLES) {
            int16_t sensorIndex =
              sensorMapping[sampleNumber%SS_NUM_SAMPLES]
                           [frameNumber];
            if (sensorIndex >= 0 && numSensors > sensorIndex) {
              SSState *sensor = sensorArr[sensorIndex];
              ss_recieved_data_for_sensor(sensor, data_decode, decodeLen,
                inband);
            }
          }

          if (data_decode) vPortFree(data_decode);
        }
        vPortFree(data);
      }
    }
  }
Esempio n. 7
0
int cobs_decode_reallylong(void) {
  uint8_t cobs_in[] = {
    0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE,
    0x02, 0xFF,
  };
  size_t in_len = sizeof(cobs_in);
  uint8_t cobs_out[in_len - 1];
  cobs_out[in_len - 2] = 0xAA;
  uint8_t cobs_out_correct[] = {
          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
    0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
  };

  size_t out_len = cobs_decode(cobs_out, cobs_in, in_len);

  if (cobs_out[in_len - 2] != 0xAA) return 1;
  if (out_len != in_len - 2) return 1;
  return memcmp(cobs_out, cobs_out_correct, out_len);
}