I2C boot loader with Blinky code Should test it with Freescale boards fingers crossed should work
Fork of I2Cboot_betav1_02 by
Diff: main.cpp
- Revision:
- 1:c39e5581f901
- Parent:
- 0:f76c26307f9a
- Child:
- 5:0801179037cd
--- a/main.cpp Thu Feb 14 17:24:48 2013 +0000 +++ b/main.cpp Sat May 23 23:04:50 2015 +0000 @@ -1,25 +1,420 @@ #include "mbed.h" - -// Read temperature from LM75BD +#include <stdbool.h> +#include <stdint.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <memory.h> + + +// BootLoader + +Serial pc(USBTX, USBRX); // tx, rx I2C i2c(p28, p27); const int addr = 0x90; -int main() { - char cmd[2]; - while (1) { - cmd[0] = 0x01; - cmd[1] = 0x00; - i2c.write(addr, cmd, 2); +#define COMMAND_PING 0x20 +#define COMMAND_DOWNLOAD 0x21 +#define COMMAND_RUN 0x22 +#define COMMAND_GET_STATUS 0x23 +#define COMMAND_SEND_DATA 0x24 +#define COMMAND_RESET 0x25 +#define COMMAND_RET_SUCCESS 0x40 +#define COMMAND_RET_UNKNOWN_CMD 0x41 +#define COMMAND_RET_INVALID_CMD 0x42 +#define COMMAND_RET_INVALID_ADR 0x43 +#define COMMAND_RET_FLASH_FAIL 0x44 +#define COMMAND_RET_CRC_FAIL 0x45 +#define COMMAND_ACK 0xcc +#define COMMAND_NAK 0x33 + +//***************************************************************************** +// +//! This variable will be set to the starting address of the binary will be +//! programmed into to device. +// +//***************************************************************************** +static uint32_t g_ui32DownloadAddress; + +//***************************************************************************** +// +//! This variable will be set to the start execution address for the binary +//! that is downloaded. +// +//***************************************************************************** +static uint32_t g_ui32StartAddress; + +//***************************************************************************** + + +uint32_t g_ui32DataSize; +uint8_t g_pui8Buffer[256]; + + +// + +int +I2CSendData(uint8_t const *pui8Data, uint8_t ui8Size) +{ + + if(i2c.write(addr, pui8Data, ui8Size) == 1) + { + return (0); + } + + else + + { + return (-1); + } - wait(0.5); + +} + +int +I2CReceiveData(uint8_t *pui8Data, uint8_t ui8Size) +{ + if(i2c.read(addr, pui8Data, ui8Size == 0) + { + return (0); + } + + return (-1); + +} - cmd[0] = 0x00; - i2c.write(addr, cmd, 1); - i2c.read(addr, cmd, 2); + +//**************************************************************************** +// +//! AckPacket() sends an Acknowledge a packet. +//! +//! This function acknowledges a packet has been received from the device. +//! +//! \return The function returns zero to indicated success while any non-zero +//! value indicates a failure. +// +//**************************************************************************** +int32_t +AckPacket(void) +{ + uint8_t ui8Ack; + + ui8Ack = COMMAND_ACK; + return(I2CSendData(&ui8Ack, 1)); +} + +//**************************************************************************** +// +//! NakPacket() sends a No Acknowledge packet. +//! +//! This function sends a no acknowledge for a packet that has been +//! received unsuccessfully from the device. +//! +//! \return The function returns zero to indicated success while any non-zero +//! value indicates a failure. +// +//**************************************************************************** +int32_t +NakPacket(void) +{ + uint8_t ui8Nak; + + ui8Nak = COMMAND_NAK; + return(I2CSendData(&ui8Nak, 1)); +} + +//***************************************************************************** +// +//! GetPacket() receives a data packet. +//! +//! \param pui8Data is the location to store the data received from the device. +//! \param pui8Size is the number of bytes returned in the pui8Data buffer that +//! was provided. +//! +//! This function receives a packet of data from UART port. +//! +//! \returns The function returns zero to indicated success while any non-zero +//! value indicates a failure. +// +//***************************************************************************** +int32_t +GetPacket(uint8_t *pui8Data, uint8_t *pui8Size) +{ + uint8_t ui8CheckSum; + uint8_t ui8Size; + + // + // Get the size and the checksum. + // + do + { + if(I2CReceiveData(&ui8Size, 1)) + { + return(-1); + } + } + while(ui8Size == 0); + + if(I2CReceiveData(&ui8CheckSum, 1)) + { + return(-1); + } + *pui8Size = ui8Size - 2; + + if(I2CReceiveData(pui8Data, *pui8Size)) + { + *pui8Size = 0; + return(-1); + } + + // + // Calculate the checksum from the data. + // + if(CheckSum(pui8Data, *pui8Size) != ui8CheckSum) + { + *pui8Size = 0; + return(NakPacket()); + } + + return(AckPacket()); +} + +//***************************************************************************** +// +//! CheckSum() Calculates an 8 bit checksum +//! +//! \param pui8Data is a pointer to an array of 8 bit data of size ui8Size. +//! \param ui8Size is the size of the array that will run through the checksum +//! algorithm. +//! +//! This function simply calculates an 8 bit checksum on the data passed in. +//! +//! \return The function returns the calculated checksum. +// +//***************************************************************************** +uint8_t +CheckSum(uint8_t *pui8Data, uint8_t ui8Size) +{ + int32_t i; + uint8_t ui8CheckSum; + + ui8CheckSum = 0; + + for(i = 0; i < ui8Size; ++i) + { + ui8CheckSum += pui8Data[i]; + } + return(ui8CheckSum); +} + +//***************************************************************************** +// +//! SendPacket() sends a data packet. +//! +//! \param pui8Data is the location of the data to be sent to the device. +//! \param ui8Size is the number of bytes to send from puData. +//! \param bAck is a boolean that is true if an ACK/NAK packet should be +//! received in response to this packet. +//! +//! This function sends a packet of data to the device. +//! +//! \returns The function returns zero to indicated success while any non-zero +//! value indicates a failure. +// +//***************************************************************************** +int32_t +SendPacket(uint8_t *pui8Data, uint8_t ui8Size, bool bAck) +{ + uint8_t ui8CheckSum; + uint8_t ui8Ack; + + ui8CheckSum = CheckSum(pui8Data, ui8Size); + + // + // Make sure that we add the bytes for the size and checksum to the total. + // + ui8Size += 2; + + // + // Send the Size in bytes. + // + if(I2CSendData(&ui8Size, 1)) + { + return(-1); + } + + // + // Send the CheckSum + // + if(I2CSendData(&ui8CheckSum, 1)) + { + return(-1); + } + + // + // Now send the remaining bytes out. + // + ui8Size -= 2; + + // + // Send the Data + // + if(I2CSendData(pui8Data, ui8Size)) + { + return(-1); + } + + // + // Return immediately if no ACK/NAK is expected. + // + if(!bAck) + { + return(0); + } + + // + // Wait for the acknowledge from the device. + // + do + { + if(I2CReceiveData(&ui8Ack, 1)) + { + return(-1); + } + } + while(ui8Ack == 0); + + if(ui8Ack != COMMAND_ACK) + { + return(-1); + } + return(0); +} + + +int32_t +SendCommand(uint8_t *pui8Command, uint8_t ui8Size) +{ + uint8_t ui8Status; + + // + // Send the command itself. + // + if(SendPacket(pui8Command, ui8Size, 1) < 0) + { + return(-1); + } + + // + // Send the get status command to tell the device to return status to + // the host. + // + ui8Status = COMMAND_GET_STATUS; + if(SendPacket(&ui8Status, 1, 1) < 0) + { + pc.printf("Failed to Get Status\n"); + return(-1); + } + + // + // Read back the status provided from the device. + // + ui8Size = sizeof(ui8Status); + if(GetPacket(&ui8Status, &ui8Size) < 0) + { + pc.printf("Failed to Get Packet\n"); + return(-1); + } + if(ui8Status != COMMAND_RET_SUCCESS) + { + pc.printf("Failed to get download command Return Code: %04x\n", + ui8Status); + return(-1); + } + return(0); +} + - float tmp = (float((cmd[0]<<8)|cmd[1]) / 256.0); - printf("Temp = %.2f\n", tmp); + +int main() { + + g_ui32DownloadAddress = 0; + g_ui32StartAddress = 0xffffffff; + g_ui32DataSize = 8; + uint8_t ui8Command; + + + uint32_t ui32TransferLength; + uint8_t *pui8FileBuffer; + uint32_t ui32Offset; + + g_pui8Buffer[0] = COMMAND_DOWNLOAD; + g_pui8Buffer[1] = (uint8_t)(g_ui32DownloadAddress >> 24); + g_pui8Buffer[2] = (uint8_t)(g_ui32DownloadAddress >> 16); + g_pui8Buffer[3] = (uint8_t)(g_ui32DownloadAddress >> 8); + g_pui8Buffer[4] = (uint8_t)g_ui32DownloadAddress; + g_pui8Buffer[5] = (uint8_t)(ui32TransferLength>>24); + g_pui8Buffer[6] = (uint8_t)(ui32TransferLength>>16); + g_pui8Buffer[7] = (uint8_t)(ui32TransferLength>>8); + g_pui8Buffer[8] = (uint8_t)ui32TransferLength; + + ui8Command = COMMAND_PING; + if(SendCommand(&ui8Command, 1) < 0) + { + pc.printf("Ping fail"); + return(-1); + } + + if(SendCommand(g_pui8Buffer, 9) < 0) + { + printf("Failed to Send Download Command\n"); + return(-1); } + + +ui32Offset = 0; + + printf("Remaining Bytes: "); + do + { + uint8_t ui8BytesSent; + + g_pui8Buffer[0] = COMMAND_SEND_DATA; + + printf("%08ld", ui32TransferLength); + + // + // Send out 8 bytes at a time to throttle download rate and avoid + // overruning the device since it is programming flash on the fly. + // + if(ui32TransferLength >= g_ui32DataSize) + { + memcpy(&g_pui8Buffer[1], &pui8FileBuffer[ui32Offset], g_ui32DataSize); + + ui32Offset += g_ui32DataSize; + ui32TransferLength -= g_ui32DataSize; + ui8BytesSent = g_ui32DataSize + 1; + } + else + { + memcpy(&g_pui8Buffer[1], &pui8FileBuffer[ui32Offset], ui32TransferLength); + ui32Offset += ui32TransferLength; + ui8BytesSent = ui32TransferLength + 1; + ui32TransferLength = 0; + } + // + // Send the Send Data command to the device. + // + if(SendCommand(g_pui8Buffer, ui8BytesSent) < 0) + { + printf("Failed to Send Packet data\n"); + break; + } + + printf("\b\b\b\b\b\b\b\b"); + } while (ui32TransferLength); + printf("00000000\n"); + } \ No newline at end of file