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 Accessing the PAN1326B Bluetooth module on the MAX32630fTHR
  • 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 18 replies
  • Subscribers 50 subscribers
  • Views 524 views
  • Users 0 members are here
Related

Accessing the PAN1326B Bluetooth module on the MAX32630fTHR

Alistair
Alistair 1 month ago

I have dome some experimentation over the long weekend and had some success in getting the MAX32630fTHR working with the Arduino IDE. In fact it is pleasingly fast to compile and upload. I will try and finish documenting this process just in case it is of help to others, or me in the future when I have forgotten everything. ;-)

There is one thing I am struggling with however, and I was wondering it anyone has the solution.

I am trying to communicate with the PAN1326B to scan for Bluetooth devices. It should be on UART0, and having dug deep in to the Arduino core for the module it looks like that is mapped correctly. However when I send data (a HCI reset of 01,03,0c,00 for example) to it nothing happens and nothing ever comes back.

I have pulsed down P1.6 (BT_RST) for a few hundred milliseconds to try and reset things and nothing changes. I have held CTS low, but also checked it high just in case.

One complication is the PAN1326B required a 32KHz signal, but this is a feature built in to the MAX32630 in P1.7. If I do not activate this then RTS remains high as expected.

When I set the PWR_PSEQ_32K_EN flag in PWRSEQ_REG4 to activate the 32KHz output RTS from the module is briefly high, but then goes low in a fraction of a second. I believe this is as expected.

Now one odd thing is if I leave the module running it will eventually do high. This is not quick though and may be some kind of power saving feature perhaps?

I am blindly assuming that the clock is being generated and being passed thought correctly, but there is a test pad TP4 so I can confirm this tomorrow. Everything else is not exposed on the board unfortunately.

So, has anyone got any thoughts on why I am not able to communicate with the module, or advice of what to try next?

  • Sign in to reply
  • Cancel

