UNABLE TO PROGRAM PIC32 DUE TO FLASH ERROR: "Program memory is not blank"

edited August 2022 in Build-it-yourself

My Cyton board is fully assembled and while I had a major victory with getting the RFDuinos to work (which was documented on another thread), that was rather shortlived. The next major issue involved having to program the chip PIC32MX250F128B. Since I assembled the board from scratch, it's obvious that the PIC would be blank or have a minimal factory bootloader, nothing which would allow it to communicate with Arduino or be programmed OTA via the RFDuinos. So, I knew I had to flash the PIC and found the requisite bootloader UDB32_MX2_DIP.hex on one of the OpenBCI github links (will have to post that later).

NOTE: The chipKIT github hosts a relatively newer version of UDB32_MX2_DIP.hex (~189 kB) which has been compiled by a newer version of MPLAB, but for some reason, the new one is NOT recognized as a valid firmware by their own IDE or IPE when you attempt to import or load the hex for flashing. Strange, I know.. but just thought I should mention this, incase someone experiences the same issue. Anyway, I stuck with the older version of the bootloader provided here on OBCI's Github archive (which is only ~8kb)
.
Next: Opened MPLAB IPE v4.15 (I havent installed their more recent v5+/v6+ versions, in the interest of saving space on my drive). Set the ICSP option to "Power Target Circuit from Tool" and then clicked Connect. PICKit3 detected the PIC32 chip successfully and this was the initial log output:

    Connecting to MPLAB PICkit 3...

    Currently loaded firmware on PICkit 3
    Firmware Suite Version.....01.51.08
    Firmware type..............PIC32MX

    Programmer to target power is enabled - VDD = 3.300000 volts.
    Target device PIC32MX250F128B found.
    Device ID Revision = A1

I loaded the working version of the UDB32_MX2_DIP.hex bootloader and was able to burn it successfully to the chip using PICKit3, that went well. The blue LED started blinking gleefully, so I knew it was ready to accept new code. So far, so good!
.
Next, I attempted to upload the DefaultBoard sketch to the PIC from within Arduino. I figured that since the bootloader was already flashed, it should be able to accept the firmware OTA, so I switched the Port# to that of the Dongle (which had already been flashed with RadioHost32.hex by now). The compilation was successful, however the upload failed. Please see the error as displayed below:

.
Out of curiosity, I decided to see what would happen if I flashed the PIC with a blank sketch instead, and lo & behold, that was flashed successfully to the PIC! (see below):

Coming back to the Cyton firmware: I tried uploading DefaultBoard several times, checked all the wiring, brought the RFDuinos closer to each other, etc.. but nothing helps. Btw, I've already read through this entire detailed thread for clues but none of the tips have worked for me at all: chipKIT uploading tips & restarting bootloader

.
Finally, I abandoned the Arduino-RFDuino-PIC route and decided to flash the firmware directly using PICkit itself. Copied the compiled DefaultBoard.ino.hex file from the Temp folder and placed it in a more convenient location. Loaded the DefaultBoard firmware hex into IPE, clicked Program and this is the error that results:

.
When I try to Erase the chip and do a Blank Check immediately after, the blank check fails with a similar error:

Blank Checking...
Program memory is not blank.
Blank check complete, device is not blank.

Seems to be an issue with writing to the chip's Flash starting from memory address 0x1d010000 onwards, I deduced this after running Verify.. this was the result:

Verifying...

The following memory areas(s) will be verified:
program memory: start address = 0x1d000000, end address = 0x1d01ffff
boot config memory
configuration memory

program memory
Address: 1d010000 Expected Value: 10600028 Received Value: 0
Verify failed

I do suspect that this Program Flash region is being write-protected, so is there a specific #pragma or predirective that needs to be specified in the code in order to disable the chip's protection scheme?

I also read on another forum that one person was able to get past this error by programming the PIC in Low-Voltage mode, while they weren't able to do so in regular mode. But I dont see anything specific about LVP mentioned in this PIC32's datasheet, does anyone have any information or clues to this??

.
Tagging @wjcroft , @Shirley , @retiutut for any help & guidance in this matter

