This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bare metal ADV_SCAN_IND PDU transmission

Hi All,

I was trying to transmit a bare-metal minimal C program to send a raw ADV_SCAN_IND PDU using nrf52840 dev board. Code is listed below:

unsigned int data = 30u;
unsigned int sum = 0u;
extern unsigned int __sflash__;
extern unsigned int __sdata__;
extern unsigned int __edata__;
extern unsigned int __sbss__;
extern unsigned int __ebss__;
int main( void );
void adv_start( void );
void startupCall( void );
volatile unsigned int zz;
void doNothing(void)
{
    zz = 0u;
    sum = 345;
    while(1)
       zz++;
}
__attribute__((section(".vectors"))) volatile unsigned int vector_table[0x100] = { 0x20000100,
                                                                                   (unsigned int)startupCall,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing,
                                                                                   (unsigned int)doNothing
                                                                                  };
// Bare metal startup
__attribute__((section(".startup"))) void copyToRam( void )
{
    unsigned int * flashStart = &__sflash__;
    unsigned int * ramStart   = &__sdata__;
    unsigned int * ramEnd     = &__edata__;
    while( ramStart < ramEnd )
    {
        *ramStart = *flashStart;
        ramStart++;
        flashStart++;
    }
}
__attribute__((section(".startup"))) void initializeBss( void )
{
    unsigned int * bssStart = &__sbss__;
    unsigned int * bssEnd   = &__ebss__;
    while( bssStart < bssEnd )
    {
           *bssStart = 0u;
              bssStart++;
    }
}
__attribute__((section(".startup"))) void startupCall( void )
{
    copyToRam();
    initializeBss();
    main();
}

int add( int x, int y )
{
   int a;
   a = x + y;
   return a;
}


int main( void )
{
    adv_start();
    while(1);
    return  0;
}

/* BLE specific code */
void init( void )
{

    volatile unsigned int * pShorts    = (volatile unsigned int *)(0x40001200);
    volatile unsigned int * pINTSET    = (volatile unsigned int *)(0x40001304);
    volatile unsigned int * pFreq      = (volatile unsigned int *)(0x40001508);
    volatile unsigned int * pTxPower   = (volatile unsigned int *)(0x4000150C);
    volatile unsigned int * pMode      = (volatile unsigned int *)(0x40001510);
    volatile unsigned int * pPCFN0     = (volatile unsigned int *)(0x40001514);
    volatile unsigned int * pPCFN1     = (volatile unsigned int *)(0x40001518);
    volatile unsigned int * pBase0     = (volatile unsigned int *)(0x4000151C);
    volatile unsigned int * pBase1     = (volatile unsigned int *)(0x40001520);
    volatile unsigned int * pPrefix0   = (volatile unsigned int *)(0x40001524);
    volatile unsigned int * pPrefix1   = (volatile unsigned int *)(0x40001528);
    volatile unsigned int * pTxAddress = (volatile unsigned int *)(0x4000152C);
    volatile unsigned int * pRxAddress = (volatile unsigned int *)(0x40001530);
    volatile unsigned int * pCRCCNF    = (volatile unsigned int *)(0x40001534);
    volatile unsigned int * pCRCPOLY   = (volatile unsigned int *)(0x40001538);
    volatile unsigned int * pCRCINIT   = (volatile unsigned int *)(0x4000153C);
    volatile unsigned int * pDATAWHITE = (volatile unsigned int *)(0x40001554);


    *pFreq      = 0x00000050u; /* set frequency to 2480 */
    *pTxPower   = 0x00000000u; /* Odbm */
    *pMode      = 0x00000003u; /* 1Mbit BLE */
    *pPCFN0     = 0x00000108u; /* LFLEN - 8, and S0LEN to 1*/
    *pPCFN1     = 0x02030025u; /* Maxlen to 37 BALEN to 3 and WHITEN to 1*/
    *pBase0     = 0x89BED600u; /* Base address for BLE */
    *pBase1     = 0x00000000u; /* NA */
    *pPrefix0   = 0x0000008Eu; /* */
    *pPrefix1   = 0x00000000u; /* */
    *pTxAddress = 0x00000000u; /* */
    *pRxAddress = 0x00000000u; /* */
    *pCRCCNF    = 0x00000103u; /* 3 Byte CRC - 24 bit*/
    *pCRCPOLY   = 0x0000065Bu; /* BLE CRC polynomial */
    *pCRCINIT   = 0x00555555u; /* BLE CRC inital value */
    *pDATAWHITE = 0x00000027u; /* Data whitening value for 2480MHz */
    *pShorts    = 0x00000003u; /* Setting up shortcut for events ready to task start and events end and task disable */

}
unsigned char payload[39] = {0x46, 0x22, 0xD3, 0xE3, 0x9B, 0xA8, 0xF7, 0xE3,
                       0x02, 0x01, 0x04, 0x03, 0x03, 0xAA, 0xFE, 0x14,
                       0x16, 0xAA, 0xFE, 0x10, 0x00, 0x00, 0x7A, 0x65,
                       0x70, 0x68, 0x79, 0x72, 0x70, 0x72, 0x6F, 0x6A,
                       0x65, 0x63, 0x74, 0x08, 0x5B, 0xA7, 0x18 };
                       /* Payload taken from zephyr OS project example.
                       First two bytes are header.
                       Next 6 are address and rest is data */
