Compare commits

...

24 Commits

Author SHA1 Message Date
cuu
c1b8f3fc3e Update Bin/PicoCalc SD
add PicoCalc_Bootloader_v0.5 and related bin files
2025-11-11 15:28:51 +08:00
cuu
a7fb3894bd update Code/uLisp/README.md 2025-11-08 14:41:00 +08:00
cuu
e677870d3b Bug fix
Update PicoCalc SD/firmware/PicoCalc_uLisp_v1.1.uf2

Fix the bug that kept restarting of uLisp when under v1.4 keyboard firmware
2025-11-08 14:24:51 +08:00
cuu
9219115667 Fix micropython endless reboot issue with keyboard v1.4 firmware
pico-sdk commit hash a1438dff1d38bd9c65dbd693f0e5db4b9ae91779

https://github.com/zenodante/PicoCalc-micropython-driver  commit hash fa8b24c3d7b4b1b6d621b46ceced787dce69f4c1

micropython commit hash 4efc5e12b94082af16520e73ecdd53a67ceddfcf

all repos above need `git submodule update` to sync with their submodules

PicoCalc-micropython-driver/pico_files/modules/picocalc.py
```
diff --git a/pico_files/modules/picocalc.py b/pico_files/modules/picocalc.py
index 6178ab1..e503ccb 100644
--- a/pico_files/modules/picocalc.py
+++ b/pico_files/modules/picocalc.py
@@ -141,7 +141,7 @@ class PicoKeyboard:
         self.ignor = True
         self.address = address
         self.temp=bytearray(2)
-        self.reset()
+        #self.reset()
         self.isShift = False
         self.isCtrl = False
         self.isAlt = False
@@ -524,4 +524,4 @@ class PicoSpeaker:
             return

         for freqc, msec in tune:
-            self._play_frequency(freqc, msec * 0.001)
\ No newline at end of file
+            self._play_frequency(freqc, msec * 0.001)
```

copy PicoCalc-micropython-driver/pico_files/modules/*.py  to  micropython/ports/rp2/modules
copy PicoCalc-micropython-driver/pico_files/root/*.py to micropython/ports/rp2/modules

get into micropython/ports/rp2/ to prepare to compile,follow the PicoCalc-micropython-driver/README.md to get it done

here is a brief tip

```
mkdir build && cd build
-DUSER_C_MODULES="Path/To/PicoCalc-micropython-driver/picocalcdisplay/micropython.cmake;Path/To/PicoCalc-micropython-driver/vtterminal/micropython.cmake" \
 32   -DMICROPY_BOARD=[TARGET_BOARD]
make
cp firmware.uf2 /media/xxxx/RPI-RP2
```

Supported `TARGET_BOARD` values:
- `RPI_PICO`
- `RPI_PICO2`
- `RPI_PICO2_W`
2025-10-30 14:47:40 +08:00
cuu
a049952189 update picocalc keyboard 2025-08-10 20:11:36 +08:00
cuu
8b6822a80c Add REG_ID_OFF to power off picocalc
add button callback when short press Power key of picocalc
2025-08-01 15:02:23 +08:00
GNU
ebdc77ad4a
Merge pull request #33 from yatli/multiboot
Multiboot
2025-06-19 14:01:26 +08:00
Yatao Li
9c449b8b03 picomite: properly save options 2025-06-18 15:30:14 +08:00
Yatao Li
763a7080a2 sd_boot: better key handling 2025-06-18 10:11:27 +08:00
Yatao Li
7ce75c9ee0 program offset back to 200k, picomite size increase to 880k (1080k in total) 2025-06-18 10:06:34 +08:00
Yatao Li
eb3b15e188 sdcard picomite: sync with upstream 2025-06-15 21:31:45 +08:00
Yatao Li
f305e6def6 Merge branch 'master' of yatao-nas:/home/yatli/git/PicoCalc 2025-06-15 18:36:33 +08:00
Yatao Li
7f62e15f55 sd_boot: move readboot logic to bootloader. 2025-06-15 18:36:30 +08:00
Yatao Li
557986bcb8 Revert "picocalc_keyboard: add bootmode register"
This reverts commit a690686270a1ea7eab0533f521d00cbe3c3a2806.
2025-06-15 18:36:13 +08:00
Yatao Li
2f6ba71531 Merge branch 'master' of yatao-nas:/home/yatli/git/PicoCalc 2025-06-15 02:51:04 +08:00
Yatao Li
a690686270 picocalc_keyboard: add bootmode register 2025-06-15 02:50:35 +08:00
Yatao Li
fa3ad399d7 sd_boot: handle bootmode 2025-06-15 02:50:03 +08:00
cuu
44615ce5d2 Update multi booter readme 2025-06-05 14:04:47 +08:00
cuu
2826755bcb Update multi booter
change battery icon/text to top right
2025-06-03 20:24:57 +08:00
cuu
26cde76df8 Update multi booter
final flash offset of bootloader set to 200k
right now bootloader code occupied 156k of flash
so there is a small space left for future modifications
2025-06-02 14:55:46 +08:00
cuu
6a15612907 Update multi booter
change status text when no bin files
2025-06-02 01:01:36 +08:00
cuu
4449860332 Update multi booter 2025-06-01 17:22:45 +08:00
cuu
bdbac6751e Update multi booter 2025-06-01 14:21:30 +08:00
cuu
cb0b1fbb63 Update multi booter
add battery percentage displaying
2025-06-01 00:15:57 +08:00
67 changed files with 5967 additions and 2535 deletions

Binary file not shown.

BIN
Bin/PicoCalc SD/BellLabs_Fine.mp3 Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
Bin/PicoCalc_BIOS_v1.4.bin Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
1c8aba4688a324db046b718dec917f5b PicoCalc_BIOS_v1.4.bin

View File

@ -76,15 +76,15 @@ add_dependencies(PREPARE_sd_boot BUILT_boot)
add_dependencies(sd_boot PREPARE_sd_boot)
add_dependencies(BUILT_sd_boot sd_boot)
add_dependencies(PREPARE_picomite BUILT_sd_boot)
add_dependencies(picomite PREPARE_picomite)
add_dependencies(BUILT_picomite picomite)
add_dependencies(PREPARE_PicoMite BUILT_sd_boot)
add_dependencies(PicoMite PREPARE_PicoMite)
add_dependencies(BUILT_PicoMite PicoMite)
# ***************************************************************************
# * Join the BOOT and all APP '.uf2' files together *
# ***************************************************************************
set(UF2S boot.uf2 sd_boot.uf2 picomite.uf2)
set(UF2S boot.uf2 sd_boot.uf2 PicoMite.uf2)
add_custom_target(JOIN
COMMENT "Combine the '.uf2' files"
@ -95,7 +95,7 @@ add_custom_target(JOIN
${UF2S}
)
add_dependencies(JOIN BUILT_picomite)
add_dependencies(JOIN BUILT_PicoMite)
add_custom_target(${PROJECT} ALL DEPENDS JOIN)

View File

@ -4,7 +4,7 @@ Here is a bootloader for PicoCalc combined slightly modified [PicoMite](https://
- Pico1
- No sdcard inserted,load default app to run from flash.
- Sdcard inserted, SD boot menu will show up, load third pico app bin to run at FLASH TARGET OFFSET 2048k-152k
- Sdcard inserted, SD boot menu will show up, load third pico app bin to run at FLASH TARGET OFFSET 2048k-200k
## How to compile
```
@ -24,20 +24,20 @@ Just copy **combined.uf2** into PicoCalc
## PicoMite
configuration.h
```
#define FLASH_TARGET_OFFSET (920 * 1024)
#define FLASH_TARGET_OFFSET (968 * 1024)
```
## sd_boot
config.h
```
#define SD_BOOT_FLASH_OFFSET (152 * 1024)
#define SD_BOOT_FLASH_OFFSET (200 * 1024)
```
### SD Card Application Build and Deployment
**Important Note:**
```
Applications intended for SD card boot "MUST REBUILD" using a custom linker script to accommodate the program's offset(152k) address.
Applications intended for SD card boot "MUST REBUILD" using a custom linker script to accommodate the program's offset(200k) address.
Applications intended for SD card boot is in **bin** format, not uf2.
@ -48,7 +48,7 @@ This section explains how to build and deploy applications on an SD card. Below
#### Step 1 Copy Custom Link Script
Copy `memmap_sdcard_app.ld` to your project repository.
Copy `memmap_default_rp2040.ld` and `memmap_default_rp2350.ld` to your project repository.
#### Step 2 Add Custom Link Script to CMakeList.txt
@ -61,7 +61,6 @@ pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
...
function(enable_sdcard_app target)
#pico_set_linker_script(${target} ${CMAKE_SOURCE_DIR}/memmap_sdcard_app.ld)
if(${PICO_PLATFORM} STREQUAL "rp2040")
pico_set_linker_script(${CMAKE_PROJECT_NAME} ${CMAKE_SOURCE_DIR}/memmap_default_rp2040.ld)
elseif(${PICO_PLATFORM} MATCHES "rp2350")

View File

@ -463,6 +463,14 @@ def Built(dir, app):
if adr + length - 1 > last : last = adr + length - 1
block = Uf2Block(f)
##enlarge sd_boot flash size
if app == "sd_boot":
print("original last: ", last," ",'{:02X}'.format(last))
print("orignal size: ","{:>3}k".format(Size(last-strt, 1024)))
print("orignal used: ","{:>3}k".format(Size(last, 4*1024)))
if last < 0x10032000:
last = 0x10032000
size = "{:>3}k".format(Size(last-strt, 1024))
used = "{:>3}k".format(Size(last, 4*1024))

View File

@ -1,7 +1,7 @@
/*arduino-pico*/
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 152k, LENGTH = __FLASH_LENGTH__ - 152k
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = __FLASH_LENGTH__ - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = __RAM_LENGTH__
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k

View File

@ -24,7 +24,7 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 152k, LENGTH = 2048k - 152k
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = 2048k - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k

View File

@ -4,7 +4,7 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 152k, LENGTH = 2048k - 152k
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = 2048k - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k

View File

@ -1,6 +1,6 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 152k, LENGTH = 2048k - 152k
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = 2048k - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k

View File

@ -23,7 +23,7 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 152k, LENGTH = 4096k - 152k
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = 4096k - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k
SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k

View File

@ -418,7 +418,7 @@ void fun_map(void);
{ (unsigned char *)"Drive", T_CMD, 0, cmd_disk },
{ (unsigned char *)"Play", T_CMD, 0, cmd_play },
{ (unsigned char *)"PIO", T_CMD, 0, cmd_pio },
{ (unsigned char *)"Text", T_CMD, 0, cmd_text },
{ (unsigned char *)"New", T_CMD, 0, cmd_new },
{ (unsigned char *)"Pixel", T_CMD, 0, cmd_pixel },
{ (unsigned char *)"Circle", T_CMD, 0, cmd_circle },
{ (unsigned char *)"Line", T_CMD, 0, cmd_line },
@ -480,7 +480,7 @@ void fun_map(void);
{ (unsigned char *)"Cat", T_CMD, 0, cmd_inc },
{ (unsigned char *)"Color", T_CMD, 0, cmd_colour },
{ (unsigned char *)"Files", T_CMD, 0, cmd_files },
{ (unsigned char *)"New", T_CMD, 0, cmd_new },
{ (unsigned char *)"Text", T_CMD, 0, cmd_text },
{ (unsigned char *)"Autosave", T_CMD, 0, cmd_autosave },
{ (unsigned char *)"WS2812", T_CMD, 0, cmd_WS2812 },
{ (unsigned char *)"Keypad", T_CMD, 0, cmd_keypad },

View File

