Author Topic: EEVblog #1144 - Padauk Programmer Reverse Engineering  (Read 389600 times)

0 Members and 4 Guests are viewing this topic.

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1896
  • Country: ca
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #650 on: September 02, 2019, 05:59:25 am »
Dear JS
Thanks for the feedback, the output is now fine, it will produce exactly 5.0V, But Still I can probe and detect the PFS173,But reading, flashing etc fails!
though I found something weird! when I measured the VDD and VPP with this command

//be carefully, remove IC from programmer!
FPDKCOM_SetOutputVoltages(comfd, 100.0, 100.0);



The output was swamped, I mean I could measure the VPP to be 13.7V and the VDD to be 6.45V with my Multi-meter, but in the terminal it was the other way around!
I double checked the schematic to see if I have connected the DAC's on my PCB swapped, But it was like your schematic!
I have attached my schematic and it's exactly like easyPDK hardware in the DAC part.
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1896
  • Country: ca
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #651 on: September 02, 2019, 06:23:09 am »
Dear JS, I have found one bug in my schematic, the ADC channels are swapped in my Design |O :palm:, so what should I change in the software to correct it.
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #652 on: September 02, 2019, 06:32:00 am »
Hi,

your output does indeed look wrong. Maybe you swapped ADC input lines on STM32? If so you can change the readout in software: "fpdk.c", in function "_FPDK_ADC_HandleData", in the for loop swap "avpp" and "avdd" (swap them in the for loop only).

On the other hand the analog values are not used (yet). They are there for future use like auto calibration of VDD and VPP and to read out protected ICs.

Next you need to do: Monitor VPP / VDD with a scope during READ / WRITE. Maybe your capacitors do not match and you have instabilities or noise. BTW did you put C1 yet?


JS
Easy PDK programmer and more: https://free-pdk.github.io
 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #653 on: September 02, 2019, 06:32:10 am »
@tim_: I have used your blinkyasm example for testing my programmer. However, while the LED turns ON, it never turns back off. I've tried commenting out the wait busy loop and I can see now with the scope the GPIO toggling. Could you tell me if the IHX file you are getting for that matches mine?

Code: [Select]
:20000000022F8201782F8301012F9101101E101C0630FF2F820B830B82110C3083110C30C7
:020020007A0064
:00000001FF

I have just compiled it using the SDCC snapshot for today (1st September 2019), so I am not sure if the compilation is broken.

My other guessing is that the SRAM is bad in this chip (hence the DCSN never reaches zero to leave). Has anybody else experienced something like this in its Padauk IC, where the CPU is indeed working but the SRAM is dead?

See disassembly of your hex file below. For some reason it is missing calls to the delay routine?!?

I would suggest you use the blinky example from the toolchain folder, as posted above. Also, always check *.asm files or use the dissembler to double check. The old examples heavily rely on workarounds to be able to cope with bugs in  the very early versions of SDCC. I will remove them soon.

Code: [Select]
0000: 2F02 mov A,#$02
0001: 0182 movio $02,A
0002: 2F78 mov A,#$78
0003: 0183 movio $03,A
0004: 2F01 mov A,#$01
0005: 0191 movio $11,A
0006: 1E10 set1io $10,#0
0007: 1C10 set0io $10,#0
0008: 3006 goto $0006
0009: 2FFF mov A,#$FF
000A: 0B82 mov $02,A
000B: 0B83 mov $03,A
000C: 1182 dzsn $02
000D: 300C goto $000C
000E: 1183 dzsn $03
000F: 300C goto $000C
0010: 007A ret
« Last Edit: September 02, 2019, 06:51:44 am by tim_ »
 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #654 on: September 02, 2019, 06:50:00 am »

I think auto generating the IO header files is not the way to go.
The most work was to add all the bit definitions for the specific IO registers (see "pms150.h" from above).
This is needed to do simple things like: _clkmd=CLKMD_ENABLE_ILRC | CLKMD_ENABLE_IHRC | CLKMD_IHRC_DIV2;