Top Replies

  • Alistair
    Alistair 1 month ago in reply to skruglewicz +2
    I have just rushed a post with the details in. I will do a deeper dive in to the lower level stuff when I post about the Bluetooth work. community.element14.com/.../programming-the-max32630fthr-with-the…
  • Alistair
    Alistair 1 month ago in reply to skruglewicz +1
    I have decided to go with the Arduino IDE and core for this project. It is a fun project that I want to be accessible to and modifiable by everyone, so it was an obvious call really. The only negative…
  • Alistair
    Alistair 1 month ago +1
    I think I have it working. There were a number of things that I will document later (honest ;-) ). The summary version is that UART0 was not enabled so neds turning on, P1.7 need a 32KHx signal mapping…
  • skruglewicz
    skruglewicz 1 month ago in reply to Alistair

    Thanks for your research... great 

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 1 month ago in reply to Alistair

    I am rather curious to see how you did this. I dug up my MAX32630FTHR to give it another go. But I have yet to crack it. I don't get any response.

    #include <Arduino.h>
    #include "pwrseq_regs.h"
    #include "rtc_regs.h"
    #include "ioman_regs.h"
    #include "clkman_regs.h"
    
    // Pin Definitions for MAX32630FTHR / PAN1326B
    #define BLE_SHUTDOWN_PIN P1_6    // nSHUTD (Active Low Reset)
    #define BLE_32K_CLK_PIN  P1_7    // Slow Clock In
    #define M4_RTS_TO_BLE    P0_2    // M4 RTS (Tells BLE it's okay to talk)
    #define BLE_RTS_TO_M4    P0_3    // BLE RTS (Tells M4 it's okay to talk)
    
    void setup() {
      // Initialize Debug Serial
      Serial.begin(115200);
      while (!Serial) continue; 
      Serial.println("\r\n--- PAN1326B Methodical Boot Sequence ---");
    
      // 1. Enable UART0 Peripheral Clock (The "Blogger's Fix")
      // Forces the UART0 hardware to "Turn On"
     // Use the registers found in your clkman_regs.h
      // We set the GATER bits to 0x2 (Force On) for UART0
      MXC_CLKMAN->clk_gate_ctrl1 |= (0x2UL << MXC_F_CLKMAN_CLK_GATE_CTRL1_UART0_CLK_GATER_POS);
      
      // Set the UART Clock Scale to 'DIV_1' (No scaling)
      MXC_CLKMAN->sys_clk_ctrl_8_uart = MXC_V_CLKMAN_CLK_SCALE_DIV_1;
      Serial.println("1. UART0 Peripheral hardware clock enabled.");
    
      // 2. Set I/O Voltage to 1.8V for BLE Pins
      useVDDIO(P0_0); // TX/RX
      useVDDIO(P0_1); // TX/RX
      useVDDIO(P0_2); // M4 RTS
      useVDDIO(P0_3); // BLE RTS
      Serial.println("2. BLE Port 0 pins set to 1.8V logic.");
    
      // 3. Configure IOMAN for Mapping B (Crossover)
      // Bit 0=1 (Map B), Bit 1=1 (FC-B), Bit 2=1 (FC-B)
      // Bits 4,5,6=1 (Request Pins)
      MXC_IOMAN->uart0_req = 0x77; 
      
      // Wait for hardware to acknowledge the pin-mapping request
      while (MXC_IOMAN->uart0_ack != MXC_IOMAN->uart0_req);
      Serial.println("3. IOMAN Mapping B (Crossover) Acknowledged.");
    
      // 4. Configure 32.768 kHz Clock
      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; // Set to 32kHz (No division)
      MXC_PWRSEQ->reg4 |= MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; // Route to P1.7
      Serial.println("4. 32.768 kHz Clock verified and routed.");
    
    
      // 5. Set Flow Control "Permission" (M4 RTS)
      // We must pull this LOW to tell the BLE module it's allowed to send data
      pinMode(M4_RTS_TO_BLE, OUTPUT);
      digitalWrite(M4_RTS_TO_BLE, LOW); 
      Serial.println("5. M4 RTS driven LOW (Permission to speak granted).");
    
      // 6. Execute Hardware Reset Pulse
      pinMode(BLE_SHUTDOWN_PIN, OUTPUT);
      digitalWrite(BLE_SHUTDOWN_PIN, LOW);
      delay(100); // Hold in reset
      digitalWrite(BLE_SHUTDOWN_PIN, HIGH);
      delay(600); // Wait for BLE firmware to boot
      
      // Initialize Serial1 (UART0)
      Serial1.begin(115200);
    
      Serial.println("6. Reset released. BLE module should be alive.");
      Serial.println("Type 'r' to send HCI_Reset command.");
    }
    
    void loop() {
      // Monitor the BLE Module's RTS pin (P0.3)
      static int lastRts = -1;
      int currentRts = digitalRead(BLE_RTS_TO_M4);
      if (currentRts != lastRts) {
        Serial.print("\n[BLE Module RTS: ");
        Serial.print(currentRts == LOW ? "LOW (Ready)" : "HIGH (Busy)");
        Serial.println("]");
        lastRts = currentRts;
      }
    
      // Handle PC Input
      if (Serial.available()) {
        delay(1);   // Short delay to buffer
        while (Serial.available()) {
          char c = Serial.read();
          if (c == 'r') {
            Serial.println("\r\n>>> Sending HCI_Reset (01 03 0C 00)...");
            uint8_t reset_cmd[] = {0x01, 0x03, 0x0C, 0x00};
            Serial1.write(reset_cmd, 4);
            //Serial1.flush();
          }
        }
      }
    
      // Handle BLE Response
      if (Serial1.available()) {
        delay(1);   // Short delay to buffer
        Serial.println(Serial1.available());      // Shows how many bytes received for debugging
          while (Serial1.available()) {
            byte b = Serial1.read();
            Serial.print("0x");
            if (b < 0x10) Serial.print("0");
            Serial.print(b, HEX);
            Serial.print(" ");
            
            // Success check: 0x04 is the start of an HCI Event packet
            if (b == 0x04) Serial.print("(HCI Event!) ");
          }
          Serial.println();
      }
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 1 month ago in reply to BigG

    The two things that jump out at me here is that you are using Serial1 while the module is on Serial0. Serial1 is in fact the same as Serial on the MAX32630FTHR. Also a lot of your setup is being redone and undone by the Serial0.being, so best do that after the 32KHz initialisation but before everything else.

    I must get that post written up about how to do it sooner rather than later. I was intending to include a bit about using HCI commands that did not than reset, but perhaps I should get out what I have and do that later. That or someone might do it for me so I don't need to. ;-)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 1 month ago in reply to Alistair

    LOL. That makes sense in so many ways (for Serial1 I was seeing a binary echo). So, I was misled by "variant.h".

    #define SERIAL_PORT_MONITOR         Serial
    #define SERIAL_PORT_HARDWARE        Serial
    #define SERIAL_PORT_HARDWARE1       Serial1
    #define SERIAL_PORT_HARDWARE2       Serial2
    #define SERIAL_PORT_HARDWARE3       Serial3
    #define SERIAL_PORT_HARDWARE_OPEN   Serial1
    #define SERIAL_PORT_HARDWARE_OPEN1  Serial2
    #define SERIAL_PORT_HARDWARE_OPEN2  Serial3

    While if I had checked "MXC_HardwareSerial.h" I may have spotted:

    extern MXC_HardwareSerial Serial0;
    extern MXC_HardwareSerial Serial1;
    extern MXC_HardwareSerial Serial2;
    extern void serialEventRun(void);
    

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 1 month ago in reply to Alistair

    That made all the difference and with a little tidy up and a few bug fixes, thanks to my AI secret agent, I got there in the end. I now get the magic sequence:

    <<< BLE Response (HEX): 04 0E 04 01 03 0C 00 



    #include <Arduino.h>
    #include "pwrseq_regs.h"
    #include "rtc_regs.h"
    #include "ioman_regs.h"
    #include "gpio_regs.h"
    
    // Define the correct Serial port based on your MXC_HardwareSerial.h discovery
    #define SerialBLE Serial0 
    
    // 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}; 
    
    void setup() {
      // Initialize Debug Serial (USB)
      Serial.begin(115200);
      while(!Serial);
      delay(500);
      Serial.println("\n--- PAN1326B Final Methodical Sketch ---");
    
      // Set 1.8V Logic for all Bluetooth UART pins
      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.");
    
      // 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...");
    }
    
    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);
        }
      }
    
      // Read and Print Module Response
      if (SerialBLE.available()) {
        // Wait briefly for the full packet to arrive
        delay(10); 
        Serial.print("<<< BLE Response (HEX): ");
        while (SerialBLE.available()) {
          byte b = SerialBLE.read();
          if (b < 0x10) Serial.print("0");
          Serial.print(b, HEX);
          Serial.print(" ");
        }
        Serial.println();
      }
    }

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 1 month ago in reply to BigG

    That indeed looks good. :-)

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • BigG
    BigG 1 month ago in reply to Alistair

    Thanks for your help.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Alistair
    Alistair 1 month ago in reply to BigG

    No problem. Happy to help. 

    • Cancel
    • Vote Up 0 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