void send_scanable_adv( void )
{
    volatile unsigned int    val            = 0u;
    volatile unsigned int * pPacketPtr      = (volatile unsigned int *)(0x40001504);
    volatile unsigned int * pTasksTXEN      = (volatile unsigned int *)(0x40001000);
    volatile unsigned int * pTasksSTART     = (volatile unsigned int *)(0x40001008);
    volatile unsigned int * pEventsReady    = (volatile unsigned int *)(0x40001100);
    volatile unsigned int * pEventsDisabled = (volatile unsigned int *)(0x40001110);
    /* Set payload */
    *pPacketPtr = (unsigned int) &payload[0];
    /* start transmission */
    *pTasksTXEN = 0x00000001u;
    /* wait for transmission to end */
    while( val == 0u )
        val = (unsigned int)*pEventsDisabled;
    *pEventsDisabled = 0u;
}
void adv_start( void )
{
    volatile int i;
    init();
    while(1)
    {
       sum++;
       send_scanable_adv();
       for( i = 0; i < 10000; i++ ); //Delay before next packet transmission
    }
}

Here is the linker script used

MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x1000
SRAM (rwx) : ORIGIN = 0x20000100, LENGTH = 0x400
}
SECTIONS {
.vectors : {               * (.vectors);                   } > FLASH
.startup : {               * (.startup);                   } > FLASH
.text   : {                * (.text)   ;                   } > FLASH
.rodata : {                * (.rodata) ; __sflash__ = .;   } > FLASH
.data   : { __sdata__ = .; * (.data)   ;   __edata__ = .;  } > SRAM AT>FLASH
.bss    : { __sbss__ = .;  * (.bss)    ; __ebss__ = .;     } > SRAM
__ebss__ = .;
}

Build script used to compile is here:

echo "Running Compiler"
echo "arm-none-eabi-gcc -g -nostdlib -T sample.ld -mcpu=cortex-m0 -mthumb  main.c -o startup.elf"
arm-none-eabi-gcc -g -nostdlib -T sample.ld -mcpu=cortex-m4 -mthumb  main.c -o startup.elf

echo "Creating Binary"
echo "arm-none-eabi-objcopy -O binary startup.elf startup.bin"
arm-none-eabi-objcopy -O binary startup.elf startup.bin


echo "Listing Symbols"
echo "arm-none-eabi-nm startup.elf"
arm-none-eabi-nm startup.elf

Code runs without any issues but I could not see the packet on BLE sniffer. Anyone has any idea why I am not able to see the packets on a BLE sniffer.

Regards

S