Well, the thinking here is very simple: Padauk seems to reuse specific peripheral modules, but moves them around in the I/O space. The description of the individual registers can be done once on a common file, this does not need to be auto generated. To cope with padauk moving around peripheral modules in the address space, it is very convenient to auto generate the register addresses. This also makes global renaming much easier.

Also since SDCC defines "_sp" and "_flags" internally I think we should keep the "_" prefix for all other registers as well

yeah, I was unsure about this. There does not seem to be any general convention for SFR naming. SDCC also uses the _xxx naming for internal variable names in SRAM, so it seems to be a bit confusing to use the same conventions for memory and SFR. I guess the _ prefix is added to avoid namespace collisions.

AVR-GCC, PIC-Utils and the STM8-libs (both official and unofficiel) all use no prefix and capital letters for SFR naming. Maybe that is the way to go? (e.g. PA, PAC)


The last byte missing problem from easypdkprog seems odd and it does not happen to me. Maybe programming the last byte was not working on your hardware and some tweaking of the code is required to make this more reliable.

Well, it exactly follows your build and the the device was directly plugged into the header, no long cables. The issue is 100% reproducible. I will try more devices.
« Last Edit: September 02, 2019, 07:36:55 am by tim_ »
 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #655 on: September 02, 2019, 07:05:36 am »
So I have mostly given up on getting the programmer running on the ATtiny - it's just not capable of doing so much realtime stuff at once - either you break USB, or you break the SMPS regulation, you can't have both at once.

Therefore, I have switched to plan B - using an Arduino as development platform instead. And it turns out this is probably the way I should have chosen from the start.

While certainly not the most professional-looking alternative, it sure is the easiest to build. It uses as little components as possible.

The schematic is attached, and the firmware along with upload scripts can be found in https://github.com/socram8888/ArduinoPDKProgrammer. This already supports uploading and verifying IHX files, as those generated by SDCC.

Very nice work! It appears that all new flash MCUs from Padauk will also support 5V programming. (See low voltage programming section in the datasheets). Hopefully that means that it will be possible to build a programmer from an Arduino without adding any additional circuitry for voltage control. This would allow much easier access to a programmer. Although I would not be surprised if they still used analog voltages control schemes to enter programming mode... we'll see.
 

Offline spth

  • Regular Contributor
  • *
  • Posts: 163
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #656 on: September 02, 2019, 07:53:08 am »
I think auto generating the IO header files is not the way to go.

The most work was to add all the bit definitions for the specific IO registers (see "pms150.h" from above).
This is needed to do simple things like: _clkmd=CLKMD_ENABLE_ILRC | CLKMD_ENABLE_IHRC | CLKMD_IHRC_DIV2;
It should be possible to just ship the header files with SDCC (this already happens for some MCS-51 derivatives and some HC08 devices). They would live in device/include/pdk13, device/include/pdk14, device/include/pdk15.
Quote

Also since SDCC defines "_sp" and "_flags" internally I think we should keep the "_" prefix for all other registers as well

On the other hand, the stack pointer and flags are special: In typical programs they will be handled entirely by the compiler, while the others would be handled by the user program (also we have one stack pointer and flag register per FPPA, while the other registers are shared across all FPPA).
« Last Edit: September 02, 2019, 08:05:36 am by spth »
 

Offline spth

  • Regular Contributor
  • *
  • Posts: 163
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #657 on: September 02, 2019, 07:57:00 am »
yeah, I was unsure about this. There does not seem to be any general convention for SFR naming. SDCC also uses the _xxx naming for internal variable names in SRAM, so it seems to be a bit confusing to use the same conventions for memory and SFR. I guess the _ prefix is added to avoid namespace collisions.

SDCC prefixes every symbol X in C by _ to get a symbol _X for asm (so this affects both variable names and function names, no matter where the objects reside).

Philipp

