Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMS152 write support #26

Closed
serisman opened this issue Jun 27, 2020 · 13 comments
Closed

PMS152 write support #26

serisman opened this issue Jun 27, 2020 · 13 comments

Comments

@serisman
Copy link
Contributor

The PMS152 is currently the cheapest 16-pin Padauk IC from LCSC. Currently, support for the PMS152 is read-only. It would be good to have write support for this device.

Here is a PR that adds compile time support to source code in the Examples directory, but there is no way to test this until the programmer can actually write these ICs. #25

@serisman
Copy link
Contributor Author

I tried to write a PMS152, after un-commenting the appropriate code in fpdkicdata.c and re-compiling easypdkprog. It seemed to mostly write correctly, but failed on calibration, and when read back, there are a few differences (maybe the differences are related to calibration?). So, it may require some more code changes in easypdkprog before it is fully supported. I already wasted two ICs before deciding to stop until someone more familiar with the code could take a look.

>easypdkprog -n PMS152 write Examples\helloworld_pms152.ihx
Writing IC... done.
Calibrating IC
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13694779Hz out of range.
ERROR: Calibration failed

Read/Write differences (left is what was written, right is what was read back):

I assume the differences from 0x10-0x1F aren't a problem, but what about the differences from 0xA6-0xB5? Is that the calibration code, or is that a block/page that didn't write properly?

image

@serisman
Copy link
Contributor Author

I found the calibration algos in fpdkiccalib.c and it looks like the second set of differences from above (0xA6-0xB5) are indeed the calibration code that easypdkprog modifies. So, it seems like the IC is being written properly. Any ideas why the calibration isn't working?

@serisman
Copy link
Contributor Author

serisman commented Jun 28, 2020

So, I used the --noblankchk and --nocalibrate option and wrote over the top of one of my 'wasted' ICs.

Interestingly, it now works (sort of).

>easypdkprog -n pms152 -r 4.0 start
Running IC (4.00V)... IC started, press [Esc] to stop.
Hello World!
Hello World!

IC stopped

