...
That's quite interesting. Is that your video?
I don't think true c-compatible paralellism was their ultimate goal. (They don't even provide a C-compiler...). Obviously that would have added a lot of additional complexity, as you point out.
The idea is probably to have specific tasks assigned to specific threads. For example one thread runs the SPI peripheral, a second one runs a control loop, while the main thread mostly sleeps and does housekeeping/reconfiguration. Each of these would reside in their own memory space with dedicated ressources and would use minimal inter-thread communication via pipes. This would keep synchronization overhead down a lot.
For SDCC, the main challenge would be to allow multiple main function to initialize each FPPA. Maybe that could be dont similar to interrupts? It would be up to the user to ensure that variables are not reused between different threads.
Of course, something needs to be done with the p-register. A very rigid approach would be to clearly assign each function to only one FPPA.
A more pragmatic approach, for now, would be to have C-code always stay on FPPA0 and use assembler for the others...
Regarding preemtive multitasking: Of course this would free up some of the synchronization headache, but then the usefulness would be quite limited compared to using multiple hardware threads.
[[sdcc::fppa(3)]] void f(int)
{
…
}
An FPPA3-specific p3 would be used instead of p when generating code for f.Still, on such a "multicore" µC, you want efficient communication between multiple cores and interrupt handlers, which means efficient lockless atomics, which means a compare-and-swap instruction, preferably with indirect addressing mode.
mov a,#1
loop:
xch a,lock
ceqsn a,#0
goto loop:
[...critical block...]
clear lock
SDCC is a C compiler, and will aim to comply with the C standard. Where that can't be done efficiently, we still need to be able to comply, but offers alternatives. E.g. when compiling for Padauk, functions are currently not reentrant by default (but reentrancy can be enabled for individual functions using __reentrant, or for the whole program using --stack-auto; it about triples code size though).
For multiple FPPA, my idea would be:
By default make the code work on any FPPA. That means a lock around any use of p. And no longer using p to pass return values (thus 16-bit return values would have to be passed on the stack, like we currently do for return values > 16 bit). Inefficient, but avoids nasty surprises.
Then provide a way for the user to specify that a function is to be used on a specific FPPA only, e.g. something likeCode: [Select][[sdcc::fppa(3)]] void f(int)
An FPPA3-specific p3 would be used instead of p when generating code for f.
{
…
}
Btw, it should also be possible to use the atomic xch instruction? This is effectively like a CAS that can only compare to a single value.
…
Thumbs up adding RX to it would be nice too
Thumbs up adding RX to it would be nice too
Apart from that, the includes now support upper case SFR names as defines. This allows intellisense in VSCODE to work to at least some extend.
07E0: 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 0282 025A 1FFE
07F0: 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF
IHRCAL: 82
IHRCRNOW: 82
ILRCRNOW: 82
BGTCAL: 5A
BGTRNOW: 5A
from include file: IHRCR IO_WO 0x0B
ILRCR IO_WO 0x39 (-) // [7:4]
BGTR IO_RW 0x1A (0x2C) // [7:3]
I have been experimenting with the IHRC and BGTR-calibration. As JS notedin an older post, there are calibration values stores on the flash in the PFS154/163 in two read-only memory addresses.
It appears to me, that these are automatically loaded into the respective registers. The dump below shows the initial value of IHRCR and BGTR and it is exactly the same as the value stored on the flash. The value is also the same that EASYPDKPROG ends up with during calibration. It appears that no calibration is needed on the flash types, unless you want to adjust to a different voltage?
Is this confirmed anywhere?
I also noted that IHRCR is readable, although it is marked as write only in the official .INC file.
Also strange: The low frequency oscillator calibration register (ILRCR) has the same initial value as the IHRCR. There is no corresponding value in the flash.Code: [Select]07E0: 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 0282 025A 1FFE
from include file:
07F0: 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF 3FFF
IHRCAL: 82
IHRCRNOW: 82
ILRCRNOW: 82
BGTCAL: 5A
BGTRNOW: 5ACode: [Select]IHRCR IO_WO 0x0B
ILRCR IO_WO 0x39 (-) // [7:4]
BGTR IO_RW 0x1A (0x2C) // [7:3]
The bandgap is probably also used by the oscillator, unless it uses a separate voltage reference. It's a good idea to trim it, too. The resolution is rather fine though, around 500mV across the entire 8 bit range of BGTR, ~2mV per count. I tested this by using the comparator and Vint_ref as reference. It may be a challenge to measure the voltage accurately enough.
I do not understand how you use SPI to calibrate IC and measure the final frequency.
Another thing I'm curious about is that there are direct ways to operate on OTP ram, such as burning programs directly into OTP ram and executing programs in ram.
Apparently only bits [7:3] of BGTR are used. I determined Vbg to be at ~1.08V for BGTR=0 and 1.47V for BGTR=240 on one PFS154. This means that the voltage resolution of the trimming register is 8*(1.47V-1.08V)/240= ~ 13mV.
To reach a trimming accuracy that is better than 13mV it would be necessary to apply 4.8V+-26mV externally (13*4.8/1.2/2=26). This assumes perfect resistor matching, which is unlikely. Certainly not impossible but also not without a challenge. If this is not possible it may be better to use the factory trimming.
A more accurate solution is obviously to apply 1.2V+-6.5mV to an external input of the comparator and use that as a trimming reference.
Hi,
I think you look to precise on this. In order to understand the magnitude of error our cheap ICs are having I suggest the following experiments:
1) output an alternating clock signal on an IO pin and measure frequency with oscilloscope
2) now touch the IC with your finger (which slightly increases temperature) and watch the HUGE difference of the clock
3) tune and perform your band gap comparator test (e.g. switch at 1.200V)
4) now touch the IC with your finger (which slightly increases temperature) and watch the HUGE difference of the band gap switch
BTW: I found factory trimming of bandgap on all FLASH and some OTP variants, however factory trimming of IHRC is available on FLASH based ICs only. ILRC does not have a factory trimming values in any of the devices I checked.
One quick question: has been the read protection of the PFS154 already documented?