DA14580 Bluetooth Smart IC writer library

Dependents:   11u35_usbLocalFilesystem

DA14580.cpp

Committer:
k4zuki
Date:
2016-08-12
Revision:
9:e2e84de053fc
Parent:
8:af5210dbfe64

File content as of revision 9:e2e84de053fc:

/*
@file DA14580.cpp
*/
#include "DA14580.h"
#include "loader.h"

DA14580::DA14580( PinName TX, PinName RX, PinName RESET ) : _ble(TX,RX), _reset(RESET)
{
    _ble.baud(57600);
    init();
}

DA14580::DA14580( RawSerial &ble, PinName RESET ) : _ble(ble), _reset(RESET)
{
    _ble.baud(57600);
    init();
}

DA14580::~DA14580()
{
}

void DA14580::init()
{

    _reset.write(_RESET);
//    _loadersize = sizeof(loader)/sizeof(loader[0]);
    _loadersize = 0;
    _crc = 0x00;
    _recieve = 0;
    _read = 0;
    _filesize = 0;
    _reset.write(_RESET);
    _timeout = _TIMEOUT;
    _status = SUCCESS;
}

int DA14580::load(char *filename)
{

    _reset.write(_RESET);
    _status = SUCCESS;

    _fp = fopen(filename, "rb" );
    if (_fp) {
        _loadersize = file_size(_fp);
    } else if( (!_fp) && (filename == LOADER_FILE) ){
        _fp = (FILE*) loader;
    } else {
        _status = E_FILE_NOT_FOUND;
    }

    if(_status == SUCCESS) {
        _reset.write(_BOOT);
        wait_us(1);
        while(1) {
            while( _ble.readable() ) {
                _recieve = _ble.getc();
            }
            if(_recieve == STX) {
                _ble.putc(SOH);
                _ble.putc(_loadersize & 0xff);
                _ble.putc( (_loadersize >> 8) & 0xff);
                break;
            }
        }

        while(1) {
            _recieve = _ble.getc();
            if(_recieve == ACK) {
                break;
            } else {
                _status = E_ACK_NOT_RETURNED;
                break;
            }
        }

        if(_status == SUCCESS) {
            for(int i = 0; i < _loadersize; i++) {
                _read = getc(_fp);
                _ble.putc(_read);
                _crc = _crc ^ _read;
            }
            while(1) {
                _recieve = _ble.getc();
                if(_recieve == _crc) {
                    _ble.putc(ACK);
                    break;
                } else {
                    _status = E_CRC_MISMATCH;
                    break;
                }
            }
        }
    }

    fclose(_fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
#warning "free(_fp)"
    free(_fp);
#endif

    return _status;

}

/*
header[0] | 0x70 | 'p'
header[1] | 0x50 | 'P'
header[2] | 0x00 | dummy[3]
header[3] | 0x00 | dummy[2]
header[4] | 0x00 | dummy[1]
header[5] | 0x00 | dummy[0]
header[6] | 0x00 | binary size MSB <- to be replaced to actual size
header[7] | 0x00 | binary size LSB <- to be replaced to actual size
*/
void DA14580::copy_to_flash(W25X40BV* flash)
{
    uint8_t Headerbuffer[8] = {0x70,0x50,0x00,0x00,0x00,0x00,0x00,0x00};
    char data[256];
    int i=1;
    _fp = fopen(TARGET_FILE, "rb" );
    if (_fp) {
        _reset.write(_RESET);
        //erase 64KByte
        flash->block32Erase(0);
        flash->block32Erase(1);

        _filesize = file_size(_fp);
        Headerbuffer[6]= (uint8_t)( (_filesize >> 8) & 0xff);
        Headerbuffer[7]= (uint8_t)(_filesize & 0xff);

        flash->writeStream(0, Headerbuffer, 8);
        if(_filesize >= 248) {
            fgets(data, 248,_fp);
            flash->writeStream(8, (uint8_t*)data, (248));
        }
        _filesize -= (256-8);

        while(_filesize >= 256) {
            fgets(data, (256), _fp);
            flash->writeStream(256*i, (uint8_t*)data, (256));
            i++;
            _filesize -= (256);
        }

        if(_filesize > 0) {
            fgets(data, _filesize, _fp);
            flash->writeStream(256*i, (uint8_t*)data, (_filesize));
        }
    }
    fclose(_fp);
#if defined(__MICROLIB) && defined(__ARMCC_VERSION) // with microlib and ARM compiler
#warning "free(_fp)"
    free(_fp);
#endif
}

int DA14580::file_size( FILE *fp )
{
    int     size;

    fseek( fp, 0, SEEK_END ); // seek to end of file
    size    = ftell( fp );    // get current file pointer
    fseek( fp, 0, SEEK_SET ); // seek back to beginning of file

    return size;
}