Esempio n. 1
0
//! @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;
}
Esempio n. 2
0
// 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();
}