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"); }
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; }
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; }
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); }
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 } }
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); } } }
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); }