@ -1,17 +1,43 @@
cmake_minimum_required(VERSION 3.13)
# Valid builds are PICO, PICOUSB, VGA, VGAUSB, HDMI(rp2350 only), HDMIUSB(rp2350 only), WEB
set(APP_NAME picomite)
set(PICOCALC true)
#set(SDBOOT true)
# For dynamic loading from SD card:
# SDBOOT requires the bootloader to be in the first 256KB of flash
# PicoMite will need to be shifted by this amount, and all references to
# positions in flash updated to accomodate. THIS OPTION IS NOT READY YET.
# details: https://github.com/adwuard/Picocalc_SD_Boot
set(SDBOOT true)
# Compile for PICO 1 Board
set(COMPILE PICO)
set(PICO_PLATFORM rp2040)
set(PICO_BOARD pico)
# Compile for PICO 2 Board
#set(COMPILE PICORP2350)
#set(COMPILE WEBRP2350)
add_executable(${APP_NAME}
if (COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "WEBRP2350" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "PICOUSBRP2350" )
set(PICO_PLATFORM rp2350)
if (COMPILE STREQUAL "WEBRP2350")
set(PICO_BOARD pico2_w)
else()
set(PICO_BOARD pimoroni_pga2350)
endif()
else()
set(PICO_PLATFORM rp2040)
if (COMPILE STREQUAL "WEB")
set(PICO_BOARD pico_w)
else()
set(PICO_BOARD pico)
endif()
endif()
include(pico_sdk_import.cmake)
project(PicoMite C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
#set(PICO_NO_COPRO_DIS 1)
pico_sdk_init()
add_executable(PicoMite
PicoMite.c
Memory.c
regex.c
@ -47,21 +73,56 @@ add_executable(${APP_NAME}
VS1053.c
aes.c
)
if (COMPILE STREQUAL "WEB" OR COMPILE STREQUAL "WEBRP2350" )
target_sources(PicoMite PRIVATE
SSD1963.c
Touch.c
GUI.c
cJSON.c
mqtt.c
MMMqtt.c
MMTCPclient.c
MMtelnet.c
MMntp.c
MMtcpserver.c
tftp.c
MMtftp.c
MMudp.c
)
set_source_files_properties(cJSON.c PROPERTIES COMPILE_FLAGS -Os)
target_include_directories(PicoMite PRIVATE
${CMAKE_CURRENT_LIST_DIR}
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts
)
Pico_enable_stdio_usb(PicoMite 1)
endif()
target_sources(${APP_NAME} PRIVATE
if ((COMPILE STREQUAL "PICO") OR (COMPILE STREQUAL "PICOUSB") OR (COMPILE STREQUAL "PICORP2350") OR (COMPILE STREQUAL "PICOUSBRP2350") OR (COMPILE STREQUAL "WEBRP2350"))
target_sources(PicoMite PRIVATE
SSD1963.c
Touch.c
GUI.c)
endif()
target_sources(${APP_NAME} PRIVATE
if (COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "PICOUSBRP2350" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "PICOUSB" OR COMPILE STREQUAL "HDMIUSB")
target_sources(PicoMite PRIVATE
USBKeyboard.c
)
else()
target_sources(PicoMite PRIVATE
Keyboard.c
mouse.c
)
endif()
if(COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "WEBRP2350" OR COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "PICOUSBRP2350")
target_sources(PicoMite PRIVATE
upng.c
)
endif()
if(PICOCALC STREQUAL "true")
target_sources(${APP_NAME} PRIVATE
target_sources(PicoMite PRIVATE
picocalc/i2ckbd.c
)
endif()
@ -79,27 +140,33 @@ set_source_files_properties(hxcmod.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(MATHS.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(Editor.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(aes.c PROPERTIES COMPILE_FLAGS -Os)
pico_generate_pio_header(${APP_NAME} ${CMAKE_CURRENT_LIST_DIR}/PicoMiteI2S.pio)
pico_define_boot_stage2(slower_boot2 ${PICO_DEFAULT_BOOT_STAGE2_FILE})
target_compile_definitions(slower_boot2 PRIVATE PICO_FLASH_SPI_CLKDIV=4)
pico_set_boot_stage2(${APP_NAME} slower_boot2)
pico_enable_stdio_usb(${APP_NAME} 1)
pico_enable_stdio_uart(${APP_NAME} 0)
pico_add_extra_outputs(${APP_NAME})
pico_add_uf2_output(${APP_NAME})
target_link_options(${APP_NAME} PRIVATE -Wl,--print-memory-usage)
target_link_options(${APP_NAME} PRIVATE -Wl,-z,max-page-size=4096)
pico_set_linker_script(${APP_NAME} ${CMAKE_BINARY_DIR}/${APP_NAME}.ld)
pico_generate_pio_header(PicoMite ${CMAKE_CURRENT_LIST_DIR}/PicoMiteI2S.pio)
if (COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "VGA" OR COMPILE STREQUAL "PICO" OR COMPILE STREQUAL "PICOUSB" OR COMPILE STREQUAL "WEB")
pico_define_boot_stage2(slower_boot2 ${PICO_DEFAULT_BOOT_STAGE2_FILE})
target_compile_definitions(slower_boot2 PRIVATE PICO_FLASH_SPI_CLKDIV=4)
pico_set_boot_stage2(PicoMite slower_boot2)
endif()
if (COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "VGA" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "VGARP2350")
pico_generate_pio_header(PicoMite ${CMAKE_CURRENT_LIST_DIR}/PicoMiteVGA.pio)
endif()
pico_set_printf_implementation(${APP_NAME} compiler)
if (COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "PICOUSB" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "PICOUSBRP2350" OR COMPILE STREQUAL "VGAUSBRP2350")
Pico_enable_stdio_usb(PicoMite 0)
target_include_directories(PicoMite PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/usb_host_files
)
else()
Pico_enable_stdio_usb(PicoMite 1)
endif()
target_compile_options(${APP_NAME} PRIVATE -DNDEBUG
pico_enable_stdio_uart(PicoMite 0)
pico_add_extra_outputs(PicoMite)
pico_set_printf_implementation(PicoMite compiler)
if(COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "WEBRP2350" OR COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "PICOUSBRP2350")
pico_set_float_implementation(PicoMite pico_dcp)
endif()
target_compile_options(PicoMite PRIVATE -DNDEBUG
-DPICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE=0
-DPICO_ADC_CLKDIV_ROUND_NEAREST
-DPICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
@ -110,22 +177,64 @@ target_compile_options(${APP_NAME} PRIVATE -DNDEBUG
-DPICO_MALLOC_PANIC
-O2
-Wall)
target_compile_options(${APP_NAME} PRIVATE -DPICOMITE
-DPICO_HEAP_SIZE=0x1000
-DGUICONTROLS
-DPICO_CORE0_STACK_SIZE=0x1000
# all RP2350 variants
if (COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "WEBRP2350" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "PICOUSBRP2350" OR COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "VGAUSBRP2350")
target_compile_options(PicoMite PRIVATE -Drp2350
-DPICO_FLASH_SPI_CLKDIV=4
-DPICO_PIO_USE_GPIO_BASE
)
endif()
# all PicoMite variants - enable the gui
if (COMPILE STREQUAL "PICO" OR COMPILE STREQUAL "PICOUSB" OR COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "PICOUSBRP2350")
target_compile_options(PicoMite PRIVATE -DPICOMITE
-DPICO_HEAP_SIZE=0x1000
-DGUICONTROLS
-DPICO_CORE0_STACK_SIZE=0x1000
)
endif()
# all VGA variants
if (COMPILE STREQUAL "VGA" OR COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "VGAUSBRP2350")
target_compile_options(PicoMite PRIVATE -DPICOMITEVGA
-DPICO_HEAP_SIZE=0x2000
-DPICO_CORE0_STACK_SIZE=0x2000
)
endif()
# HDMI variants
if (COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "HDMIUSB")
target_compile_options(PicoMite PRIVATE -DPICOMITEVGA
-DHDMI
-DPICO_HEAP_SIZE=0x2000
-DPICO_CORE0_STACK_SIZE=0x2000
)
endif()
#Web variants need more heap
if(COMPILE STREQUAL "WEB" OR COMPILE STREQUAL "WEBRP2350")
target_compile_options(PicoMite PRIVATE -DPICOMITEWEB
-DPICO_HEAP_SIZE=0x4000
-DGUICONTROLS
-DCYW43_HOST_NAME="WebMite"
-DPICO_CYW43_ARCH_POLL
-DPICO_CORE0_STACK_SIZE=0x4000
)
endif()
#USB variants
if (COMPILE STREQUAL "PICOUSB" OR COMPILE STREQUAL "PICOUSBRP2350" OR COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "HDMIUSB")
target_compile_options(PicoMite PRIVATE -DUSBKEYBOARD
)
endif()
#special case WEB RP2350 gets the GUI controls
if(COMPILE STREQUAL "WEBRP2350")
target_compile_options(PicoMite PRIVATE -DGUICONTROLS
)
endif()
#set the PICOCALC flag
if(PICOCALC STREQUAL "true")
target_compile_options(${APP_NAME} PRIVATE -DPICOCALC
target_compile_options(PicoMite PRIVATE -DPICOCALC
)
endif()
target_link_libraries(${APP_NAME}
target_link_libraries(PicoMite
pico_stdlib
hardware_flash
hardware_irq
@ -136,39 +245,65 @@ target_link_libraries(${APP_NAME}
hardware_dma
hardware_exception
hardware_pio
pico_multicore
pico_unique_id
)
if(COMPILE STREQUAL "VGAUSB" OR COMPILE STREQUAL "PICOUSB" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "PICOUSBRP2350" OR COMPILE STREQUAL "VGAUSBRP2350")
target_link_libraries(PicoMite
tinyusb_host
tinyusb_board
pico_multicore
)
endif()
set(UF2_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/${APP_NAME}.uf2)
set(UF2_DEST ${CMAKE_BINARY_DIR}/${APP_NAME}.uf2)
if(COMPILE STREQUAL "VGA" OR COMPILE STREQUAL "PICO" OR COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "PICORP2350")
target_link_libraries(PicoMite
pico_multicore
)
endif()
if(COMPILE STREQUAL "VGARP2350" OR COMPILE STREQUAL "WEBRP2350" OR COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "HDMI" OR COMPILE STREQUAL "HDMIUSB" OR COMPILE STREQUAL "VGAUSBRP2350" OR COMPILE STREQUAL "PICOUSBRP2350")
target_link_libraries(PicoMite
pico_rand
)
endif()
if(COMPILE STREQUAL "WEB" OR COMPILE STREQUAL "WEBRP2350" )
target_link_libraries(PicoMite
pico_cyw43_arch_lwip_poll
)
endif()
if(SDBOOT STREQUAL "true" AND (COMPILE STREQUAL "PICORP2350" OR COMPILE STREQUAL "WEBRP2350"))
pico_set_linker_script(PicoMite ${CMAKE_SOURCE_DIR}/memmap_default_rp2350.ld)
endif()
if(SDBOOT STREQUAL "true" AND (COMPILE STREQUAL "PICO"))
pico_set_linker_script(PicoMite ${CMAKE_SOURCE_DIR}/memmap_default_rp2040.ld)
endif()
set(UF2_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/PicoMite.uf2)
set(UF2_DEST ${CMAKE_BINARY_DIR}/PicoMite.uf2)
add_custom_command(
OUTPUT ${UF2_DEST}
DEPENDS ${UF2_SOURCE}
COMMAND ${CMAKE_COMMAND} -E copy ${UF2_SOURCE} ${UF2_DEST}
COMMENT "Copying ${APP_NAME}.uf2 to top-level build dir"
COMMENT "Copying PicoMite.uf2 to top-level build dir"
)
add_custom_target(PREPARE_${APP_NAME}
COMMENT "Create Linker Script for '${APP_NAME}'"
add_custom_target(PREPARE_PicoMite
COMMENT "Create Linker Script for 'PicoMite'"
COMMAND ${Python3_EXECUTABLE}
${CMAKE_SOURCE_DIR}/applink.py PREPARE
${CMAKE_BINARY_DIR}
${APP_NAME})
PicoMite)
add_custom_target(BUILT_${APP_NAME}
COMMENT "Record Build Details for '${APP_NAME}'"
add_custom_target(BUILT_PicoMite
COMMENT "Record Build Details for 'PicoMite'"
DEPENDS ${UF2_DEST}
COMMAND ${Python3_EXECUTABLE}
${CMAKE_SOURCE_DIR}/applink.py BUILT
${CMAKE_BINARY_DIR}
${APP_NAME})
PicoMite)
if(SDBOOT STREQUAL "true")
pico_set_linker_script(${APP_NAME} ${CMAKE_SOURCE_DIR}/memmap_sdcard_app.ld)
endif()

View File

@ -955,13 +955,13 @@ int printWrappedText(const char *text, int screenWidth, int listcnt, int all) {
void cmd_help(void){
getargs(&cmdline,1,(unsigned char *)",");
if(!ExistsFile("A:/help.txt"))error("A:/help.txt not found");
if(!ExistsFile("B:/help.txt"))error("B:/help.txt not found");
if(!argc){
MMPrintString("Enter help and the name of the command or function\r\nUse * for multicharacter wildcard or ? for single character wildcard\r\n");
} else {
int fnbr = FindFreeFileNbr();
char *buff=GetTempMemory(STRINGSIZE);
BasicFileOpen("A:/help.txt",fnbr, FA_READ);
BasicFileOpen("B:/help.txt",fnbr, FA_READ);
int ListCnt = CurrentY/(FontTable[gui_font >> 4][1] * (gui_font & 0b1111)) + 2;
char *p=(char *)getCstring(argv[0]);
bool end=false;
@ -1251,9 +1251,20 @@ retest_an_if:
// and it is just a number, so get it and find the line
nextstmt = findline(getinteger(argv[4]), true);
else {
// there is a statement after the ELSE clause so just point to it (the byte after the ELSE token)
/* // there is a statement after the ELSE clause so just point to it (the byte after the ELSE token)
for(p = cmdline; *p && *p != ss[1]; p++); // search for the token
nextstmt = p + 1; // and point to the byte after
*/
// IF <condition> THEN <statement1> ELSE <statement2>
// Find and read the THEN function token.
for(p = cmdline; *p && *p != ss[0]; p++){}
// Skip the command that <statement1> must start with.
p++;
skipspace(p);
p += sizeof(CommandToken);
// Find and read the ELSE function token.
for(; *p && *p != ss[1]; p++);
nextstmt = p+1; // The statement after the ELSE token.
}
} else {
// no ELSE on a single line IF statement, so just continue with the next statement
@ -1608,7 +1619,7 @@ void MIPS16 do_chain(unsigned char *cmdline){
SaveContext();
ClearVars(0,false);
InitHeap(false);
if (*filename && !FileLoadProgram(buf, true)) return;
if (*buf && !FileLoadProgram(buf, true)) return;
ClearRuntime(false);
PrepareProgram(true);
RestoreContext(false);
@ -2108,7 +2119,8 @@ void MIPS16 __not_in_flash_func(cmd_do)(void) {
unsigned char *p, *tp, *evalp;
if(cmdtoken==cmdWHILE)error("Unknown command");
// if it is a DO loop find the WHILE token and (if found) get a pointer to its expression
while(*cmdline && *cmdline != tokenWHILE) cmdline++;
while(*cmdline && *cmdline != tokenWHILE && *cmdline != tokenUNTIL) cmdline++;
if(*cmdline == tokenUNTIL)error("Syntax");
if(*cmdline == tokenWHILE) {
evalp = ++cmdline;
}
@ -3638,7 +3650,7 @@ void execute(char* mycmd) {
}
else {
unsigned char* p = inpbuf;
char* q;
// char* q;
// char fn[STRINGSIZE] = { 0 };
unsigned short tkn=GetCommandValue((unsigned char *)"RUN");
tknbuf[0] = (tkn & 0x7f ) + C_BASETOKEN;
@ -3646,10 +3658,10 @@ void execute(char* mycmd) {
p[0] = (tkn & 0x7f ) + C_BASETOKEN;
p[1] = (tkn >> 7) + C_BASETOKEN; //tokens can be 14-bit
memmove(&p[2], &p[4], strlen((char *)p) - 4);
if ((q = strchr((char *)p, ':'))) {
/* if ((q = strchr((char *)p, ':'))) {
q--;
*q = '0';
}
}*/
p[strlen((char*)p) - 2] = 0;
// MMPrintString(fn); PRet();
// CloseAudio(1);

View File

@ -46,7 +46,6 @@ extern mutex_t frameBufferMutex;
#define LONG long
#define max(x, y) (((x) > (y)) ? (x) : (y))
#define min(x, y) (((x) < (y)) ? (x) : (y))
#define RoundUptoInt(a) (((a) + (32 - 1)) & (~(32 - 1)))// round up to the nearest whole integer
void DrawFilledCircle(int x, int y, int radius, int r, int fill, int ints_per_line, uint32_t *br, MMFLOAT aspect, MMFLOAT aspect2);
void hline(int x0, int x1, int y, int f, int ints_per_line, uint32_t *br);
void SaveTriangle(int bnbr, char *buff);
@ -118,7 +117,7 @@ typedef struct _BMPDECODER
short gui_font;
int gui_fcolour;
int gui_bcolour;
short low_y=LCDMaxV, high_y=0, low_x=LCDMaxH, high_x=0;
short low_y=2000, high_y=-1, low_x=2000, high_x=-1;
int PrintPixelMode=0;
short CurrentX=0, CurrentY=0; // the current default position for the next char to be written
@ -4982,7 +4981,7 @@ void restorepanel(void){
DrawPixel = DrawPixelNormal;
DrawBLITBuffer = DrawBufferSPISCR;
ScrollLCD = ScrollLCDSPISCR;
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
ReadBuffer = ReadBufferSPISCR;
ReadBLITBuffer = ReadBufferSPISCR;
}
@ -4992,7 +4991,7 @@ void restorepanel(void){
DrawBuffer = DrawBufferSPI;
DrawPixel = DrawPixelNormal;
DrawBLITBuffer = DrawBufferSPI;
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
ReadBLITBuffer = ReadBufferSPI;
ReadBuffer = ReadBufferSPI;
ScrollLCD = ScrollLCDSPI;
@ -5024,7 +5023,7 @@ void restorepanel(void){
WriteBuf=NULL;
}
void setframebuffer(void){
if(!((Option.DISPLAY_TYPE>I2C_PANEL && Option.DISPLAY_TYPE < BufferedPanel) || (Option.DISPLAY_TYPE>=SSDPANEL && Option.DISPLAY_TYPE<VIRTUAL)))return;
if(!((Option.DISPLAY_TYPE>I2C_PANEL && Option.DISPLAY_TYPE < BufferedPanel) || (Option.DISPLAY_TYPE>=SSDPANEL && Option.DISPLAY_TYPE<VIRTUAL) || Option.DISPLAY_TYPE>=NEXTGEN))return;
DrawRectangle=DrawRectangle16;
DrawBitmap= DrawBitmap16;
ScrollLCD=ScrollLCD16;
@ -5294,7 +5293,7 @@ void blitmerge (int x0, int y0, int w, int h, uint8_t colour){
#ifdef PICOMITE
mutex_enter_blocking(&frameBufferMutex); // lock the frame buffer
#endif
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P ){
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P ){
while(GetLineILI9341()!=0){}
}
for(int y=y0;y<y0+h;y++){
@ -5331,7 +5330,7 @@ void merge(uint8_t colour){
#ifdef PICOMITE
mutex_enter_blocking(&frameBufferMutex); // lock the frame buffer
#endif
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P ){
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P ){
while(GetLineILI9341()!=0){}
}
for(int y=0;y<VRes;y++){
@ -5353,9 +5352,9 @@ void merge(uint8_t colour){
copyframetoscreen(LineBuf,0,HRes-1,y,y,0);
}
#ifdef PICOMITE
mutex_exit(&frameBufferMutex);
mergedone=true;
__dmb();
mutex_exit(&frameBufferMutex);
mergedone=true;
__dmb();
#endif
}
/* @endcond */
@ -5459,7 +5458,7 @@ void cmd_framebuffer(void){
LayerBuf=GetMemory(HRes*VRes/2);
} else error("Layer already exists");
} else if((p=checkstring(cmdline, (unsigned char *)"WAIT"))) {
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P ){
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P ){
while(GetLineILI9341()!=0){}
}
} else if((p=checkstring(cmdline, (unsigned char *)"CLOSE"))) {
@ -7023,7 +7022,7 @@ void cmd_refresh(void){
void DrawPixel16(int x, int y, int c){
if(x<0 || y<0 || x>=HRes || y>=VRes)return;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
unsigned char colour = RGB121(c);
uint8_t *p=(uint8_t *)(((uint32_t) WriteBuf)+(y*(HRes>>1))+(x>>1));
if(x & 1){
@ -7039,7 +7038,7 @@ void DrawRectangle16(int x1, int y1, int x2, int y2, int c){
// unsigned char mask;
unsigned char colour = RGB121(c);;
unsigned char bcolour=(colour<<4) | colour;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if(x1 < 0) x1 = 0;
if(x1 >= HRes) x1 = HRes - 1;
if(x2 < 0) x2 = 0;
@ -7077,7 +7076,7 @@ void DrawBitmap16(int x1, int y1, int width, int height, int scale, int fc, int
if(x1>=HRes || y1>=VRes || x1+width*scale<0 || y1+height*scale<0)return;
unsigned char fcolour = RGB121(fc);
unsigned char bcolour = RGB121(bc);
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
for(i = 0; i < height; i++) { // step thru the font scan line by line
for(j = 0; j < scale; j++) { // repeat lines to scale the font
for(k = 0; k < width; k++) { // step through each bit in a scan line
@ -7139,7 +7138,7 @@ void DrawBuffer16(int x1, int y1, int x2, int y2, unsigned char *p){
} c;
unsigned char fcolour;
uint8_t *pp;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
@ -7175,7 +7174,7 @@ void DrawBuffer16Fast(int x1, int y1, int x2, int y2, int blank, unsigned char *
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
for(y=y1;y<=y2;y++){
for(x=x1;x<=x2;x++){
if(x>=0 && x<HRes && y>=0 && y<VRes){
@ -7210,7 +7209,7 @@ void DrawBuffer16Fast(int x1, int y1, int x2, int y2, int blank, unsigned char *
void ReadBuffer16(int x1, int y1, int x2, int y2, unsigned char *c){
int x,y,t;
uint8_t *pp;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
int xx1=x1, yy1=y1, xx2=x2, yy2=y2;
@ -7254,7 +7253,7 @@ void ReadBuffer16Fast(int x1, int y1, int x2, int y2, unsigned char *c){
uint8_t *pp;
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
for(y=y1;y<=y2;y++){
for(x=x1;x<=x2;x++){
if(x>=0 && x<HRes && y>=0 && y<VRes){
@ -7283,7 +7282,7 @@ void Display_Refresh(void){
#endif
void DrawPixel2(int x, int y, int c){
if(x<0 || y<0 || x>=HRes || y>=VRes)return;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
uint8_t *p=(uint8_t *)(((uint32_t) WriteBuf)+(y*(HRes>>3))+(x>>3));
uint8_t bit = 1<<(x % 8);
if(c)*p |=bit;
@ -7293,7 +7292,7 @@ void DrawRectangle2(int x1, int y1, int x2, int y2, int c){
int x,y,x1p, x2p, t;
unsigned char mask;
volatile unsigned char *p;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if(x1 < 0) x1 = 0;
if(x1 >= HRes) x1 = HRes - 1;
if(x2 < 0) x2 = 0;
@ -7361,7 +7360,7 @@ void DrawBitmap2(int x1, int y1, int width, int height, int scale, int fc, int b
unsigned char mask;
if(x1>=HRes || y1>=VRes || x1+width*scale<0 || y1+height*scale<0)return;
int tilematch=0;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
#ifdef PICOMITEVGA
int xa= 8;
int ya=ytileheight;
@ -7560,7 +7559,7 @@ void DrawBuffer2(int x1, int y1, int x2, int y2, unsigned char *p){
char rgbbytes[4];
unsigned int rgb;
} c;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
@ -7597,7 +7596,7 @@ void DrawBuffer2Fast(int x1, int y1, int x2, int y2, int blank, unsigned char *p
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
for(y=y1;y<=y2;y++){
for(x=x1;x<=x2;x++){
if(x>=0 && x<HRes && y>=0 && y<VRes){
@ -7629,7 +7628,7 @@ void ReadBuffer2(int x1, int y1, int x2, int y2, unsigned char *c){
int x,y,t,loc;
// uint8_t *pp;
unsigned char mask;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
int xx1=x1, yy1=y1, xx2=x2, yy2=y2;
@ -7670,7 +7669,7 @@ void ReadBuffer2Fast(int x1, int y1, int x2, int y2, unsigned char *c){
int x,y,t,loc,toggle=0;;
// uint8_t *pp;
unsigned char mask;
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if((Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN) && WriteBuf==NULL) WriteBuf=GetMemory(VMaxH*VMaxV/8);
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
for(y=y1;y<=y2;y++){
@ -7713,7 +7712,7 @@ void MIPS16 ConfigDisplayVirtual(unsigned char *p) {
Option.DISPLAY_ORIENTATION = LANDSCAPE;
}
void MIPS16 InitDisplayVirtual(void){
if(Option.DISPLAY_TYPE==0 || Option.DISPLAY_TYPE < VIRTUAL) return;
if(Option.DISPLAY_TYPE==0 || Option.DISPLAY_TYPE < VIRTUAL || Option.DISPLAY_TYPE >= NEXTGEN) return;
DisplayHRes = HRes = display_details[Option.DISPLAY_TYPE].horizontal;
DisplayVRes = VRes = display_details[Option.DISPLAY_TYPE].vertical;
if(Option.DISPLAY_TYPE==VIRTUAL_M){

View File

@ -105,8 +105,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#define PIN_RESTART 9997 // reset caused by entering 0 at the PIN prompt
#define RESTART_NOAUTORUN 9996 // reset required after changing the LCD or touch config
#define PinRead(a) gpio_get(PinDef[a].GPno)
#define LCDMaxV 480
#define LCDMaxH 800
#define VMaxV 480
#define VMaxH 640
extern int GetJustification(char *p, int *jh, int *jv, int *jo);

View File

@ -374,8 +374,8 @@ void edit(unsigned char *cmdline, bool cmdfile) {
gui_fcolour = WHITE;
gui_bcolour = BLACK;
}
if(Option.DISPLAY_CONSOLE == true && gui_font_width > 16*HRes/640) error("Font is too large");
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf)FreeMemorySafe((void **)&WriteBuf);
if(Option.DISPLAY_CONSOLE == true && HRes/gui_font_width <32) error("Font is too large");
if(Option.DISPLAY_TYPE>=VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN && WriteBuf)FreeMemorySafe((void **)&WriteBuf);
if(cmdfile){
ClearVars(0,true);
ClearRuntime(true);
@ -578,12 +578,9 @@ void FullScreenEditor(int xx, int yy, char *fname, int edit_buff_size, bool cmdf
int ytileheightsave;
ytileheightsave=ytileheight;
OptionY_TILESave=Y_TILE;
if(!Option.ColourCode)ytileheight=16;
else {
ytileheight=gui_font_height;
Y_TILE=VRes/ytileheight;
if(VRes % ytileheight)Y_TILE++;
}
ytileheight=gui_font_height;
Y_TILE=VRes/ytileheight;
if(VRes % ytileheight)Y_TILE++;
#else
char RefreshSave=Option.Refresh;
Option.Refresh=0;

View File

@ -1581,7 +1581,6 @@ void cmd_port(void) {
if(!code)pin=codemap(pincode);
else pin=pincode;
if(IsInvalidPin(pin) || !(ExtCurrentConfig[pin] == EXT_DIG_OUT )) error("Invalid output pin");
gpio_set_input_enabled(PinDef[pin].GPno, true);
mask |=(1<<PinDef[pin].GPno);
if(value & 1)setmask |= (1<<PinDef[pin].GPno);
value >>= 1;
@ -1589,23 +1588,9 @@ void cmd_port(void) {
pincode++;
}
}
readmask=gpio_get_all64();
readmask=gpio_get_out_level_all64();
readmask &=mask;
gpio_xor_mask64(setmask ^ readmask);
#ifdef rp2350
#ifdef PICOMITEWEB
int n=NBRPINS;
#else
int n=rp2350a ? 44: NBRPINS;
#endif
#else
int n=NBRPINS;
#endif
for(int i=0;i<n;i++){
if(mask & 1)gpio_set_input_enabled(PinDef[i].GPno, false);
mask>>=1;
}
gpio_xor_mask(setmask ^ readmask);
}
@ -1660,6 +1645,7 @@ void fun_port(void) {
getargs(&ep, NBRPINS * 4, (unsigned char *)",");
if((argc & 0b11) != 0b11) error("Invalid syntax");
uint64_t pinstate=gpio_get_all64();
uint64_t outpinstate=gpio_get_out_level_all64();
for(i = argc - 3; i >= 0; i -= 4) {
code=0;
if(!(code=codecheck(argv[i])))argv[i]+=2;
@ -1673,7 +1659,8 @@ void fun_port(void) {
else pin=pincode;
if(IsInvalidPin(pin) || !(ExtCurrentConfig[pin] == EXT_DIG_IN || ExtCurrentConfig[pin] == EXT_DIG_OUT || ExtCurrentConfig[pin] == EXT_INT_HI || ExtCurrentConfig[pin] == EXT_INT_LO || ExtCurrentConfig[pin] == EXT_INT_BOTH)) error("Invalid input pin");
value <<= 1;
value |= (pinstate & (1<<PinDef[pin].GPno)? 1:0);
if(ExtCurrentConfig[pin] == EXT_DIG_OUT)value |= (outpinstate & (1<<PinDef[pin].GPno)? 1:0);
else value |= (pinstate & (1<<PinDef[pin].GPno)? 1:0);
nbr--;
pincode--;
}

View File

@ -476,8 +476,10 @@ void MIPS16 cmd_psram(void)
pp--;
if ((unsigned char)*pp == T_NEWLINE)
{
char *p=(char *)pp;
MMPrintString(": \"");
llist((unsigned char *)buff, (unsigned char *)pp);
buff[0]='\'';buff[1]='#';
while(buff[0]=='\'' && buff[1]=='#')p=(char *)llist((unsigned char *)buff, (unsigned char *)p);
MMPrintString(buff);
MMPrintString("\"\r\n");
}
@ -495,32 +497,6 @@ void MIPS16 cmd_psram(void)
}
}
}
else if ((p = checkstring(cmdline, (unsigned char *)"DISK LOAD")))
{
int fsize,overwrite=0;
getargs(&p,5,(unsigned char *)",");
if(!(argc==3 || argc==5))error("Syntax");
int i = getint(argv[0], 1, MAXRAMSLOTS);
if(argc==5){
if(checkstring(argv[4],(unsigned char *)"O") || checkstring(argv[4],(unsigned char *)"OVERWRITE"))overwrite=1;
else error("Syntax");
}
uint32_t *c = (uint32_t *)(PSRAMblock + ((i - 1) * MAX_PROG_SIZE));
if (*c != 0x0 && overwrite==0) error("Already programmed");
int fnbr = FindFreeFileNbr();
if (!InitSDCard()) return;
char *pp = (char *)getFstring(argv[2]);
if (!BasicFileOpen((char *)pp, fnbr, FA_READ)) return;
if(filesource[fnbr]!=FLASHFILE) fsize = f_size(FileTable[fnbr].fptr);
else fsize = lfs_file_size(&lfs,FileTable[fnbr].lfsptr);
if(fsize>MAX_PROG_SIZE)error("File size % cannot exceed %",fsize,MAX_PROG_SIZE);
uint8_t *q=(uint8_t *)c;
memset(q,0,MAX_PROG_SIZE);
for(int k = 0; k < fsize; k++){ // write to the flash byte by byte
*q++=FileGetChar(fnbr);
}
FileClose(fnbr);
}
else if ((p = checkstring(cmdline, (unsigned char *)"FILE LOAD")))
{
int overwrite=0;
@ -533,6 +509,7 @@ void MIPS16 cmd_psram(void)
}
uint8_t *c = (uint8_t *)(PSRAMblock + ((i - 1) * MAX_PROG_SIZE));
if (*c != 0x0 && overwrite==0) error("Already programmed");
memset(c,0xFF,MAX_PROG_SIZE);
ClearTempMemory();
SaveContext();
MemLoadProgram(argv[2],c);
@ -717,8 +694,10 @@ void MIPS16 cmd_flash(void)
pp--;
if ((unsigned char)*pp == T_NEWLINE)
{
char *p=(char *)pp;
MMPrintString(": \"");
llist((unsigned char *)buff, (unsigned char *)pp);
buff[0]='\'';buff[1]='#';
while(buff[0]=='\'' && buff[1]=='#')p=(char *)llist((unsigned char *)buff, (unsigned char *)p);
MMPrintString(buff);
MMPrintString("\"\r\n");
}
@ -5017,7 +4996,7 @@ void LoadOptions(void)
RGB121map[15] = WHITE;
#ifdef PICOCALC
Option.DISPLAY_TYPE = ILI9488P;
Option.DISPLAY_TYPE = ST7796SP;
Option.SYSTEM_CLK = 14;
Option.SYSTEM_MOSI = 15;
Option.SYSTEM_MISO = 16;
@ -5083,6 +5062,7 @@ void ResetOptions(bool startup)
Option.DefaultBrightness = 100;
Option.Baudrate = CONSOLE_BAUDRATE;
Option.PROG_FLASH_SIZE=MAX_PROG_SIZE;
Option.ColourCode=0x01;
#ifdef PICOMITEVGA
Option.DISPLAY_CONSOLE = 1;
Option.DISPLAY_TYPE = SCREENMODE1;
@ -5259,7 +5239,6 @@ void FlashWriteAlign(void)
}
FlashWriteWord(0xFFFFFFFF);
}
void FlashWriteClose(void)
{
while (mi8p != 0)
@ -5505,13 +5484,19 @@ void ClearSavedVars(void)
}
void SaveOptions(void)
{
uint8_t buf[FLASH_ERASE_SIZE];
// load flash content to buf
memcpy(buf, (const void*)(XIP_BASE + FLASH_TARGET_OFFSET), FLASH_ERASE_SIZE);
// overwrite the options
memcpy(buf, (const uint8_t *)&Option, sizeof(struct option_s));
uSec(100000);
disable_interrupts_pico();
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_ERASE_SIZE);
enable_interrupts_pico();
uSec(10000);
disable_interrupts_pico();
flash_range_program(FLASH_TARGET_OFFSET, (const uint8_t *)&Option, sizeof(struct option_s));
// save flash block back
flash_range_program(FLASH_TARGET_OFFSET, buf, FLASH_ERASE_SIZE);
enable_interrupts_pico();
}
/* @endcond */

View File

@ -508,8 +508,8 @@ typedef enum {
MMCMDLINE,
#ifdef PICOMITEWEB
MMMESSAGE,
MMTOPIC,
MMADDRESS,
MMTOPIC,
#endif
MMFLAG,
MMDISPLAY,
@ -575,16 +575,16 @@ typedef enum {
Mstrcpy(sret,messagebuff);
targ=T_STR;
break;
case MMTOPIC:
sret = GetTempMemory(STRINGSIZE); // this will last for the life of the command
Mstrcpy(sret,topicbuff);
targ=T_STR;
break;
case MMADDRESS:
sret = GetTempMemory(STRINGSIZE); // this will last for the life of the command
Mstrcpy(sret,addressbuff);
targ=T_STR;
break;
case MMTOPIC:
sret = GetTempMemory(STRINGSIZE); // this will last for the life of the command
Mstrcpy(sret,topicbuff);
targ=T_STR;
break;
#endif
case MMFLAG:
iret=g_flag;

View File

@ -62,6 +62,7 @@ extern volatile unsigned int PauseTimer;
extern volatile unsigned int IntPauseTimer;
extern volatile unsigned int Timer1, Timer2, Timer3, Timer4, Timer5; //1000Hz decrement timer
extern volatile unsigned int diskchecktimer;
extern volatile unsigned int clocktimer;
extern volatile int ds18b20Timer;
extern volatile int CursorTimer;
extern volatile unsigned int I2CTimer;
@ -297,8 +298,10 @@ extern struct tagMTRand *g_myrand;
#define putch _putch
#endif
#endif
#define nunaddr 0xA4 / 2
#define CURSOR_OFF 350 // cursor off time in mS
#define CURSOR_ON 650 // cursor on time in mS
#define RoundUptoInt(a) (((a) + (32 - 1)) & (~(32 - 1)))// round up to the nearest whole integer
#define dp(...) {unsigned char s[140];sprintf((char *)s, __VA_ARGS__); MMPrintString((char *)s); MMPrintString((char *)"\r\n");}

View File

@ -40,7 +40,6 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#include "hardware/irq.h"
#define nunaddr 0xA4 / 2;
#define PinRead(a) gpio_get(PinDef[a].GPno)
extern void DrawBufferMEM(int x1, int y1, int x2, int y2, unsigned char * p);
extern void ReadBufferMEM(int x1, int y1, int x2, int y2, unsigned char * buff);
@ -304,11 +303,17 @@ void cmd_i2c(void) {
"CLOSE")) != NULL)
i2cDisable(p);
else if ((p = checkstring(cmdline, (unsigned char * )
"WRITE")) != NULL)
i2cSend(p);
"WRITE")) != NULL){
if(I2C0SDApin==Option.SYSTEM_I2C_SDA) I2C_Timeout=1000;
i2cSend(p);
if(I2C0SDApin==Option.SYSTEM_I2C_SDA) I2C_Timeout=SystemI2CTimeout;
}
else if ((p = checkstring(cmdline, (unsigned char * )
"READ")) != NULL)
i2cReceive(p);
"READ")) != NULL){
if(I2C0SDApin==Option.SYSTEM_I2C_SDA) I2C_Timeout=1000;
i2cReceive(p);
if(I2C0SDApin==Option.SYSTEM_I2C_SDA) I2C_Timeout=SystemI2CTimeout;
}
else if ((p = checkstring(cmdline, (unsigned char * )
"CHECK")) != NULL)
i2cCheck(p);
@ -338,11 +343,17 @@ void cmd_i2c2(void) {
"CLOSE")) != NULL)
i2c2Disable(p);
else if ((p = checkstring(cmdline, (unsigned char * )
"WRITE")) != NULL)
i2c2Send(p);
"WRITE")) != NULL){
if(I2C1SDApin==Option.SYSTEM_I2C_SDA) I2C2_Timeout=1000;
i2c2Send(p);
if(I2C1SDApin==Option.SYSTEM_I2C_SDA) I2C2_Timeout=SystemI2CTimeout;
}
else if ((p = checkstring(cmdline, (unsigned char * )
"READ")) != NULL)
i2c2Receive(p);
"READ")) != NULL){
if(I2C1SDApin==Option.SYSTEM_I2C_SDA) I2C2_Timeout=1000;
i2c2Receive(p);
if(I2C1SDApin==Option.SYSTEM_I2C_SDA) I2C2_Timeout=SystemI2CTimeout;
}
else if ((p = checkstring(cmdline, (unsigned char * )
"CHECK")) != NULL)
i2c2Check(p);
@ -614,6 +625,7 @@ void CheckI2CKeyboard(int noerror, int read) {
void RtcGetTime(int noerror) {
char * buff = GetTempMemory(STRINGSIZE); // Received data is stored here
int DS1307;
clocktimer=(1000*60*60);
if (I2C0locked) {
I2C_Sendlen = 1; // send one byte
I2C_Rcvlen = 0;
@ -691,9 +703,24 @@ void MIPS16 cmd_rtc(void) {
unsigned char * p;
void * ptr = NULL;
if (!(I2C0locked || I2C1locked)) error("SYSTEM I2C not configured");
if (checkstring(cmdline, (unsigned char * )
"GETTIME")) {
RtcGetTime(0);
if (checkstring(cmdline, (unsigned char * )"GETTIME")) {
int repeat=5;
noRTC=0;
while(1){
while(!(classicread==0 && nunchuckread==0)){routinechecks();}
RtcGetTime(1);
if(noRTC==0)break;
repeat--;
if(!repeat)break;
}
if(noRTC){
if (CurrentLinePtr) error("RTC not responding");
if (Option.RTC) {
MMPrintString("RTC not responding");
MMPrintString("\r\n");
}
}
return;
}
if ((p = checkstring(cmdline, (unsigned char * )
@ -1072,8 +1099,10 @@ void i2cCheck(unsigned char * p) {
addr = getinteger(argv[0]);
if (addr < 0 || addr > 0x7F) error("Invalid I2C address");
// int ret=i2c_read_blocking(i2c0, addr, &rxdata, 1, false);
int ret = i2c_read_timeout_us(i2c0, addr, & rxdata, 1, false, 100);
mmI2Cvalue = ret < 0 ? 1 : 0;
int i2cret = i2c_read_timeout_us(i2c0, addr, & rxdata, 1, false, 1000);
mmI2Cvalue = 0;
if (i2cret == PICO_ERROR_GENERIC) mmI2Cvalue = 1;
if (i2cret == PICO_ERROR_TIMEOUT) mmI2Cvalue = 2;
}
void i2c2Check(unsigned char * p) {
int addr;
@ -1084,8 +1113,10 @@ void i2c2Check(unsigned char * p) {
addr = getinteger(argv[0]);
if (addr < 0 || addr > 0x7F) error("Invalid I2C address");
// int ret=i2c_read_blocking(i2c1, addr, &rxdata, 1, false);
int ret = i2c_read_timeout_us(i2c1, addr, & rxdata, 1, false, 100);
mmI2Cvalue = ret < 0 ? 1 : 0;
int i2cret = i2c_read_timeout_us(i2c1, addr, & rxdata, 1, false, 1000);
mmI2Cvalue = 0;
if (i2cret == PICO_ERROR_GENERIC) mmI2Cvalue = 1;
if (i2cret == PICO_ERROR_TIMEOUT) mmI2Cvalue = 2;
}
// receive data from an I2C slave - master mode
void i2cReceive(unsigned char * p) {
@ -1446,6 +1477,7 @@ void GeneralReceive(unsigned int addr, int nbr, char * p) {
if (I2C0locked) {
I2C_Rcvbuf_Float = NULL;
I2C_Rcvbuf_Int = NULL;
I2C_Rcvbuf_String = NULL;
I2C_Sendlen = 0; // send one byte
I2C_Rcvlen = nbr;
I2C_Addr = addr; // address of the device
@ -1453,6 +1485,7 @@ void GeneralReceive(unsigned int addr, int nbr, char * p) {
} else {
I2C2_Rcvbuf_Float = NULL;
I2C2_Rcvbuf_Int = NULL;
I2C2_Rcvbuf_String = NULL;
I2C2_Sendlen = 0; // send one byte
I2C2_Rcvlen = nbr;
I2C2_Addr = addr; // address of the device

View File

@ -65,7 +65,11 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
#define I2C_Status_Slave_Receive_Rdy 0x00100000
#define I2C_Status_Slave_Receive_Full 0x00200000
#define SSD1306_I2C_Addr 0x3c
#ifdef PICOCALC
#define SystemI2CTimeout 500
#else
#define SystemI2CTimeout 5
#endif
// Global variables provided by I2C.c
extern unsigned int I2C_Timer; // master timeout counter
extern char *I2C_IntLine; // pointer to the master interrupt line number

View File

@ -557,33 +557,34 @@ void MIPS16 DefinedSubFun(int isfun, unsigned char *cmd, int index, MMFLOAT *fa,
#else
void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, int index, MMFLOAT *fa, long long int *i64a, unsigned char **sa, int *typ) {
#endif
unsigned char *p, *s, *tp, *ttp, tcmdtoken;
unsigned char *CallersLinePtr, *SubLinePtr = NULL;
unsigned char *p, *s, *tp, *ttp, tcmdtoken;
unsigned char *CallersLinePtr, *SubLinePtr = NULL;
unsigned char *argbuf1; unsigned char **argv1; int argc1;
unsigned char *argbuf2; unsigned char **argv2; int argc2;
unsigned char fun_name[MAXVARLEN + 1];
unsigned char *argbyref;
int i;
int i;
int ArgType, FunType;
int *argtype;
union u_argval {
MMFLOAT f; // the value if it is a float
long long int i; // the value if it is an integer
MMFLOAT *fa; // pointer to the allocated memory if it is an array of floats
long long int *ia; // pointer to the allocated memory if it is an array of integers
unsigned char *s; // pointer to the allocated memory if it is a string
MMFLOAT f; // the value if it is a float
long long int i; // the value if it is an integer
MMFLOAT *fa; // pointer to the allocated memory if it is an array of floats
long long int *ia; // pointer to the allocated memory if it is an array of integers
unsigned char *s; // pointer to the allocated memory if it is a string
} *argval;
int *argVarIndex;
CallersLinePtr = CurrentLinePtr;
SubLinePtr = subfun[index]; // used for error reporting
p = SubLinePtr + sizeof(CommandToken); // point to the sub or function definition
SubLinePtr = subfun[index]; // used for error reporting
p = SubLinePtr + sizeof(CommandToken); // point to the sub or function definition
skipspace(p);
ttp = p;
// copy the sub/fun name from the definition into temp storage and terminate
// p is left pointing to the end of the name (ie, start of the argument list in the definition)
CurrentLinePtr = SubLinePtr; // report errors at the definition
CurrentLinePtr = SubLinePtr; // report errors at the definition
tp = fun_name;
*tp++ = *p++; while(isnamechar(*p)) *tp++ = *p++;
if(*p == '$' || *p == '%' || *p == '!') {
@ -620,7 +621,6 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
FunType |= (V_FIND | V_DIM_VAR | V_LOCAL | V_EMPTY_OK);
}
// from now on
// tp = the caller's argument list
// p = the argument list for the definition
@ -637,7 +637,7 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
if(gosubindex >= MAXGOSUB) error("Too many nested SUB/FUN");
errorstack[gosubindex] = CallersLinePtr;
gosubstack[gosubindex++] = isfun ? NULL : nextstmt; // NULL signifies that this is returned to by ending ExecuteProgram()
gosubstack[gosubindex++] = isfun ? NULL : nextstmt; // NULL signifies that this is returned to by ending ExecuteProgram()
#define buffneeded MAX_ARG_COUNT*(sizeof(union u_argval)+ 2*sizeof(int)+3*sizeof(unsigned char *)+sizeof(unsigned char))+ 2*STRINGSIZE
// allocate memory for processing the arguments
argval=GetSystemMemory(buffneeded);
@ -664,7 +664,7 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
CurrentLinePtr = CallersLinePtr; // report errors at the caller
if(argc1 > argc2 || (argc1 && (argc1 & 1) == 0)) error("Argument list");
// step through the arguments supplied by the caller and get the value supplied
// step through the arguments supplied by the caller and get the value supplied
// these can be:
// - missing (ie, caller did not supply that parameter)
// - a variable, in which case we need to get a pointer to that variable's data and save its index so later we can get its type
@ -690,19 +690,26 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
// check for BYVAL or BYREF in sub/fun definition
argbyref[i]=0;
skipspace(argv2[i]);
if(toupper(*argv2[i]) == 'B' && toupper(*(argv2[i]+1)) == 'Y') {
if((checkstring(argv2[i] + 2, (unsigned char *)"VAL")) != NULL) { // if BYVAL
argtype[i] = 0; // remove any pointer flag in the caller
argv2[i] += 5; // skip to the variable start
} else {
if((checkstring(argv2[i] + 2, (unsigned char *)"REF")) != NULL) { // if BYREF
if((argtype[i] & T_PTR) == 0) error("Variable required for BYREF");
argv2[i] += 5; // skip to the variable start
}
argbyref[i]=1;
}
skipspace(argv2[i]);
}
if(toupper(*argv2[i]) == 'B' && toupper(*(argv2[i]+1)) == 'Y') {
if((checkstring(argv2[i] + 2, (unsigned char *)"VAL")) != NULL) { // if BYVAL
//Only if not an array remove any pointer flag in the caller
if(g_vartbl[argVarIndex[i]].dims[0] == 0){
argtype[i] = 0;
}else{
error("Array as BYVAL not allowed $",argv1[i]);
}
argv2[i] += 5; // skip to the variable start
argbyref[i]=2;
} else {
if((checkstring(argv2[i] + 2, (unsigned char *)"REF")) != NULL) { // if BYREF
//if((argtype[i] & T_PTR) == 0) error("Variable required for BYREF $", argv1[i]);
argv2[i] += 5; // skip to the variable start
argbyref[i]=1;
if((argtype[i] & T_PTR) == 0)error("Variable required for BYREF $", argv1[i]);
}
}
skipspace(argv2[i]);
}
// if argument is present and is not a pointer to a variable then evaluate it as an expression
if(argtype[i] == 0) {
@ -724,6 +731,16 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
g_LocalIndex++;
for(i = 0; i < argc2; i += 2) { // count through the arguments in the definition of the sub/fun
ArgType = T_NOTYPE;
//skip BYVAL/BYREF keywords
if(toupper(*argv2[i]) == 'B' && toupper(*(argv2[i]+1)) == 'Y') {
if((checkstring(argv2[i] + 2,(unsigned char *) "VAL")) != NULL) {
argv2[i] += 5;
}else if((checkstring(argv2[i] + 2, (unsigned char *)"REF")) != NULL) { // if BYREF
argv2[i] += 5; // skip to the variable start
}
}
// if (argbyref[i] )argv2[i] += 5;
tp = skipvar(argv2[i], false); // point to after the variable
skipspace(tp);
if(*tp == tokenAS) { // are we using Microsoft syntax (eg, AS INTEGER)?
@ -739,6 +756,7 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
// if the definition called for an array, special processing and checking will be required
if(g_vartbl[g_VarIndex].dims[0] == -1) {
//if( (argbyref[i]==2)) error("Array must be passed as BYREF $",argv1[i]);
int j;
if(g_vartbl[argVarIndex[i]].dims[0] == 0) error("Expected an array");
if(TypeMask(g_vartbl[g_VarIndex].type) != TypeMask(argtype[i])) error("Incompatible type: $", argv1[i]);
@ -749,8 +767,8 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
// if this is a pointer check and the type is NOT the same as that requested in the sub/fun definition
if((argtype[i] & T_PTR) && TypeMask(g_vartbl[g_VarIndex].type) != TypeMask(argtype[i])) {
if(argbyref[i]){ error("BYREF requires same types: $", argv1[i]);}
if((TypeMask(g_vartbl[g_VarIndex].type) & T_STR) || (TypeMask(argtype[i]) & T_STR))
if(argbyref[i]==1){ error("BYREF requires same types: $", argv1[i]);}
if((TypeMask(g_vartbl[g_VarIndex].type) & T_STR) || (TypeMask(argtype[i]) & T_STR))
error("Incompatible type: $", argv1[i]);
// make this into an ordinary argument
if(g_vartbl[argVarIndex[i]].type & T_PTR) {
@ -842,9 +860,9 @@ void MIPS16 __not_in_flash_func(DefinedSubFun)(int isfun, unsigned char *cmd, in
else
*sa = tp; // for a string we just need to return the local memory
*typ = FunType; // save the function type for the caller
ClearVars(g_LocalIndex--, true); // delete any local variables
ClearVars(g_LocalIndex--, true); // delete any local variables
g_TempMemoryIsChanged = true; // signal that temporary memory should be checked
gosubindex--;
gosubindex--;
}
char MIPS16 *strcasechr(const char *p, int ch)
@ -2785,11 +2803,11 @@ void MIPS16 error(char *msg, ...) {
}
if(OptionErrorSkip) longjmp(ErrNext, 1); // if OPTION ERROR SKIP/IGNORE is in force
#ifdef PICOMITE
multicore_fifo_push_blocking(0xFF);
busy_wait_ms(mergetimer+200);
if(mergerunning){
_excep_code = RESET_COMMAND;
SoftReset();
multicore_fifo_push_blocking(0xFF);
busy_wait_ms(mergetimer+200);
if(mergerunning){
_excep_code = RESET_COMMAND;
SoftReset();
}
#endif

View File

@ -2050,7 +2050,7 @@ void MIPS16 printoptions(void){
}
PRet();
}
if(Option.DISPLAY_TYPE >= VIRTUAL){
if(Option.DISPLAY_TYPE >= VIRTUAL && Option.DISPLAY_TYPE<NEXTGEN){
PO("LCDPANEL"); MMPrintString((char *)display_details[Option.DISPLAY_TYPE].name); PRet();
}
#ifdef GUICONTROLS
@ -2835,9 +2835,6 @@ OPTION MODBUFF ENABLE 192 */
#ifdef PICOCALC
if(checkstring(p,(unsigned char *) "PICOCALC")) {
ResetOptions(false);
//Option.CPU_Speed=252000;
//Option.modbuffsize=192;
//Option.modbuff = true;
Option.ColourCode = 1;
Option.SYSTEM_CLK = 14;
Option.SYSTEM_MOSI = 15;
@ -2853,7 +2850,7 @@ OPTION MODBUFF ENABLE 192 */
Option.AUDIO_DCS_PIN = 0;
Option.AUDIO_DREQ_PIN = 0;
Option.AUDIO_RESET_PIN = 0;
Option.DISPLAY_TYPE = ILI9488;
Option.DISPLAY_TYPE = ST7796SP;
Option.DISPLAY_BL = 0; //stm32 controls the backlight
Option.DISPLAY_ORIENTATION = PORTRAIT;
Option.LCD_CD = 19;
@ -3116,8 +3113,7 @@ void MIPS16 cmd_option(void) {
#ifndef PICOMITEVGA
tp = checkstring(cmdline, (unsigned char *)"LCD320");
if(tp) {
if(!( SSD16TYPE || Option.DISPLAY_TYPE==IPS_4_16 || SPI480 || Option.DISPLAY_TYPE==ILI9488P)) error("Only available on SSD1963, 480x320 SPI displays and IPS_4_16 displays");
if(!(Option.DISPLAY_ORIENTATION==LANDSCAPE || Option.DISPLAY_ORIENTATION==RLANDSCAPE || Option.DISPLAY_TYPE==ILI9488P))error("Only available in landscape mode");
if(!( SSD16TYPE && (Option.DISPLAY_ORIENTATION==LANDSCAPE || Option.DISPLAY_ORIENTATION==RLANDSCAPE))) error("Only available on 16-bit SSD1963 and IPS_4_16 displays in Landscape");
if(( SSD16TYPE || Option.DISPLAY_TYPE==IPS_4_16)){
if(checkstring(tp, (unsigned char *)"OFF")) {
clear320();
@ -3135,24 +3131,6 @@ void MIPS16 cmd_option(void) {
buff320=GetMemory(320*6);
return;
} else error("Syntax");
} else if(Option.DISPLAY_TYPE==ILI9488P){
if(checkstring(tp, (unsigned char *)"OFF")) {
VRes=320;
return;
}
else if(checkstring(tp, (unsigned char *)"ON")) {
HRes=320;
return;
}
} else if(SPI480){
if(checkstring(tp, (unsigned char *)"OFF")) {
clear320();
return;
}
else if(checkstring(tp, (unsigned char *)"ON")) {
VRes=240;
return;
} else error("Syntax");
} else error("Invalid display type");
}
#endif
@ -3657,7 +3635,7 @@ tp = checkstring(cmdline, (unsigned char *)"HEARTBEAT");
if(tp) {
if(CurrentLinePtr) error("Invalid in a program");
Option.NoScroll = 0;
if(!(Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE>=VGADISPLAY))Option.NoScroll=1;
if(!(Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE>=VGADISPLAY))Option.NoScroll=1;
if(!(Option.DISPLAY_ORIENTATION == DISPLAY_LANDSCAPE) && Option.DISPLAY_TYPE==SSDTYPE) error("Landscape only");
skipspace(tp);
Option.DefaultFC = WHITE;
@ -4675,14 +4653,7 @@ tp = checkstring(cmdline, (unsigned char *)"HEARTBEAT");
}
Option.Magic=MagicKey; //This isn't ideal but it improves the chances of a older config working in a new build
FileClose(fnbr);
uSec(100000);
disable_interrupts_pico();
flash_range_erase(FLASH_TARGET_OFFSET, FLASH_ERASE_SIZE);
enable_interrupts_pico();
uSec(10000);
disable_interrupts_pico();
flash_range_program(FLASH_TARGET_OFFSET, (const uint8_t *)&Option, 768);
enable_interrupts_pico();
SaveOptions();
_excep_code = RESET_COMMAND;
SoftReset();
}

View File

@ -55,20 +55,25 @@ extern const uint8_t *flash_progmemory;
unsigned char __attribute__ ((aligned (4096))) AllMemory[HEAP_MEMORY_SIZE+256+320*240*2];
unsigned char *FRAMEBUFFER=AllMemory+HEAP_MEMORY_SIZE+256;
uint32_t framebuffersize=320*240*2;
#else
unsigned char __attribute__ ((aligned (256))) AllMemory[HEAP_MEMORY_SIZE+256];
#endif
unsigned char *MMHeap=AllMemory;
unsigned char *MMHeap=AllMemory;
#else
unsigned char __attribute__ ((aligned (256))) AllMemory[HEAP_MEMORY_SIZE+256];
unsigned char *MMHeap=AllMemory;
uint32_t framebuffersize=0;
unsigned char *FRAMEBUFFER=NULL;
#endif
#else
#ifdef PICOMITEVGA
unsigned char __attribute__ ((aligned (4096))) Heap[HEAP_MEMORY_SIZE+256];
unsigned char __attribute__ ((aligned (256))) video[640*480/8];
unsigned char *FRAMEBUFFER=video;
uint32_t framebuffersize=640*480/8;
unsigned char *MMHeap=Heap;
#else
#else
unsigned char __attribute__ ((aligned (256))) AllMemory[HEAP_MEMORY_SIZE+256];
unsigned char *MMHeap=AllMemory;
uint32_t framebuffersize=0;
unsigned char *FRAMEBUFFER=NULL;
#endif
#endif

View File

@ -497,7 +497,6 @@ void __not_in_flash_func(routinechecks)(void){
if(clocktimer==0 && Option.RTC){
if(classicread==0 && nunchuckread==0){
RtcGetTime(0);
clocktimer=(1000*60*60);
}
}
#ifndef USBKEYBOARD
@ -3282,16 +3281,16 @@ void MIPS32 __not_in_flash_func(HDMIloop3)(void){
case SCREENMODE2: //400 X 300 x 4bit-colour mapped to 256 or 424 X 240 x 4bit-colour mapped to 256
{
uint16_t *p=(uint16_t *)HDMIlines[line_to_load];
uint8_t l,d,s;
uint8_t l,d;
int pp= (Line_dup)*vgaloop4;
for(int i=0; i<vgaloop4 ; i++){
l=LayerBuf[pp+i];d=DisplayBuf[pp+i];s=SecondLayer[pp+i];
l=LayerBuf[pp+i];d=DisplayBuf[pp+i];
if((l&0xf)!=transparent){
*p++=map16d[l&0xf];
} else {
*p++=map16d[d&0xf];
}
d>>=4;l>>=4;s>>=4;
d>>=4;l>>=4;
if((l&0xf)!=transparent){
*p++=map16d[l&0xf];
} else {
@ -4095,16 +4094,6 @@ int MIPS16 main(){
LoadOptions();
#ifdef rp2350
if(rom_get_last_boot_type()==BOOT_TYPE_FLASH_UPDATE)restart_reason=0xFFFFFFFC;
// if(Option.PSRAM_CS_PIN){
// gpio_init(47);
// gpio_set_dir(47, GPIO_OUT);
// gpio_put(47,GPIO_PIN_SET);
//}
// if(!rp2350a){
// gpio_init(47);
// gpio_set_dir(47, GPIO_OUT);
// gpio_put(47,GPIO_PIN_SET);
// }
#else
if(restart_reason==0x10001 || restart_reason==0x101)restart_reason=0xFFFFFFFC;
#endif
@ -4637,7 +4626,7 @@ autorun:
i=0;
WatchdogSet=savewatchdog;
CommandToken tkn=commandtbl_decode(tknbuf);
if(tkn==GetCommandValue((unsigned char *)"RUN"))i=1;
if(tkn==GetCommandValue((unsigned char *)"RUN") || tkn==GetCommandValue((unsigned char *)"EDIT") || tkn==GetCommandValue((unsigned char *)"AUTOSAVE"))i=1;
if (setjmp(jmprun) != 0) {
PrepareProgram(false);
CurrentLinePtr = 0;

View File

@ -31,10 +31,15 @@ SETUP PICOCALC FIRMWARE
mkdir -p ~/picocalc && cd ~/picocalc
git clone https://github.com/madcock/PicoMiteAllVersions.git
cd PicoMiteAllVersions
mv ~/pico/pico-sdk/src/rp2_common/hardware_flash/flash.c ~/pico/pico-sdk/src/rp2_common/hardware_flash/flash.bak
ln -s ~/picocalc/PicoMiteAllVersions/flash.c ~/pico/pico-sdk/src/rp2_common/hardware_flash/flash.c
mv ~/pico/pico-sdk/src/rp2_common/hardware_gpio/gpio.c ~/pico/pico-sdk/src/rp2_common/hardware_gpio/gpio.bak
ln -s ~/picocalc/PicoMiteAllVersions/gpio.c ~/pico/pico-sdk/src/rp2_common/hardware_gpio/gpio.c
mv ~/pico/pico-sdk/src/rp2_common/hardware_gpio/include/hardware/gpio.h ~/pico/pico-sdk/src/rp2_common/hardware_gpio/include/hardware/gpio.bak
ln -s ~/picocalc/PicoMiteAllVersions/gpio.h ~/pico/pico-sdk/src/rp2_common/hardware_gpio/include/hardware/gpio.h
mv ~/pico/pico-sdk/src/rp2_common/pico_float/float_sci_m33_vfp.S ~/pico/pico-sdk/src/rp2_common/pico_float/float_sci_m33_vfp.bak
ln -s ~/picocalc/PicoMiteAllVersions/float_sci_m33_vfp.S ~/pico/pico-sdk/src/rp2_common/pico_float/float_sci_m33_vfp.S
mv ~/pico/pico-sdk/src/rp2_common/hardware_flash/flash.c ~/pico/pico-sdk/src/rp2_common/hardware_flash/flash.bak
ln -s ~/picocalc/PicoMiteAllVersions/flash.c ~/pico/pico-sdk/src/rp2_common/hardware_flash/flash.c
```
EDIT ``~/picocalc/PicoMiteAllVersions/CMakeLists.txt`` TO CHOOSE TARGET
-----------------------------------------------------------------------
@ -62,9 +67,11 @@ make
(_original readme follows..._)
# PicoMiteRP2350
This contains files to build MMbasic V6.00.02RC23 to run on both RP2040 and RP2350<br>
This contains files to build MMbasic V6.00.02 to run on both RP2040 and RP2350<br>
Compile with GCC 13.3.1 arm-none-eabi<br>
Build with sdk V2.1.1 but replace gpio.c and flash.c with the ones included here<br>
<b style="color:red;"> Build with sdk V2.1.1 but replace gpio.c, gpio.h, float_sci_m33_vfp.S, and flash.c with the ones included here<br></b>
Change CMakeLists.txt line 4 to determine which variant to build<br>
<br>
RP2040<br>

View File

@ -0,0 +1,532 @@
/***********************************************************************************************************************
PicoMite MMBasic
SPI-LCD.c
<COPYRIGHT HOLDERS> Geoff Graham, Peter Mather
Copyright (c) 2021, <COPYRIGHT HOLDERS> All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the distribution.
3. The name MMBasic be used when referring to the interpreter in any documentation and promotional material and the original copyright message be displayed
on the console at startup (additional copyright messages may be added).
4. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed
by the <copyright holder>.
5. Neither the name of the <copyright holder> nor the names of its contributors may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDERS> AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDERS> BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
************************************************************************************************************************/
#include <stdarg.h>
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
const uint32_t maskSPI111[32]={0x00000001,0x00000003,0x00000007,0x0000000f,0x0000001f,0x0000003f,0x0000007f,0x000000ff,
0x000001ff,0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,0x00007fff,0x0000ffff,
0x0001ffff,0x0003ffff,0x0007ffff,0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,0x3fffffff,0x7fffffff,0xffffffff};
const uint32_t rmaskSPI111[32]={0x80000000,0xC0000000,0xe0000000,0xf0000000,0xf8000000,0xfc000000,0xfe000000,0xff000000,
0xff800000,0xffC00000,0xffe00000,0xfff00000,0xfff80000,0xfffc0000,0xfffe0000,0xffff0000,
0xffff8000,0xffffC000,0xffffe000,0xfffff000,0xfffff800,0xfffffc00,0xfffffe00,0xffffff00,
0xffffff80,0xffffffC0,0xffffffe0,0xfffffff0,0xfffffff8,0xfffffffc,0xfffffffe,0xffffffff};
uint32_t *VideoBufRed = NULL; // Image buffer for red
uint32_t *VideoBufGrn = NULL; // Image buffer for green
uint32_t *VideoBufBlu = NULL; // Image buffer for blue
volatile int lcnt;
volatile int VCount; // counter for the number of lines in a frame
volatile int VState; // the state of the state machine
volatile int showbuffer = 0; // the next counter table (initialise in initVideo() below)
void SPI111hline(int x0, int x1, int y, int con, int which);
inline void plot(int x, int y, int con) ;
void SPI111init(void){
// if(Option.DISPLAY_TYPE !=SPI111) return;
DrawRectangle = DrawRectangleSPI111;
DrawBitmap = DrawBitmapSPI111;
ScrollLCD = ScrollSPI111;
DrawBuffer=DrawBufferSPI111;
ReadBuffer=ReadBufferSPI111;
}
void DrawRectangleSPI111(int x1, int y1, int x2, int y2, int c){
int i, t;
int col=0;
if(c & 0xFF0000)col =1;
if(c & 0xFF00)col +=2;
if(c & 0xFF)col +=4;
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(x1 < 0) x1 = 0;
if(x1 >= HRes) x1 = HRes - 1;
if(x2 < 0) x2 = 0;
if(x2 >= HRes) x2 = HRes - 1;
if(y1 < 0) y1 = 0;
if(y1 >= VRes) y1 = VRes - 1;
if(y2 < 0) y2 = 0;
if(y2 >= VRes) y2 = VRes - 1;
for(i=y1;i<=y2;i++){
SPI111hline(x1,x2,i,col,0);
}
}
void DrawBitmapSPI111(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap){
int i, j, k, m;
unsigned char fcol,bcol;
int vertCoord, horizCoord, XStart, XEnd, YEnd;
// adjust when part of the bitmap is outside the displayable coordinates
vertCoord = y1; if(y1 < 0) y1 = 0; // the y coord is above the top of the screen
XStart = x1; if(XStart < 0) XStart = 0; // the x coord is to the left of the left marginn
XEnd = x1 + (width * scale) - 1; if(XEnd >= HRes) XEnd = HRes - 1; // the width of the bitmap will extend beyond the right margin
YEnd = y1 + (height * scale) - 1; if(YEnd >= VRes) YEnd = VRes - 1;// the height of the bitmap will extend beyond the bottom margin
fcol=0; bcol=0;
if(fc & 0xFF0000)fcol =1;
if(fc & 0xFF00)fcol +=2;
if(fc & 0xFF)fcol +=4;
if(bc!=-1){
if(bc & 0xFF0000)bcol =1;
if(bc & 0xFF00)bcol +=2;
if(bc & 0xFF)bcol +=4;
} else bcol=0xff;
for(i = 0; i < height; i++) { // step thru the font scan line by line
for(j = 0; j < scale; j++) { // repeat lines to scale the font
if(vertCoord++ < 0) continue; // we are above the top of the screen
if(vertCoord > VRes) return; // we have extended beyond the bottom of the screen
horizCoord = x1;
for(k = 0; k < width; k++) { // step through each bit in a scan line
for(m = 0; m < scale; m++) { // repeat pixels to scale in the x axis
if(horizCoord++ < 0) continue; // we have not reached the left margin
if(horizCoord > HRes) continue; // we are beyond the right margin
if((bitmap[((i * width) + k)/8] >> (((height * width) - ((i * width) + k) - 1) %8)) & 1) {
plot(horizCoord-1,vertCoord-1,fcol);
} else {
if(bcol!=0xff)plot(horizCoord-1,vertCoord-1,bcol);
}
}
}
}
}
}
void SPI111hline(int x0, int x1, int y, int con, int which) { //draw a horizontal line
uint32_t w1, xx1, w0, xx0, x, xn, i;
const uint32_t a[]={0xFFFFFFFF,0x7FFFFFFF,0x3FFFFFFF,0x1FFFFFFF,0xFFFFFFF,0x7FFFFFF,0x3FFFFFF,0x1FFFFFF,
0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF,0xFFFFF,0x7FFFF,0x3FFFF,0x1FFFF,
0xFFFF,0x7FFF,0x3FFF,0x1FFF,0xFFF,0x7FF,0x3FF,0x1FF,
0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01};
const uint32_t b[]={0x80000000,0xC0000000,0xe0000000,0xf0000000,0xf8000000,0xfc000000,0xfe000000,0xff000000,
0xff800000,0xffC00000,0xffe00000,0xfff00000,0xfff80000,0xfffc0000,0xfffe0000,0xffff0000,
0xffff8000,0xffffC000,0xffffe000,0xfffff000,0xfffff800,0xfffffc00,0xfffffe00,0xffffff00,
0xffffff80,0xffffffC0,0xffffffe0,0xfffffff0,0xfffffff8,0xfffffffc,0xfffffffe,0xffffffff};
uint32_t *br, *bg, *bb;
br=VideoBufRed;
bg=VideoBufGrn;
bb=VideoBufBlu;
w0 = y * (SPIints_per_line) + x0/32;
xx0 = (x0 & 0x1F);
w1 = y * (SPIints_per_line) + x1/32;
xx1 = (x1 & 0x1F);
if(w1==w0){ //special case both inside same word
x=(a[xx0] & b[xx1]);
xn=~x;
if(con & 1) br[w0] |= x; else br[w0] &= xn; // turn on the red pixel
if(con & 2) bg[w0] |= x; else bg[w0] &= xn; // turn on the green pixel
if(con & 4) bb[w0] |= x; else bb[w0] &= xn; // turn on the blue pixel
} else {
if(w1-w0>1){ //first deal with full words
for(i=w0+1;i<w1;i++){
// draw the pixel
br[i] = 0; // turn off the red pixels
bg[i] = 0; // turn off the green pixels
bb[i] = 0; // turn off the blue pixels
if(con & 1) br[i] = 0xFFFFFFFF; // turn on the red pixels
if(con & 2) bg[i] = 0xFFFFFFFF; // turn on the green pixels
if(con & 4) bb[i] = 0xFFFFFFFF; // turn on the blue pixels
}
}
x=~a[xx0];
br[w0] &= x; // turn off the red pixel
bg[w0] &= x; // turn off the green pixel
bb[w0] &= x; // turn off the blue pixel
x=~x;
if(con & 1) br[w0] |= x; // turn on the red pixel
if(con & 2) bg[w0] |= x; // turn on the green pixel
if(con & 4) bb[w0] |= x; // turn on the blue pixel
x=~b[xx1];
br[w1] &= x; // turn off the red pixel
bg[w1] &= x; // turn off the green pixel
bb[w1] &= x; // turn off the blue pixel
x=~x;
if(con & 1) br[w1] |= x; // turn on the red pixel
if(con & 2) bg[w1] |= x; // turn on the green pixel
if(con & 4) bb[w1] |= x; // turn on the blue pixel
}
}
void DrawBufferSPI111(int x1, int y1, int x2, int y2, unsigned char* p) {
int t,x,y,w, xd, c1;
unsigned int xx, xxn;
uint32_t *br, *bg, *bb;
br=VideoBufRed, bg=VideoBufGrn, bb=VideoBufBlu;
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
for(y=y1;y<=y2;y++){
c1=y * (SPIints_per_line);
for(x=x1;x<=x2;x++){
xx = (0x80000000>>(x & 0x1f));
xxn=~xx;
xd=x>>5;
w = c1 + xd;
// draw the pixel
if(y>=0 && y<VRes && x>=0 && x<HRes){
if(*p++ > 0x80){
bb[w] |= xx;
} else {
bb[w] &= xxn;
}// turn on the blue pixel
if(*p++ > 0x80){
bg[w] |= xx;
} else {
bg[w] &= xxn;
}// turn on the green pixel
if(*p++ > 0x80){
br[w] |= xx;
} else {
br[w] &= xxn;
}// turn on the red pixel
} else p+=3;
}
}
}
void ReadBufferSPI111(int x1, int y1, int x2, int y2, unsigned char* p) {
int t,x,y, w, xx, xd, c1;
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
for(y=y1;y<=y2;y++){
c1=y * (SPIints_per_line);
for(x=x1;x<=x2;x++){
xx=(0x80000000>>(x & 0x1f));
xd=x>>5;
w = c1 + xd;
if(y>=0 && y<VRes && x>=0 && x<HRes){
*p++ = ((VideoBufBlu[w]) & xx) ? 0xff : 0;
*p++ = ((VideoBufGrn[w]) & xx) ? 0xff : 0;
*p++ = ((VideoBufRed[w]) & xx) ? 0xff : 0;
} else p+=3;
}
}
}
void plot121(int x, int y, int con) {
int w, xx,xxn, xd;
uint32_t *br, *bg, *bb;
br=VideoBufRed, bg=VideoBufGrn, bb=VideoBufBlu;
xx = (0x80000000>>(x & 0x1f));
xd=x>>5;
w = y * (SPIints_per_line) + xd;
// draw the pixel
xxn = ~xx;
if(con & 1) br[w] |= xx; else br[w] &= xxn; // turn on the red pixel
if(con & 6) bg[w] |= xx; else bg[w] &= xxn; // turn on the green pixel
if(con & 8) bb[w] |= xx; else bb[w] &= xxn; // turn on the blue pixel
}
inline void plot(int x, int y, int con) {
int w, xx,xxn, xd;
uint32_t *br, *bg, *bb;
br=VideoBufRed, bg=VideoBufGrn, bb=VideoBufBlu;
xx = (0x80000000>>(x & 0x1f));
xd=x>>5;
w = y * (SPIints_per_line) + xd;
// draw the pixel
xxn = ~xx;
if(con & 1) br[w] |= xx; else br[w] &= xxn; // turn on the red pixel
if(con & 2) bg[w] |= xx; else bg[w] &= xxn; // turn on the green pixel
if(con & 4) bb[w] |= xx; else bb[w] &= xxn; // turn on the blue pixel
}
void copyframetoscreen(uint8_t *s,int xstart, int xend, int ystart, int yend, int odd){
int c;
int i=(xend-xstart+1)*(yend-ystart+1);
int x=xstart,y=ystart;
if(odd){
c=(*s & 0xF0)>>4;
plot121(x,y,c);
if(x==xend){
x=xstart;
y++;
} else x++;
s++;
i--;
}
while(i>0){
c=*s & 0xF;
plot121(x,y,c);
if(x==xend){
x=xstart;
y++;
} else x++;
if(i>1){
c=(*s & 0xF0)>>4;
plot121(x,y,c);
if(x==xend){
x=xstart;
y++;
} else x++;
s++;
i-=2;
}
}
}
void ScrollSPI111sideways(int lines){
int i, j;
uint32_t k, l, prevr=0, prevg=0, prevb=0;
uint32_t *pdr,*pdg,*pdb;
uint32_t *br, *bg, *bb;
br=VideoBufRed, bg=VideoBufGrn, bb=VideoBufBlu;
int m1=0x0;
int m2=0x0;
if(lines > 0) {
for(j=0; j<VRes;j++){
pdr = br + (SPIints_per_line * j);
pdg = bg + (SPIints_per_line * j);
pdb = bb + (SPIints_per_line * j);
for(i=0;i<=HRes/32;i++){
l = *pdr;
k=l & maskSPI111[lines-1];
l = l >> lines;
l |= prevr;
if(i==0)l &= m1;
if(i==HRes/32)l &= m2;
*pdr++ = l;
prevr=k<<(32-lines);
l = *pdg;
k= l & maskSPI111[lines-1];
l = l >> lines;
l |= prevg;
if(i==0)l &= m1;
if(i==HRes/32)l &= m2;
*pdg++ = l;
prevg=k<<(32-lines);
l = *pdb;
k=l & maskSPI111[lines-1];
l = l >>lines;
l |= prevb;
if(i==0)l &= m1;
if(i==HRes/32)l &= m2;
*pdb++ = l;
prevb=k<<(32-lines);
}
}
} else {
int m=-lines;
for(j=0; j<VRes;j++){
pdr = br + HRes/32 + (SPIints_per_line * j);
pdg = bb + HRes/32 + (SPIints_per_line * j);
pdb = bg + HRes/32 + (SPIints_per_line * j);
for(i=HRes/32;i>=0;i--){
l = *pdr;
k=l & rmaskSPI111[m];
l = l << m;
l |= prevr;
if(i==0)l &= m1;
if(i==HRes/32)l &= m2;
*pdr-- = l;
prevr=k>>(32-m);
l = *pdg;
k= l & rmaskSPI111[m];
l = l << m;
l |= prevg;
if(i==0)l &= m1;
if(i==HRes/32)l &= m2;
*pdg-- = l;
prevg=k>>(32-m);
l = *pdb;
k=l & rmaskSPI111[m];
l = l << m;
l |= prevb;
if(i==0)l &= m1;
if(i==HRes/32)l &= m2;
*pdb-- = l;
prevb=k>>(32-m);
}
}
}
}
void ScrollSPI111(int lines) {
int i,amount;
uint32_t *pdr,*pdg,*pdb;
uint32_t *psr,*psg,*psb;
uint32_t *br, *bg, *bb;
br=VideoBufRed, bg=VideoBufGrn, bb=VideoBufBlu;
if(lines >= 0) {
amount = SPIints_per_line * (VRes - lines);
pdr = br;
psr = pdr + SPIints_per_line * lines;
pdg = bg;
psg = pdg + SPIints_per_line * lines;
pdb = bb;
psb = pdb + SPIints_per_line * lines;
for(i=0; i < amount; i+=8) {
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
}
DrawRectangle(0, VRes-lines, HRes - 1, VRes - 1, gui_bcolour); // erase the lines introduced at the bottom
} else {
lines = -lines;
amount = SPIints_per_line * (VRes - lines);
psr = br + SPIints_per_line * (VRes - lines);
pdr = psr + SPIints_per_line * lines;
psg = bg + SPIints_per_line * (VRes - lines);
pdg = psg + SPIints_per_line * lines;
psb = bb + SPIints_per_line * (VRes - lines);
pdb = psb + SPIints_per_line * lines;
for(i=0; i < amount; i+=8){
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
}
DrawRectangle(0, 0, HRes - 1, lines-1 , gui_bcolour); // erase the lines introduced at the top
}
}
void ScrollSPI111vertical(int lines, int blank) {
int i,amount;
uint32_t *pdr,*pdg,*pdb;
uint32_t *psr,*psg,*psb;
uint32_t *br, *bg, *bb;
br=VideoBufRed, bg=VideoBufGrn, bb=VideoBufBlu;
if(lines >= 0) {
amount = SPIints_per_line * (VRes - lines);
pdr = br;
psr = pdr + SPIints_per_line * lines;
pdg = bg;
psg = pdg + SPIints_per_line * lines;
pdb = bb;
psb = pdb + SPIints_per_line * lines;
for(i=0; i < amount; i+=8) {
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdr++ = *psr++; // scroll up
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdg++ = *psg++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
*pdb++ = *psb++;
}
} else {
lines = -lines;
amount = SPIints_per_line * (VRes - lines);
psr = br + SPIints_per_line * (VRes - lines);
pdr = psr + SPIints_per_line * lines;
psg = bg + SPIints_per_line * (VRes - lines);
pdg = psg + SPIints_per_line * lines;
psb = bb + SPIints_per_line * (VRes - lines);
pdb = psb + SPIints_per_line * lines;
for(i=0; i < amount; i+=8){
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdr = *--psr; // scroll down
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdg = *--psg;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
*--pdb = *--psb;
}
}
}

View File

@ -46,46 +46,47 @@ const struct Displays display_details[]={
{14,"ST7789_320", 50000000, 320, 240, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{15,"ILI9488W", LCD_SPI_SPEED, 480, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{16,"ST7796S", 50000000, 480, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{17,"ST7735S_W", LCD_SPI_SPEED, 128, 128, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{18,"GC9A01", LCD_SPI_SPEED, 240, 240, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{19,"ILI9481IPS", 12000000, 480, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{20,"N5110", NOKIA_SPI_SPEED, 84, 48, 1, 1, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{21,"SSD1306SPI", LCD_SPI_SPEED, 128, 64, 1, 1, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{22,"ST7920", ST7920_SPI_SPEED, 128, 64, 1, 1, SPI_POLARITY_HIGH, SPI_PHASE_2EDGE},
{23,"", TOUCH_SPI_SPEED, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{24,"SPIReadSpeed", 12000000, 480, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{25,"ST7789RSpeed", 6000000, 320, 240, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{26,"", SLOW_TOUCH_SPEED, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{27,"User", 0, 0, 0, 0, 0, 0 ,0},
{28,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{17,"ST7796SP",50000000, 320, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{18,"ST7735S_W", LCD_SPI_SPEED, 128, 128, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{19,"GC9A01", LCD_SPI_SPEED, 240, 240, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{20,"ILI9481IPS", 12000000, 480, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{21,"N5110", NOKIA_SPI_SPEED, 84, 48, 1, 1, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{22,"SSD1306SPI", LCD_SPI_SPEED, 128, 64, 1, 1, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{23,"ST7920", ST7920_SPI_SPEED, 128, 64, 1, 1, SPI_POLARITY_HIGH, SPI_PHASE_2EDGE},
{24,"", TOUCH_SPI_SPEED, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{25,"SPIReadSpeed", 12000000, 480, 320, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{26,"ST7789RSpeed", 6000000, 320, 240, 16, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{27,"", SLOW_TOUCH_SPEED, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{28,"User", 0, 0, 0, 0, 0, 0 ,0},
{29,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{30,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{31,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{32,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{33,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{34,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{35,"SSD1963_4", 0, 0, 0, 0, 0, 0 ,0},
{36,"SSD1963_5", 0, 0, 0, 0, 0, 0 ,0},
{37,"SSD1963_5A", 0, 0, 0, 0, 0, 0 ,0},
{38,"SSD1963_7", 0, 0, 0, 0, 0, 0 ,0},
{39,"SSD1963_7A", 0, 0, 0, 0, 0, 0 ,0},
{40,"SSD1963_8", 0, 0, 0, 0, 0, 0 ,0},
{41,"ILI9341_8", 0, 0, 0, 0, 0, 0 ,0},
{42,"SSD1963_4_16", 0, 0, 0, 0, 0, 0 ,0},
{43,"SSD1963_5_16", 0, 0, 0, 0, 0, 0 ,0},
{44,"SSD1963_5A_16" , 0, 0, 0, 0, 0, 0 ,0},
{45,"SSD1963_7_16", 0, 0, 0, 0, 0, 0 ,0},
{46,"SSD1963_7A_16", 0, 0, 0, 0, 0, 0 ,0},
{47,"SSD1963_8_16", 0, 0, 0, 0, 0, 0 ,0},
{48,"ILI9341_16", 0, 0, 0, 0, 0, 0 ,0},
{49,"IPS_4_16", 0, 0, 0, 0, 0, 0 ,0},
{50,"SSD1963_5E_16", 0, 0, 0, 0, 0, 0 ,0},
{51,"SSD1963_7E_16", 0, 0, 0, 0, 0, 0 ,0},
{52,"ILI9486_16", 0, 0, 0, 0, 0, 0 ,0},
{53,"VIRTUAL_C", 0, 320, 240, 0, 0, 0, 0},
{54,"VIRTUAL_M", 0, 640, 480, 0, 0, 0, 0},
{55,"VS1053slow", 200000, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{56,"VS1053fast", 4000000, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{35,"Dummy", 0, 0, 0, 0, 0, 0 ,0},
{36,"SSD1963_4", 0, 0, 0, 0, 0, 0 ,0},
{37,"SSD1963_5", 0, 0, 0, 0, 0, 0 ,0},
{38,"SSD1963_5A", 0, 0, 0, 0, 0, 0 ,0},
{39,"SSD1963_7", 0, 0, 0, 0, 0, 0 ,0},
{40,"SSD1963_7A", 0, 0, 0, 0, 0, 0 ,0},
{41,"SSD1963_8", 0, 0, 0, 0, 0, 0 ,0},
{42,"ILI9341_8", 0, 0, 0, 0, 0, 0 ,0},
{43,"SSD1963_4_16", 0, 0, 0, 0, 0, 0 ,0},
{44,"SSD1963_5_16", 0, 0, 0, 0, 0, 0 ,0},
{45,"SSD1963_5A_16" , 0, 0, 0, 0, 0, 0 ,0},
{46,"SSD1963_7_16", 0, 0, 0, 0, 0, 0 ,0},
{47,"SSD1963_7A_16", 0, 0, 0, 0, 0, 0 ,0},
{48,"SSD1963_8_16", 0, 0, 0, 0, 0, 0 ,0},
{49,"ILI9341_16", 0, 0, 0, 0, 0, 0 ,0},
{50,"IPS_4_16", 0, 0, 0, 0, 0, 0 ,0},
{51,"SSD1963_5E_16", 0, 0, 0, 0, 0, 0 ,0},
{52,"SSD1963_7E_16", 0, 0, 0, 0, 0, 0 ,0},
{53,"ILI9486_16", 0, 0, 0, 0, 0, 0 ,0},
{54,"VIRTUAL_C", 0, 320, 240, 0, 0, 0, 0},
{55,"VIRTUAL_M", 0, 640, 480, 0, 0, 0, 0},
{56,"VS1053slow", 200000, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
{57,"VS1053fast", 4000000, 0, 0, 0, 0, SPI_POLARITY_LOW, SPI_PHASE_1EDGE},
};
void __not_in_flash_func(spi_write_fast)(spi_inst_t *spi, const uint8_t *src, size_t len) {
@ -115,8 +116,6 @@ void __not_in_flash_func(spi_finish)(spi_inst_t *spi){
int LCD_CS_PIN=0;
int LCD_CD_PIN=0;
int LCD_Reset_PIN=0;
static bool ST7796Swritestate=true;
#define ST7796Schangetowrite 1600
unsigned char LCDBuffer[1440]={0};
void DefineRegionSPI(int xstart, int ystart, int xend, int yend, int rw);
@ -153,6 +152,7 @@ void MIPS16 ConfigDisplaySPI(unsigned char *p) {
char code,CD,RESET,CS=0;
uint8_t BACKLIGHT=0;
int DISPLAY_TYPE=0;
int orientation=1;
getargs(&p, 13, (unsigned char *)",");
if(checkstring(argv[0], (unsigned char *)"ILI9163")) {
DISPLAY_TYPE = ILI9163;
@ -180,6 +180,8 @@ void MIPS16 ConfigDisplaySPI(unsigned char *p) {
DISPLAY_TYPE = ILI9488W;
} else if(checkstring(argv[0], (unsigned char *)"ST7796S")) {
DISPLAY_TYPE = ST7796S;
} else if(checkstring(argv[0], (unsigned char *)"ST7796SP")) {
DISPLAY_TYPE = ST7796SP;
} else if(checkstring(argv[0], (unsigned char *)"ILI9341")) {
DISPLAY_TYPE = ILI9341;
} else if(checkstring(argv[0], (unsigned char *)"ST7735S_W")) {
@ -195,15 +197,18 @@ void MIPS16 ConfigDisplaySPI(unsigned char *p) {
} else return;
if(!Option.SYSTEM_CLK)error("System SPI not configured");
if(!(argc == 7 || argc == 9 || argc==11 || argc==13)) error("Argument count");
if(checkstring(argv[2], (unsigned char *)"L") || checkstring(argv[2], (unsigned char *)"LANDSCAPE"))
Option.DISPLAY_ORIENTATION = LANDSCAPE;
else if(checkstring(argv[2], (unsigned char *)"P") || checkstring(argv[2], (unsigned char *)"PORTRAIT"))
Option.DISPLAY_ORIENTATION = PORTRAIT;
else if(checkstring(argv[2], (unsigned char *)"RL") || checkstring(argv[2], (unsigned char *)"RLANDSCAPE"))
Option.DISPLAY_ORIENTATION = RLANDSCAPE;
else if(checkstring(argv[2], (unsigned char *)"RP") || checkstring(argv[2], (unsigned char *)"RPORTRAIT"))
Option.DISPLAY_ORIENTATION = RPORTRAIT;
else error("Orientation");
if(*argv[2]){
if(checkstring(argv[2], (unsigned char *)"L") || checkstring(argv[2], (unsigned char *)"LANDSCAPE"))
orientation = LANDSCAPE;
else if(checkstring(argv[2], (unsigned char *)"P") || checkstring(argv[2], (unsigned char *)"PORTRAIT"))
orientation = PORTRAIT;
else if(checkstring(argv[2], (unsigned char *)"RL") || checkstring(argv[2], (unsigned char *)"RLANDSCAPE"))
orientation = RLANDSCAPE;
else if(checkstring(argv[2], (unsigned char *)"RP") || checkstring(argv[2], (unsigned char *)"RPORTRAIT"))
orientation = RPORTRAIT;
else error("Orientation");
}
Option.DISPLAY_ORIENTATION=orientation;
if(DISPLAY_TYPE==ST7789 || DISPLAY_TYPE == ST7789A|| DISPLAY_TYPE == ST7789A)Option.DISPLAY_ORIENTATION=(Option.DISPLAY_ORIENTATION+2) % 4;
if(!(code=codecheck(argv[4])))argv[4]+=2;
CD = getinteger(argv[4]);
@ -266,7 +271,7 @@ void MIPS16 InitDisplaySPI(int InitOnly) {
DrawPixel = DrawPixelNormal;
ScrollLCD = ScrollLCDSPISCR;
DrawBLITBuffer = DrawBufferSPISCR;
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
ReadBuffer = ReadBufferSPISCR;
ReadBLITBuffer = ReadBufferSPISCR;
}
@ -276,7 +281,7 @@ void MIPS16 InitDisplaySPI(int InitOnly) {
DrawBuffer = DrawBufferSPI;
DrawBLITBuffer = DrawBufferSPI;
DrawPixel = DrawPixelNormal;
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
if(Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ST7789B){
ReadBLITBuffer = ReadBufferSPI;
ReadBuffer = ReadBufferSPI;
ScrollLCD = ScrollLCDSPI;
@ -296,6 +301,7 @@ void MIPS16 InitDisplaySPI(int InitOnly) {
// the initialisation sequences and the SPI driver code was written by Peter Mather (matherp on The Back Shed forum)
switch(Option.DISPLAY_TYPE) {
case ST7796S:
case ST7796SP:
ResetController();
spi_write_cd(0xC5, 1, 0x1C); //VCOM Control 1 [1C]
spi_write_cd(0x3A, 1, 0x55); //565
@ -303,6 +309,8 @@ void MIPS16 InitDisplaySPI(int InitOnly) {
uSec(150000);
//0xB1, 2, 0xB0, 0x11, //Frame Rate Control [A0 10]
spi_write_cd(0xB4, 1, 0x01); //Inversion Control [01]
if(Option.BGR)spi_write_command(0x21);
else spi_write_command(0x20);
spi_write_cd(0xB6, 3, 0x80, 0x02, 0x3B); // Display Function Control [80 02 3B] .kbv SS=1, NL=480
spi_write_cd(0xB7, 1, 0xC6); //Entry Mode [06]
// 0xF7, 4, 0xA9, 0x51, 0x2C, 0x82, //Adjustment Control 3 [A9 51 2C 82]
@ -315,12 +323,17 @@ void MIPS16 InitDisplaySPI(int InitOnly) {
case RLANDSCAPE: spi_write_cd(ILI9341_MEMCONTROL,1,ILI9341_Landscape180); break;
case RPORTRAIT: spi_write_cd(ILI9341_MEMCONTROL,1,ILI9341_Portrait180); break;
}
if(Option.DISPLAY_TYPE==ST7796SP){
spi_write_cd(0x33,6,0x00,0x00,0x01,0x40,0x00,0xA0);
} else {
spi_write_cd(0x33,6,0x00,0x00,0x01,0xE0,0x00,0x00);
}
spi_write_command(0x11);
uSec(150000);
spi_write_command(0x29); //Display on
uSec(150000);
break;
case ILI9488:
case ILI9488:
case ILI9488P:
case ILI9488W:
ResetController();
@ -1138,10 +1151,6 @@ void spisendfast(unsigned char *n, int i){
void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c){
// convert the colours to 565 format
unsigned char col[3];
if(Option.DISPLAY_TYPE==ST7796S && !ST7796Swritestate){
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
if(x1==x2 && y1==y2){
if(x1 < 0) return;
if(x1 >= HRes) return;
@ -1262,10 +1271,6 @@ void DrawRectangleSPISCR(int x1, int y1, int x2, int y2, int c){
// convert the colours to 565 format
int t;
// make sure the coordinates are kept within the display area
if(Option.DISPLAY_TYPE==ST7796S && !ST7796Swritestate){
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(x1 < 0) x1 = 0;
@ -1304,11 +1309,7 @@ void DrawBitmapSPI(int x1, int y1, int width, int height, int scale, int fc, int
} c;
if(bc == -1 && (void *)ReadBuffer == (void *)DisplayNotSet) bc = 0x0;
if(x1>=HRes || y1>=VRes || x1+width*scale<0 || y1+height*scale<0)return;
if(Option.DISPLAY_TYPE==ST7796S && !ST7796Swritestate){
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
// adjust when part of the bitmap is outside the displayable coordinates
// adjust when part of the bitmap is outside the displayable coordinates
vertCoord = y1; if(y1 < 0) y1 = 0; // the y coord is above the top of the screen
XStart = x1; if(XStart < 0) XStart = 0; // the x coord is to the left of the left marginn
XEnd = x1 + (width * scale) - 1; if(XEnd >= HRes) XEnd = HRes - 1; // the width of the bitmap will extend beyond the right margin
@ -1318,8 +1319,6 @@ void DrawBitmapSPI(int x1, int y1, int width, int height, int scale, int fc, int
j = width * height * scale * scale * 3;
p = GetMemory(j); //allocate some temporary memory
ReadBuffer(XStart, y1, XEnd, YEnd, (unsigned char *)p);
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
// convert the colours to 565 format
if(Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ILI9481IPS ){
@ -1421,10 +1420,6 @@ void DrawBitmapSPISCR(int x1, int y1, int width, int height, int scale, int fc,
}
if(bc == -1 && (void *)ReadBuffer == (void *)DisplayNotSet) bc = 0x0;
if(x1>=HRes || y1>=VRes || x1+width*scale<0 || y1+height*scale<0)return;
if(Option.DISPLAY_TYPE==ST7796S && !ST7796Swritestate){
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
// adjust when part of the bitmap is outside the displayable coordinates
vertCoord = y1; if(y1 < 0) y1 = 0; // the y coord is above the top of the screen
XStart = x1; if(XStart < 0) XStart = 0; // the x coord is to the left of the left marginn
@ -1433,8 +1428,6 @@ void DrawBitmapSPISCR(int x1, int y1, int width, int height, int scale, int fc,
j = width * height * scale * scale * 3;
p = GetMemory(j); //allocate some temporary memory
ReadBuffer(XStart, y1, XEnd, (y1 + (height * scale) - 1) , (unsigned char *)p);
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
yt = y = (y1 + ScrollStart) % VRes;
YEnd=(y + (height * scale) - 1) % VRes;
@ -1492,9 +1485,6 @@ const unsigned char map32[256];
void ReadBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p) {
int r, N, t;
unsigned char h,l;
if(Option.DISPLAY_TYPE==ST7796S && ST7796Swritestate){
ST7796Swritestate=false;
}
// SInt(x1);SIntComma(y1);SIntComma(x2);SIntComma(y2);SRet();
// make sure the coordinates are kept within the display area
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
@ -1507,7 +1497,7 @@ void ReadBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p) {
if(y1 >= VRes) y1 = VRes - 1;
if(y2 < 0) y2 = 0;
if(y2 >= VRes) y2 = VRes - 1;
N=(x2- x1+1) * (y2- y1+1) * (Option.DISPLAY_TYPE==ST7796S ? 2 : 3);
N=(x2- x1+1) * (y2- y1+1) * ((Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE == ST7796SP)? 2 : 3);
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE==ST7789B )spi_write_cd(ILI9341_PIXELFORMAT,1,0x66); //change to RGB666 for read
DefineRegionSPI(x1, y1, x2, y2, 0);
SPISpeedSet( (Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9481IPS) ? ST7789RSpeed : SPIReadSpeed); //need to slow SPI for read on this display
@ -1520,7 +1510,7 @@ void ReadBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p) {
// revert to non enhanced SPI mode
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE==ST7789B )spi_write_cd(ILI9341_PIXELFORMAT,1,0x55); //change back to rdb565
r=0;
if(Option.DISPLAY_TYPE==ST7796S){
if(Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE == ST7796SP){
int n=(x2- x1+1) * (y2- y1+1)*3;
while(N){
h=p[N-2];
@ -1548,9 +1538,6 @@ void ReadBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) {
unsigned char h,l;
// PInt(x1);PIntComma(y1);PIntComma(x2);PIntComma(y2);PRet();
// make sure the coordinates are kept within the display area
if(Option.DISPLAY_TYPE==ST7796S && ST7796Swritestate){
ST7796Swritestate=false;
}
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(x1 < 0) x1 = 0;
@ -1566,7 +1553,7 @@ void ReadBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) {
y1 = (y1 + ScrollStart) % VRes;
y2 = y1 + t;
if(y2 >= VRes) {
N=(x2- x1+1) * (y2- VRes) * (Option.DISPLAY_TYPE==ST7796S ? 2 : 3);
N=(x2- x1+1) * (y2- VRes) * ((Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE == ST7796SP) ? 2 : 3);
DefineRegionSPI(x1, y1, x2, VRes - 1,0);
SPISpeedSet( (Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9481IPS) ? ST7789RSpeed : SPIReadSpeed); //need to slow SPI for read on this display
rcvr_byte_multi((uint8_t *)p, 1);
@ -1576,7 +1563,7 @@ void ReadBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) {
ClearCS(Option.LCD_CS); //set CS high
SPISpeedSet(Option.DISPLAY_TYPE);
p+=N;
N=(x2- x1+1) * (y2 - VRes) * (Option.DISPLAY_TYPE==ST7796S ? 2 : 3);
N=(x2- x1+1) * (y2 - VRes) * ((Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE == ST7796SP) ? 2 : 3);
DefineRegionSPI(x1, 0, x2, y2 - VRes,0);
SPISpeedSet( (Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9481IPS) ? ST7789RSpeed : SPIReadSpeed); //need to slow SPI for read on this display
rcvr_byte_multi((uint8_t *)p, 1);
@ -1587,7 +1574,7 @@ void ReadBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) {
SPISpeedSet(Option.DISPLAY_TYPE);
N=(x2- x1+1) * (y2- y1+1) * 3;
} else {
N=(x2- x1+1) * (y2- y1+1) * (Option.DISPLAY_TYPE==ST7796S ? 2 : 3);
N=(x2- x1+1) * (y2- y1+1) * ((Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE == ST7796SP) ? 2 : 3);
DefineRegionSPI(x1, y1, x2, y2, 0);
SPISpeedSet( (Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE==ST7789B || Option.DISPLAY_TYPE==ILI9481IPS) ? ST7789RSpeed : SPIReadSpeed); //need to slow SPI for read on this display
rcvr_byte_multi((uint8_t *)p, 1);
@ -1600,7 +1587,7 @@ void ReadBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) {
}
if(Option.DISPLAY_TYPE==ILI9341 || Option.DISPLAY_TYPE==ST7789B )spi_write_cd(ILI9341_PIXELFORMAT,1,0x55); //change back to rdb565
r=0;
if(Option.DISPLAY_TYPE==ST7796S){
if(Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE == ST7796SP){
N=(x2- x1+1) * (y2- y1+1)*2;
int n=(x2- x1+1) * (y2- y1+1)*3;
while(N){
@ -1634,10 +1621,6 @@ void DrawBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p) {
} c;
unsigned char q[3];
int i,t;
if(Option.DISPLAY_TYPE==ST7796S && !ST7796Swritestate){
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(x1 < 0) x1 = 0;
@ -1680,10 +1663,6 @@ void DrawBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) {
} c;
unsigned char q[3];
int i,t;
if(Option.DISPLAY_TYPE==ST7796S && !ST7796Swritestate){
uSec(ST7796Schangetowrite);
ST7796Swritestate=true;
}
if(x2 <= x1) { t = x1; x1 = x2; x2 = t; }
if(y2 <= y1) { t = y1; y1 = y2; y2 = t; }
if(x1 < 0) x1 = 0;
@ -2054,6 +2033,7 @@ void ST7920SetXY(int x, int y){
void Display_Refresh(void){
if(!(Option.DISPLAY_TYPE<=I2C_PANEL || Option.DISPLAY_TYPE>=BufferedPanel)) return;
unsigned char* p=(void *)((unsigned int)LCDBuffer);
if(low_x==2000 && high_x==-1 && low_y==2000 && high_y==-1)return; //Nothing to do
if(low_x<0)low_x=0;
if(low_y<0)low_y=0;
if(high_x>DisplayHRes)high_x=DisplayHRes-1;
@ -2065,18 +2045,15 @@ void Display_Refresh(void){
SetCS();
gpio_put(LCD_CD_PIN,GPIO_PIN_SET);
xmit_byte_multi(p+(y*DisplayHRes)+low_x,high_x-low_x+1);
// HAL_SPI_Transmit(&hspi3,p+(y*DisplayHRes)+low_x,high_x-low_x+1,500);
ClearCS(Option.LCD_CS);
}
}
if(Option.DISPLAY_TYPE<=I2C_PANEL){
} else if(Option.DISPLAY_TYPE<=I2C_PANEL){
int y;
for(y=low_y/8;y<(high_y & 0xf8)/8+1;y++){
SSD1306I2CSetXY(Option.I2Coffset+low_x,y);
I2C_Send_Data(p+(y*DisplayHRes)+low_x,high_x-low_x+1);
}
}
if(Option.DISPLAY_TYPE==SSD1306SPI){
} else if(Option.DISPLAY_TYPE==SSD1306SPI){
int y;
for(y=low_y/8;y<(high_y & 0xf8)/8+1;y++){
SSD1306SPISetXY(Option.I2Coffset+low_x,y);
@ -2086,8 +2063,7 @@ void Display_Refresh(void){
// HAL_SPI_Transmit(&hspi3,p+(y*DisplayHRes)+low_x,high_x-low_x+1,500);
ClearCS(Option.LCD_CS);
}
}
if(Option.DISPLAY_TYPE==ST7920){
} else if(Option.DISPLAY_TYPE==ST7920){
int y,i;
unsigned char x_array[33];
unsigned char *q;
@ -2105,7 +2081,7 @@ void Display_Refresh(void){
ClearCS(Option.LCD_CD);
}
}
low_y=2000; high_y=0; low_x=2000; high_x=0;
low_y=2000; high_y=-1; low_x=2000; high_x=-1;
}
#endif

View File

@ -284,58 +284,61 @@ extern void __not_in_flash_func(spi_finish)(spi_inst_t *spi);
#define ST7789B 14
#define ILI9488W 15
#define ST7796S 16
#define ST7735S_W 17
#define GC9A01 18
#define ILI9481IPS 19
#define N5110 20
#define ST7796SP 17
#define ST7735S_W 18
#define GC9A01 19
#define ILI9481IPS 20
#define N5110 21
#define BufferedPanel N5110
#define SSD1306SPI 21
#define ST7920 22
#define TOUCH 23
#define SPIReadSpeed 24
#define ST7789RSpeed 25
#define SLOWTOUCH 26
#define DISP_USER 27
#define SCREENMODE1 28
#define SSD1306SPI 22
#define ST7920 23
#define TOUCH 24
#define SPIReadSpeed 25
#define ST7789RSpeed 26
#define SLOWTOUCH 27
#define DISP_USER 28
#define SCREENMODE1 29
#define VGADISPLAY SCREENMODE1
#define SCREENMODE2 29
#define SCREENMODE3 30
#define SCREENMODE4 31
#define SCREENMODE5 32
#define SCREENMODE6 33
#define SCREENMODE7 34
#define SSD1963_4 35
#define SCREENMODE2 30
#define SCREENMODE3 31
#define SCREENMODE4 32
#define SCREENMODE5 33
#define SCREENMODE6 34
#define SCREENMODE7 35
#define SSD1963_4 36
#define SSDPANEL SSD1963_4
#define SSD1963_5 36
#define SSD1963_5A 37
#define SSD1963_7 38
#define SSD1963_7A 39
#define SSD1963_8 40
#define ILI9341_8 41
#define SSD1963_5 37
#define SSD1963_5A 38
#define SSD1963_7 39
#define SSD1963_7A 40
#define SSD1963_8 41
#define ILI9341_8 42
#define SSD_PANEL_8 ILI9341_8
#define SSD1963_4_16 42
#define SSD1963_5_16 43
#define SSD1963_5A_16 44
#define SSD1963_7_16 45
#define SSD1963_7A_16 46
#define SSD1963_8_16 47
#define ILI9341_16 48
#define IPS_4_16 49
#define SSD1963_5ER_16 50
#define SSD1963_7ER_16 51
#define ILI9486_16 52
#define VIRTUAL_C 53
#define SSD1963_4_16 43
#define SSD1963_5_16 44
#define SSD1963_5A_16 45
#define SSD1963_7_16 46
#define SSD1963_7A_16 47
#define SSD1963_8_16 48
#define ILI9341_16 49
#define IPS_4_16 50
#define SSD1963_5ER_16 51
#define SSD1963_7ER_16 52
#define ILI9486_16 53
#define VIRTUAL_C 54
#define VIRTUAL VIRTUAL_C
#define VIRTUAL_M 54
#define VS1053slow 55
#define VS1053fast 56
#define VIRTUAL_M 55
#define VS1053slow 56
#define VS1053fast 57
#define NEXTGEN1 58
#define NEXTGEN NEXTGEN1
#define TFT_NOP 0x00
#define TFT_SWRST 0x01
#define SSDTYPE (Option.DISPLAY_TYPE>=SSDPANEL && Option.DISPLAY_TYPE<VIRTUAL_C && !(Option.DISPLAY_TYPE==ILI9341_16 || Option.DISPLAY_TYPE==ILI9341_8 || Option.DISPLAY_TYPE==IPS_4_16 || Option.DISPLAY_TYPE==ILI9486_16))
#define SSD16TYPE (Option.DISPLAY_TYPE>SSD_PANEL_8 && Option.DISPLAY_TYPE<VIRTUAL_C && !(Option.DISPLAY_TYPE==ILI9341_16 || Option.DISPLAY_TYPE==IPS_4_16 || Option.DISPLAY_TYPE==ILI9486_16))
#define SPIREAD (Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ST7789B)
#define SPIREAD (Option.DISPLAY_TYPE == ILI9341 || Option.DISPLAY_TYPE == ILI9488P || Option.DISPLAY_TYPE == ILI9488 || Option.DISPLAY_TYPE == ST7796SP || Option.DISPLAY_TYPE == ST7796S || Option.DISPLAY_TYPE == ST7789B)
#define FASTSCROLL (SSDTYPE || Option.DISPLAY_TYPE==SCREENMODE1 || Option.DISPLAY_TYPE == SCREENMODE2 || Option.DISPLAY_TYPE == VIRTUAL_C || Option.DISPLAY_ORIENTATION == VIRTUAL_M)
#define SPI480 (Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ILI9488W || Option.DISPLAY_TYPE==ILI9481 || Option.DISPLAY_TYPE==ILI9481IPS)
#define SPI480 (Option.DISPLAY_TYPE==ILI9488 || Option.DISPLAY_TYPE==ST7796S || Option.DISPLAY_TYPE==ILI9488W || Option.DISPLAY_TYPE==ILI9481 || Option.DISPLAY_TYPE==ILI9481IPS)
#define TFT_SLPIN 0x10
#define TFT_SLPOUT 0x11
@ -475,5 +478,6 @@ extern void BitBangReadSPI(BYTE *buff, int cnt);
extern void ScrollLCDSPI(int lines);
extern void SetCS(void);
extern int GetLineILI9341(void);
extern void SPI111init(void);
#endif
/* @endcond */

View File

@ -29,7 +29,7 @@ list all
#define VERSION "6.00.02RC23" // define the version number
#define VERSION "6.00.02" // define the version number
#define YEAR "2011-2025" // and the year
#define YEAR2 "2016-2025"
#ifdef rp2350

View File

@ -44,10 +44,10 @@ extern "C" {
#ifdef HDMI
#define MAXMODES 5
#ifdef USBKEYBOARD
#define MagicKey 0x81613124
#define MagicKey 0x84223124
#define HEAPTOP 0x2007D000
#else
#define MagicKey 0x976EB2A0
#define MagicKey 0x9687B2A0
#define HEAPTOP 0x2007D000
#endif
#define MAX_CPU Freq378P
@ -55,10 +55,10 @@ extern "C" {
#else
#define MAXMODES 3
#ifdef USBKEYBOARD
#define MagicKey 0x8E605904
#define MagicKey 0x82115904
#define HEAPTOP 0x2007C000
#else
#define MagicKey 0x600EAFAF
#define MagicKey 0x84005FAF
#define HEAPTOP 0x2007C000
#endif
#ifdef rp2350
@ -71,12 +71,12 @@ extern "C" {
#else
#ifdef USBKEYBOARD
#define FLASH_TARGET_OFFSET (848* 1024)
#define MagicKey 0x41FBA715
#define MagicKey 0x4776A715
#define HEAPTOP 0x2003F000
#define MAXVARS 480 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#else
#define FLASH_TARGET_OFFSET (864 * 1024)
#define MagicKey 0xA0529A2F
#define MagicKey 0xA2349A2F
#define HEAPTOP 0x2003f000
#define MAXVARS 480 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#endif
@ -151,7 +151,7 @@ extern "C" {
#include "lwipopts_examples_common.h"
#define FLASH_TARGET_OFFSET (1080 * 1024)
#define MagicKey 0x57128B1C
#define MagicKey 0x53472B1C
#define MaxPcb 8
#define MAX_CPU 252000
#define MIN_CPU 126000
@ -162,27 +162,27 @@ extern "C" {
#ifdef rp2350
#define HEAP_MEMORY_SIZE (288*1024)
#define MAXVARS 768 // 8 + MAXVARLEN + MAXDIM * 4 (ie, 64 bytes) - these do not incl array members
#define FLASH_TARGET_OFFSET (920 * 1024)
#define FLASH_TARGET_OFFSET (1080 * 1024) // 200k + 880k -- make sure PicoMite binary is under 880k! (currently ~780k, leave 100k for expansion)
#define MAX_CPU (rp2350a ? 396000 : 378000)
#define MAXSUBFUN 512 // each entry takes up 4 bytes
#ifdef USBKEYBOARD
#define MagicKey 0xD8069F27
#define MagicKey 0xD27F4F27
#define HEAPTOP 0x20078000
#else
#define MagicKey 0x119B6ED7
#define MagicKey 0x18207ED7
#define HEAPTOP 0x20078000
#endif
#else
#define HEAP_MEMORY_SIZE (128*1024)
#define MAXVARS 512 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#define FLASH_TARGET_OFFSET (920 * 1024)
#define FLASH_TARGET_OFFSET (1080 * 1024) // 200k + 880k -- make sure PicoMite binary is under 880k! (currently ~780k, leave 100k for expansion)
#define MAX_CPU 420000
#define MAXSUBFUN 256 // each entry takes up 4 bytes
#ifdef USBKEYBOARD
#define MagicKey 0x68EFA19E
#define MagicKey 0x6110519E
#define HEAPTOP 0x2003F000
#else
#define MagicKey 0xE1473B93
#define MagicKey 0xE0799B93
#define HEAPTOP 0x2003EC00
#endif
#endif
@ -243,7 +243,7 @@ extern "C" {
#define PIOMAX 3
#define NBRPINS 62
#define PSRAMbase 0x11000000
#define PSRAMblock (PSRAMbase+PSRAMsize+0x40000)
#define PSRAMblock (PSRAMbase+PSRAMsize+0x60000)
#define PSRAMblocksize 0x1C0000
#else
#define PIOMAX 2
@ -263,7 +263,7 @@ extern "C" {
#define FNV_offset_basis 2166136261
#define use_hash
#define DISKCHECKRATE 500 //check for removal of SDcard every 200mSec
#define EDIT_BUFFER_SIZE heap_memory_size-2048-3*HRes// this is the maximum RAM that we can get
#define EDIT_BUFFER_SIZE heap_memory_size-3072-3*HRes// this is the maximum RAM that we can get
#define SCREENWIDTH 80
#define SCREENHEIGHT 24 // this is the default and it can be changed using the OPTION command
#define CONSOLE_BAUDRATE 115200 // only applies to the serial console
@ -383,8 +383,8 @@ typedef enum {
MMCMDLINE,
#ifdef PICOMITEWEB
MMMESSAGE,
MMTOPIC,
MMADDRESS,
MMTOPIC,
#endif
MMFLAG,
MMDISPLAY,

View File

@ -0,0 +1,856 @@
/*
* Copyright (c) 2024 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#if !PICO_RP2040
#include "pico/asm_helper.S"
pico_default_asm_setup
.macro float_section name
#if PICO_FLOAT_IN_RAM
.section RAM_SECTION_NAME(\name), "ax"
#else
.section SECTION_NAME(\name), "ax"
#endif
.endm
.macro float_wrapper_section func
float_section WRAPPER_FUNC_NAME(\func)
.endm
@ load a 32-bit constant n into register rx
.macro movlong rx,n
movw \rx,#(\n)&0xffff
movt \rx,#((\n)>>16)&0xffff
.endm
float_section frrcore_v
.p2align 2
// 1/2π to plenty of accuracy
.long 0 @ this allows values of e down to -32
rtwopi:
.long 0,0
.long 0x28BE60DB, 0x9391054A, 0x7F09D5F4, 0x7D4D3770, 0x36D8A566, 0x4F10E410
@ input:
@ r0 mantissa m Q23
@ r1 exponent e>=-32, typically offset by +9
@ output:
@ r0..r1 preserved
@ r6 range reduced result in revolutions Q32
@ r2,r3,r4,r5 trashed
.thumb_func
frr_core:
adr r2,rtwopi
asrs r3,r1,#5 @ k=e/32, k<=5 for e offsets up to 9+32
add r2,r2,r3,lsl#2 @ p
and r3,r1,#31 @ s=e%32
mov r4,#1
lsls r4,r4,r3 @ 1<<s
umull r3,r4,r4,r0
@ r2 p
@ r3:r4 u0:u1 = m<<(e%32); u1 is never more than 2<<23
ldr r5,[r2,#12] @ a0=p[3]
umull r5,r6,r5,r4 @ r0=a0*u1 hi, discard lo
@ r6 r0
ldr r5,[r2,#8] @ a1=p[2]
mla r6,r5,r4,r6 @ a1*u1 lo, discard hi
umlal r5,r6,r5,r3 @ a1*u0 hi, discard lo
@ r6 r0
ldr r5,[r2,#4] @ a2=p[1]
mla r6,r5,r3,r6 @ r0+=a2*u0
bx r14
float_wrapper_section expf
wrapper_func expf
@ soft float version, via 2^x
asrs r1,r0,#23
bmi 1f
cmp r1,#0x85
bge 3f
10:
movs r2,#1
bfi r0,r2,#23,#9
subs r1,#0x7e
bmi 2f
lsl r0,r1 @ x Q24
11:
movlong r3,0x5c551d95 @ 1/log(2) Q30
smull r0,r1,r0,r3 @ Q54
adr r2,k_exp2
vldmia r2,{s8-s10}
lsrs r2,r0,#22
bfi r2,r1,#10,#17 @ ε Q32
vmov s0,r2
vcvt.f32.u32 s0,s0,#32
vmul.f32 s1,s0,s0
ubfx r2,r1,#17,#5
vmul.f32 s4,s0,s8
adr r3,exptab3
vmul.f32 s2,s0,s1
ldr r2,[r3,r2,lsl#2]
vmla.f32 s4,s1,s9
asrs r1,#22
vmla.f32 s4,s2,s10
add r2,r2,r1,lsl#23
vmov s0,r2
vmla.f32 s0,s0,s4
vmov r0,s0
bx r14
2: @ x≤0.5
rsbs r1,#0
lsrs r0,r1
@ adc r0,#0 @ rounding not needed
b 11b
3: @ risk of overflow, Inf,NaN
movlong r2,0x42B17218
cmp r0,r2
blo 10b @ in range after all
cmp r0,#0x7f800000
bls 4f @ not NaN?
orrs r0,#0x00400000
bx r14
4:
movlong r0,0x7f800000 @ return +Inf
bx r14
1: @ x<0, r1=0xffffffXX where XX is biased exponent
cmn r1,#0x7b
bge 5f @ risk of underflow, -Inf, -NaN?
13:
movs r2,#1
bfi r0,r2,#23,#9
adds r1,#0x82
bpl 6f
rsbs r1,#0
lsrs r0,r1
adc r0,r0,#0 @ rounding
12:
rsbs r0,#0
b 11b
6:
lsls r0,r1
b 12b
5:
movlong r2,0xC2AEAC4F
cmp r0,r2
bls 13b
cmp r0,#0xff800000
bls 14f
orrs r0,#0x00400000
bx r14
14:
mov r0,#0
bx r14
.p2align 3
k_exp2:
.float 0.693147181 @ log2
.float 0.240226507 @ log²2/2
.float 0.055504109 @ log³2/6
exptab3: @ pow(2,[0..31]/32)
.word 0x3f800000
.word 0x3f82cd87
.word 0x3f85aac3
.word 0x3f88980f
.word 0x3f8b95c2
.word 0x3f8ea43a
.word 0x3f91c3d3
.word 0x3f94f4f0
.word 0x3f9837f0
.word 0x3f9b8d3a
.word 0x3f9ef532
.word 0x3fa27043
.word 0x3fa5fed7
.word 0x3fa9a15b
.word 0x3fad583f
.word 0x3fb123f6
.word 0x3fb504f3
.word 0x3fb8fbaf
.word 0x3fbd08a4
.word 0x3fc12c4d
.word 0x3fc5672a
.word 0x3fc9b9be
.word 0x3fce248c
.word 0x3fd2a81e
.word 0x3fd744fd
.word 0x3fdbfbb8
.word 0x3fe0ccdf
.word 0x3fe5b907
.word 0x3feac0c7
.word 0x3fefe4ba
.word 0x3ff5257d
.word 0x3ffa83b3
float_wrapper_section logf
wrapper_func logf
cmp r0,#0x7f800000 @ catch Inf, NaN, -ve
bhs 1f
asrs r1,r0,#23 @ get exponent; C from here is preserved...
beq 2f @ ±0?
mov r2,#1
bfi r0,r2,#23,#9 @ fix implied 1
it cc @ 50% ... to here...
lslcc r0,#1 @ this plus sbc below means we work relative to nearby power of 2
adr r3,#k_log3
vldmia r3,{s8-s10}
@ 0x00c00000 ≤ r0 < 0x017fffff
adr r3,logtab3-24*8+4
add r3,r3,r0,lsr#16 @ look up r0>>19 rounded, preserving flags
bic r3,#7
ldrd r2,r3,[r3]
mul r0,r0,r2 @ ε
vmov s0,s1,r3,r0 @ s0=-log u, s1=ε
vcvt.f32.s32 s1,s1,#32
vmul.f32 s2,s1,s1 @ power series in ε
sbc r1,r1,#0x7e @ ... and here
vmul.f32 s3,s1,s2
lsls r1,#23 @ e Q23
vmul.f32 s4,s2,s2 @ to ε⁴
@ movlong r2,0x58b90bfc @ log 2 Q31, more accurate than we deserve
movw r2,0x0bfc
vmul.f32 s2,s2,s8
movt r2,0x58b9
vmul.f32 s3,s3,s9
smmulr r1,r1,r2 @ Q22
vmul.f32 s4,s4,s10
vmov s7,r1
vsub.f32 s3,s3,s4
vcvt.f32.s32 s7,s7,#22
vsub.f32 s2,s2,s3
vsub.f32 s1,s1,s2
vadd.f32 s0,s0,s1 @ log ε - log u
vadd.f32 s0,s0,s7 @ e log 2 + log ε - log u
vmov r0,s0
bx r14
1:
bgt 3f @ +NaN?
beq 10f @ +Inf?
2:
cmp r0,#0x80800000 @ -0?
blo 11f
cmp r0,#0xff800000 @ -NaN/-Inf?
3:
orr r0,#0x00400000
bhi 10f
movlong r0,0xffc00000
10:
bx r14
11:
movlong r0,0xff800000
bx r14
.p2align 3
k_log3:
.float 0.5
.float 0.333333333333333
.float 0.25
.float 0 @ alignment
logtab3:
@ u=64/[48:2:96]; u Q8, -log u F32
.word 0x0155,0xbe92cb01 @ 00003e9b..00004145
.word 0x0148,0xbe7dc8c3 @ 00003ec8..00004158
.word 0x013b,0xbe545f68 @ 00003ec1..00004137
.word 0x012f,0xbe2c99c7 @ 00003ebb..00004119
.word 0x0125,0xbe0a3c2c @ 00003ef3..0000413d
.word 0x011a,0xbdc61a2f @ 00003eca..000040fe
.word 0x0111,0xbd83acc2 @ 00003eeb..0000410d
.word 0x0108,0xbcfc14d8 @ 00003ee8..000040f8
.word 0x0100,0x00000000 @ 00003f00..00004100
.word 0x00f8,0x3d020aec @ 00003ef8..000040e8
.word 0x00f1,0x3d77518e @ 00003f13..000040f5
.word 0x00ea,0x3db80698 @ 00003f12..000040e6
.word 0x00e4,0x3ded393b @ 00003f3c..00004104
.word 0x00dd,0x3e168b08 @ 00003f05..000040bf
.word 0x00d8,0x3e2dfa03 @ 00003f48..000040f8
.word 0x00d2,0x3e4ad2d7 @ 00003f2a..000040ce
.word 0x00cd,0x3e637fde @ 00003f43..000040dd
.word 0x00c8,0x3e7cc8e3 @ 00003f48..000040d8
.word 0x00c3,0x3e8b5ae6 @ 00003f39..000040bf
.word 0x00bf,0x3e95f784 @ 00003f6b..000040e9
.word 0x00ba,0x3ea38c6e @ 00003f36..000040aa
.word 0x00b6,0x3eaeadef @ 00003f46..000040b2
.word 0x00b2,0x3eba0ec4 @ 00003f46..000040aa
.word 0x00ae,0x3ec5b1cd @ 00003f36..00004092
.word 0x00ab,0x3ece995f @ 00003f75..000040cb
float_wrapper_section fsin_fcos
30:
lsls r1,r0,#9
bne 1f @ NaN? return it
orrs r0,r0,#0x80000000 @ Inf: make a NaN
1:
orrs r0,r0,#0x00400000 @ set top mantissa bit of NaN
bx r14
@ heavy-duty range reduction
@ here x≥256, -e in r1
40:
push {r4-r7,r14}
movs r3,#1
bfi r0,r3,#23,#9 @ insert implied 1 in mantissa, clear sign
rsb r1,#9 @ e+9
mov r7,#0x7e @ this will be the exponent of the reduced angle - 1
42:
bl frr_core
@ here r6 is revolutions Q32
lsrs r3,r6,#30 @ quadrant count
adcs r3,r3,#0 @ rounded
add r12,r12,r3
subs r6,r6,r3,lsl#30 @ reduced angle/2π Q32 -.125≤x<+.125
@ comment out from here...
lsls r2,r6,#2 @ Q34
it cs
rsbcs r2,r2,#0 @ absolute value
cmp r2,#1<<28 @ big enough for accuracy?
bhs 41f
@ ... to here for slightly better accuracy
43:
adds r1,r1,#2 @ try again with increased exponent
bl frr_core
eors r2,r6,r6,asr#32 @ absolute value
adc r2,r2,#0
cmp r2,#1<<28 @ big enough yet?
bhs 44f
subs r7,r7,#2
bpl 43b @ safety net
44:
41:
ldr r4,=0xC90FDAA2 @ 2π Q29
umull r2,r4,r2,r4 @ r4 has reduced angle Q34+Q29-Q32=Q31
@ add r4,r4,r2,lsr#31
clz r2,r4 @ normalise
lsls r4,r4,r2
lsrs r4,r4,#8
sub r2,r7,r2
adc r0,r4,r2,lsl#23 @ with rounding
lsrs r1,r0,#23 @ re-extract exponent as there may have been a carry into it
rsbs r1,r1,#0x7f @ prepare exponent for re-entry
lsrs r6,r6,#31
add r3,r0,r6,lsl#31 @ apply sign of reduced angle
pop {r4-r7,r14}
b 5f @ re-enter with no risk of looping
.ltorg
@ light-duty range reduction
@ here argument ≥1
@ r0: argument
@ r1: -e
@ r12: quadrant count
@ required result is sin(r0+r12*π/2)
10:
cmn r1,#0x80
beq 30b @ Inf/NaN
bics r2,r0,r12,lsl#31 @ negative argument,doing sin -> +2 quadrants
it mi
addmi r12,r12,#2
bic r0,r0,#0x80000000 @ make positive: original sign is now captured in quadrant count in r12
@ this may not actually be faster than doing it in integer registers
vmov s0,r0
adr r2,k_sc4
vldmia r2!,{s5-s7}
@ vmul.f32 s4,s4,s0 @ this accurate calculation of the quadrant count does not seem necessary
@ vfma.f32 s4,s5,s0
vmul.f32 s4,s5,s0 @ this is BALGE
cmn r1,#8 @ ≥256?
vrintn.f32.f32 s4,s4 @ round to quadrant count: x<256 so count≤163
ble 40b @ then do heavy-duty range reduction
vfms.f32 s0,s4,s7
vfms.f32 s0,s4,s6
vmov r3,s0 @ reduced angle
vcvt.s32.f32 s3,s4
ubfx r2,r3,#23,#8 @ get exponent
cmp r2,#0x78
blo 40b @ very small result? use heavy-duty reduction to get a more accurate answer
rsbs r1,r2,#0x7f @ ready for re-entry
vmov r2,s3 @ integer quadrant count
add r12,r12,r2
@ prepare to re-enter with no risk of looping
b 5f
k_sc4:
@ 2/π=0.A2F9836E4E441529FC...
.word 0x3f22f983 @ 2/π
@ π/2=1.921FB54442D1846989...
.word 0xb695777a,0x3fc91000 @ these two add up to π/2 with error ~1.6e-13
wrapper_func sincosf
push {r0-r2,r14}
ubfx r1,r0,#23,#8
cmp r1,#0xff @ Inf/NaN?
beq 2f
bl cosf_entry @ this will exit via 1f or 2f...
pop {r1-r2,r14}
str r0,[r14]
@ here C is still set from lsrs r12,r12,#1
bcs 1f
mvns r1,r1
eor r12,r12,r1,lsr#31
@ this is fsc_costail:
@ here calculate cos φ+ε = cosθ
vmul.f32 s5,s7,s1 @ sinφ sinε
vfma.f32 s5,s2,s6 @ sinφ sinε + cosφ(1-cosε)
vsub.f32 s5,s6,s5 @ cosφ - (sinφ sinε + cosφ(1-cosε)) = cosφ cosε - sinφ sinε
vmov.f32 r0,s5
eor r0,r0,r12,lsl#31
str r0,[r2]
pop {r15}
1:
eor r12,r12,r1,lsr#31
@ this is fsc_sintail:
@ here calculate sin φ+ε = sinθ
vmul.f32 s4,s2,s7 @ sinφ(1-cosε)
vfms.f32 s4,s6,s1 @ sinφ(1-cosε) - cosφ sinε
eor r1,r12,r3,lsr#31 @ flip sign if (reduced) argument was negative
vsub.f32 s4,s7,s4 @ cosφ sinε + sinφ cosε
vmov.f32 r0,s4
eor r0,r0,r1,lsl#31
str r0,[r2] @ save cos result
pop {r15}
@ sincos of Inf or NaN
2:
lsls r1,r0,#9
pop {r1-r3,r14}
bne 1f @ NaN? return it
orrs r0,r0,#0x80000000 @ Inf: make a NaN
1:
orrs r0,r0,#0x00400000 @ set top mantissa bit of NaN
str r0,[r2] @ both sin and cos results
str r0,[r3]
bx r14
wrapper_func sinf
@ r12b1..0: quadrant count
movs r12,#0
b 1f
wrapper_func cosf
.thumb_func
cosf_entry:
movs r12,#1 @ cos -> +1 quadrant
1:
ubfx r1,r0,#23,#8 @ get exponent
cbz r1,20f @ 0/denormal?
22:
rsbs r1,r1,#0x7f
bls 10b @ argument ≥1? needs reduction; also Inf/NaN handling
bic r3,r0,r12,lsl#31 @ this would mess up NaNs so do it here
5:
@ here we have a quadrant count in r12 and a signed offset r0 from r12*π/2
bic r0,r3,#0x80000000 @ this would mess up NaNs so do it here
vmov s0,r0
ubfx r0,r0,#18,#5 @ extract top of mantissa
adds r0,r0,#32 @ insert implied 1
lsrs r1,r0,r1 @ to fixed point Q5
ldr r2,=k_sc3
adcs r1,r1,#0 @ rounding
vldmia r2!,{s8-s9}
add r2,r2,r1,lsl#2 @ 12 bytes per entry
add r2,r2,r1,lsl#3
vldmia r2,{s5-s7} @ φ, cosφ, sinφ
vsub.f32 s1,s0,s5 @ ε
vmul.f32 s2,s1,s1 @ ε²
lsrs r12,r12,#1 @ computing cosine?
vmul.f32 s3,s2,s1 @ ε³
bcs 2f
vmul.f32 s2,s2,s8 @ ε²/2! ~ 1-cosε
vmul.f32 s3,s3,s9 @ ε³/3!
vsub.f32 s1,s1,s3 @ ε-ε³/3! ~ sinε
@ here:
@ s1: sinε
@ s2: 1-cosε
@ s6: cosφ
@ s7: sinφ
@ r12: quadrant count
fsc_sintail:
@ here calculate sin φ+ε = sinθ
vmul.f32 s4,s2,s7 @ sinφ(1-cosε)
vfms.f32 s4,s6,s1 @ sinφ(1-cosε) - cosφ sinε
eor r1,r12,r3,lsr#31 @ flip sign if (reduced) argument was negative
vsub.f32 s4,s7,s4 @ cosφ sinε + sinφ cosε
vmov.f32 r0,s4
eor r0,r0,r1,lsl#31
bx r14
20:
and r0,r0,#0x80000000 @ make signed zero
b 22b
.p2align 2
2:
vmul.f32 s3,s3,s9 @ ε³/3!
vsub.f32 s1,s1,s3 @ ε-ε³/3! ~ sinε
vmul.f32 s2,s2,s8 @ ε²/2! ~ 1-cosε
fsc_costail:
@ here calculate cos φ+ε = cosθ
vmul.f32 s5,s7,s1 @ sinφ sinε
vfma.f32 s5,s2,s6 @ sinφ sinε + cosφ(1-cosε)
vsub.f32 s5,s6,s5 @ cosφ - (sinφ sinε + cosφ(1-cosε)) = cosφ cosε - sinφ sinε
vmov.f32 r0,s5
eor r0,r0,r12,lsl#31
bx r14
.p2align 3
k_sc3:
.word 0x3EFFFEC1 @ ~ 1/2! with PMC
.word 0x3e2aaa25 @ ~ 1/3! with PMC
trigtab2:
// φ cos φ sin φ
.word 0x00000000,0x3f800000,0x00000000
.word 0x3cfcc961,0x3f7fe0cd,0x3cfcbf1c @ φ=0.03085774 : cos φ=3feffc199ff28ef4 33.3b; sin φ=3f9f97e38006c678 39.2b
.word 0x3d810576,0x3f7f7dfe,0x3d80ef9e @ φ=0.06299870 : cos φ=3fefefbfc00d6b6d 33.3b; sin φ=3fb01df3c000dfd5 40.2b
.word 0x3dbf0c09,0x3f7ee30f,0x3dbec522 @ φ=0.09328467 : cos φ=3fefdc61dff4f58e 33.5b; sin φ=3fb7d8a43ffdf9ac 39.0b
.word 0x3dff24b6,0x3f7e0414,0x3dfe7be2 @ φ=0.12458174 : cos φ=3fefc0827fdaf90f 31.8b; sin φ=3fbfcf7c3ff9dd0c 37.4b
.word 0x3e1f0713,0x3f7ceb48,0x3e1e63a0 @ φ=0.15530042 : cos φ=3fef9d68ffe680a0 32.3b; sin φ=3fc3cc73fffa6d09 36.5b
.word 0x3e40306d,0x3f7b811d,0x3e3f1015 @ φ=0.18768473 : cos φ=3fef70239fe32301 32.1b; sin φ=3fc7e2029ffdbc2c 37.8b
.word 0x3e60ada2,0x3f79dccf,0x3e5ee13e @ φ=0.21941236 : cos φ=3fef3b99e023f5aa 31.8b; sin φ=3fcbdc27bffe216d 38.1b
.word 0x3e800d7b,0x3f7808fa,0x3e7d7196 @ φ=0.25010285 : cos φ=3fef011f401572a6 32.6b; sin φ=3fcfae32c00328bb 37.3b
.word 0x3e8f986e,0x3f75ff65,0x3e8db868 @ φ=0.28045982 : cos φ=3feebfeca0aaaf99 29.6b; sin φ=3fd1b70cfffc1468 36.0b
.word 0x3e9fe1f4,0x3f739e93,0x3e9d4bfd @ φ=0.31227076 : cos φ=3fee73d25fbf733b 31.0b; sin φ=3fd3a97fa0002ced 40.5b
.word 0x3eb054c6,0x3f70f7ae,0x3eacddb3 @ φ=0.34439677 : cos φ=3fee1ef5bfcf70cb 31.4b; sin φ=3fd59bb65fff5c30 38.6b
.word 0x3ebf89c5,0x3f6e4b60,0x3ebb1a0a @ φ=0.37409797 : cos φ=3fedc96bffdebb8a 31.9b; sin φ=3fd763414003344b 36.3b
.word 0x3ecfc426,0x3f6b35ca,0x3eca1c63 @ φ=0.40579337 : cos φ=3fed66b93fe27dc6 32.1b; sin φ=3fd9438c5ffe5d45 37.3b
.word 0x3ee054f2,0x3f67d166,0x3ed93907 @ φ=0.43814808 : cos φ=3fecfa2cbffc16e9 35.0b; sin φ=3fdb2720dffef5b6 37.9b
.word 0x3eeff0dd,0x3f64664b,0x3ee74116 @ φ=0.46863452 : cos φ=3fec8cc95f714272 29.8b; sin φ=3fdce822c00479ad 35.8b
.word 0x3f002b31,0x3f609488,0x3ef5c30f @ φ=0.50065905 : cos φ=3fec1290ffc99208 31.2b; sin φ=3fdeb861dfff3932 38.4b
.word 0x3f07e407,0x3f5cc5a2,0x3f01992b @ φ=0.53082317 : cos φ=3feb98b44034cd46 31.3b; sin φ=3fe033255ffff628 41.7b
.word 0x3f101fc5,0x3f587d8f,0x3f08a165 @ φ=0.56298476 : cos φ=3feb0fb1e0ceda6f 29.3b; sin φ=3fe1142c9ffd5ae4 35.6b
.word 0x3f17f68a,0x3f5434b5,0x3f0f31ca @ φ=0.59360564 : cos φ=3fea8696a038a06f 31.2b; sin φ=3fe1e639400269fb 35.7b
.word 0x3f1fffe2,0x3f4f9b59,0x3f15c8d7 @ φ=0.62499821 : cos φ=3fe9f36b1f428363 29.4b; sin φ=3fe2b91ae001d55d 36.1b
.word 0x3f280646,0x3f4acf6b,0x3f1c37c4 @ φ=0.65634573 : cos φ=3fe959ed61449f08 28.7b; sin φ=3fe386f87ffd9617 35.7b
.word 0x3f303041,0x3f45b9e0,0x3f229ae4 @ φ=0.68823630 : cos φ=3fe8b73c0047ae7a 30.8b; sin φ=3fe4535c7ffdf1ac 36.0b
.word 0x3f381da7,0x3f4098ca,0x3f28a620 @ φ=0.71920246 : cos φ=3fe81319402ae6e1 31.6b; sin φ=3fe514c3ffff423c 37.4b
.word 0x3f3fc72f,0x3f3b76ac,0x3f2e564a @ φ=0.74913305 : cos φ=3fe76ed5809d419f 29.7b; sin φ=3fe5cac93fffaf1d 38.7b
.word 0x3f4813db,0x3f35b6cc,0x3f34526b @ φ=0.78155297 : cos φ=3fe6b6d9800e8b52 33.1b; sin φ=3fe68a4d5ffe89fc 36.5b
.word 0x3f4fc779,0x3f30352f,0x3f39b4d0 @ φ=0.81163746 : cos φ=3fe606a5dfdc2b5b 31.8b; sin φ=3fe73699fffd7fc8 35.7b
.word 0x3f57dd52,0x3f2a4170,0x3f3f2d91 @ φ=0.84322083 : cos φ=3fe5482e011ba752 28.9b; sin φ=3fe7e5b21ffcb223 35.3b
.word 0x3f5fce26,0x3f243e9f,0x3f445dc3 @ φ=0.87423933 : cos φ=3fe487d3e0b9864b 29.5b; sin φ=3fe88bb85ffde6d5 35.9b
.word 0x3f6825f1,0x3f1dc250,0x3f499d1c @ φ=0.90682894 : cos φ=3fe3b849ffea9b8f 32.6b; sin φ=3fe933a38002730d 35.7b
.word 0x3f703be1,0x3f175041,0x3f4e7ebf @ φ=0.93841368 : cos φ=3fe2ea0820791b4e 30.1b; sin φ=3fe9cfd7e0053e65 34.6b
.word 0x3f781078,0x3f10ed71,0x3f5306af @ φ=0.96900129 : cos φ=3fe21dae1fdea23e 31.9b; sin φ=3fea60d5e001b90b 36.2b
.word 0x3f7ff4d4,0x3f0a5aa7,0x3f57649b @ φ=0.99982953 : cos φ=3fe14b54deeaa407 28.9b; sin φ=3feaec9360012825 36.8b
float_wrapper_section tanf
wrapper_func tanf
push {r0,r14}
ubfx r1,r0,#23,#8
cmp r1,#0xff @ Inf/NaN?
beq 2f
bl cosf_entry @ this will exit via sintail or costail...
ldr r1,[sp,#0]
@ here C is still set from lsrs r12,r12,#1
bcs 1f
@ we exited via sintail
@ this is fsc_costail:
@ here calculate cos φ+ε = cosθ
vmul.f32 s5,s7,s1 @ sinφ sinε
vfma.f32 s5,s2,s6 @ sinφ sinε + cosφ(1-cosε)
eors r1,r1,r3
vsub.f32 s5,s6,s5 @ cosφ - (sinφ sinε + cosφ(1-cosε)) = cosφ cosε - sinφ sinε
vdiv.f32 s0,s5,s4
vmov.f32 r0,s0
it pl
eorpl r0,r0,#0x80000000
pop {r1,r15}
1:
@ we exited via costail
@ this is fsc_sintail:
@ here calculate sin φ+ε = sinθ
vmul.f32 s4,s2,s7 @ sinφ(1-cosε)
vfms.f32 s4,s6,s1 @ sinφ(1-cosε) - cosφ sinε
eors r1,r1,r3
vsub.f32 s4,s7,s4 @ cosφ sinε + sinφ cosε
vdiv.f32 s0,s4,s5
vmov.f32 r0,s0
it mi
eormi r0,r0,#0x80000000
pop {r1,r15}
@ tan of Inf or NaN
2:
lsls r1,r0,#9
bne 1f @ NaN? return it
orrs r0,r0,#0x80000000 @ Inf: make a NaN
1:
orrs r0,r0,#0x00400000 @ set top mantissa bit of NaN
pop {r3,r15}
float_wrapper_section atan2f
50:
60:
orrs r0,r1,#0x00400000
bx r14
51:
bne 52f @ NaN?
cmp r3,#0x7f800000 @ y an infinity; x an infinity too?
bne 55f @ no: carry on
@ here x and y are both infinities
b 66f
52:
62:
orrs r0,r0,#0x00400000
bx r14
61:
bne 62b @ NaN?
cmp r3,#0x7f800000 @ y an infinity; x an infinity too?
bne 65f @ no: carry on
66:
@ here x and y are both infinities
subs r0,r0,#1 @ make both finite (and equal) with same sign and retry
subs r1,r1,#1
b 86f
70:
and r3,#0x80000000
cmp r2,#0x00800000
bhs 72f @ y 0 or denormal?
@ here both x and y are zeros
b 85f
71:
and r2,#0x80000000
72:
vmov s0,s1,r2,r3
vdiv.f32 s2,s0,s1 @ restart the division
b 73f @ and go back and check for NaNs
80:
and r3,#0x80000000
cmp r2,#0x00800000
bhs 82f @ y 0 or denormal?
85:
@ here both x and y are zeros
orr r1,r1,0x3f800000 @ retry with x replaced by ~1 with appropriate sign
b 86f
81:
and r2,#0x80000000
82:
vmov s0,s1,r2,r3
vdiv.f32 s2,s1,s0 @ restart the division
b 83f @ and go back and check for NaNs
wrapper_func atan2f
86:
bic r2,r0,#0x80000000
bic r3,r1,#0x80000000
vmov s0,s1,r2,r3
cmp r2,r3 @ |y| vs. |x|
bhi 1f
@ here |x|≥|y| so we need |y|/|x|; octant/xs/ys: 0++,3-+,4--,7+-
vdiv.f32 s2,s0,s1 @ get this division started; result ≤1
cmp r3,#0x00800000
blo 70b @ x 0 or denormal?
cmp r2,#0x00800000
blo 71b @ y 0 or denormal?
73:
cmp r3,#0x7f800000
bhi 50b @ x NaN?
cmp r2,#0x7f800000
bhs 51b @ y Inf or NaN?
55:
cmp r1,#0
ite mi
ldrmi r12,pi @ if x<0, need two extra quadrants
movpl r12,#0
@ inner negation is the sign of x
b 2f
1:
@ here |x|<|y| so we need |x|/|y|; octant/xs/ys: 1++,2-+,5--,6+-
vdiv.f32 s2,s1,s0 @ result <1
cmp r3,#0x00800000
blo 80b @ x 0 or denormal?
cmp r2,#0x00800000
blo 81b @ y 0 or denormal?
83:
cmp r3,#0x7f800000
bhi 60b @ x NaN?
cmp r2,#0x7f800000
bhs 61b @ y Inf or NaN?
65:
ldr r12,piover2 @ always one extra quadrant in this path
eors r1,r1,#0x80000000 @ inner negation is the complement of the sign of x
2:
@ here
@ r0 y
@ r1 ±x
@ r2 |y|
@ r3 |x|
@ s0,s1 = |x|,|y|
@ s2=s0/s1 or s1/s0, 0≤s2≤1
@ r12=quadrant count * π/2
@ where the final result is
@ ± (r12 ± atn s2) where the inner negation is given by r1b31 and the outer negation by r0b31
adr r2,trigtab3
vmov.f32 s3,s2
vcvt.u32.f32 s3,s3,#6
vmov.f32 r3,s3
lsrs r3,r3,#1
adcs r3,r3,#0 @ rounding; set Z if in φ==0 case
add r2,r2,r3,lsl#3
vldr s5,[r2,#4] @ t=tanφ
vmul.f32 s0,s5,s2 @ ty
vsub.f32 s1,s2,s5 @ y-t
vmov.f32 s5,#1.0
vadd.f32 s0,s5,s0 @ 1+ty
beq 9f @ did we look up zeroth table entry?
@ now (s0,s1) = (x,y)
vdiv.f32 s0,s1,s0 @ ε
ldr r2,[r2] @ φ Q29
@ result is now ±(r12±(r2+atn(s0))
cmp r1,#0 @ inner negation
it mi
rsbmi r2,r2,#0
add r2,r12,r2 @ Q29
cmp r0,#0 @ outer negation
it mi
rsbmi r2,r2,#0
cmp r2,#0
bpl 1f
rsbs r2,r2,#0
clz r3,r2
lsls r2,r2,r3
beq 3f
rsb r3,#0x180
b 2f
1:
clz r3,r2
lsls r2,r2,r3
beq 3f
rsb r3,#0x80
2:
lsrs r2,r2,#8 @ rounding bit to carry
adc r2,r2,r3,lsl#23 @ with rounding
3:
vmul.f32 s2,s0,s0 @ ε²
vldr.f32 s3,onethird
vmul.f32 s2,s2,s0 @ ε³
teq r0,r1
vmul.f32 s2,s2,s3 @ ε³/3
vmov.f32 s4,r2
vsub.f32 s0,s0,s2 @ ~atn(ε)
ite pl
vaddpl.f32 s0,s4,s0
vsubmi.f32 s0,s4,s0
vmov.f32 r0,s0
bx r14
9: @ we looked up the zeroth table entry; we could generate slightly more accurate results here
@ now (s0,s1) = (x,y)
vdiv.f32 s0,s1,s0 @ ε
@ result is now ±(r12±(0+atn(s0))
mov r2,r12 @ Q29; in fact r12 is only ±π/2 or ±π so can probably simplify this
cmp r0,#0 @ outer negation
it mi
rsbmi r2,r2,#0
cmp r2,#0
bpl 1f
rsbs r2,r2,#0
clz r3,r2
lsls r2,r2,r3
beq 3f
rsb r3,#0x180
b 2f
1:
clz r3,r2
lsls r2,r2,r3
beq 3f
rsb r3,#0x80
2:
lsrs r2,r2,#8 @ rounding bit to carry
adc r2,r2,r3,lsl#23 @ with rounding
3:
vmul.f32 s2,s0,s0 @ ε²
vldr.f32 s3,onethird
vmul.f32 s2,s2,s0 @ ε³
teq r0,r1
vmul.f32 s2,s2,s3 @ ε³/3
vmov.f32 s4,r2
vsub.f32 s0,s0,s2 @ ~atn(ε)
ite pl
vaddpl.f32 s0,s4,s0
vsubmi.f32 s0,s4,s0
vmov.f32 r0,s0
tst r0,#0x7f800000 @ about to return a denormal?
it ne
bxne r14
and r0,r0,#0x80000000 @ make it zero
bx r14
piover2: .word 0x3243f6a9 @ Q29
pi: .word 0x6487ed51 @ Q29
onethird: .float 0.33333333
trigtab3:
// φ Q29 tan φ SP
.word 0x00000000,0x00000000
.word 0x00ffee23,0x3d0001bb @ φ=0.03124148 : tan φ=3fa000375fffff9d 50.4b
.word 0x01fe88dc,0x3d7f992a @ φ=0.06232112 : tan φ=3faff3253fffea1f 44.5b
.word 0x02fe0a70,0x3dc01203 @ φ=0.09351084 : tan φ=3fb8024060002522 42.8b
.word 0x03fad228,0x3e000368 @ φ=0.12436779 : tan φ=3fc0006cfffffc90 45.2b
.word 0x04f5ab70,0x3e1ffdea @ φ=0.15498897 : tan φ=3fc3ffbd400014d5 42.6b
.word 0x05ed56f8,0x3e3fdddc @ φ=0.18522213 : tan φ=3fc7fbbb80000beb 43.4b
.word 0x06e4cfa0,0x3e601425 @ φ=0.21543103 : tan φ=3fcc02849fffe817 42.4b
.word 0x07d8d3e0,0x3e80215d @ φ=0.24521822 : tan φ=3fd0042b9ffff89f 43.1b
.word 0x08c60460,0x3e9000a5 @ φ=0.27417201 : tan φ=3fd20014a000182b 41.4b
.word 0x09b26770,0x3ea01492 @ φ=0.30302784 : tan φ=3fd402923ffff932 43.2b
.word 0x0a996d50,0x3eb01377 @ φ=0.33122888 : tan φ=3fd6026ee0001062 42.0b
.word 0x0b7a6d10,0x3ebff4a0 @ φ=0.35869458 : tan φ=3fd7fe93ffff8c38 39.1b
.word 0x0c593ce0,0x3ed0019f @ φ=0.38589329 : tan φ=3fda0033e0001354 41.7b
.word 0x0d33ebd0,0x3ee01bbc @ φ=0.41258803 : tan φ=3fdc0377800162a1 37.5b
.word 0x0e087ab0,0x3ef01fbd @ φ=0.43853506 : tan φ=3fde03f79fffddf2 40.9b
.word 0x0ed56180,0x3effef98 @ φ=0.46354747 : tan φ=3fdffdf30000767d 39.1b
.word 0x0fa1de80,0x3f080ebf @ φ=0.48850942 : tan φ=3fe101d7dfffb9fc 38.9b
.word 0x10639d00,0x3f0fec31 @ φ=0.51215982 : tan φ=3fe1fd862000aad5 37.6b
.word 0x112690e0,0x3f180cfd @ φ=0.53595775 : tan φ=3fe3019fa00069ea 38.3b
.word 0x11e014c0,0x3f200065 @ φ=0.55860364 : tan φ=3fe4000ca00022e5 39.9b
.word 0x129651e0,0x3f2808be @ φ=0.58084959 : tan φ=3fe50117c00015a7 40.6b
.word 0x1346d400,0x3f300a7d @ φ=0.60239601 : tan φ=3fe6014f9fffa020 38.4b
.word 0x13efc7c0,0x3f37ee2f @ φ=0.62302005 : tan φ=3fe6fdc5dfff98d7 38.3b
.word 0x14988960,0x3f400c32 @ φ=0.64362019 : tan φ=3fe801863fffff81 46.0b
.word 0x1537a8c0,0x3f47ef42 @ φ=0.66304433 : tan φ=3fe8fde8400062a4 38.4b
.word 0x15d4cc60,0x3f4ff630 @ φ=0.68222636 : tan φ=3fe9fec5ffff76e2 37.9b
.word 0x166ef280,0x3f581534 @ φ=0.70104337 : tan φ=3feb02a680004e91 38.7b
.word 0x16ff75c0,0x3f5fef1e @ φ=0.71868408 : tan φ=3febfde3c0001404 40.7b
.word 0x179116a0,0x3f68184d @ φ=0.73646098 : tan φ=3fed03099ffed6e5 36.8b
.word 0x181b5aa0,0x3f701722 @ φ=0.75333911 : tan φ=3fee02e43fffd351 39.5b
.word 0x18a10560,0x3f781071 @ φ=0.76965588 : tan φ=3fef020e20005c05 38.5b
.word 0x19214060,0x3f7ff451 @ φ=0.78530902 : tan φ=3feffe8a1fffe11b 40.1b
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 256k, LENGTH = 2048k - 256k
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = 2048k - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k

View File

@ -0,0 +1,302 @@
/* Based on GCC ARM embedded samples .
Defines the following symbols for use by code:
__exidx_start
__exidx_end
__etext
__data_start__
__preinit_array_start
__preinit_array_end
__init_array_start
__init_array_end
__fini_array_start
__fini_array_end
__data_end__
__bss_start__
__bss_end__
__end__
end
__HeapLimit
__StackLimit
__StackTop
__stack (== StackTop)
*/
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 200k, LENGTH = 4096k - 200k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k
SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k
}
ENTRY(_entry_point)
SECTIONS
{
.flash_begin : {
__flash_binary_start = .;
} > FLASH
/* The bootrom will enter the image at the point indicated in your
IMAGE_DEF, which is usually the reset handler of your vector table.
The debugger will use the ELF entry point, which is the _entry_point
symbol, and in our case is *different from the bootrom's entry point.*
This is used to go back through the bootrom on debugger launches only,
to perform the same initial flash setup that would be performed on a
cold boot.
*/
.text : {
__logical_binary_start = .;
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.embedded_block))
__embedded_block_end = .;
KEEP (*(.reset))
/* TODO revisit this now memset/memcpy/float in ROM */
/* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
* FLASH ... we will include any thing excluded here in .data below by default */
*(.init)
*libgcc.a:cmse_nonsecure_call.o
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
*(.fini)
/* Pull all c'tors into .text */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* Followed by destructors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.eh_frame*)
. = ALIGN(4);
} > FLASH
/* Note the boot2 section is optional, and should be discarded if there is
no reference to it *inside* the binary, as it is not called by the
bootrom. (The bootrom performs a simple best-effort XIP setup and
leaves it to the binary to do anything more sophisticated.) However
there is still a size limit of 256 bytes, to ensure the boot2 can be
stored in boot RAM.
Really this is a "XIP setup function" -- the name boot2 is historic and
refers to its dual-purpose on RP2040, where it also handled vectoring
from the bootrom into the user image.
*/
.boot2 : {
__boot2_start__ = .;
*(.boot2)
__boot2_end__ = .;
} > FLASH
ASSERT(__boot2_end__ - __boot2_start__ <= 256,
"ERROR: Pico second stage bootloader must be no more than 256 bytes in size")
.rodata : {
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
*(.srodata*)
. = ALIGN(4);
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
. = ALIGN(4);
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
.binary_info :
{
KEEP(*(.binary_info.keep.*))
*(.binary_info.*)
} > FLASH
__binary_info_end = .;
. = ALIGN(4);
.ram_vector_table (NOLOAD): {
*(.ram_vector_table)
} > RAM
.uninitialized_data (NOLOAD): {
. = ALIGN(4);
*(.uninitialized_data*)
} > RAM
.data : {
__data_start__ = .;
*(vtable)
*(.time_critical*)
/* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
*(.text*)
. = ALIGN(4);
*(.rodata*)
. = ALIGN(4);
*(.data*)
*(.sdata*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__mutex_array_start = .);
KEEP(*(SORT(.mutex_array.*)))
KEEP(*(.mutex_array))
PROVIDE_HIDDEN (__mutex_array_end = .);
*(.jcr)
. = ALIGN(4);
} > RAM AT> FLASH
.tdata : {
. = ALIGN(4);
*(.tdata .tdata.* .gnu.linkonce.td.*)
/* All data end */
__tdata_end = .;
} > RAM AT> FLASH
PROVIDE(__data_end__ = .);
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);
.tbss (NOLOAD) : {
. = ALIGN(4);
__bss_start__ = .;
__tls_base = .;
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
__tls_end = .;
} > RAM
.bss (NOLOAD) : {
. = ALIGN(4);
__tbss_end = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
PROVIDE(__global_pointer$ = . + 2K);
*(.sbss*)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
/* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however
to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */
. = ORIGIN(RAM) + LENGTH(RAM);
__HeapLimit = .;
} > RAM
/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
*(.scratch_x.*)
. = ALIGN(4);
__scratch_x_end__ = .;
} > SCRATCH_X AT > FLASH
__scratch_x_source__ = LOADADDR(.scratch_x);
.scratch_y : {
__scratch_y_start__ = .;
*(.scratch_y.*)
. = ALIGN(4);
__scratch_y_end__ = .;
} > SCRATCH_Y AT > FLASH
__scratch_y_source__ = LOADADDR(.scratch_y);
/* .stack*_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later
*
* stack1 section may be empty/missing if platform_launch_core1 is not used */
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
* stack is not used then all of SCRATCH_X is free.
*/
.stack1_dummy (NOLOAD):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (NOLOAD):
{
KEEP(*(.stack*))
} > SCRATCH_Y
.flash_end : {
KEEP(*(.embedded_end_block*))
PROVIDE(__flash_binary_end = .);
} > FLASH =0xaa
/* stack limit is poorly named, but historically is maximum heap ptr */
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* picolibc and LLVM */
PROVIDE (__heap_start = __end__);
PROVIDE (__heap_end = __HeapLimit);
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1));
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
/* llvm-libc */
PROVIDE (_end = __end__);
PROVIDE (__llvm_libc_heap_limit = __HeapLimit);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary")
ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary")
/* todo assert on extra code */
}

View File

@ -1504,11 +1504,7 @@ void InitReservedIO(void) {
I2C_enabled=1;
I2C0SDApin=Option.SYSTEM_I2C_SDA;
I2C0SCLpin=Option.SYSTEM_I2C_SCL;
#ifdef PICOCALC
I2C_Timeout=500;
#else
I2C_Timeout=2;
#endif
I2C_Timeout=SystemI2CTimeout;
} else {
I2C1locked=1;
#ifdef PICOCALC
@ -1521,11 +1517,7 @@ void InitReservedIO(void) {
I2C2_enabled=1;
I2C1SDApin=Option.SYSTEM_I2C_SDA;
I2C1SCLpin=Option.SYSTEM_I2C_SCL;
#ifdef PICOCALC
I2C2_Timeout=500;
#else
I2C2_Timeout=2;
#endif
I2C2_Timeout=SystemI2CTimeout;
}
if(Option.RTC)RtcGetTime(1);
#ifndef USBKEYBOARD

View File

@ -40,9 +40,10 @@ target_compile_options(${APP_NAME} PRIVATE
-Wall
-Wno-unused-variable
-Wno-unused-function
-DPICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE=0
)
pico_enable_stdio_usb(${APP_NAME} 0)
pico_enable_stdio_usb(${APP_NAME} 1)
pico_enable_stdio_uart(${APP_NAME} 1)
pico_add_extra_outputs(${APP_NAME})

View File

@ -36,7 +36,7 @@
// According to the applink.map ,with combined PicoMite, here is 920k
// This offset is used to ensure that the bootloader does not get overwritten
// when loading a new application from the SD card
#define SD_BOOT_FLASH_OFFSET (152 * 1024)
#define SD_BOOT_FLASH_OFFSET (200 * 1024)
// Maximum size of the application that can be loaded
// This ensures we don't overwrite the bootloader itself

View File

@ -17,4 +17,8 @@ void init_i2c_kbd();
int read_i2c_kbd();
int read_battery();
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitClear(value, bit) ((value) &= ~(1 << (bit)))
#define bitSet(value, bit) ((value) |= (1 << (bit)))
#endif

View File

@ -141,3 +141,11 @@ int keypad_get_key(void)
return act_key;
}
int keypad_get_battery() {
int bat_pcnt = read_battery();
bat_pcnt = bat_pcnt >> 8;
//int bat_charging = bitRead(bat_pcnt, 7);
bitClear(bat_pcnt, 7);
return bat_pcnt;
}

View File

@ -17,5 +17,5 @@ typedef enum {
void keypad_init(void);
int keypad_get_key(void);
int keypad_get_battery(void);
#endif // KEY_EVENT_H

View File

@ -344,6 +344,22 @@ void draw_rect_spi(int x1, int y1, int x2, int y2, int c) {
lcd_spi_raise_cs();
}
//16x6
void draw_battery_icon(int x0, int y0, int level) {
draw_rect_spi(x0, y0, x0+14, y0+6, WHITE);
draw_rect_spi(x0 + 1, y0 + 1, x0+12, y0+5, BLACK);
// (2x2)
draw_rect_spi(x0 + 14, y0 + 2, x0+14+2, y0+2+2, WHITE);
for (int i = 0; i <= 13; i++) {
if (i < level) {
draw_rect_spi(x0 + 1 + i * 1, y0 + 1, x0 + 1 + i*1+1, y0+1+4, WHITE);
}
}
}
/******************************************************************************************
Print a char on the LCD display
Any characters not in the font will print as a space.

View File

@ -123,7 +123,7 @@ void draw_rect_spi(int x1, int y1, int x2, int y2, int c);
void define_region_spi(int xstart, int ystart, int xend, int yend, int rw);
void draw_line_spi(int x1, int y1, int x2, int y2, int color);
void lcd_print_string_color(char *s, int fg, int bg);
void draw_battery_icon(int x0, int y0, int level);
//Print the bitmap of a char on the video output
// x, y - the top left of the char
// width, height - size of the char's bitmap

View File

@ -15,6 +15,8 @@
#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/bootrom.h"
#include "pico/usb_reset_interface.h"
#include "hardware/gpio.h"
#include "hardware/clocks.h"
#include "debug.h"
@ -202,6 +204,35 @@ static bool is_valid_application(uint32_t *app_location)
return true;
}
void boot_default()
{
DEBUG_PRINT("entering boot_default\n");
// Get the pointer to the application flash area
uint32_t *app_location = (uint32_t *)(XIP_BASE + SD_BOOT_FLASH_OFFSET);
launch_application_from(app_location);
// We should never reach here
while (1)
{
tight_loop_contents();
}
}
void boot_fwupdate()
{
DEBUG_PRINT("entering boot_fwupdate\n");
lcd_init();
lcd_clear();
draw_rect_spi(20, 140, 300, 180, WHITE);
lcd_set_cursor(30, 150);
lcd_print_string_color((char *)"FIRMWARE UPDATE", BLACK, WHITE);
sleep_ms(2000);
uint gpio_mask = 0u;
reset_usb_boot(gpio_mask, PICO_STDIO_USB_RESET_BOOTSEL_INTERFACE_DISABLE_MASK);
}
int load_firmware_by_path(const char *path)
{
text_directory_ui_set_status("STAT: Flashing firmware...");
@ -254,7 +285,7 @@ void final_selection_callback(const char *path)
if(path == NULL) {
//load default app from flash
snprintf(status_message, sizeof(status_message), "SEL: %s", "FLASH+152k");
snprintf(status_message, sizeof(status_message), "SEL: %s", "FLASH+200k");
text_directory_ui_set_status(status_message);
sleep_ms(200);
load_firmware_by_path(path);
@ -283,9 +314,30 @@ void final_selection_callback(const char *path)
load_firmware_by_path(path);
}
int read_bootmode()
{
int key = keypad_get_key();
int _x;
DEBUG_PRINT("read_bootmode key = %d\n", key);
while((_x = keypad_get_key()) > 0) {
// drain the keypad input buffer
DEBUG_PRINT("read_bootmode subsequent key = %d\n", _x);
}
int bootmode = 0; // Default boot mode
if (key == KEY_ARROW_UP)
{
bootmode = 1; // SD card boot mode
}
else if (key == KEY_ARROW_DOWN)
{
bootmode = 2; // Firmware update mode
}
return bootmode;
}
int main()
{
char buf[64];
uint32_t cur_time,last_time=0;
stdio_init_all();
uart_init(uart0, 115200);
@ -298,10 +350,33 @@ int main()
gpio_pull_up(SD_DET_PIN); // Enable pull-up resistor
keypad_init();
// Check bootmode now: 0=default, 1=sdcard, 2=fwupdate
int bootmode = read_bootmode();
DEBUG_PRINT("bootmode = %d\n", bootmode);
switch(bootmode) {
case 0:
// BOOTMODE_DEFAULT
boot_default();
break;
case 2:
// BOOTMODE_FWUPDATE
boot_fwupdate();
break;
case 1:
// BOOTMODE_SDCARD
default:
break;
}
// BEGIN SDCARD BOOT
lcd_init();
lcd_clear();
text_directory_ui_pre_init();
cur_time = time_us_64() / 1000;
last_time = cur_time;
// Check for SD card presence
DEBUG_PRINT("Checking for SD card...\n");
if (!sd_card_inserted())
@ -309,16 +384,22 @@ int main()
DEBUG_PRINT("SD card not detected\n");
text_directory_ui_set_status("Enter to exec.");
text_directory_ui_update_header(1);
text_directory_ui_update_title();
// Poll until SD card is inserted
text_directory_ui_draw_default_app();
text_directory_ui_set_final_callback(final_selection_callback);
while (!sd_card_inserted())
{
cur_time = time_us_64() / 1000;
int key = keypad_get_key();
if (key != 0)
process_key_event(key);
sleep_ms(20);
if(cur_time - last_time > BAT_UPDATE_MS) {
text_directory_ui_update_title();
last_time = cur_time;
}
}
// Card detected, wait for it to stabilize
@ -348,5 +429,9 @@ int main()
text_directory_ui_init();
text_directory_ui_set_final_callback(final_selection_callback);
while(keypad_get_key() > 0) {
// drain the keypad input buffer
}
text_directory_ui_run();
}

View File

@ -49,7 +49,7 @@ extern bool fs_init(void);
// UI Colors
#define COLOR_BG BLACK
#define COLOR_FG WHITE
#define COLOR_HIGHLIGHT GRAY
#define COLOR_HIGHLIGHT LITEGRAY
// Maximum number of directory entries
#define MAX_ENTRIES 128
@ -146,7 +146,7 @@ static void format_file_size(off_t size, int is_dir, char *buf, size_t buf_size)
static void set_default_entry(){
entry_count = 0;
strncpy(entries[entry_count].name, "[Default app]", sizeof(entries[entry_count].name) - 1);
strncpy(entries[entry_count].name, "[Default App]", sizeof(entries[entry_count].name) - 1);
entries[entry_count].name[sizeof(entries[entry_count].name) - 1] = '\0';
entries[entry_count].is_dir = IS_LAST_APP;
entries[entry_count].file_size = 0;
@ -340,8 +340,8 @@ static void ui_draw_directory_entry(int entry_idx)
size_buffer, sizeof(size_buffer));
// Draw filename and file size
draw_text(FILE_NAME_X, posY, display_buffer, COLOR_FG , is_selected ? COLOR_HIGHLIGHT : COLOR_BG);
draw_text(FILE_SIZE_X, posY, size_buffer, COLOR_FG, is_selected ? COLOR_HIGHLIGHT : COLOR_BG);
draw_text(FILE_NAME_X, posY, display_buffer, is_selected?COLOR_BG:COLOR_FG , is_selected ? COLOR_HIGHLIGHT : COLOR_BG);
draw_text(FILE_SIZE_X, posY, size_buffer, is_selected?COLOR_BG: COLOR_FG, is_selected ? COLOR_HIGHLIGHT : COLOR_BG);
}
/**
@ -426,17 +426,35 @@ static void ui_draw_status_bar(void)
}
static void ui_draw_battery_status(){
char buf[8];
int pcnt = keypad_get_battery();
if(pcnt < 0) return;
int level = pcnt * 13 / 100;
int pad = 0;
sprintf(buf,"%d%%",pcnt);
int y = UI_Y;
if(pcnt < 10) { pad = 8;}
else if( pcnt >= 10 && pcnt < 100){pad = 0;}
else if(pcnt == 100){pad = -8;}
draw_rect_spi(UI_X + UI_WIDTH-16-20-5-8, y, UI_X + UI_WIDTH, y + HEADER_TITLE_HEIGHT, COLOR_BG);
draw_text(UI_X + UI_WIDTH-16-20-5+pad, y + 2, buf, COLOR_FG, COLOR_BG);
draw_battery_icon(UI_X+UI_WIDTH-16,y+4,level);
}
// Refresh the entire UI
static void ui_refresh(void)
{
ui_draw_title();
ui_draw_path_header(0);
ui_draw_directory_list();
ui_draw_status_bar();
if(entry_count == 0) {
text_directory_ui_set_status("Enter to exec.");
ui_draw_empty_tip();
}
}else{
ui_draw_status_bar();
}
text_directory_ui_update_title();
}
// Handle key events for navigation and selection
@ -563,10 +581,15 @@ void text_directory_ui_set_status(const char *msg)
ui_draw_status_bar();
}
void text_directory_ui_update_header(uint8_t nosd) {
ui_draw_path_header(nosd);
}
void text_directory_ui_update_title(){
ui_draw_battery_status();
}
void text_directory_ui_draw_default_app() {
set_default_entry();
@ -578,16 +601,14 @@ void text_directory_ui_draw_default_app() {
void text_directory_ui_run(void)
{
uint32_t last_scroll_update = 0;
const uint32_t SCROLL_UPDATE_MS = 500; // Update scrolling text every 100ms
uint32_t last_bat_update = 0;
while (true)
{
uint32_t current_time = time_us_64() / 1000;
int key = keypad_get_key();
if (key != 0)
process_key_event(key);
uint32_t current_time = time_us_64() / 1000;
// Update scrolling text periodically
if (current_time - last_scroll_update > SCROLL_UPDATE_MS)
{
@ -599,21 +620,30 @@ void text_directory_ui_run(void)
}
last_scroll_update = current_time;
}
if(current_time - last_bat_update > BAT_UPDATE_MS){
text_directory_ui_update_title();
last_bat_update = current_time;
}
// Check for SD card removal during runtime
if (!sd_card_inserted()) {
text_directory_ui_set_status("SD card removed. Please reinsert.");
ui_draw_path_header(1);
text_directory_ui_update_header(!status_flag);
text_directory_ui_update_title();
ui_clear_directory_list();
update_required = 1;
ui_draw_directory_list();
// Wait until the SD card is reinserted
while (!sd_card_inserted()) {
current_time = time_us_64() / 1000;
key = keypad_get_key();
if (key != 0)
process_key_event(key);
sleep_ms(20);
if(current_time - last_bat_update > BAT_UPDATE_MS){
text_directory_ui_update_title();
last_bat_update = current_time;
}
}
// Once reinserted, update the UI and reinitialize filesystem

View File

@ -11,6 +11,8 @@
#define ITEMS_PER_PAGE 16
#define FONT_HEIGHT 12
#define ENTRY_PADDING 2
#define BAT_UPDATE_MS 60000
#define SCROLL_UPDATE_MS 500
// Callback type: invoked when the user makes a final selection. The selected path is passed as an argument.
typedef void (*final_selection_callback_t)(const char *selected_path);
@ -32,6 +34,8 @@ void text_directory_ui_set_status(const char *msg);
void text_directory_ui_update_header(uint8_t nosd);
void text_directory_ui_update_title();
void text_directory_ui_draw_default_app();
void process_key_event(int);

View File

@ -58,6 +58,8 @@ enum key_state
#define KEY_F9 0x89
#define KEY_F10 0x90
#define KEY_POWER 0x91
typedef void (*key_callback)(char, enum key_state);
typedef void (*lock_callback)(bool, bool);

View File

@ -18,7 +18,7 @@
#define DEBUG_UART
TwoWire Wire2 = TwoWire(CONFIG_PMU_SDA, CONFIG_PMU_SCL);
bool pmu_flag = 0;
bool pmu_online = 0;
uint8_t pmu_online = 0;
uint8_t keycb_start = 0;
uint8_t head_phone_status=LOW;
@ -168,6 +168,24 @@ void receiveEvent(int howMany) {
write_buffer[1] = js_bits;
write_buffer_len = 2;
}break;
case REG_ID_OFF:{
if(is_write){
pmu_online = rcv_data[1];
if(pmu_online < 6){
pmu_online = 6;
}
}
write_buffer[0] = reg;
write_buffer[1] = 1;
}break;
case REG_ID_RST:{
if(is_write){
delay(rcv_data[1]*1000);
}else{
delay(1000);
}
NVIC_SystemReset();
}break;
default: {
write_buffer[0] = 0;
write_buffer[1] = 0;
@ -265,6 +283,12 @@ void check_pmu_int() {
if (!pmu_online) return;
if(pmu_online > 1) {
delay(1000*pmu_online);
PMU.shutdown();
return;
}
if (time_uptime_ms() - run_time > 20000) {
run_time = millis(); // reset time
pcnt = PMU.getBatteryPercent();
@ -345,6 +369,7 @@ void check_pmu_int() {
if (PMU.isPekeyShortPressIrq()) {
Serial1.println("isPekeyShortPress");
// enterPmuSleep();
key_cb(KEY_POWER,KEY_STATE_PRESSED);//send a KEY_POWER to i2c
Serial1.print("Read pmu data buffer .");
uint8_t data[4] = {0};

View File

@ -19,6 +19,7 @@ enum reg_id
REG_ID_BAT = 0x0b,// battery
REG_ID_C64_MTX = 0x0c,// read c64 matrix
REG_ID_C64_JS = 0x0d, // joystick io bits
REG_ID_OFF = 0x0e, // POWER OFF
REG_ID_LAST,
};

View File

@ -1,3 +1,8 @@
# Official uLisp for PicoCalc
https://github.com/technoblogy/ulisp-picocalc
# How to compile uLisp
uLisp for PicoCalc uses [Arduino IDE](https://www.arduino.cc/en/software) for development
@ -77,9 +82,6 @@ It should be noted that uLisp's default serial port speed is **9600**
## Pre-compiled uf2
https://github.com/clockworkpi/PicoCalc/blob/master/Bin/PicoCalc%20SD/firmware/PicoCalc_uLisp_v1.0.uf2
https://github.com/clockworkpi/PicoCalc/blob/master/Bin/PicoCalc%20SD/firmware/PicoCalc_uLisp_v1.1.uf2
# Official uLisp for PicoCalc
https://github.com/technoblogy/ulisp-picocalc