element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Smart Security and Surveillance
  • Challenges & Projects
  • Design Challenges
  • Smart Security and Surveillance
  • More
  • Cancel
Smart Security and Surveillance
Forum BLE scanning and CC256X firmware uploading
  • News
  • Projects
  • Forum
  • DC
  • Leaderboard
  • Files
  • Members
  • More
  • Cancel
  • New
Join Smart Security and Surveillance to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • Replies 13 replies
  • Subscribers 46 subscribers
  • Views 288 views
  • Users 0 members are here
Related

BLE scanning and CC256X firmware uploading

Alistair
Alistair 13 days ago

After thinking I had everything in place I have just got wound to the BLE scanning, and it turns out that it it not working. Basic Bluetooth functionality appraiser fine, but the BLE functionality is not there. Doh!

Following a hint from online I trued the command 01 01 FE 01 00 (HCI_VS_Write_BD_Addr) and that returned 0x01 (Unknown HCI Command), and that shown new firmware needs uploading. Has anyone done this?Any other suggestions for that matter?

  • Sign in to reply
  • Cancel

Top Replies

  • BigG
    BigG 12 days ago in reply to BigG +1
    LOL. I could've saved myself some time by actually looking what's under my dev board. Assumption shows it teeth, yet again... the XIP flash IC turns out to be optional.
  • Alistair
    Alistair 11 days ago in reply to BigG +1
    That is amazing thanks. Yes the LE was separate, and I was making the mistake of also applying the AVR patch when i should not have done, so lets just pretend that did not happen and move on. ;-) It…
  • BigG
    BigG 13 days ago

    Did you try the BTstack library: https://bluekitchen-gmbh.com/btstack-arduino/tutorial/#btstack-library

    The reason the command did not work is that you have to first upload a "service pack" to the PAN1326 module so that it understands what you are asking.

    The DIY route requires this (think this is the correct one, if not search on TI: https://www.ti.com/tool/CC256XB-BT-SP)

    PS.

    I was going to test to see whether you can upload this service pack onto the external flash on the MAX32630FTHR with an Arduino utility sketch. Then you wouldn't have to bundle it in with your code.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 12 days ago in reply to BigG

    LOL. I could've saved myself some time by actually looking what's under my dev board. Assumption shows it teeth, yet again... the XIP flash IC turns out to be optional.

    image

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 12 days ago in reply to BigG

    I downloaded the required zip file from ti.com. It looks like CC256XB.h is the file to use to get the service pack.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 12 days ago in reply to BigG

    Ha, We have all been there. My super power is to loose something in front of me. :-)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 12 days ago in reply to BigG

    I did look at BTstack, but it is adding a lot of bloat and complexity that I do not need for this project. I now see that part of the bloat is the patch, but I will hope to be able to keep things simple.

    I have had a go at uploading the patch myself. To start I am using the commands already converted to an almost usable from from BTstack. I ma having mixed success. Most of it uploads fine, but one or two commands causes the module to hang. Commands that were not available before become available, but nothing is working just yet. In short I am making progress, but slow progress. I will report back if I have any success.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 12 days ago

    I quick update. After some very hackey code I have managed to get the patch from BTstack to load, and the mask and scan commands are accepted, but no results are returned. I also have the original TI mod loading, but that does not appear to change anything. I will take a break and come back to this another time with a fresh head.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 11 days ago in reply to Alistair

    I thought to give it a try. I now have the service pack loaded... will now see if I can scan for devices

    >>> Sending HCI_Reset Command...
    <<< BLE Response (HEX): 04 0E 04 01 03 0C 00 
    Size of buffer: 7
    <<< BLE Response (HEX): 04 0E 0C 01 01 10 00 06 00 00 06 0D 00 90 1B 
    Size of buffer: 15
    
    Size of service pack: 9118
    
    Bluetooth successfully patched!

    UPDATE.
    I had only patched with the base patch. Just discovered that you also have to patch with the LowEnergyPatch[] and set the #ifdef __SUPPORT_LOW_ENERGY__

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 11 days ago in reply to BigG

    It's all rather weird logic. Thank goodness for AI!

    So, I've got it working.

    The key to actually seeing any output from the scan is to set up the "Event Mask". You do this before setting up scan.

    // Set event mask and LE event mask
    const uint8_t SET_EVENT_MASK[] = {0x01, 0x01, 0x0C, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    const uint8_t SET_LE_EVENT_MASK[] = {0x01, 0x01, 0x20, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    <<< BLE Response (HEX): 04 01 0B 20 00 
    Enabling BLE Scan...
    Scanning for devices... (Watch for 04 3E events)
    <<< BLE Response (HEX): 04 01 0C 20 00 
    <<< BLE Response (HEX): 04 3E 2B 02 01 03 01 E1 CD 48 2E 2E 2F 1F 1E 
    Size of buffer: 15
    <<< BLE Response (HEX): 04 3E 2B 02 01 03 01 E1 CD 48 2E 2E 2F 1F 1E 
    Size of buffer: 15
    <<< BLE Response (HEX): 04 3E 28 02 01 02 01 96 23 5E B8 B8 78 1C 03 
    Size of buffer: 15
    <<< BLE Response (HEX): 04 3E 28 02 01 02 01 48 1D 94 8E B3 73 1C 03 
    Size of buffer: 15
    <<< BLE Response (HEX): 04 3E 28 02 01 02 01 96 23 5E B8 B8 78 1C 03 
    Size of buffer: 15
    <<< BLE Response (HEX): 04 3E 2B 02 01 03 01 E1 CD 48 2E 2E 2F 1F 1E 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 11 days ago in reply to BigG

    here's the Arduino code, if it helps.

    #include <Arduino.h>
    #include "pwrseq_regs.h"
    #include "rtc_regs.h"
    #include "ioman_regs.h"
    #include "gpio_regs.h"
    #include "CC256XB.h" // Your TI Service Pack file
    
    // Define the correct Serial port based on your MXC_HardwareSerial.h discovery
    #define SerialBLE Serial0
    
    #define BUFFER_ARRAY_SIZE   (128u)
    
    // Pin Definitions for MAX32630FTHR
    #define BLE_SHUTDOWN_PIN P1_6    // nSHUTD (Active Low)
    #define M4_RTS_OUT_TO_BLE P0_2   // M4 RTS Output
    #define BLE_RTS_IN_TO_M4  P0_3   // BLE Module RTS Input (M4 CTS)
    #define M4_TX_PIN         P0_0   // UART0 TX (Mapping B)
    #define M4_RX_PIN         P0_1   // UART0 RX (Mapping B)
    
    // HCI_Reset Command: [PacketType][OpCode Low][OpCode High][Length]
    const uint8_t HCI_RESET_CMD[] = {0x01, 0x03, 0x0C, 0x00}; 
    const uint8_t HCI_SERIALNUM_CMD[] = {0x01, 0x01, 0x10, 0x00}; 
    const uint8_t VS_STATUS_CMD[] = {0x01, 0x19, 0xFE, 0x00};
    
    // Set event mask and LE event mask
    const uint8_t SET_EVENT_MASK[] = {0x01, 0x01, 0x0C, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    const uint8_t SET_LE_EVENT_MASK[] = {0x01, 0x01, 0x20, 0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    
    // Write LE Host Supported (Bit 0: LE Supported, Bit 1: Simultaneous LE/BR)
    const uint8_t ENABLE_LE[] = {0x01, 0x6D, 0x0C, 0x02, 0x01, 0x01};
    // Set Scan Parameters (Passive scanning, 0x64 interval/window)
    const uint8_t SET_SCAN_PARAMS[] = {0x01, 0x0B, 0x20, 0x07, 0x00, 0x64, 0x00, 0x64, 0x00, 0x00, 0x00};
    // Set Scan Enable (Enable=1, Filter Duplicates=0)
    const uint8_t SCAN_ENABLE[]     = {0x01, 0x0C, 0x20, 0x02, 0x01, 0x00};
    
    uint8_t buffer[BUFFER_ARRAY_SIZE] = {'\0'};
    uint16_t cntr = 0;
    bool eventMask = false;
    bool eventLEMask = false;
    bool enableBLE = false;
    bool servicePackDone = false;
    bool initialiseScan = false;
    bool ScanEnabled = false;
    
    void setup() {
      Serial.begin(115200);
      while (!Serial);
    
      // --- 1. SET VOLTAGES (Arduino Way) ---
      // Set 1.8V Logic for all Bluetooth UART pins
      useVDDIO(BLE_SHUTDOWN_PIN); 
      useVDDIO(M4_TX_PIN); 
      useVDDIO(M4_RX_PIN);
      useVDDIO(M4_RTS_OUT_TO_BLE); 
      useVDDIO(BLE_RTS_IN_TO_M4);
    
      Serial.println("1. VDDIO set to 1.8V.");
    
      // --- 2. INITIALIZE HARDWARE ---
      // Configure 32.768 kHz Clock (P1.7)
      MXC_RTCCFG->clk_ctrl |= MXC_F_RTC_CLK_CTRL_NANO_EN;
      MXC_RTCCFG->osc_ctrl |= MXC_F_RTC_OSC_CTRL_OSC_WARMUP_ENABLE;
      MXC_RTCTMR->prescale = MXC_V_RTC_PRESCALE_DIV_2_0; 
      MXC_PWRSEQ->reg4 |= MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN;
      Serial.println("2. 32kHz Heartbeat active on P1.7.");
    
      // Prepare Pins: Set M4 RTS LOW BEFORE the module wakes up
      // This ensures the BLE module sees "Permission to Speak" immediately.
      pinMode(M4_RTS_OUT_TO_BLE, OUTPUT);
      digitalWrite(M4_RTS_OUT_TO_BLE, LOW); 
      
      pinMode(BLE_RTS_IN_TO_M4, INPUT); // Monitor the module's RTS
      pinMode(M4_RX_PIN, INPUT);        // Prepare RX for data
      Serial.println("3. Flow control pins staged (M4 RTS = LOW).");
    
      // Initialize SerialBLE (Serial0)
      // Note: We use 115200 but re-assert IOMAN immediately after.
      SerialBLE.begin(115200);
    
      // Force IOMAN to Mapping B (Crossover)
      // Serial0.begin() often reverts to Mapping A. We force it back to B.
      // 0x11 = Request Mapping B for RX/TX pins.
      MXC_IOMAN->uart0_req = 0x11;
      while (MXC_IOMAN->uart0_ack != 0x11);
      Serial.println("4. UART0 Mapping B (Crossover) Locked.");
    
      // Pulse Reset (nSHUTD)
      pinMode(BLE_SHUTDOWN_PIN, OUTPUT);
      digitalWrite(BLE_SHUTDOWN_PIN, LOW);
      delay(100);
      digitalWrite(BLE_SHUTDOWN_PIN, HIGH);
      Serial.println("5. BLE Reset released. Waiting for module...");
      
    }
    
    bool wait_for_hci_ack() {
      uint32_t timeout = millis();
      while (millis() - timeout < 1000) {
        if (SerialBLE.available() >= 3) {
          if (SerialBLE.read() == 0x04 && SerialBLE.read() == 0x0E) return true;
        }
      }
      return false;
    }
    
    // --- 3. THE SIMPLE LOADER ---
    void upload_service_pack() {
      uint32_t cursor = 0;
    
      const uint32_t BasePatchLength = sizeof(BasePatch);
      const uint32_t LowEnergyPatchLength = sizeof(LowEnergyPatch);
      
      Serial.print("\r\nSize of base service pack: "); Serial.println(BasePatchLength);
    
      while (cursor < BasePatchLength) {
        // Read the packet length from the header (index 3)
        uint8_t payload_len = pgm_read_byte(&BasePatch[cursor + 3]);
        uint16_t total_packet = 4 + payload_len;
    
        // Send full HCI packet
        for (uint16_t i = 0; i < total_packet; i++) {
          SerialBLE.write(pgm_read_byte(&BasePatch[cursor + i]));
        }
    
        // Wait for Command Complete (04 0E) before sending next
        if (!wait_for_hci_ack()) {
          Serial.print("Failed at: "); Serial.println(cursor);
          return;
        }
        
        cursor += total_packet;
        if (cursor % 1000 == 0) Serial.print("."); 
      }
      Serial.println("\nBluetooth base successfully patched!");
      delay(100);
    
      Serial.print("\r\nSize of LE service pack: "); Serial.println(LowEnergyPatchLength);
      cursor = 0;
    
      while (cursor < LowEnergyPatchLength) {
        // Read the packet length from the header (index 3)
        uint8_t payload_len = pgm_read_byte(&LowEnergyPatch[cursor + 3]);
        uint16_t total_packet = 4 + payload_len;
    
        // Send full HCI packet
        for (uint16_t i = 0; i < total_packet; i++) {
          SerialBLE.write(pgm_read_byte(&LowEnergyPatch[cursor + i]));
        }
    
        // Wait for Command Complete (04 0E) before sending next
        if (!wait_for_hci_ack()) {
          Serial.print("Failed at: "); Serial.println(cursor);
          return;
        }
        
        cursor += total_packet;
        if (cursor % 1000 == 0) Serial.print("."); 
      }
      Serial.println("\nBluetooth LE successfully patched!");
      delay(100);  
    
      servicePackDone = true;
    
    }
    
    void loop() {
      static int lastRtsState = -1;
      int currentRtsState = digitalRead(BLE_RTS_IN_TO_M4);
    
      // Monitor for the Module's RTS drop (Signaling it is ready)
      if (currentRtsState != lastRtsState) {
        Serial.print("\n[Module RTS Change: ");
        Serial.print(currentRtsState == LOW ? "LOW (Ready)" : "HIGH (Busy)");
        Serial.println("]");
        lastRtsState = currentRtsState;
    
        // AUTO-TRIGGER: If the module just became ready, send the reset command
        if (currentRtsState == LOW) {
          Serial.println(">>> Sending HCI_Reset Command...");
          SerialBLE.write(HCI_RESET_CMD, 4);
        }
      }
    
      // Handle Manual 'r' Trigger from PC
      if (Serial.available()) {
        char c = Serial.read();
        if (c == 'r') {
          Serial.println("\n>>> Manual Trigger: Sending HCI_Reset...");
          // Clear buffer first
          while(SerialBLE.available()) SerialBLE.read();
          SerialBLE.write(HCI_RESET_CMD, 4);
        }
        else if (c == 'v') {
          Serial.println("\n>>> Manual Trigger: Sending TI_VS_Get_System_Status...");
          SerialBLE.write(VS_STATUS_CMD, 4);    }
      }
    
      // Read and Print Module Response
      if (SerialBLE.available()) {
        // Wait briefly for the full packet to arrive
        delay(10); 
        memset(buffer,'\0', BUFFER_ARRAY_SIZE);
        cntr = 0;
        Serial.print("<<< BLE Response (HEX): ");
        while (SerialBLE.available()) {
          byte b = SerialBLE.read();
          if (b < 0x10) Serial.print("0");
          Serial.print(b, HEX);
          Serial.print(" ");
          if (cntr < (BUFFER_ARRAY_SIZE - 1)) {
            buffer[cntr] = b;
            cntr++;
          }
          else {
            buffer[cntr] = b;
            break;
          }
        }
        Serial.println();
        // Review the buffer array...
        if (buffer[0] == 0x04 && buffer[1] == 0x0E) {
          Serial.print("Size of buffer: "); Serial.println(cntr);
          if (buffer[2] == 0x04 && buffer[4] == 0x03  && buffer[5] == 0x0C && buffer[cntr] == 0x00)
            SerialBLE.write(HCI_SERIALNUM_CMD, 4);
    
          if (cntr == 15 && !servicePackDone) {
             upload_service_pack();
          }
        }
        else if (buffer[0] == 0x04 && buffer[1] == 0x3E) {
          Serial.print("Size of buffer: "); Serial.println(cntr);
        }
      }
      if (servicePackDone) {
    
        if (eventMask) {
          if (eventLEMask) {
            // We can now set up our BLE application
            if (enableBLE) {
              if (initialiseScan) {
                if (ScanEnabled) {
                  
                }
                else {
                  Serial.println("Enabling BLE Scan...");
                  Serial0.write(SCAN_ENABLE, sizeof(SCAN_ENABLE));
                  wait_for_hci_ack();
                  ScanEnabled = true;
                  Serial.println("Scanning for devices... (Watch for 04 3E events)");
                }
              }
              else {
                Serial.println("Setting Scan Parameters...");
                SerialBLE.write(SET_SCAN_PARAMS, sizeof(SET_SCAN_PARAMS));
                wait_for_hci_ack();
                initialiseScan = true;
              }
            }
            else {
                Serial.println("Enabling BLE...");
                SerialBLE.write(ENABLE_LE, sizeof(ENABLE_LE));
                wait_for_hci_ack();
                enableBLE = true;
            }
          }
          else {
            Serial.println("Setting LE Event Mask...");
            SerialBLE.write(SET_LE_EVENT_MASK, sizeof(SET_LE_EVENT_MASK));
            wait_for_hci_ack();
            eventLEMask = true;
          }
        }
        else {
          Serial.println("Setting Event Mask...");
          SerialBLE.write(SET_EVENT_MASK, sizeof(SET_EVENT_MASK));
          wait_for_hci_ack();
          eventMask = true;
        }
    
      }
    }
    

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 11 days ago in reply to BigG

    That is amazing thanks. Yes the LE was separate, and I was making the mistake of also applying the AVR patch when i should not have done, so lets just pretend that did not happen and move on. ;-)

    It looks like the mistake I was making is not applying both the event masks and enabling the low energy after.

    So I now have a lot of data to decode. :-) I guess this is one of those things that is described as a nice problem to have. That and a lot of tidying of the code. As my commands will be static I might just create a blob of commands to send at compile time, including the patch, and use my uploader code to apply then at start up. My main focus is making the code easy to understand and easy to build on, and at the moment it is a bit of a mess of experimentation and debugging code. Again let us pretend that is not the case and move on. ;-)

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube