I2C boot loader with Blinky code Should test it with Freescale boards fingers crossed should work
Fork of I2Cboot_betav1_02 by
main.cpp
- Committer:
- Piasiv1206
- Date:
- 2015-05-23
- Revision:
- 1:c39e5581f901
- Parent:
- 0:f76c26307f9a
- Child:
- 5:0801179037cd
File content as of revision 1:c39e5581f901:
#include "mbed.h" #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; #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); } } int I2CReceiveData(uint8_t *pui8Data, uint8_t ui8Size) { if(i2c.read(addr, pui8Data, ui8Size == 0) { return (0); } return (-1); } //**************************************************************************** // //! 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); } 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"); }