Parents
  • I think you forgot to send the START trigger after the TXEN trigger and subsequent READY event:

    "A TXRU ramp-up sequence is initiated when the TXEN task is triggered. After the radio has successfully ramped up it will generate the READY event indicating that a packet transmission can be initiate. A packet transmission is initiated by triggering the START task. As illustrated in Radio states on page 290 the START task can first be triggered after the RADIO has entered into the TXIDLE state."

  • The shortcut register pShorts in the code is assigned 0x03 value which takes care of that by itself.

  • Ah, I missed that. What is the advertising packet, I don't decode it (not familiar with zephyr examples):

        //  |  +-- 0x01 flags value 0x04 -> BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED
        //  |  |
        //  |  |     +-- 0x03 3-byte code 0x03 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE
        //  |  |     |
        //  |  |     |           +-- 0x14 20-bytes code 0x16 BLE_GAP_AD_TYPE_SERVICE_DATA
        //  |  |     |           |<--------------------------------------------------------->|
        //  |  |     |           |                                                           |
        //  |  |     |           |                                                           |
        //  |  |     |           |                                                           |  +-- ?
        //  |  |     |           |                                                           |  |  
        //  |  |     |           |                                                           |  |  
        //  |  |     |           |                                                           |  |  
        //  |  |     |           |                                                           |  |  
        //  |  |  |  |  |        |  |                                                        |  |  
        // 02 01 04 03 03 AA FE 14 16 AA FE 10 00 00 7A 65 70 68 79 72 70 72 6F 6A 65 63 74 08 5B A7 18
    
    unsigned char payload[39] =
      {0x46, 0x22, 0xD3, 0xE3, 0x9B, 0xA8, 0xF7, 0xE3, // Header & address
       0x02, 0x01, 0x04, 0x03, 0x03, 0xAA, 0xFE, 0x14, // Data
       0x16, 0xAA, 0xFE, 0x10, 0x00, 0x00, 0x7A, 0x65,
       0x70, 0x68, 0x79, 0x72, 0x70, 0x72, 0x6F, 0x6A,
       0x65, 0x63, 0x74, 0x08, 0x5B, 0xA7, 0x18 };
    
    /**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
     * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
     * @{ */
    #define BLE_GAP_AD_TYPE_FLAGS                               0x01 /**< Flags for discoverability. */
    #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE   0x02 /**< Partial list of 16 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE         0x03 /**< Complete list of 16 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE   0x04 /**< Partial list of 32 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE         0x05 /**< Complete list of 32 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE  0x06 /**< Partial list of 128 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE        0x07 /**< Complete list of 128 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME                    0x08 /**< Short local device name. */
    #define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME                 0x09 /**< Complete local device name. */
    #define BLE_GAP_AD_TYPE_TX_POWER_LEVEL                      0x0A /**< Transmit power level. */
    #define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE                     0x0D /**< Class of device. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C               0x0E /**< Simple Pairing Hash C. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R         0x0F /**< Simple Pairing Randomizer R. */
    #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE           0x10 /**< Security Manager TK Value. */
    #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS          0x11 /**< Security Manager Out Of Band Flags. */
    #define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE     0x12 /**< Slave Connection Interval Range. */
    #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT       0x14 /**< List of 16-bit Service Solicitation UUIDs. */
    #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT      0x15 /**< List of 128-bit Service Solicitation UUIDs. */
    #define BLE_GAP_AD_TYPE_SERVICE_DATA                        0x16 /**< Service Data - 16-bit UUID. */
    #define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS               0x17 /**< Public Target Address. */
    #define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS               0x18 /**< Random Target Address. */
    #define BLE_GAP_AD_TYPE_APPEARANCE                          0x19 /**< Appearance. */
    #define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL                0x1A /**< Advertising Interval. */
    #define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS         0x1B /**< LE Bluetooth Device Address. */
    #define BLE_GAP_AD_TYPE_LE_ROLE                             0x1C /**< LE Role. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256            0x1D /**< Simple Pairing Hash C-256. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256      0x1E /**< Simple Pairing Randomizer R-256. */
    #define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID             0x20 /**< Service Data - 32-bit UUID. */
    #define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID            0x21 /**< Service Data - 128-bit UUID. */
    #define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE             0x22 /**< LE Secure Connections Confirmation Value */
    #define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE                   0x23 /**< LE Secure Connections Random Value */
    #define BLE_GAP_AD_TYPE_URI                                 0x24 /**< URI */
    #define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA                 0x3D /**< 3D Information Data. */
    #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA          0xFF /**< Manufacturer Specific Data. */
    /**@} */
    

    However even if incorrect format, it wouldn't stop the radio.