P.S.: This implies that the name, to be usable from C, has to be _-prefixed in asm.
« Last Edit: September 02, 2019, 08:14:02 am by spth »
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #658 on: September 02, 2019, 08:12:02 am »
Well, the thinking here is very simple: Padauk seems to reuse specific peripheral modules, but moves them around in the I/O space. The description of the individual registers can be done once on a common file, this does not need to be auto generated. To cope with padauk moving around peripheral modules in the address space, it is very convenient to auto generate the register addresses. This also makes global renaming much easier.

Unfortunately this is not entirely true. On some MCUs some functions (bits) inside of the peripheral modules do have different meanings.
Examples: Interrupt Enable/Request register, CLKMD register, TIMER register, ...

That's why I decided to do one file per MCU.

BTW: I think in reality only a hand full of MCU's will be popular, so not many include files are needed. And if somebody needs one for a specific MCU, adaption is easy, when you only need to copy an existing file and modify it according to the data sheet.

JS
Easy PDK programmer and more: https://free-pdk.github.io
 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1896
  • Country: ca
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #659 on: September 02, 2019, 09:16:41 am »
Quote
BTW did you put C1 yet?!
What C1? do you mean a cap on VCC and GND and the PFS173? something like this?
Also I have connected VPP to PA5 or RST pin, is it correct?


ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline socram

  • Regular Contributor
  • *
  • Posts: 72
  • Country: es
    • orca.pet
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #660 on: September 02, 2019, 10:44:58 am »
See disassembly of your hex file below. For some reason it is missing calls to the delay routine?!?
Sorry, I had removed call to see if a loop without any call worked fine (which it did, it worked and I could see the pin toggling on a scope) and forgot to recompile to paste it here.

This is it with the call:
Code: [Select]
:20000000022F8201782F8301012F9101101E0B38101C0B380630FF2F820B830B82110E300F
:0600200083110E307A008E
:00000001FF

I am getting the following disassembly:
Code: [Select]
0000:   2F02    mov     A,#$02
0001:   0182    movio   $02,A
0002:   2F78    mov     A,#$78
0003:   0183    movio   $03,A
0004:   2F01    mov     A,#$01
0005:   0191    movio   $11,A
0006:   1E10    set1io  $10,#0
0007:   380B    call    $000B
0008:   1C10    set0io  $10,#0
0009:   380B    call    $000B
000A:   3006    goto    $0006
000B:   2FFF    mov     A,#$FF
000C:   0B82    mov     $02,A
000D:   0B83    mov     $03,A
000E:   1182    dzsn    $02
000F:   300E    goto    $000E
0010:   1183    dzsn    $03
0011:   300E    goto    $000E
0012:   007A    ret

It looks fine, but I had to adjust the assembler (change "SDAS=sdaspdk" to "SDAS=sdaspdk14") so I'm not sure if anything else could have gotten broken.

I would suggest you use the blinky example from the toolchain folder, as posted above. Also, always check *.asm files or use the dissembler to double check. The old examples heavily rely on workarounds to be able to cope with bugs in  the very early versions of SDCC. I will remove them soon.
Okay, I will try this evening with the ones from toolchain, and using another IC to rule out that the chip is damaged. Many thanks.
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #661 on: September 02, 2019, 02:53:37 pm »
Quote
BTW did you put C1 yet?!
What C1? do you mean a cap on VCC and GND and the PFS173? something like this?

I mean C1 on your programmer board (I think it is for the high voltage output). Also Y1 (the oscillator) was missing in the picture from you. Did you change the firmware to use the HSI48 clock source instead of the external OSC?

The cap you added on the PADAUK MCU is contra productive since it might require different timing for VPP / VDD phase of programming (remove it for testing).

JS
Easy PDK programmer and more: https://free-pdk.github.io
 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #662 on: September 02, 2019, 03:54:52 pm »
See disassembly of your hex file below. For some reason it is missing calls to the delay routine?!?
Sorry, I had removed call to see if a loop without any call worked fine (which it did, it worked and I could see the pin toggling on a scope) and forgot to recompile to paste it here.

This is it with the call:
Code: [Select]
:20000000022F8201782F8301012F9101101E0B38101C0B380630FF2F820B830B82110E300F
:0600200083110E307A008E
:00000001FF

I am getting the following disassembly:


