diff --git a/FloBLE/FloJackExample/OadFile.h b/FloBLE/FloJackExample/OadFile.h index e1370f3..0530419 100644 --- a/FloBLE/FloJackExample/OadFile.h +++ b/FloBLE/FloJackExample/OadFile.h @@ -9,6 +9,7 @@ #import #import +#define OAD_IMG_METADATA_SIZE 18 #define HAL_FLASH_WORD_SIZE 4 #define OAD_IMG_ID_SIZE 4 // Image Identification size @@ -39,10 +40,23 @@ typedef struct { UInt8 res[4]; // Reserved space for future use. } oad_img_hdr_t; // definition of header block in OAD image +typedef struct { + UInt16 crc0; // CRC must not be 0x0000 or 0xFFFF. + UInt16 crc1; // CRC-shadow must be 0xFFFF. + // User-defined Image Version Number - default logic uses simple a '!=' comparison to start an OAD. + UInt16 ver; + UInt16 len; // Image length in 4-byte blocks (i.e. HAL_FLASH_WORD_SIZE blocks). + UInt8 uid[4]; // User-defined Image Identification bytes. + UInt8 startAddress[4]; // The start address in the on-chip flash memory the downloaded image is to be copied to. The actual start address will be 4 x Start Address, where Start Address is multiple of 4 for 16-byte alignment. + UInt8 imageType; // 1: Application or Application+Stack 2: Stack 3: Network Processor + UInt8 state; //0xFF: Image should be copied to on-chip flash 0x80: Image has already been copied. +} oad_img_metadata_t; // definition of header block in 2650 Externla Flash OAD image + typedef NS_ENUM(NSUInteger, imageType) { imageAtype = 0, imageBtype = 1, + imageEtype = 2, // 2650 OAD image type for external FLASH undefinedType }; @@ -53,20 +67,21 @@ typedef NS_ENUM(NSUInteger, imageType) @optional - (void)endOfUploadNotification; - (void)cancelationOfUploadNotification; -- (void)connectionLostNotification; @end @interface OadFile : NSObject { imageType currentImageType; NSString * currentFirmwareVersion; + NSString * imageVersion; imageType oadImageType; NSMutableString * oadFileName; + NSData * oadHexFile; NSData * oadData; NSInteger oadDataLength; oad_img_hdr_t oadImageHeader; - BOOL isUploadInProgress; +// oad_img_metadata_t oadImageMetaData; BOOL canceled; BOOL uploadComplete; BOOL hasValidFile; @@ -79,12 +94,15 @@ typedef NS_ENUM(NSUInteger, imageType) NSInteger blocksSent; } @property (strong, nonatomic) NSString * currentFirmwareVersion; +@property (strong, nonatomic) NSString * imageVersion; @property (strong, nonatomic) NSMutableString * oadFileName; +@property (strong, nonatomic) NSData * oadHexFile; @property (strong, nonatomic) NSData * oadData; @property (assign, nonatomic) NSInteger oadDataLength; @property (assign, nonatomic) imageType currentImageType; @property (assign, nonatomic) imageType oadImageType; @property (assign, nonatomic) oad_img_hdr_t oadImageHeader; +@property (assign, nonatomic) oad_img_metadata_t oadImageMetaData; @property (assign, nonatomic) BOOL isUploadInProgress; @property (assign, nonatomic) BOOL canceled; @property (assign, nonatomic) BOOL uploadComplete;; @@ -104,6 +122,7 @@ typedef NS_ENUM(NSUInteger, imageType) - (id)init; - (id)initWithDelegate:(id)oadFileDelegate; - (void)extractImageHeader; +- (void)extractImageHeader:(NSData *)hexFile; - (void)clearImageHeader; - (NSData*)getOadHeaderBlock; - (NSData*)getOadDataBlockAtIndex:(NSInteger)index; diff --git a/FloBLE/FloJackExample/OadFile.m b/FloBLE/FloJackExample/OadFile.m index da0d76b..c531f89 100644 --- a/FloBLE/FloJackExample/OadFile.m +++ b/FloBLE/FloJackExample/OadFile.m @@ -7,12 +7,17 @@ // #import "OadFile.h" +//#import +#import + @implementation OadFile @synthesize currentFirmwareVersion; +@synthesize imageVersion; @synthesize oadFileName; @synthesize oadData; +@synthesize oadHexFile; @synthesize oadDataLength; @synthesize currentImageType; @synthesize oadImageType; @@ -38,6 +43,7 @@ - (id)init { currentFirmwareVersion = @" - "; currentImageType = undefinedType; + imageVersion = @" - "; [self resetOadFileAttributes]; [self resetOadUploadAttributes]; // hasValidFile = NO; @@ -70,6 +76,138 @@ - (void)extractImageHeader blocksToSend = oadImageHeader.len / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE); } +//oad_img_metadata_t oadImageMetaData; + +//convert from hex file format to bin file format; +- (void)extractImageHeader:(NSData *)hexFile +{ +#define SHOULD_BE_COPIED 0xFF +#define ALREADY_COPIED 0x80 +#define APPLICATION 0x01 +#define APPLICATION_PLUS_STACK 0x02 +#define NETWORK_PROCESSOR 0x03 + +#define ON_CHIP_FLASH_START 0x0000 +#define ON_CHIP_APP_START 0x1000 +#define ON_CHIP_APP_END 0xBFFF + +#define DATA_START_OFFSET 9 +#define END_CRC_LEN 2 +#define END_NEWLINE_LEN 2 + + char str[16]; + + NSInteger fileLen = hexFile.length; // length of hex file data + NSRange range; + UInt16 address; + UInt8 num; + +// UInt8* uartByte = (UInt8*)hexFile.bytes; //theData.bytes; + +// range.location = 3; range.length = 4; str[4] = 0; +// [hexFile getBytes:str range:range]; +// address = (UInt16)strtol(str,NULL,16); + address = ON_CHIP_APP_START; // Start of FLASH + + + char * numbs = (char*)malloc(sizeof(char)*(ON_CHIP_APP_END-ON_CHIP_FLASH_START+1)); + + for(int i = 0; i <= (ON_CHIP_APP_END-ON_CHIP_FLASH_START); i++) + { + numbs[i] = 0xFF; + } + + NSInteger fileReadCount = 0; // num of chars read from hex file + NSInteger binDataLen = 0; // binary data length + NSInteger lineLen; + NSInteger lineStart = 0; + bool stop = NO; + str[2] = 0; + UInt16 lineAddress = 0; + int lineOffset = 0; + UInt16 lastAddress = 0; + + while ((fileReadCount < fileLen) && (!stop)) + { + // get first line + range.location = lineStart+3; range.length = 4; str[4] = 0; + [hexFile getBytes:str range:range]; + lineAddress = (UInt16)strtol(str,NULL,16); + + range.location = lineStart+1; range.length = 2; str[2] = 0; + [hexFile getBytes:str range:range]; + lineLen = (UInt16)strtol(str,NULL,16); + lineOffset = 0; + for (int j = 0; j < lineLen*2; j+=2) + { + range.location = lineStart + j + DATA_START_OFFSET; range.length = 2 ; + [hexFile getBytes:str range:range]; + num = (UInt16)strtol(str,NULL,16); + numbs[lineAddress+lineOffset] = (char)num; + lastAddress = lastAddress < lineAddress+lineOffset ? lineAddress+lineOffset :lastAddress; + lineOffset += 1; + binDataLen += 1; + } + fileReadCount += lineLen+lineLen + DATA_START_OFFSET + END_CRC_LEN+2; + lineStart += lineLen+lineLen + DATA_START_OFFSET + END_CRC_LEN+2; + } + + // Flush out to modulo 4 in length +// int rem = 15 - (lastAddress - address)%16; + int rem = ON_CHIP_APP_END - lastAddress; + for(int i = 0; i < rem; i++) + { + lastAddress += 1; + numbs[lastAddress] = 0xFF; + binDataLen += 1; + } + + // compute CRC + UInt16 imageCRC = 0; + + for(int i = ON_CHIP_APP_START+4; i <= lastAddress; i++) + { + imageCRC = crc16(imageCRC, (UInt8) numbs[i]); + } + // IAR note explains that poly must be run with value zero for each byte of + // the crc. + imageCRC = crc16(imageCRC, 0); + imageCRC = crc16(imageCRC, 0); + + + oadData = [NSData dataWithBytes:numbs length:lastAddress+1]; +// NSString * wrPath = @"/Users/ccarter/pc_shared/FlomioVisaNightlyBackup/hexFile.bin"; +// [oadData writeToFile:wrPath atomically:NO]; + free(numbs); + + oadImageHeader.crc0 = (UInt16) imageCRC; // crc[0] + oadImageHeader.crc1 = 0xFFFF; // shadow CRC + oadImageHeader.ver = 0x0000 ; // Ignore version number and always over write + oadImageHeader.len = (lastAddress+1-address)>> 2; //binDataLen>>2; + oadImageHeader.uid[0] = 0x45;oadImageHeader.uid[1] = 0x45;oadImageHeader.uid[2] = 0x45;oadImageHeader.uid[3] = 0x45; // = "E" + oadImageHeader.res[0] = (UInt8) ((ON_CHIP_APP_START>>2) & 0x00FF); //0x00; // Address + oadImageHeader.res[1] = (UInt8)((ON_CHIP_APP_START>>2) >> 8); //0x04; // Address = 0x1000 +// oadImageHeader.res[0] = (UInt8) ((address>>2) & 0x00FF); // Address +// oadImageHeader.res[1] = (UInt8)((address>>2) >> 8); // Address = 0x1000 + oadImageHeader.res[2] = APPLICATION; // Type + oadImageHeader.res[3] = SHOULD_BE_COPIED; // State + + imageVersion = 0x0000; + oadImageType = (imageType)(oadImageHeader.ver & 0x03); + oadDataLength = oadImageHeader.len * HAL_FLASH_WORD_SIZE; //[oadData length]; + bytesSent = 0; + blocksSent = 0; + bytesToSend = oadImageHeader.len * HAL_FLASH_WORD_SIZE; + blocksToSend = oadImageHeader.len / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE); + + address = (oadImageHeader.res[0] | oadImageHeader.res[1] << 8)*4; + + NSLog(@"address 0x%4.4x binDataLen 0x%4.4x crc 0x%4.4x\n ",address, (lastAddress-address + 1), imageCRC); + NSLog(@"bytesToSend %ld blocksToSend %ld \n ",(long)bytesToSend, (long)blocksToSend); + +} + + - (void)clearImageHeader { oadImageHeader.crc0 = 0; @@ -84,8 +222,30 @@ - (void)clearImageHeader - (NSData*)getOadHeaderBlock { + UInt8 headerData[OAD_IMG_METADATA_SIZE]; // 16Bytes + + headerData[0] = LO_UINT16(oadImageHeader.crc0); + headerData[1] = HI_UINT16(oadImageHeader.crc0); + + headerData[2] = LO_UINT16(oadImageHeader.crc1); + headerData[3] = HI_UINT16(oadImageHeader.crc1); + + headerData[4] = LO_UINT16(oadImageHeader.ver); + headerData[5] = HI_UINT16(oadImageHeader.ver); + + headerData[6] = LO_UINT16(oadImageHeader.len); + headerData[7] = HI_UINT16(oadImageHeader.len); + + memcpy(headerData + 8, &oadImageHeader.uid, sizeof(oadImageHeader.uid)); + + memcpy(headerData + 12, &oadImageHeader.res, sizeof(oadImageHeader.res)); + + NSData* headerBlock = [NSData dataWithBytes:headerData length:OAD_IMG_METADATA_SIZE]; + + +#if 0 // NSData* headerBlock = [NSData dataWithBytes:oadData.bytes length:sizeof(oad_img_hdr_t)]; - uint8_t headerData[OAD_IMG_HDR_SIZE + 2 + 2]; // 12Bytes + UInt8 headerData[OAD_IMG_HDR_SIZE + 2 + 2]; // 12Bytes headerData[0] = LO_UINT16(oadImageHeader.ver); headerData[1] = HI_UINT16(oadImageHeader.ver); @@ -107,15 +267,17 @@ - (NSData*)getOadHeaderBlock NSData* headerBlock = [NSData dataWithBytes:headerData length:OAD_IMG_HDR_SIZE + 2 + 2]; - +#endif return headerBlock; } - (NSData*)getOadDataBlockAtIndex:(NSInteger)theIndex { NSRange blockRange; + UInt16 appStartAddress = (oadImageHeader.res[0] | oadImageHeader.res[1] << 8)*4; + blockRange.length = OAD_BLOCK_SIZE; - blockRange.location = theIndex*(OAD_BLOCK_SIZE); + blockRange.location = theIndex*(OAD_BLOCK_SIZE)+appStartAddress; UInt8 oadDataStuff[2+OAD_BLOCK_SIZE]; oadDataStuff[0] = LO_UINT16(theIndex); @@ -131,6 +293,8 @@ - (NSData*)getOadDataBlockAtIndex:(NSInteger)theIndex - (bool)validateImageTypes { + return YES; // cc2650 has only one type of image +/* if ((currentImageType == undefinedType) || (oadImageType == undefinedType)) { return NO; @@ -139,20 +303,21 @@ - (bool)validateImageTypes { return (currentImageType != oadImageType); } + */ } - (bool)requestCurrentImageType { + /* unsigned char data = 0x01; NSData* block = [NSData dataWithBytes:&data length:1]; [delegate writeBlockToOadImageIdentify:(NSData*)block]; - + */ return YES; } - (bool)initiateUpload { - [self resetOadUploadAttributes]; canceled = NO; @@ -160,7 +325,7 @@ - (bool)initiateUpload { isUploadInProgress = YES; uploadComplete = NO; -// bytesToSend = oadDataLength; + bytesToSend = oadImageHeader.len * HAL_FLASH_WORD_SIZE; return YES; @@ -168,7 +333,7 @@ - (bool)initiateUpload else { // display error dialog - NSLog(@"Failed imageTypes %2.2x %2.2x",currentImageType, oadImageType); + NSLog(@"Failed imageTypes %2.2lx %2.2lx",currentImageType, oadImageType); return NO; } } @@ -184,11 +349,6 @@ - (bool)establishUpload - (bool)doUpload { - if(![self isConnected]) - { - [self cancelUpload]; - [delegate connectionLostNotification]; - } if (canceled) { isUploadInProgress = NO; @@ -256,12 +416,12 @@ - (void)receivedImageIdentifyCharacteristic:(NSData*)imageBlockCharacteristic { // unsigned char data[imageBlockCharacteristic.value.length]; // [characteristic.value getBytes:&data]; -// self.imgVersion = ((uint16_t)data[1] << 8 & 0xff00) | ((uint16_t)data[0] & 0xff); +// self.imgVersion = ((UInt16)data[1] << 8 & 0xff00) | ((UInt16)data[0] & 0xff); // NSLog(@"self.imgVersion : %04hx",self.imgVersion); UInt8* bytes = (UInt8*)imageBlockCharacteristic.bytes; - NSInteger version = ((uint16_t)bytes[1] << 8 & 0xff00) | ((uint16_t)bytes[0] & 0xff); + NSInteger version = ((UInt16)bytes[1] << 8 & 0xff00) | ((UInt16)bytes[0] & 0xff); [self setCurrentImageType:(imageType)(version & 1)]; @@ -315,7 +475,7 @@ - (void)resetOadFileAttributes oadImageHeader.uid[0] = 0;oadImageHeader.uid[1] = 0;oadImageHeader.uid[2] = 0;oadImageHeader.uid[0] = 0; oadImageHeader.res[0] = 0;oadImageHeader.res[1] = 0;oadImageHeader.res[2] = 0;oadImageHeader.res[3] = 0; oadFileName = [[NSMutableString alloc ]initWithCapacity:128];//@"-.bin"; - [oadFileName setString:@"https://dl.dropboxusercontent.com/u/74911655/OAD_A.bin"]; + [oadFileName setString:@"https://dl.dropboxusercontent.com/u/74911655/SimpleBLEPeripheral_411.hex"]; oadDataLength = 0; hasValidFile = NO; blocksToSend = 0; @@ -335,5 +495,40 @@ - (void)resetOadUploadAttributes blocksSent = 0; } +/********************************************************************* + * @fn crc16 + * + * @brief Run the CRC16 Polynomial calculation over the byte parameter. + * + * @param crc - Running CRC calculated so far. + * @param val - Value on which to run the CRC16. + * + * @return crc - Updated for the run. + */ +static UInt16 crc16(UInt16 crc, UInt8 val) +{ + const UInt16 poly = 0x1021; + UInt8 cnt; + + for (cnt = 0; cnt < 8; cnt++, val <<= 1) + { + UInt8 msb = (crc & 0x8000) ? 1 : 0; + + crc <<= 1; + + if (val & 0x80) + { + crc |= 0x0001; + } + + if (msb) + { + crc ^= poly; + } + } + + return crc; +} + @end diff --git a/FloBLE/FloJackExample/OadScreenViewController.m b/FloBLE/FloJackExample/OadScreenViewController.m index 16ec975..e43be51 100644 --- a/FloBLE/FloJackExample/OadScreenViewController.m +++ b/FloBLE/FloJackExample/OadScreenViewController.m @@ -176,10 +176,10 @@ - (IBAction)UploadFileSet:(id)sender NSString * fileName = [self FileName].text; NSLog(@"fileName %@",fileName); - NSRange theRange = [fileName rangeOfString:@".bin" options:NSBackwardsSearch]; + NSRange theRange = [fileName rangeOfString:@".hex" options:NSBackwardsSearch]; if (theRange.location == NSNotFound) { - [self showAlertWithTitle:@"Error in file..." andMessage:@"File must be of type -.bin"]; + [self showAlertWithTitle:@"Error in file..." andMessage:@"File must be of type -.hex"]; return; } else @@ -191,13 +191,13 @@ - (IBAction)UploadFileSet:(id)sender dispatch_async(dispatch_get_main_queue(), ^{ NSError * errorPtr; NSData * theData = [NSData dataWithContentsOfURL:[NSURL URLWithString: fileName] options:NSDataReadingUncached error:&errorPtr]; - [_appDelegate.oadFile setOadData:theData]; +// [_appDelegate.oadFile setOadData:theData]; // oadFile.oadData = [theData copy]; NSLog(@"Error %@",errorPtr); if(!errorPtr) { - [oadFile extractImageHeader]; + [oadFile extractImageHeader:theData]; // [UpdateButtonIBOutlet setEnabled:YES]; [_appDelegate.oadFile setHasValidFile:YES]; [self updateUpdateButton]; @@ -212,7 +212,7 @@ - (IBAction)UploadFileSet:(id)sender NSLog(@"Error opening file... %@",[errorPtr localizedFailureReason]); [self showAlertWithTitle:@"Error opening file..." andMessage:[errorPtr localizedFailureReason]]; } - if([oadFile isConnected]) [oadFile requestCurrentImageType]; +// if([oadFile isConnected]) [oadFile requestCurrentImageType]; [oadFile.oadFileName setString:fileName]; [oadFile setBytesSent:0]; [self updateFileName:[oadFile oadFileName]]; //[self updateFileName:fileName]; @@ -236,7 +236,7 @@ - (void) setOadFile:(OadFile *)theOadFile { oadFile = theOadFile; // NSLog(@"setOadFile"); - if([oadFile isConnected]) [oadFile requestCurrentImageType]; +// if([oadFile isConnected]) [oadFile requestCurrentImageType]; [oadFile resetOadUploadAttributes]; [self updateAllFields]; diff --git a/FloBLE/FloJackExample/TagReadWriteViewController.mm b/FloBLE/FloJackExample/TagReadWriteViewController.mm index ba6a227..79121e1 100644 --- a/FloBLE/FloJackExample/TagReadWriteViewController.mm +++ b/FloBLE/FloJackExample/TagReadWriteViewController.mm @@ -95,7 +95,7 @@ - (void)viewDidLoad _ledPicker.hidden = YES; // [_consoleTextView insertText:[NSString stringWithFormat:@"FloBLE OSX\n"]]; - [self updateLogTextViewWithString:@"FloBLE IOS [alpha 0.8]\n"]; + [self updateLogTextViewWithString:@"FloBLE IOS [alpha 0.9]\n"]; // NSString *textUpdate = [NSString stringWithFormat:@":::FloBLE Hardware Version %@", theVersionNumber]; // [self updateLogTextViewWithString:textUpdate];