I attached a logic analyzer, and measured the uart bit length at approx 9.75 uS, which according to my calculations means a baud rate of ~102564. Seeing that it is supposed to be running at 115942 (approx 115200), I think that means this IC is running at around 88% speed. Interestingly, 88% of 16MHz is 14.14MHz which is pretty close to the 13.7MHz that the calibration routine was reading (although, shouldn't the calibration have been reading closer to half that since the clock should have been /2?).

So, I'm still not exactly sure what the issue is, but it seems to have to do with clock speed calibration more than writing to the OTP.

@serisman
Copy link
Contributor Author

serisman commented Jun 28, 2020

After reading through a bunch more code, and thinking about this a bit more, the only explanation I can come up with is the PMS152 is/was using a 16MHz sys clock (instead of 16MHz / 2 = 8 MHz), and could only be calibrated down to about 13.7 MHz. But, I can't prove that, or figure out why it is doing that. I didn't even think it was possible for these MCUs to use a 16MHz sys clock. I double checked the datasheet and the original Padauk IDE include files, and also verified that the file I am trying to flash does indeed try to set the clkmd register to 0x34, which should be the correct value for IHRC/2 = 8 MHz, unless all the documentation is incorrect somehow.

I don't think it is a hardware issue. I can successfully program and calibrate flash based parts (PFS154 and PFS173), and did not experience any issues programming or calibrating a PMS150C OTP IC.

@serisman
Copy link
Contributor Author

Ok, this is interesting... I modified easypdkprog to include the closest matching calibration value when it prints the 'out of range' error. Here are the 'simplified' results after running it a bunch of times on the same IC:

>easypdkprog -n PMS152 --noblankchk write Examples\helloworld_pms152.ihx
Writing IC... done.
Calibrating IC
...
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13666632Hz (0x17)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13671266Hz (0x61)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13670111Hz (0x6B)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13669530Hz (0x74)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13670398Hz (0x8F)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13671266Hz (0x10)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13669530Hz (0x82)  out of range.
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 13666632Hz (0x4B)  out of range.
...
ERROR: Calibration failed

Notice how the calibration values are all over the place even though the frequency is staying about the same.

So, that tells me that for some reason the calibration code running inside the MCU is failing to actually change the IHRCR register, or for some reason it isn't doing anything.

It could be that the register is set to the wrong address, but I doubt it. As far as I can tell it should be using 0x0B which according to the Padauk IDE include file is correct for this MCU.

It could also be that PA4 isn't being read as a 1 for some reason. Either because the programmer isn't driving it, or because it isn't set as an input on the MCU maybe? I checked the dis-assembled code and nothing is changing the pac register away from it's default values of all 0's (i.e. inputs). The pac register is at address 0x11, and the pa register is at address 0x10, all of which matches the datasheet.

@kaweksl
Copy link

kaweksl commented Jun 28, 2020

+1 to PMS152 write support

Did you tried without calibrating at all ? Maybe simple pin changing in loop. I'm still waiting to for my order with PMS152 to arrive . Having RW support for it would be nice.

EDIT, missed that you tried without calibration.

@kaweksl
Copy link

kaweksl commented Jun 28, 2020

When using official IDE you have option "Code options" and inside of it are options like PWM Source 16Mhz/32Mhz and this values are stored inside undocumented ROP (0x3A) register.

So from where it gets that 32MHz ?

Also it sets PADIER and PBDIER, so maybe that is reason why PA4 isn't read as its digital input is disabled by default ?

@serisman
Copy link
Contributor Author

Yeah, I have it working without calibration. Or, at least it sends "Hello World!" out on PA7 with some uncalibrated baudrate. I haven't tried reading a pin yet.

I did try setting PADIER to 0xFF on the off chance that the datasheet is wrong (like the PMS173, both of which specifies a default value of 0xFF). But, that didn't change the behavior at all. And, another IC wasted.

None of the ROP options seem to have anything to do with the system clock. They only adjust things like the PWM clock or TM2 clock. So, I don't think that is what is going on here.

I did hook up a logic analyzer and verified that the programmer is definitely pulsing PA4 every so often while the MCU is toggling PA3. The bit width of the PA3 toggling doesn't seem to change in response to the PA4 pulse though, so it definitely seems like PA4 isn't being read by the MCU for some reason.

And... just for reference, the code I am talking about is this block that the programmer injects into the IC for calibration purposes (and then changes afterwards to be mostly NOP instructions):

  set1 IO(0x11).3 (PAC.3)
  mov a, 0xFF
loop:
  set1 IO(0x10).3 (PA.3)
  mov IO(0x0B), A (IHRCR)
  t0sn IO(0x10).4 (PA.4)
    add 1, 0x01
  set0 IO(0x10).4 (PA.3)
  goto loop

One, thing that I find odd is that the code starts with IHRCR = 0xFF until the first toggle of PA4. I know that the 0xFF is needed so it can later be programmed with the actual value, but that means that for a period of time the MCU is running at the fastest (and potentially unstable) setting. Possibly, some instability is causing it to not be able to read PA4, and therefore it never adjusts IHRCR? It would waste another code word, but there could be an additional mov a 0x00 right before the loop (that would eventually be turned into a nop), that would mean that the clock would be running slower and more stable at the beginning.

I can't keep wasting ICs without at least some confidence that I know what is going on (i.e. a hypothesis that explains the symptoms and hints at a potential solution). I only bought 50 of them to begin with, and when the flash based ones (with almost double the code and ram sizes) are only $0.02 more to begin with (around $0.07 instead of ~$0.05), I'm not sure how much effort these really deserve. But, it would be nice to know what is going on.

I might be able to re-use some of the existing wasted ICs by first writing the used portions with all 0's (effectively nop instructions) and then starting my code in the unused portion. I would probably have to whip up a custom assembly program to work in this way.

@kaweksl
Copy link

kaweksl commented Jun 28, 2020

Where did you set PADIER ? I flashed PFS154 with PADIER=E9 ( disabled input for PA4 and PA1, PA2 as last two don't exist) and it failed to calibrate in similar way but with much lower frequency
also burned PMC150C and got 12153043Hz out of range

now i see why this things need calibration.

Calibrating IC
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 11524933Hz out of range.
ERROR: Calibration failed
unsigned char _sdcc_external_startup(void)
{
  
  EASY_PDK_FUSE(FUSE_SECURITY_OFF|FUSE_BOOTUP_SLOW);
  EASY_PDK_INIT_SYSCLOCK_8MHZ();                //use 8MHz sysclock
  //PADIER = 0xF9       //Should be
  PADIER = 0xE9;
  EASY_PDK_CALIBRATE_IHRC(8000000,4000);        //tune SYSCLK to 8MHz @ 4.000V
  return 0;                                     //perform normal initialization
}

From things that i will try is before calibration routine, disable lvr, set PAC, PADIER, PAPH to values that they should have by default and clear ROP register

@serisman
Copy link
Contributor Author

serisman commented Jun 28, 2020

I switched to the development branch, and now can't even probe the PMS152 anymore. Probe/erase/write/read for PFS154 still works fine. And yes, I did re-compile easypdkprog and re-compile and upload the new 1.3 firmware.

EDIT: I can't probe the PMS150C anymore either. PFS154 and PFS173 are both still fine. So it looks like something in the development branch may have broken support for non flash based parts.

@serisman
Copy link
Contributor Author

serisman commented Jun 28, 2020

Where did you set PADIER ?

Right before the call to EASY_PDK_INIT_SYSCLOCK_8MHZ();

EDIT: It's possible I had programmed the old version accidentally. I'll try it again after I get my programmer working at least in the same state again.

@serisman
Copy link
Contributor Author

serisman commented Jun 29, 2020

IT WORKS!

>easypdkprog -n PMS152 write Examples\helloworld_pms152.ihx
Writing IC (186 words)... done.
Calibrating IC
* IHRC SYSCLK=8000000Hz @ 4.00V ... calibration result: 8006747Hz (0x4E)  done.
>easypdkprog -n PMS152 -r 4.0 start
Running IC (4.00V)... IC started, press [Esc] to stop.
Hello World!
Hello World!

IC stopped

First, I was able to fix my programmer by pulling down the Flash type bug fix from yesterday (my local was missing it for some reason).

Then, I flashed a new IC, after first making absolutely sure I was using the correct .ihx file with the PADIER fix in it. And, it worked on the first try.

So, it seems that like the PFS173, the datasheet is wrong, and PADIER does not default to 0xFF like it indicates.

I'll update the pms152.h include file to use the appropriate calibration routine.

@freepdk
Copy link
Contributor

freepdk commented Jul 5, 2020

PMS152 support was merged into development now

@freepdk freepdk closed this as completed Jul 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants