BM78 Bluetooth Module – First glance

To enable interaction with the environment our project will need some kind of communication interface. After some research we decided to go with Bluetooth. A nice comparison can be seen in the video below starting at 8:20.

To summarize:

Tech.BandData RateTopologyPower
Phone
Support
Bluetooth2.4GHzup to
2MHz
Mesh
(w/ BT5)
Low
(BLE)
Yes
Thread2.4GHz250 kbpsMeshLowNo
WiFi2.4GHz,
5GHz
up to
1Gbps
Limited
mesh
High Yes
Z-WaveSub-GHz100kbpsMeshLowNo
ZigBee915MHz-2.4GHz250 kbpsMeshLowNo

After searching for a viable bluetooth module with BLE, Bluetooth 5 support and also classic SPP the BM78 module from Microchip came up. Full datasheet can be looked up at http://ww1.microchip.com/downloads/enDeviceDoc/60001380A.pdf.

Microchip also provides a prototyping/development HW https://www.microchip.com/DevelopmentTools/ProductDetails/BM-78-PICTAIL.

Basic wiring

The module needs at least the BAT_IN, GND, SW_BTN, P2_0, P2_4, EAN, UART_RX and UART_TX pins to be connected to a microcontroller in order it to be operational. A simple connection example:

Simple connection of BM78 module
SymbolTypeDescription
BAT_INPowerBattery Input (3.3V to 4.2V)
Main positive supply input
Connect to 10 uF (X5R/X7R) capacitor
SW_BTNDISoftware Button
H: Power On, L: Power Off
LDO33_OPowerInternal 3.3V LDO output,
can source no more than 50 mA
VDD_IOPowerI/O positive supply input.
Internal use only, N/C
LDO18_OPowerN/C
WAKEUPDIWakeup from Sleep mode
(active- low, internal pull-up)
PMODULO_OPowerN/C
P0_4DOStatus 1 indication pin / UART_TX_IND (DO)
P1_5DOStatus 2 indication pin.
P1_2/SCLDOI2C Clock
P1_3/SDADIOI2C Data
P1_7/CTSDIOUART CTS (by default not used)
P0_5DION/C
P0_0/RTSDIOUART RTS (by default not used)
P2_0DISystem configuration pin.
P2_4DISystem configuration pin.
EANDISystem configuration pin.
RTS_NDIModule reset (active-low, internal pull-up)
RXDDIUART data input
TXDDOUART data output
P3_1DIOConfigurable control or indication pin
(Internally pulled-up, if configured as an input)
Default: INQUIRY_CONTROL
P3_2DIOConfigurable control or indication pin
(Internally pulled-up, if configured as an input)
Default: DISCONNECT (DI)
P3_3DIOConfigurable control or indication pin
(Internally pulled-up, if configured as an input)
Default: UART_RX_IND (DI)
P3_4DIOConfigurable control or indication pin
(Internally pulled-up, if configured as an input)
Default: PAIRING_KEY
P3_6DIOConfigurable control or indication pin
(Internally pulled-up, if configured as an input)
Default: N/C
P3_7DIOConfigurable control or indication pin
(Internally pulled-up, if configured as an input)
Default: LOW_BATTERY_IND
LED1DOStatus LED, connect to LDO33_O
GNDPowerGround reference

The bolded symbols are necessary to operate the BM78 module. The striked-through will not be used un our examples, should not be used, or are only for internal use. The rest is optional. For details consult the datasheet mentioned above.

Operation