Reply
  • Ah, I missed that. What is the advertising packet, I don't decode it (not familiar with zephyr examples):

        //  |  +-- 0x01 flags value 0x04 -> BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED
        //  |  |
        //  |  |     +-- 0x03 3-byte code 0x03 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE
        //  |  |     |
        //  |  |     |           +-- 0x14 20-bytes code 0x16 BLE_GAP_AD_TYPE_SERVICE_DATA
        //  |  |     |           |<--------------------------------------------------------->|
        //  |  |     |           |                                                           |
        //  |  |     |           |                                                           |
        //  |  |     |           |                                                           |  +-- ?
        //  |  |     |           |                                                           |  |  
        //  |  |     |           |                                                           |  |  
        //  |  |     |           |                                                           |  |  
        //  |  |     |           |                                                           |  |  
        //  |  |  |  |  |        |  |                                                        |  |  
        // 02 01 04 03 03 AA FE 14 16 AA FE 10 00 00 7A 65 70 68 79 72 70 72 6F 6A 65 63 74 08 5B A7 18
    
    unsigned char payload[39] =
      {0x46, 0x22, 0xD3, 0xE3, 0x9B, 0xA8, 0xF7, 0xE3, // Header & address
       0x02, 0x01, 0x04, 0x03, 0x03, 0xAA, 0xFE, 0x14, // Data
       0x16, 0xAA, 0xFE, 0x10, 0x00, 0x00, 0x7A, 0x65,
       0x70, 0x68, 0x79, 0x72, 0x70, 0x72, 0x6F, 0x6A,
       0x65, 0x63, 0x74, 0x08, 0x5B, 0xA7, 0x18 };
    
    /**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
     * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
     * @{ */
    #define BLE_GAP_AD_TYPE_FLAGS                               0x01 /**< Flags for discoverability. */
    #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE   0x02 /**< Partial list of 16 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE         0x03 /**< Complete list of 16 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE   0x04 /**< Partial list of 32 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE         0x05 /**< Complete list of 32 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE  0x06 /**< Partial list of 128 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE        0x07 /**< Complete list of 128 bit service UUIDs. */
    #define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME                    0x08 /**< Short local device name. */
    #define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME                 0x09 /**< Complete local device name. */
    #define BLE_GAP_AD_TYPE_TX_POWER_LEVEL                      0x0A /**< Transmit power level. */
    #define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE                     0x0D /**< Class of device. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C               0x0E /**< Simple Pairing Hash C. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R         0x0F /**< Simple Pairing Randomizer R. */
    #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE           0x10 /**< Security Manager TK Value. */
    #define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS          0x11 /**< Security Manager Out Of Band Flags. */
    #define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE     0x12 /**< Slave Connection Interval Range. */
    #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT       0x14 /**< List of 16-bit Service Solicitation UUIDs. */
    #define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT      0x15 /**< List of 128-bit Service Solicitation UUIDs. */
    #define BLE_GAP_AD_TYPE_SERVICE_DATA                        0x16 /**< Service Data - 16-bit UUID. */
    #define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS               0x17 /**< Public Target Address. */
    #define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS               0x18 /**< Random Target Address. */
    #define BLE_GAP_AD_TYPE_APPEARANCE                          0x19 /**< Appearance. */
    #define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL                0x1A /**< Advertising Interval. */
    #define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS         0x1B /**< LE Bluetooth Device Address. */
    #define BLE_GAP_AD_TYPE_LE_ROLE                             0x1C /**< LE Role. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256            0x1D /**< Simple Pairing Hash C-256. */
    #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256      0x1E /**< Simple Pairing Randomizer R-256. */
    #define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID             0x20 /**< Service Data - 32-bit UUID. */
    #define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID            0x21 /**< Service Data - 128-bit UUID. */
    #define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE             0x22 /**< LE Secure Connections Confirmation Value */
    #define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE                   0x23 /**< LE Secure Connections Random Value */
    #define BLE_GAP_AD_TYPE_URI                                 0x24 /**< URI */
    #define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA                 0x3D /**< 3D Information Data. */
    #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA          0xFF /**< Manufacturer Specific Data. */
    /**@} */
    

    However even if incorrect format, it wouldn't stop the radio.

Children
No Data
Related