This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Writing BLE Scan data to SD Card

Hi,

Right now I have a program on nRF52-DK (SDK 11) that scans for BLE adv packets, and transfers data from some specific addresses to PC through UART. Around every 10ms there is 30 bytes of new data to be transferred. In the current program, the UART transfer is within the same function that is called whenever there is a new BLE packet received. This program is running fine.

Now, I want to eliminate the UART->PC parts, and write to a SD card instead. While I'm waiting to receive the required hardware, I tried to look for SD card examples. So, here are what I found and my questions about the feasibility of what I'm trying to implement:

The closest example I found is from Jorgen in post1 . This is the ble_app_uart_fatfs, which combines the ble_uart example and the FATFS for SD card. The difference is that it's not for continuous writing to the file (data logging), as it closes the file at the end of the write. Again, based on Ole's answer in post2, it seems the better practice is to use f_sync after each f_write and leave the file open.

The main concern here is that as writing to the SD card might take a long time around 250-500 ms, what will happen to the BLE scan that needs to scan all the time and update data every 10ms. What I understand from Pawel's answer in post3 is that 

- FATFS is using SPI master in EasyDMA mode; so does that mean if BLE writes to Buffer1 and FATFS transfers Buffer2, SD card operation won't affect BLE scanning?

- we need to call FATFS API in the main context; My BLE scanning also starts from the main, but before any FATFS operation; and radio interrupt has the highest priority, so SD operation should not block the radio. Right?

- In post3 he says: "However, when there is a serial data transfer in the background (card read/write operation), higher priority interrupts should not affect SD communication (except the possible delay), as far as SPI driver interrupts are being handled." 

So, considering my application, what is this delay? If it's caused by the BLE scan, then that needs to run all the time. So will it block the SD operation? 

I'm not familiar with the fine details of the EasyDMA, but my assumption is that as it doesn't need the CPU, so probably CPU is free to do the scanning and when they are working on to different buffers (memory spaces), they should not block each other.

(I know that FATFS example is from SDK 12.2 and I need to move my code to at least 12.2 to use the example, but hopefully that shouldn't be a big deal).

  • Ok, so either my question was very easy or everyone was waiting to see what happens after implementation! Slight smile Here is a summary of what I have right now. Hope it can be useful for others + let me know your comments.

    1- I ported my program w/ UART from SDK 11 to SDK 12.3 using the template of ble_uart_app example, and everything worked fine.

    2- I tested the FATFS example from SDK 12.3 with this SD card interface/nRF52-DK and it worked. One issue that I noticed was that when the GND pin of the SDC was connected to the GND pin available on the header where VDD pin is, SDC mounting failed every now and then. Connecting the GND to above P0.25 solved the issue and mounting never failed again.

    3- I added the FATFS functions and files to my own program. Complied without error, but program was restarted whenever BLE scanning was called. It turned out the issue was using the NRF_LOG settings. I still have the UART in my code, and it seems NRF_LOG has an issue when used with UART. I noticed some posts that they can work together if we change some settings, but as the LOG was not important, I unchecked the NRF_LOG from sdk.config.h and the restart issue was solved. Let me know if you know an easy and straight forward way of using the NRF_LOG without facing this issue.

    4- I started testing with a few seconds between receiving BLE packets and using only one buffer to write. I decreased the packet intervals down to 500ms and still the data was written to SDC without any issue. I haven't precisely compared the packet loss with and without write to SDC, but looking at the counter in the packets, the error rates seems to be close to each other. This means so far the SDC interface is not blocking the BLE. Buffer size was changed between hundred bytes to 10 Kbyte. File was open before starting the scan, f_sync used after f_open and f_write, write performed in main.

    5- For msec intervals, the 2 buffer approach was implemented. Same results, and to verify the code, I toggled 3 pins as follows:

    Pin 1: Toggle to 1 and then 0 at the start/end BLE handler when an address match is detected.

    Pin 2: Toggle to 1 and 0 at the start/end of the flag check that writes to SDC when any buffer is full.

    Pin 4: SDC Clk used, 8 MHz here.

    - Writes to SDC needs different times (2nd trace) in each write, although buffer size is the same 

    - Still receiving BLE packets (1st trace) while the buffer is being written to SDC 

    - No SDC Clock (3rd trace) while running the code in the BLE handler (1st trace)

    - SDC clocked (3rd trace) even while running the code in the BLE handler (1st trace)

Related