Ah ok, that explain.

Well, from your description the issue could be explained by corruption of the last instruction during writing. You could add some dummy instructions to the end of the program (nops) to check.
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #663 on: September 02, 2019, 06:46:55 pm »
I am getting the following disassembly:
Code: [Select]
0000:   2F02    mov     A,#$02
0001:   0182    movio   $02,A
0002:   2F78    mov     A,#$78
0003:   0183    movio   $03,A
0004:   2F01    mov     A,#$01
0005:   0191    movio   $11,A
0006:   1E10    set1io  $10,#0
0007:   380B    call    $000B
0008:   1C10    set0io  $10,#0
0009:   380B    call    $000B
000A:   3006    goto    $0006
000B:   2FFF    mov     A,#$FF
000C:   0B82    mov     $02,A
000D:   0B83    mov     $03,A
000E:   1182    dzsn    $02
000F:   300E    goto    $000E
0010:   1183    dzsn    $03
0011:   300E    goto    $000E
0012:   007A    ret

For me it looks like you trash your stack...

This sets the SP to point to memory location #2
0000:   2F02    mov     A,#$02
0001:   0182    movio   $02,A
...
The call will put the return address at SP (memory location #2 and #3, SP will point to #4 when call is executed)
0007:   380B    call    $000B
...
In the function you overwrite memory location #2,#3 (the return address)
000B:   2FFF    mov     A,#$FF
000C:   0B82    mov     $02,A
000D:   0B83    mov     $03,A
...
Both decrements will have 0 as result in memory location #2 and #3
000E:   1182    dzsn    $02
000F:   300E    goto    $000E
0010:   1183    dzsn    $03
0011:   300E    goto    $000E
The ret will "jump" to address #0 which is almost same as reset
0012:   007A    ret

The following code is never executed
0008:   1C10    set0io  $10,#0
0009:   380B    call    $000B
000A:   3006    goto    $0006

==> your IC works absolute correct

JS
Easy PDK programmer and more: https://free-pdk.github.io
 
The following users thanked this post: socram

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #664 on: September 02, 2019, 06:57:08 pm »
For me it looks like you trash your stack...

Indeed, that seems to be the case. So the newer versions of SDCC start the data segment at 0x02 for some reason.

As mentioned before, better use the newer code.
 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #665 on: September 02, 2019, 08:11:37 pm »

It should be possible to just ship the header files with SDCC (this already happens for some MCS-51 derivatives and some HC08 devices).

The HC08 headers are actually quite interesting. They use bitfield structs to declare individual bits in the I/O ports. I tried to do the same for the PDK14, but got mixed results, see code below.

"PORTA4" is defined as bit4 on PA.

PORTA4^=1  creates functional, but very inefficient code. (11 instructions instead of 3)

PORTA4=1/PORTA4|=1/PORTA4&=~1  creates broken code and SDCC exits with an assembler error.

Code: [Select]
struct __pdk_bits
{
  unsigned int bit0:1;
  unsigned int bit1:1;
  unsigned int bit2:1;
  unsigned int bit3:1;
  unsigned int bit4:1;
  unsigned int bit5:1;
  unsigned int bit6:1;
  unsigned int bit7:1;
};

#define PORTA4 ((struct __pdk_bits *)(&pa))->bit4

#define LEDPIN PA4

unsigned char _sdcc_external_startup(void)
{
clkmd = CLKMD_IHRC_DIV2|CLKMD_ENABLE_IHRC;  // 8 Mhz main clock
return 0; // perform normal initialization
}

void main(void)
{
  pac |= _BV(LEDPIN);     // Use this exact syntax to infer set0/set1
  for (;;) {
  // pa ^= _BV(LEDPIN); // Toggle LED
PORTA4 ^=1;   // works, but creates 11 instructions
delay_ms(500);
PORTA4 = 1;   // creates broken assembler code

  }
}

Code: [Select]
; blinky.c: 38: PORTA4 ^=1;   // works, but creates 11 instructions
mov a, _pa+0
swap a
and a, #0x01
xor a, #0x01
clear p
sr a
mov a, _pa+0
and a, #0xef
t0sn f, c
or a, #0x10
mov _pa+0, a
; blinky.c: 39: delay_ms(500);
mov a, #0xf4
mov _delay_ms_PARM_1+0, a
mov a, #0x01
mov _delay_ms_PARM_1+1, a
call _delay_ms
; blinky.c: 40: PORTA4 = 1;   // creates broken assembler code
mov a, #0x10
or _pa+0, a
goto 00102$
 

Offline socram

  • Regular Contributor
  • *
  • Posts: 72
  • Country: es
    • orca.pet
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #666 on: September 02, 2019, 10:26:28 pm »
...
Many thanks! After setting the stack address to something else I got the assembly blink working.

The reason why I was considering if my IC's RAM was bad it's because I couldn't get neither the assembly one nor the C one to work, so given this is the first and only PFS154 I've used for testing and has been subject to pretty harsh conditions (such as yesterday when I accidentally got it connected backwards with VCC on GND and vice-versa  |O ), it wouldn't had surprised me.

However the reason the C version wasn't working either wasn't a change in SDCC but an oversight on my side - the library I am using for parsing Intel HEX files gives offsets in bytes, but expects the actual data to be requested in terms of words, so I was writing all the time the wrong data at the wrong address. After fixing that I do get the LED to blink just fine.

There's one last blink not working though: the toolkit one. I do not get the LED to turn ON at all, neither I see anything on the scope. I just realized the toolkit one uses PA4, so it's my fault. It's the last time I try to dev stuff past midnight  :palm:

The IHX files from tim_'s repo are these. They have been compiled using the SDCC snapshot of 1st September 2019, and had both been tested to work. I'll leave them there in case somebody wants a quick test hex file:

PFS154Examples/blinkasm (put LED on PA0)
Code: [Select]
:16000000102F8201782F8301012F9101101E2038101C20380630FB
:10004000FF2F820B830B82112330831123307A0020
:00000001FF

PFS154Examples/blinkc (put LED on PA0)
Code: [Select]
:020020007B0063
:1000000000000113042F0128FE2C82011D3812303C
:16002400022F800B1930002F80030012022F022800171530113005
:0200220020308C
:20003A00782F83010002012F9101302F820B752F830B820F0129800B830F6100830B80133F
:20005A00820B8013800E002A2630002F9001302F820B752F830B820F0129800B830F610041
:16007A00830B8013820B8013800E002A3830012F900122307A0082
:00000001FF

Toolchain/examples/pfs1xx_blinky (put LED on PA4)
Code: [Select]
:020020007B0063
:1000000000000113042F0328FE2C82011D3812303A
:16002400022F800B1930002F80030012022F022800171530113005
:0200220020308C
:1C003A00302F83010002111FD001102E9001F42F820B012F830B2B3821307A0059
:20005600820F840B830F850B850F800B840F84128510800E002B42300013800F2829401AF3
:140076002F30322F0129001A3D30001238307A0000007A0097
:00000001FF
« Last Edit: September 02, 2019, 10:37:34 pm by socram »
 

Offline spth

  • Regular Contributor
  • *
  • Posts: 163
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #667 on: September 03, 2019, 07:36:10 am »

It should be possible to just ship the header files with SDCC (this already happens for some MCS-51 derivatives and some HC08 devices).

The HC08 headers are actually quite interesting. They use bitfield structs to declare individual bits in the I/O ports. I tried to do the same for the PDK14, but got mixed results, see code below.

"PORTA4" is defined as bit4 on PA.

PORTA4^=1  creates functional, but very inefficient code. (11 instructions instead of 3)

PORTA4=1/PORTA4|=1/PORTA4&=~1  creates broken code and SDCC exits with an assembler error.

However, the pdk (unlike stm8 and hc08) has a separate address space for the I/O to be accessed via __sfr (and __sfr16 for the one 16-bit I/O-register Padauk has).

 So far, I only used and tested access via the __sfr keyword (as in my examples on https://github.com/free-pdk/sdcc-pdk-code-examples). I don't know if the struct / bit-field approach canbe combined with __sfr.


 

Offline ali_asadzadeh

  • Super Contributor
  • ***
  • Posts: 1896
  • Country: ca
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #668 on: September 03, 2019, 09:50:00 am »
Quote
I mean C1 on your programmer board (I think it is for the high voltage output). Also Y1 (the oscillator) was missing in the picture from you. Did you change the firmware to use the HSI48 clock source instead of the external OSC?

The cap you added on the PADAUK MCU is contra productive since it might require different timing for VPP / VDD phase of programming (remove it for testing).

JS
I have soldered a 47uF 1206 ceramic cap for the 15V output already. Also I have not soldered a 8MHz crystal yet, because I do not have stock yet, Since the programmer can talk to PC, it means it can generate the USB 48MHz clock internally, does this may be a problem?
ASiDesigner, Stands for Application specific intelligent devices
I'm a Digital Expert from 8-bits to 64-bits
 

Offline ebclr

  • Super Contributor
  • ***
  • Posts: 2328
  • Country: 00
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #669 on: September 03, 2019, 12:12:33 pm »
I was interested in build this programmer,  but I realize that is a nonsense use this CPU, while I have a 15 cents Cpu that is 8051 compatible, as USB , and don't need any programer just plug to USB and is all set.

12 cents will not cover all the trouble, it's easy to cut development cost and pay 12 cents more on the CPU CH551G is just 15 cents

 

Offline socram

  • Regular Contributor
  • *
  • Posts: 72
  • Country: es
    • orca.pet
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #670 on: September 03, 2019, 12:54:03 pm »
That's like 500% more expensive  ;)

Besides, it's not only more expensive, but it's also way way more power hungry, using 11mA peak vs 300uA peak, and 20uA vs 500nA in sleep. If you're gonna run on batteries, which is my purpose for these micros, it's a no-go.

A MDT micro would be a suitable replacement, but a power-hungry, AVR-priced USB thing? Geez no.

Besides, at least for me, this is just a matter of trying exotic, chinese stuff rather than getting anything serious working on the platform. It's like that evening you spend coding in Brainfuck just for fun, except on the hardware side.
« Last Edit: September 03, 2019, 01:06:12 pm by socram »
 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #671 on: September 03, 2019, 05:42:25 pm »
So far, I only used and tested access via the __sfr keyword (as in my examples on https://github.com/free-pdk/sdcc-pdk-code-examples). I don't know if the struct / bit-field approach canbe combined with __sfr.

Well, lets look at the positive side. Some of it already works :)

I looked at gen.c and it is quite clear why it behaves like it currently does. Implementing bitfield for I/O could actually be easier than for memory, since there are dedicated instructions for bit moving like "SWAPC".

 

Offline tim_

  • Regular Contributor
  • *
  • Posts: 237
  • Country: de
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #672 on: September 03, 2019, 05:43:45 pm »
Besides, at least for me, this is just a matter of trying exotic, chinese stuff rather than getting anything serious working on the platform. It's like that evening you spend coding in Brainfuck just for fun, except on the hardware side.

So, how about Brainfuck on a $0.03 Padauk MCU?

Edit:
Looks very doable. The brainfuck program will reside in the flash. And one should precalc the target addresses, so most of the RAM can be used for the array.

Code: [Select]
/* simple brainfuck interpreter */
/* 20 April 2006 */
/* Daniel B. Cristofani */
/* http://www.brainfuck.org/ */

#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE 65536
#define MAXCODESIZE 65536

//For simplicity, we'll use statically allocated arrays with matching indices.
int stack[MAXCODESIZE], stackp; //to store locations of still-unmatched '['s.
char code[MAXCODESIZE]; int codep, codelength; //copy of the program we'll read into memory.
short int array[ARRAYSIZE], memp; //the memory used by the brainfuck program.
int targets[MAXCODESIZE]; //to save matching '[' for each ']' and vice versa.
int c;
FILE *prog;

int main(int argc, char **argv){
    if (argc > 2) fprintf(stderr, "Too many arguments.\n"), exit(1);
    if (argc < 2) fprintf(stderr, "I need a program filename.\n"), exit(1);
    if(!(prog = fopen(argv[1], "r"))) fprintf(stderr,"Can't open the file %s.\n", argv[1]),exit(1);
    codelength = fread(code, 1, MAXCODESIZE, prog);
    fclose(prog);
    for(codep=0; codep<codelength; codep++){
        if (code[codep]=='[') stack[stackp++]=codep;//put each '[' on the stack
        if (code[codep]==']'){ //If we meet a ']',
            if(stackp==0){ //and there is no '[' left on the stack, it's an error.
                fprintf(stderr,"Unmatched ']' at byte %d.", codep), exit(1);
            } else {
                --stackp; //if there is one, we take the matching '[' from the stack top,
                targets[codep]=stack[stackp]; //save it as the match for the current ']',
                targets[stack[stackp]]=codep; //and save the current ']' as the match for it.
            }
        }
    }
    if(stackp>0){ //Any unmatched '['s still left on the stack are an error too.
        fprintf(stderr,"Unmatched '[' at byte %d.", stack[--stackp]), exit(1);
    }
    for(codep=0;codep<codelength;codep++){//Everything is okay; we start executing the program.
         switch(code[codep]){
            case '+': array[memp]++; break;
            case '-': array[memp]--; break;
            case '<': memp--; break;
            case '>': memp++; break;
            case ',': if((c=getchar())!=EOF) array[memp]=c=='\n'?10:c; break;
            case '.': putchar(array[memp]==10?'\n':array[memp]); break;
            case '[': if(!array[memp]) codep=targets[codep]; break;
            case ']': if(array[memp]) codep=targets[codep]; break;
        }
    }
    exit(0);
}
« Last Edit: September 03, 2019, 05:47:23 pm by tim_ »
 

Offline socram

  • Regular Contributor
  • *
  • Posts: 72
  • Country: es
    • orca.pet
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #673 on: September 04, 2019, 01:49:41 pm »
So I have been still working with the PFS154. I have just sent the PCBs for the Arduino-based programmer to JLCPCB, and we'll see how good they work. At least on my protoboard it's been working fine, so that one better do too  :D

The project on EasyEDA is here: https://easyeda.com/socram8888/arduino-pfs-programmer

Regarding the chip itself, yesterday night I got working my first project from scratch for the PFS154. It's meant to replace the microcontroller inside a particular model of bike horns sold on Aliexpress, which generates a siren similar to ambulances. My solution generates a different tone, more similar to a horn and thus more suitable for a bike or a Xiaomi scooter.

It's using timer features, deep sleep modes, clock switching and some other features, so if you want to try something more advanced, here it is: https://github.com/socram8888/PFS154Horn

It generates a tone in PA3 whenever the button on PA0 is pressed (connected to ground)

PS: I do wonder if the original horn is using a PMC150 for the siren sound effect, since it's also a number-less part in SOIC8 whose epoxy case looks a lot like that of my PFS154.
 

Offline js_12345678_55AA

  • Frequent Contributor
  • **
  • Posts: 337
  • Country: ht
Re: EEVblog #1144 - Padauk Programmer Reverse Engineering
« Reply #674 on: September 04, 2019, 03:20:20 pm »
Hi,

today some PCBs arrived.  :)

I have made a PMS150C-8/PFS154-8/PFS173-8 audio player (PCM, 8 bit, 32kHz) reading from SPI flash or SD card. Sound quality is very nice.
Total cost for MCU/Flash/Amplifier/Speaker is less than 60 cent  :) I think this is the cheapest option to play any high quality sound.
My particular use case is to play the Apple-Startup sound on my hackintosh whenever it is power cycled 8)

I will cleanup some things and upload the complete project as an example soon. It contains a nice set of features like SPI, PWM, Timer Interrupts and is still very small.

JS
Easy PDK programmer and more: https://free-pdk.github.io
 
The following users thanked this post: icraftcrafts


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf