//! @brief Read from peripheral until start byte found. static status_t read_start_byte(framing_header_t * header) { #if defined(BOOTLOADER_HOST) uint32_t startByteReadCount = 0; #endif // Read until start byte found. do { status_t status = read_data(&header->startByte, 1, 0); // no timeout for first byte of packet if (status != kStatus_Success) { return status; } #if defined(BOOTLOADER_HOST) if (startByteReadCount++ > kHostMaxStartByteReadCount) { return kStatus_Timeout; } if (header->startByte != kFramingPacketStartByte) { // This will keep us from doing non necessary delays in case the byte received // is actually the start byte, this delay and retry scenario is for cases when waiting // for a response from a device that was issued a long running command like a flash-erase-region // that may take several seconds to complete. host_delay(kDefaultByteReadTimeoutMs); } #endif } while (header->startByte != kFramingPacketStartByte); return kStatus_Success; }
// See serial_packet.h for documentation on this function. status_t serial_packet_write(const peripheral_descriptor_t *self, const uint8_t *packet, uint32_t byteCount, packet_type_t packetType) { if (!packet || (byteCount > kOutgoingPacketBufferSize)) { debug_printf("Error: invalid packet or packet size %d\r\n", byteCount); return kStatus_InvalidArgument; } // Send ACK if needed. status_t status = send_deferred_ack(); if (status != kStatus_Success) { return status; } // Back-to-back writes require delay for receiver to enter peripheral read routine. if (g_serialContext.isBackToBackWrite) { g_serialContext.isBackToBackWrite = false; #if defined(BOOTLOADER_HOST) host_delay(100); #endif } // Initialize the framing data packet. serial_framing_packet_t *framingPacket = &g_serialContext.framingPacket; framingPacket->dataPacket.header.startByte = kFramingPacketStartByte; framingPacket->dataPacket.header.packetType = kFramingPacketType_Command; if (packetType != kPacketType_Command) { framingPacket->dataPacket.header.packetType = kFramingPacketType_Data; } framingPacket->dataPacket.length = (uint16_t)byteCount; // Copy the caller's data buffer into the framing packet. if (byteCount) { memcpy(framingPacket->data, packet, byteCount); } // Calculate and set the framing packet crc. framingPacket->dataPacket.crc16 = calculate_framing_crc16(&framingPacket->dataPacket, (uint8_t *)framingPacket->data); #if defined(TEST_NAK) ++framingPacket->dataPacket.crc16; #endif // TEST_NAK // Send the framing data packet. status = write_data((uint8_t *)framingPacket, sizeof(framing_data_packet_t) + byteCount); if (status != kStatus_Success) { return status; } return wait_for_ack_packet(); }