Operating the BM78 module is done over UART commands send to the module. The module response is an asynchronous event also over the same UART interface (http://ww1.microchip.com/downloads/en/DeviceDoc/IS1678S_UARTCommandSet_UserGuide.pdf).

UART Command Packet Format

By default the BM78 operates in so called Auto-Mode. This mode is meant to easily hook-up 2 BM78 modules and create a simple UART bridge between 2 devices using those same modules. For other applications the other, Manual-Mode, needs to be configured. This is the biggest obstacle when starting with this module. For this the module needs to be reconfigured in its flash memory. There are 2 ways how to achieve that. First is with the provided UI tool. This can be easily done if you are using the BM78 PICTAIL since it has a UART/USB converter and a USB interface. More you move to embedded devices you may not want to always integrate a UART/USB converter to “just” setup the BM78 module.

Configuring the BM78

After a lot of googling and lot of trying out we found out that the most feasible way is to make the configuration with the UI tool, export the configuration, transform it to C code and load it into our PIC project where it gets executed. I wrote a converter for for that: [TODO share link to repo]. The resulting C code looks like:

typedef struct {
    uint16_t address;  // Address
    uint8_t  length;   // Packet length
    uint8_t  data[32]; // Data (max. 32 bytes per packet)
} Flash32_t;

const Flash32_t BM78_configuration[48] = {
    0x0007, 0x03, {0x80,0x28,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, 0x000B, 0x20, {0x4E,0x75,0x6B,0x6C,0x65,0x61,0x72,0x20,
0x46,0x6F,0x6F,0x74,0x62,0x61,0x6C,0x6C,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //... };

To save memory we only record packets which needs to be changed. Thus the Flash32_t type.

After powering up the BM78 module it goes to a mode depending on the P2_0, P2_4 and EAN pin configuration:

P2_0P2_4EANOperation Mode
LowLowHighWrite FLASH
LowHighLowWrite EEPROM (Test-Mode)
HighHighLowNormal operation (Application-Mode)

We are considering here only the Flash variant BM78SPPx5MC2 here.

To switch between the Application-Mode and the Test-Mode we use the following:

void BM78_clear() {
// Clear any state neccessary
}

void BM78_reset(void) {
BM78_clear();
BM78_RST_N_SetLow(); // Set the reset pin low
__delay_ms(2); // A reset pulse must be greater than 1ms
BM78_RST_N_SetHigh(); // Pull the reset pin back up
}

void BM78_resetMode(void) { BM78_reset(); // Reset the device __delay_ms(100); // Wait a minimum of 24 seconds for mode to be detected } void BM78_resetToTestMode(void) { BM78.mode = BM78_MODE_TEST; BM78_power(false); __delay_ms(200); BM78_power(true); __delay_ms(200); BM78_reset(); __delay_ms(200); BM78_P2_0_SetLow(); BM78_P2_4_SetHigh(); BM78_EAN_SetLow(); BM78_resetMode(); } void BM78_resetToAppMode(void) { BM78.mode = BM78_MODE_INIT;
BM78_P2_0_SetHigh(); BM78_P2_4_SetHigh(); BM78_EAN_SetLow(); BM78_resetMode(); }

The program relies on the following pin configuration of the PIC:

BM78 relevant PIC PIN configuration

Notice the “Start High” configuration for BM78_P2_0, BM78_P2_4 and BM78_EAN putting the BM78 module into Application-Mode after powering up. The common “BM78_” prefix used in the pin names is a convention used further in the code.

Then we need to send the BM78_configuration array to the BM78 module over the UART interface. An implementation of that can be found in the MCLIB.

Prototyping with BM78-PICTAIL

BM78 PICTAIL

This board allows fast prototyping and finding stuff out missing or buried deep in the datasheets. IMHO you will have a very hard time starting with BM78 without this PICTAIL since I had to find a lot of stuff out by try-fail approach since not everything can be found in listed datasheets.

The most important 2 schematics is the module’s test interface:

BM78-PICTAIL Module Test Interface

There are other development boards where this one can be connected to via one if its connectors, but for simple BM78 development this one can be operated by its own.

Conclusion

It took me quite some time to figure out how to properly use this module working properly. Especially configuring the module from a PIC directly was a quite a pickle. See my MCLIB for the implementation of that. I will write another post detailing the communication between the BM78 module and a microcontroller.

Leave a Reply

Your email address will not be published. Required fields are marked *