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."

  • you are correct. Format of the packet shall have no impact on transmission or detection by the sniffer. Based on Bluetooth Corev5.2 ADV_SCAN_IND PDU has two bytes of header which has some subfields, then follows 6 byte of address and then follows 31 byte of data. Payload in the code follows this format. ADV data has random zephyr project info. 

Reply Children
Related