Saturday, October 26, 2013

osal_snv_read and osal_snv_write on BLE112 (CC2540 - 128kb version)

osal_svn_read and osal_snv_write provides a way for applications to store information into device's memory persistently.

Please refer to OSAL API pdf. There is a range of ID's which can be used for your applications to store data in. Others are reserved or used by the stack or ble platform.
Usable ID's are in range:

0x80 - 0xFE

When you run this code on BLE112 (or other cc2540 128kb version):

uint8 array[]={0,1,2,3,4,5,6,7,8,9};
uint8 read_array[10];
uint8_t result = osal_snv_write(0x80,6,array);

You will receive NV_OPER_FAILED in result. Same result when trying to read using osal_snv_read.

After some digging around net I found explanation. Code provided in sample applications (ie. SimpleBLEPeripheral) and HAL subsystem was designed to run on 256kb chip.
One file need to be fixed to use osal_snv read/write functions properly.

Search for hal_board_cfg.h file, look for code shown below:


// NV page definitions must coincide with segment declaration in project *.xcl file.
#if defined NON_BANKED
#define HAL_NV_PAGE_END                30
#elif defined HAL_BOARD_CC2541S
#define HAL_NV_PAGE_END                125
#else
#define HAL_NV_PAGE_END                126
#endif

change it to :


// NV page definitions must coincide with segment declaration in project *.xcl file.
#if defined NON_BANKED
#define HAL_NV_PAGE_END                30
#elif defined HAL_BOARD_CC2541S
#define HAL_NV_PAGE_END                125
#elif defined HAL_BOARD_128K
#define HAL_NV_PAGE_END                62
#else
#define HAL_NV_PAGE_END                126
#endif



and add HAL_BOARD_128K to your preprocessor settings:


Friday, October 4, 2013

connecting CC2540 (BLE112) to MCP23009 using I2C

CC2540 does not have hardware i2c interface. Implementing i2c protocol in software is quite easy task. A lot of samples could be found around the net.

Ive used i2c implementation found on: https://github.com/RedBearLab/Biscuit

Remember to change #defines to reflect your wiring. Also check .c file for hardcoded ports. You need to change this before running code.

My wiring of MCP23009 to BLE112:


wiring MCP23009 i2c extender to CC2540 (BLE112)
Next use the code below to turn on LED diode.

First you need to establish connection to MCP23009 (i2c address: 0x40) and set few registers:

    i2c_init();
    i2c_start(0x40);
      
    // io mode
    i2c_write(0x00);  // IODIR
    i2c_write(0x00);  // 00 - all pins as output
    i2c_stop();
    // polarity
    i2c_restart(0x40);
    i2c_write(0x01);
    i2c_write(0x00);
    i2c_stop();    
    // config
    i2c_restart(0x40);    
    i2c_write(0x05);
    i2c_write(0x00);
    i2c_stop();    
    // pullup
    i2c_restart(0x40);    
    i2c_write(0x06);
    i2c_write(0x00); // 00 - disable pullups
    i2c_stop();    
 
Registers can be found in datasheet, quick look to understand what registers was set in code:



Then you can turn on LED:

    i2c_restart(0x40);
    i2c_write(0x09);
    i2c_write(0xFE);
    i2c_stop();    

Useful links:

MCP23009 datasheet