Seeed XIAO BLE

Posted on
  • Just wanted to mention that Seeed Studio put an NRF52840 in the XIAO form factor:

    https://www.seeedstudio.com/Seeed-XIAO-BLE-nRF52840-p-5201.html

    Would be a good stopgap until we finally get an official MDBT50Q breakout with Espruino programmed in, if only it's in stock :P

  • ZigBee module ?

    this could be a game changer.
    how many ZigBee compatible MCUs are out there?

  • An Espruino build for this board would be really cool. The IMU is the same as in the Puck and there's also a flash chip!!
    As a Bangle.js 2 owner, I'm also very intrigued by the concept of having a file system on the SPI flash that can be accessed via BLE through the web IDE. This would enable really cool data logging options on the simpler, cheaper espruino boards.
    Is this hard to implement? You'd require some kind of simplified, stripped-down build of Bangle.js 2 or is there a simpler way?
    In this context I also thought about spinning my own Puck PCB with the MDBT42 and for example a GD25Q16 flash chip, since I have some laying around here.

  • The Storage module on external flash is independent of Bangle.js, so actually it should be pretty easy to get it running on the XIAO. The IMU isn't independent of Puck.js though, so I guess you'd have to make a modified Puck.js build for it - even so, it wouldn't be a huge deal

  • I have a build working based of the NRF52840DK.py and changing the console to bluetooth.

    Any thoughts or points on how to get the console going on the built in USB as a serial device?

    I have tried the 'EV_USBSERIAL' without any luck, is that working on any of the other nRF52840 boards?

  • yes, works for me on nrf52840 dongle and also Particle XENON, there is no special trick except this line https://gist.github.com/fanoush/c081c1d7c8eb2a4562785bbb684f661e#file-nrf52840dongle-py-L43 which is in NRF52840DK board file too.

  • I finally got a couple of these and found the time to look into making a board file.

    1. #!/bin/false
    2. # This file is part of Espruino, a JavaScript interpreter for Microcontrollers
    3. #
    4. # Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
    5. #
    6. # This Source Code Form is subject to the terms of the Mozilla Public
    7. # License, v. 2.0. If a copy of the MPL was not distributed with this
    8. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
    9. #
    10. # ----------------------------------------------------------------------------------------
    11. # This file contains information for a specific board - the available pins, and where LEDs,
    12. # Buttons, and other in-built peripherals are. It is used to build documentation as well
    13. # as various source and header files for Espruino.
    14. # ----------------------------------------------------------------------------------------
    15. '''
    16. source ./scripts/provision.sh ALL
    17. rm bin/*.hex
    18. make clean && BOARD=XIAOBLE RELEASE=1 make
    19. uf2conv.py ./bin/*.hex -c -f 0xADA52840
    20. mv flash.uf2 ~/Desktop/
    21. '''
    22. import pinutils;
    23. info = {
    24. 'name' : "Seeed Xiao BLE",
    25. 'link' : [ "https://www.seeedstudio.com/Seeed-XIAO-BLE-nRF52840-p-5201.html" ],
    26. 'default_console' : "EV_SERIAL1",
    27. 'default_console_tx' : "D6",
    28. 'default_console_rx' : "D7",
    29. 'default_console_baudrate' : "9600",
    30. 'variables' : 14000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
    31. # 'bootloader' : 1,
    32. 'binary_name' : 'espruino_%v_xiaoble.hex',
    33. 'build' : {
    34. 'optimizeflags' : '-Os',
    35. 'libraries' : [
    36. 'BLUETOOTH',
    37. # 'NET',
    38. 'GRAPHICS',
    39. # 'NFC',
    40. 'NEOPIXEL',
    41. 'JIT',
    42. ],
    43. 'makefile' : [
    44. 'DEFINES += -DCONFIG_GPIO_AS_PINRESET', # Allow the reset pin to work
    45. 'DEFINES += -DNRF_USB=1 -DUSB',
    46. 'DEFINES += -DNEOPIXEL_SCK_PIN=33 -DNEOPIXEL_LRCK_PIN=34', # nRF52840 needs LRCK pin defined for neopixel
    47. 'DEFINES += -DBLUETOOTH_NAME_PREFIX=\'"XIAOBLE"\'',
    48. 'DEFINES += -DSPIFLASH_READ2X', # Read SPI flash at 2x speed using MISO and MOSI for IO
    49. 'DEFINES += -DESPR_UNICODE_SUPPORT=1',
    50. 'NRF_SDK15=1',
    51. ]
    52. }
    53. };
    54. chip = {
    55. 'part' : "NRF52840",
    56. 'family' : "NRF52",
    57. 'package' : "AQFN73",
    58. 'ram' : 256,
    59. 'flash' : 1024,
    60. 'speed' : 64,
    61. 'usart' : 1,
    62. 'spi' : 1,
    63. 'i2c' : 2,
    64. 'adc' : 1,
    65. 'dac' : 0,
    66. 'saved_code' : {
    67. 'address' : ((0xf4 - 2 - 96) * 4096), # Bootloader at 0xF4000
    68. 'page_size' : 4096,
    69. 'pages' : 96,
    70. 'flash_available' : 1024 - ((0x26 + 0x20 + 2 + 96)*4) # Softdevice 140 uses 38 pages of flash, bootloader 8, FS 2, code 10. Each page is 4 kb.
    71. },
    72. };
    73. devices = {
    74. 'LED1' : { 'pin' : 'H0' }, # Pin negated in software
    75. 'LED2' : { 'pin' : 'H1' }, # Pin negated in software
    76. 'LED3' : { 'pin' : 'H2' }, # Pin negated in software
    77. # Pin D33 and D34 are used for clock when driving neopixels - as not specifying a pin seems to break things
    78. 'SPIFLASH' : {
    79. 'pin_cs' : 'H25',
    80. 'pin_sck' : 'H21',
    81. 'pin_mosi' : 'H20',
    82. 'pin_miso' : 'H24',
    83. 'pin_wp' : 'H22',
    84. 'pin_rst' : 'H23',
    85. 'size' : 4096*512, # 2MB
    86. 'memmap_base' : 0x60000000 # map into the address space (in software)
    87. }
    88. };
    89. # left-right, or top-bottom order
    90. board = {
    91. };
    92. # schematic at https://files.seeedstudio.com/wiki/XIAO-BLE/Seeed-Studio-XIAO-nRF52840-Sense-v1.1.pdf
    93. def get_pins():
    94. pins = [
    95. { "name":"PD0", "sortingname":"D00", "port":"D", "num":"2", "functions":{}, "csv":{} },
    96. { "name":"PD1", "sortingname":"D01", "port":"D", "num":"3", "functions":{}, "csv":{} },
    97. { "name":"PD2", "sortingname":"D02", "port":"D", "num":"28", "functions":{}, "csv":{} },
    98. { "name":"PD3", "sortingname":"D03", "port":"D", "num":"29", "functions":{}, "csv":{} },
    99. { "name":"PD4", "sortingname":"D04", "port":"D", "num":"4", "functions":{}, "csv":{} },
    100. { "name":"PD5", "sortingname":"D05", "port":"D", "num":"5", "functions":{}, "csv":{} },
    101. { "name":"PD6", "sortingname":"D06", "port":"D", "num":"43", "functions":{}, "csv":{} },
    102. { "name":"PD7", "sortingname":"D07", "port":"D", "num":"44", "functions":{}, "csv":{} },
    103. { "name":"PD8", "sortingname":"D08", "port":"D", "num":"45", "functions":{}, "csv":{} },
    104. { "name":"PD9", "sortingname":"D09", "port":"D", "num":"46", "functions":{}, "csv":{} },
    105. { "name":"PD10", "sortingname":"D10", "port":"D", "num":"47", "functions":{}, "csv":{} },
    106. { "name":"PA0", "sortingname":"A00", "port":"A", "num":"2", "functions":{ "ADC1_IN0":0 }, "csv":{} },
    107. { "name":"PA1", "sortingname":"A01", "port":"A", "num":"3", "functions":{ "ADC1_IN1":0 }, "csv":{} },
    108. { "name":"PA2", "sortingname":"A02", "port":"A", "num":"28", "functions":{ "ADC1_IN2":0 }, "csv":{} },
    109. { "name":"PA3", "sortingname":"A03", "port":"A", "num":"29", "functions":{ "ADC1_IN3":0 }, "csv":{} },
    110. { "name":"PA4", "sortingname":"A04", "port":"A", "num":"4", "functions":{ "ADC1_IN4":0 }, "csv":{} },
    111. { "name":"PA5", "sortingname":"A05", "port":"A", "num":"5", "functions":{ "ADC1_IN5":0 }, "csv":{} },
    112. { "name":"PH0", "sortingname":"H0", "port":"H", "num":"26", "functions":{"NEGATED":0}, "csv":{} }, # LED1
    113. { "name":"PH1", "sortingname":"H1", "port":"H", "num":"30", "functions":{"NEGATED":0}, "csv":{} }, # LED2
    114. { "name":"PH2", "sortingname":"H2", "port":"H", "num":"6", "functions":{"NEGATED":0}, "csv":{} }, # LED3
    115. { "name":"PH25", "sortingname":"H25", "port":"H", "num":"25", "functions":{}, "csv":{} },
    116. { "name":"PH21", "sortingname":"H21", "port":"H", "num":"21", "functions":{}, "csv":{} },
    117. { "name":"PH20", "sortingname":"H20", "port":"H", "num":"20", "functions":{}, "csv":{} },
    118. { "name":"PH24", "sortingname":"H24", "port":"H", "num":"24", "functions":{}, "csv":{} },
    119. { "name":"PH22", "sortingname":"H22", "port":"H", "num":"22", "functions":{}, "csv":{} },
    120. { "name":"PH23", "sortingname":"H23", "port":"H", "num":"23", "functions":{}, "csv":{} },
    121. ];
    122. # everything is non-5v tolerant
    123. for pin in pins:
    124. pin["functions"]["3.3"]=0;
    125. return pins

    not all pin assignments are implemented yet (especially on the sense version the IMU and the mic) but everything works so far. The QSPI flash is also connected although I'm not really sure how to test if the entirety of the flash is usable.

    It's also compatible with the built-in adafruit bootloader, so if you use the u2conv.py script you can create a uf2 file you can just drag and drop onto the xiao ble to flash espruino on it (no need for SWD).


    1 Attachment

  • Update: I also just tested out EV_USBSERIAL as mentioned by fanoush above, and it works well on the Web IDE (you'll need to choose Web Serial and look for the nRF CDC serial device).

    Although I really still prefer the wireless BT console :P

  • Those H pins are quite unusual for nrf52, but if they work for you ...
    nrf52 uses just Dnum as all pins except analog are universal, there are no letter named ports like on stm32.

  • Ah I didn't know that was the case :D I thought H was just a way to differentiate unexposed pins (vs D which are exposed).

    They do work though, and I guess it's somewhat an advantage that a user doesn't get to accidentally configure a pin that they're not supposed to change (like those for QSPI for example). Or would there be any issues with using non-existent ports?

  • I've experimented a bit more and yeah, the extra H port is messing up some of the pins that Espruino expects are contiguous.

    I"ve since made a board def that's a lot simpler.

    1. #!/bin/false
    2. # This file is part of Espruino, a JavaScript interpreter for Microcontrollers
    3. #
    4. # Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
    5. #
    6. # This Source Code Form is subject to the terms of the Mozilla Public
    7. # License, v. 2.0. If a copy of the MPL was not distributed with this
    8. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
    9. #
    10. # ----------------------------------------------------------------------------------------
    11. # This file contains information for a specific board - the available pins, and where LEDs,
    12. # Buttons, and other in-built peripherals are. It is used to build documentation as well
    13. # as various source and header files for Espruino.
    14. # ----------------------------------------------------------------------------------------
    15. """
    16. source ./scripts/provision.sh ALL
    17. rm bin/*.hex
    18. make clean && BOARD=XIAOBLE RELEASE=1 make
    19. uf2conv.py ./bin/*.hex -c -f 0xADA52840
    20. mv flash.uf2 ~/Desktop/
    21. """
    22. import pinutils
    23. info = {
    24. "name": "Seeed Xiao BLE",
    25. "link": ["https://www.seeedstudio.com/Seeed-XIAO-BLE-nRF52840-p-5201.html"],
    26. "default_console": "EV_USBSERIAL",
    27. # 'default_console' : "EV_SERIAL1",
    28. # 'default_console_tx' : "D6",
    29. # 'default_console_rx' : "D7",
    30. # 'default_console_baudrate' : "9600",
    31. "variables": 14000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
    32. # 'bootloader' : 1,
    33. "binary_name": "espruino_%v_xiaoble.hex",
    34. "build": {
    35. "optimizeflags": "-Os",
    36. "libraries": [
    37. "BLUETOOTH",
    38. # 'NET',
    39. "GRAPHICS",
    40. # 'NFC',
    41. "NEOPIXEL",
    42. "JIT",
    43. ],
    44. "makefile": [
    45. "DEFINES += -DESPR_LSE_ENABLE", # Ensure low speed external osc enabled
    46. "DEFINES += -DCONFIG_GPIO_AS_PINRESET", # Allow the reset pin to work
    47. "DEFINES += -DNRF_USB=1 -DUSB",
    48. "DEFINES += -DNEOPIXEL_SCK_PIN=33 -DNEOPIXEL_LRCK_PIN=34", # nRF52840 needs LRCK pin defined for neopixel
    49. "DEFINES += -DBLUETOOTH_NAME_PREFIX='\"XIAOBLE\"'",
    50. "DEFINES += -DSPIFLASH_READ2X", # Read SPI flash at 2x speed using MISO and MOSI for IO
    51. "DEFINES += -DESPR_UNICODE_SUPPORT=1",
    52. "DEFINES += -DNRF_SDH_BLE_GATT_MAX_MTU_SIZE=131", # 23+x*27 rule as per https://devzone.nordicsemi.com/f/nordic-q-a/44825/ios-mtu-size-why-only-185-bytes
    53. # 'DEFINES += -DPIN_NAMES_DIRECT=1', # Package skips out some pins, so we can't assume each port starts from 0
    54. "LDFLAGS += -Xlinker --defsym=LD_APP_RAM_BASE=0x2ec0", # set RAM base to match MTU
    55. "NRF_SDK15=1",
    56. ],
    57. },
    58. }
    59. chip = {
    60. "part": "NRF52840",
    61. "family": "NRF52",
    62. "package": "AQFN73",
    63. "ram": 256,
    64. "flash": 1024,
    65. "speed": 64,
    66. "usart": 1,
    67. "spi": 1,
    68. "i2c": 2,
    69. "adc": 1,
    70. "dac": 0,
    71. "saved_code": {
    72. "address": ((0xF4 - 2 - 96) * 4096), # Bootloader at 0xF4000
    73. "page_size": 4096,
    74. "pages": 96,
    75. "flash_available": 1024
    76. - (
    77. (0x26 + 0x20 + 2 + 96) * 4
    78. ), # Softdevice 140 uses 38 pages of flash, bootloader 8, FS 2, code 10. Each page is 4 kb.
    79. },
    80. }
    81. devices = {
    82. "LED1": {"pin": "D26"}, # Pin negated in software
    83. "LED2": {"pin": "D30"}, # Pin negated in software
    84. "LED3": {"pin": "D6"}, # Pin negated in software
    85. # Pin D33 and D34 are used for clock when driving neopixels - as not specifying a pin seems to break things
    86. "BAT": {
    87. "pin_charging": "D17", # active low
    88. "pin_voltage": "D31",
    89. },
    90. "NFC": {"pin_a": "D9", "pin_b": "D10"},
    91. "SPIFLASH": {
    92. "pin_cs": "D25",
    93. "pin_sck": "D21",
    94. "pin_mosi": "D20",
    95. "pin_miso": "D24",
    96. "pin_wp": "D22",
    97. "pin_rst": "D23",
    98. "size": 4096 * 512, # 2MB
    99. "memmap_base": 0x60000000, # map into the address space (in software)
    100. },
    101. }
    102. # left-right, or top-bottom order
    103. board = {}
    104. # schematic at https://files.seeedstudio.com/wiki/XIAO-BLE/Seeed-Studio-XIAO-nRF52840-Sense-v1.1.pdf
    105. # pinout sheet https://files.seeedstudio.com/wiki/XIAO-BLE/XIAO-nRF52840-pinout_sheet.xlsx
    106. # see also https://github.com/Seeed-Studio/Adafruit_nRF52_Arduino/blob/master/variants/Seeed_XIAO_nRF52840/variant.h
    107. def get_pins():
    108. pins = pinutils.generate_pins(0, 47) # 48 General Purpose I/O Pins.
    109. pinutils.findpin(pins, "PD2", True)["functions"]["ADC1_IN0"] = 0
    110. pinutils.findpin(pins, "PD3", True)["functions"]["ADC1_IN1"] = 0
    111. pinutils.findpin(pins, "PD4", True)["functions"]["ADC1_IN2"] = 0
    112. pinutils.findpin(pins, "PD5", True)["functions"]["ADC1_IN3"] = 0
    113. pinutils.findpin(pins, "PD9", True)["functions"]["NFC1"] = 0
    114. pinutils.findpin(pins, "PD10", True)["functions"]["NFC2"] = 0
    115. pinutils.findpin(pins, "PD17", True)["functions"]["NEGATED"] = 0
    116. pinutils.findpin(pins, "PD26", True)["functions"]["NEGATED"]=0;
    117. pinutils.findpin(pins, "PD28", True)["functions"]["ADC1_IN4"] = 0
    118. pinutils.findpin(pins, "PD29", True)["functions"]["ADC1_IN5"] = 0
    119. pinutils.findpin(pins, "PD31", True)["functions"]["ADC1_IN7"] = 0
    120. # D13 PIN_CHARGING_CURRENT
    121. # battery charging current see https://wiki.seeedstudio.com/XIAO_BLE/#battery-charging-current
    122. # HIGH: 100mA, LOW: 50mA
    123. # D14 VBAT_ENABLE
    124. # enable battery voltage reading by digitalWrite(D14, false)
    125. # D17 CHG
    126. # get charge state via digitalRead(D17)
    127. # HIGHT: not charging, LOW: charging
    128. # D31 PIN_VBAT
    129. # everything is non-5v tolerant
    130. for pin in pins:
    131. pin["functions"]["3.3"] = 0
    132. return pins

    1 Attachment

  • I've just started playing with one of these - and this works well, I'm running over the Bluetooth serial console, and the upload as uf2 is nice and fast.
    I've connected it with a Seeed Round display before I dig too far, I wondered if anyone else had used this combo already.
    I got (slightly) excited when I saw that the screen controller GC9A01 was in the codebase, but (I think) it's only compiled into the jswrap_bangle.c file and not available to a base Espruino build as a js module, and I couldn't see a compatible module already to use.
    I did briefly try a tweaked bangle build, but unsurprisingly, that just created a screen of random garbage and appeared to freeze on boot so decided to leave that for now, although I think that might be just because I'm still using the AdaFruit uf2 bootloader and I should switch to the full bangle build.

    So, before I go any further, just wanted to ask/see if anyone had done this combination already - I assume I just need to create a new js module probably based on https://www.espruino.com/modules/ST7789.js

    I was planning on printing a custom case and hooking up two buttons to the NFC pins so I think this would work pretty well with a bangle build.

  • brilliant @fanoush thanks, that's a great starting point... still no picture but getting there.

  • Great, progress. Thanks. Right, next to get some programs up and running.


    1 Attachment

    • 20240903_195924.jpg
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
    • $ Donate
About

Seeed XIAO BLE

Posted by Avatar for parasquid @parasquid

Actions