Comments

  • wjcroftwjcroft Mount Shasta, CA

    Sent you an email along with one of the OpenBCI engineers most familiar with flashing issues.

  • Okay great, thank you William! Looking forward to hearing from Ioannis, hopefully soon..

  • @wjcroft: Is there another way to get in touch with Ioannis? Or if there's anyone else on the team who might be familiar with this error? It's been more than a month since I've been facing this issue and my progress with the Cyton board has been totally stalled due to this.

  • Months later and this issue has only been partially resolved by replacing the PIC32 chip on the board with a new one that I sourced from another supplier. I am now able to burn the bootloader with MPLAB IPE, followed by the PIC code via Arduino (v1.8.12) successfully. However, when testing the board with OBCI GUI, I am not receiving any data at all from the board. When I check the Raw log file, only the initial header is present but no data has been recorded at all. Finally, even if I attempt to send any of the board commands via the Serial Monitor, I do not receive any responses back from the board. From the point of construction, the Cyton board is completely done now.. but I'm gonna need some tips & pointers on how to troubleshoot this lack of data stream.

    Calling @wjcroft & @retiutut : How do I even begin to debug this board??

  • wjcroftwjcroft Mount Shasta, CA

    How do you know that the usb serial port data flow from the laptop to the Cyton (and back) is working properly? You mentioned the RFduinos are working here?

    https://openbci.com/forum/index.php?p=/discussion/comment/18091/#Comment_18091

    Perhaps one way to debug is to upload a tiny 'echo' program to the PIC32 that echoes back what it receives on the serial port. Then see if you can verify the full path working.

    It's also possible that your radio channels on the two RFduino's are not aligned. There is an AUTOSCAN feature built into the GUI, that realigns the radio channels, if not matching. This feature only uses the serial port commands unique to the RFduinos. Those commands are not seen by the PIC32.

    William

  • edited January 2023

    Hi William, yes I'm sure that the radios are working perfectly fine because they are able to detect and communicate well with each other over Serial COM3. Within the GUI v4+, the Radio Config Status shows 'Success: System is Up' and clicking Get Channel yields: Host & Device are on Channel 20. However, once I attempt to start the Cyton LIVE session, it fails and then displays an Init error in the status bar, as seen here:

    I suspect that there is the PIC is not communicating with its RFDuino properly, there's certainly a lack of data flow. Your suggestion to test the PIC with an echo program sounds good, but I'm not proficient in coding for PIC32. So, if you could share any code examples or test programs that are used by your OBCI staff to test the Cyton boards, that would be most helpful, thank you!

  • wjcroftwjcroft Mount Shasta, CA

    You do not have to code in PIC assembler. Just make a tiny Arduino program loop. Or modify the default program. Check the code to see how the serial port functions read and write the RFduino port. If you have a scope you could check the mainboard RFduino serial transmit pin to confirm that it is reaching the PIC serial receive pin. And conversely if the PIC transmit serial is reaching the RFduino receive pin. You can also do continuity checks on these routes with a simple ohmmeter.

  • Thanks for the suggestions, @wjcroft! So here's what I did.. I wondered if I could use any of the Debug examples that came with the OpenBCI library instead of having to write it . So, I settled for the BoardNoAccepSDWifiDebug example and made a tiny modification to it, just so I could see if there was a change in streaming status. Also, I realized that instead of having to feed my Cyton board with an external signal, I could use its own internal signal commands to see if the board was able to detect or stream the test signal. Please see this screenshot, where I entered the displayed commands in sequence and got the following responses:

    So, as you can see here, my initial assumption about the lack of communication between the PIC and RFduino was wrong. There is indeed sufficient communication occurring between the two, otherwise I wouldn't be able to upload to the PIC OTA via Arduino and the dongle.. and I am able to print to the Serial port as well (visible on the Serial Monitor, but this is obviously for debug purposes only). The problem seems to between the PIC and the ADC, or rather, there is a lack of data streaming. I mean, the PIC does seem to be reading the ADS' device ID# correctly (although the LIS3DH shows 0x00). But either way, there is no streaming of actual/analog data happening at all, whether it's with the internal test signals or external inputs. Is there something I'm missing here when it comes to using the internal test signal correctly??

    Also, the line I added to display any Change in Status does indicate the the board.loop is running. But it's as if the PIC is not receiving ANY of the ADC data at all, not even 0's.

  • @wjcroft & @retiutut : Guys, I'd really appreciate some help here. The problem I'm facing seems to be the lack of data flow from the ADS to the PIC32. I made a few temporary modifications to the Cyton library files (merely changed the declaration of a few ADS-related variables to public instead of private) and added a simple function to display the status of those ADS variables once the board is initialized and starts streaming. Please see this screenshot:

    As you can see here, even after the board loop has started, the variables iADSDataAvailable remains 0 (when it should be 1) and the DRDYpinValue remains 1 (when it ought to drop to 0) whenever there is EEG data available from the ADS. I've inspected the ADS1299 on the board and I cant spot any issues with how I'd soldered it. Oh and this is after I configured the board to use the ADS' internal test signal generation, so at the very least, it ought to show SOME data but I'm not even seeing a stream of zeros from this thing. Is there ANY other way I can debug the ADS directly and see if it is capturing any internal/analog signals at all??

    PS: I've been trying to troubleshoot this board's issues for the past few months now, and every time it feels like I'm SO close and yet so far!

  • wjcroftwjcroft Mount Shasta, CA

    Do you have some type of oscilloscope there? Is there any way to check if the ADS1299 is generating a clock signal on the 'CLK' pin? (Present both on the chip and on the Daisy board connector.) It sounds like the ADS is responding to SPI bus transactions. But is just not generating samples. I would start to suspect a bad chip. Or chip damaged by potential static discharge.

    Regards,

  • Yes William, I do have one of those small handheld oscilloscopes. I'm not seeing a clock signal on the CLK pin, although I am seeing a clock stream on the SCLK pin. However, the average voltage level at SCLK is rather small, like just around 120 mV or so (peak 2 peak). But that clock signal is coming directly from the Xtal circuit via the PIC32, so I'm assuming that this is fine as of now?

    Regarding the CLK pin, is the clock signal supposed to be present constantly once the board is powered up, or only after the ADS is started with the Begin command? Also, what's the frequency and average voltage range of the clock signal I should expect to see at CLK??

  • @teknomage is your issue solved?
    I'm also trying to build cyton from scratch.
    could you please provide your BOM where you mentioned that you have replaced some components on your own.
    thank you!

  • No, the issue hasnt been resolved. Save yourself the unnecessary hassle, unless you really want to assemble the board from scratch just for your own knowledge and experience. IMO, it's not worth the trouble, just buy the Cyton board directly, or you can get it cheaper on eBay.

  • @teknomage did you give up?
    or still trying to figure out the issue...
    I have a lot of hopes on this (making from scratch & then an application).
    thank you for the reply and time!

  • I did almost give up, but finally succeeded in getting my Cyton to work. Took a break from messing with the board for a couple of months, but then got back to it with a fresh pair of eyes. As stated earlier, the main issue was that, even though the Cyton was responding to commands, it was not streaming actual data from the ADS1299. There was no issue with the clock stream on the CLK pin but I decided to take a closer look at the DRDY pin and inspect the signals there. To do this, I temporarily soldered a wire on pin# 47 of the ADS and hooked it up to my handheld DSO. Check out the modification and the pulse waveforms captured here:

    So initially, when the Cyton is idle and not streaming at all, you will only see a flat DC line on the DRDY pin, like this:

    But once I issue the 'b' command to begin streaming (or simply click Start Streaming inside the OBCI GUI), then you will see a pulse on the pin. However, what I was seeing was not the right kind of pulse (which indicates that data was not being outputted correctly), it was just a short spike like this:

    I corrected the problem by briefly injecting / shorting the DRDY pin to Vcc (just momentarily), and then the ADS started working properly. The pulse waveform was corrected as well, as you can see here:

    So, the ADS data started streaming to Serial COM via the RFduino, as it is should have. You can see the ASCII characters corresponding to the ADS data being displayed on the Serial Monitor in the background here:

    Next, to test the viability of the Cyton board, I used my heartbeat / ECG as the test signal source and tested out the channels one-by-one. Check it out, this is a composite picture of the channels tested on my board:

    As you can see from the image above, Channel #3 is currently dead. But I'm sure this is due to either a loose connection or a shorting on one of the components connected to the terminal of chann#3. So, that's the next order of business, to troubleshoot that particular channel.. and once I have that resolved, I will have a fully-functional, 8-channel Cyton board :)

  • great to hear this from you @teknomage
    could you please drop down your BOM & some details on how you ordered PCB, components etc.,
    I gave up on making cyton from scratch but suddenly you have given me hope :smiley:
    Thank you so much for your time

  • edited July 2023

    UPDATE: Channel# 3 has been fixed, turned out to be a simple short between the legs of the input quad TVS/diode for that particular channel. All 8 channels of my Cyton board are working perfectly now.

    @bharadwaj_Sudula : I used the very same Cyton v3 BOM and gerbers that have been provided here on OpenBCI's website. I made only a couple of changes in the PCB labels that were purely cosmetic in nature. Components were obtained from a chinese supplier via Alibaba but they're not currently operational.. and in any case, I wouldn't recommend them to anyone at all because a few of the crucial components they sent me turned out to be complete duds including one of the PICs, and I wasted MONTHS trying to figure out what went wrong! I suggest you do your own research and find a reliable local supplier that can source the parts you need. And just to remind you, some of the original components listed in Cyton's BOM are either obsolete or EOL, no longer available. So, you'll have to find your own alternatives. Take it from me, I still think it's better you buy the pre-soldered board from the OBCI store itself, just to save yourself the entire hassle.

    @wjcroft : Hi William, got a quick question about the Cyton's reference terminals. From the Cyton board, I can see that the both the BIAS pins are connected or tied to each other, but the SRB pins are not shorted to each other at all. This might seem like a noob query, but what would be the point of having separate SRB/reference pins like this.. does each SRB pin work as a separate reference for that particular row of inputs? i.e., is SRB1 meant for the pins on the top row and SRB2 for the bottom row?

    I have further questions about the 16-channel Cyton+Daisy setup that's described in the 'Getting Started' guide, specifically regarding the bottom SRB pins being ganged on the Cyton and Daisy. In this case, what's to be done with the SRB pins on the top rows of each board, are they to be simply ignored/NC??

  • wjcroftwjcroft Mount Shasta, CA

    @teknomage said:
    ...
    @wjcroft : Hi William, got a quick question about the Cyton's reference terminals. From the Cyton board, I can see that the both the BIAS pins are connected or tied to each other, but the SRB pins are not shorted to each other at all. This might seem like a noob query, but what would be the point of having separate SRB/reference pins like this.. does each SRB pin work as a separate reference for that particular row of inputs? i.e., is SRB1 meant for the pins on the top row and SRB2 for the bottom row?

    That is 'sort of' true. For complete explanation please see the ADS1299 data sheet. In the default configuration SRB2 acts as common reference bus, connecting all the INP[1-8] top row pins as reference. It also allows more flexibility in managing the on/off status of various hardware registers in the ADS1299. Using SRB1 as reference (bussing the bottom row pins) does not have the same advantages.

    I have further questions about the 16-channel Cyton+Daisy setup that's described in the 'Getting Started' guide, specifically regarding the bottom SRB pins being ganged on the Cyton and Daisy. In this case, what's to be done with the SRB pins on the top rows of each board, are they to be simply ignored/NC??

    In the case of Daisy, the Y-adapter connecting both SRB2 pins, is needed because otherwise the references would not be connected. SRB1 is not used in the default Cyton configuration.

  • @wjcroft: Okay great, thank you for this, William. I'll definitely have a look at the ADS1299 datasheet but just as a quick confirmation.. you're saying that SRB1 is not internally ganged (as reference) across the bottom pins.. But SRB2 is internally ganged across the top row pins as the Common Reference, correct? So, I can simply use the bottom row pins as individual 'unipolar' EEG channels (with SRB2 as common reference), unless I wish to specifically implement a mixed/differential channel (for e.g., 2 ECG +/- leads on channel#8). In this particular case, I will have to manually switch off the SRB2 reference for Chann#8 inside the OBCI GUI. Otherwise, ALL the channels refer to SRB2 as common reference by DEFAULT, correct??

  • wjcroftwjcroft Mount Shasta, CA

    @teknomage said:
    @wjcroft: Okay great, thank you for this, William. I'll definitely have a look at the ADS1299 datasheet but just as a quick confirmation.. you're saying that SRB1 is not internally ganged (as reference) across the bottom pins.. But SRB2 is internally ganged across the top row pins as the Common Reference, correct?

    This is not a 'hardware' / hardwired configuration, but done in the ADS1299 registers. Yes follow the guidelines shown:

    https://docs.openbci.com/GettingStarted/Boards/CytonGS/
    https://docs.openbci.com/GettingStarted/Biosensing-Setups/EEGSetup/

    So, I can simply use the bottom row pins as individual 'unipolar' EEG channels (with SRB2 as common reference), unless I wish to specifically implement a mixed/differential channel (for e.g., 2 ECG +/- leads on channel#8). In this particular case, I will have to manually switch off the SRB2 reference for Chann#8 inside the OBCI GUI. Otherwise, ALL the channels refer to SRB2 as common reference by DEFAULT, correct??

    Yes, you want to switch off SRB2 in the settings, BUT ALSO switch off Bias injection / sensing on that channel. Otherwise ECG signal swamps out the anti-mains injection sensing / counter-voltage.

    https://docs.openbci.com/GettingStarted/Biosensing-Setups/ExGSetup/

  • Okay, got it! Thank you very much for the clarification, William :)

Sign In or Register to comment.