Pico Computer 3 / FUZIX v0.12 - buses, and text on the far end of one
v0.11 gave the machine pins it could drive. This one gives it buses,
and a way to put its own text on something at the far end of one.
I2C2 and SPI0, from BASIC
Both with MMBasic's spelling and MMBasic's semantics, so a PicoMite
program moves across unchanged apart from naming the pins.
SETPIN 38, 39, I2C2
I2C2 OPEN 400, 1000
I2C2 WRITE &H77, 1, 1, &HAA
I2C2 READ &H77, 0, 22, calib$SETPIN 2, 3, 4, SPI
SPI OPEN 62500000, 0, 8
SPI WRITE 240, row$The three SPI pins go in any order — the RP2350 fixes each pin's
role from its number, which is how MMBasic resolves them too. Chip
select is the program's, as on a PicoMite. A whole transfer is one
system call whatever its length: there is no MMU, so the controller
reads your buffer where it lies. A 240x320 screen of 16-bit pixels is
153,600 bytes and goes out in 26 ms.
I2C2 adds MMBasic's option word, its OPEN timeout, and bus recovery
when a device leaves SDA held low.
Reading the built-in fonts
TEXT draws on the PC3's own screen. If you have hung a panel off the
I/O header, the firmware knows nothing about it — and you would rather
not carry your own copy of a font to draw on it.
a = MM.INFO(FONT ADDRESS 3)
w = PEEK(BYTE a) : h = PEEK(BYTE a + 1)That is a machine address, and here a machine address is something you
can simply read: no MMU, and the fonts are const so they sit in flash
where nothing moves them. The first four bytes are the font describing
itself — width, height, first character, count — so having the address
you need nothing else.
PEEK is new, in all of MMBasic's widths, and without it the
address would be useless. MM.INFO(FONT ADDRESS n) is MMBasic's own
spelling. Both are as sharp as they are on a PicoMite: a wrong address
is not an error message on a machine with no memory protection.
There is a fully worked example in the manual and on the card — a
barometric station reading a BMP180 over I2C2, a potentiometer on the
ADC and the clock, drawing all of it, text included, onto an ILI9341.
/root/cc/qnh.bas, with /root/cc/fontaddr.bas alongside it.
Two hardware faults, both of them quietly limiting everything
clk_peri was on the USB PLL at 48 MHz whatever the system clock
was doing. The SDK only attaches it to clk_sys when
PICO_CLOCK_ADJUST_PERI_CLOCK_WITH_SYS_CLOCK is defined, and that
defaults off — so every peripheral divisor was computed from 48 MHz.
SPI could not exceed 24 MHz, and the console UART and the SD card were
under the same ceiling. A full ILI9341 frame went from 63 ms to 26 ms.
Clearing EN32kHz in the DS3231 bricks a PC3. Board detection
reads that square wave, so without it a PC3 reads as a PC2, the card is
probed on the wrong MISO, and the machine will not boot far enough to
be repaired. The kernel now refuses the write and re-enables the output
at every boot, so a board damaged this way heals itself on the next
power up.
Also fixed
PICOIOC_BOARDandSNDIOC_PCMOPENshared ioctl 0x0021. The board
test ran first, so every PCM open had a 2 or a 3 written over its
sample rate and returned success —PLAY MP3played silence and
reported nothing wrong. There is a gate against duplicates now.printfunderstands%lldand%llX. It did not, silently,
which made every&Hconstant zero in a program translated on the
board.mmb_spi.hreached both front ends and the sync script but never the
card image, so a freshly built card compiled everything except a
program that opened SPI.- The RTC alarm is armable, and was re-tested properly — the v0.11 note
that it worked came from a test that could not tell an alarm from the
DS3231's 1 Hz square wave.
Coverage
87 statements, 85 functions, 5 scalar and 6 array MATH.
Gates
make check 29, cgate 0 diff lines (both front ends byte-identical),
fcctests 29, qemutests 30, ctest 165, cpptest clean,
ioctlcheck 49 codes with no duplicates.
The flash disk, and a bricking hazard closed
The kernel now gets 1 MB of flash rather than 512 KB, and the dhara
flash disk gets everything above it. The root had stopped fitting: the
printf fix above grew every statically linked binary, and the 142 of
them in that image went over.
Behind that were two mis-sizings. PICO_FLASH_SIZE_BYTES was the
pico2 board header's default of 4 MB, and a PC2 or PC3 always
carries 16 MB — devflash.c sizes the disk as
PICO_FLASH_SIZE_BYTES - FLASH_OFFSET, so it had the first quarter of
the chip and the other twelve megabytes were doing nothing at all. The
FTL ceiling goes from 2555 sectors to 20,549, and the flash root
from 2547 to 8000 with 512 inodes.
Three other things were wrong on their own account, each of them a
number written down twice:
- The Makefile converted
filesystem.uf2at0x10018000— 96 KB,
theFLASH_OFFSETfrom before the incident that made it 512 KB in
the first place. Flashing that image would have written the disk
straight over the kernel, which is the failure that leaves a board
dead until reflashed and then dead again on the next boot. It is
0x10100000now. Not a release asset and the SD card is the real
root, which is why it went unnoticed — but it was live in the tree. CMakeLists.txtchecked the kernel's footprint against a
hand-copied$((512*1024)), so raisingFLASH_OFFSETwould have
left the build enforcing the old number. It readsglobals.hnow.
update-flash.sh also refuses to be quiet about a root that does not
fit: ucp does not stop on ENOSPC and fsck passes a short image, so
the warning is the only sign you would get.
Installing
Hold BOOTSEL, copy fuzix.uf2, and write pc3-sd-cc.img.gz to a card.