Compare commits

...

4 Commits

Author SHA1 Message Date
cuu
b57f1f916e add Code/pico_multi_booter/sd_boot/ base commit hash log 2025-05-19 14:53:10 +08:00
cuu
beb05b7ca7 add pico_multi_booter code 2025-05-19 14:50:19 +08:00
cuu
f0058240cd add pico_multi_booter code 2025-05-19 14:44:50 +08:00
cuu
4c74e3b3fe add pico_multi_booter code 2025-05-19 14:41:19 +08:00
158 changed files with 168907 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
build
cmake-build-*
.idea

3
.gitmodules vendored
View File

@ -16,3 +16,6 @@
[submodule "Bin/PicoMite/PicoMiteAllVersions"]
path = Bin/PicoMite/PicoMiteAllVersions
url = https://github.com/madcock/PicoMiteAllVersions.git
[submodule "Code/pico_multi_booter/sd_boot/lib/pico-vfs"]
path = Code/pico_multi_booter/sd_boot/lib/pico-vfs
url = https://github.com/oyama/pico-vfs.git

View File

@ -0,0 +1,104 @@
# .-------------------------------------------------------------------------.
# | MIT Licensed : Copyright 2022, "Hippy" |
# `-------------------------------------------------------------------------'
# ***************************************************************************
# * This project - Build a combined booter and some apps *
# ***************************************************************************
set(PROJECT pico_multi_booter)
set(BOOT boot)
set(OUTPUT combined.uf2)
# .-------------------------------------------------------------------------.
# | The usual CMake prerequisites |
# `-------------------------------------------------------------------------'
cmake_minimum_required(VERSION 3.12)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(${PROJECT} C CXX ASM)
pico_sdk_init()
# .-------------------------------------------------------------------------.
# | The other things we need to complete the build |
# `-------------------------------------------------------------------------'
find_package(Python3 REQUIRED COMPONENTS Interpreter)
add_subdirectory(picomite)
add_subdirectory(sd_boot)
### build boot.uf2
add_executable(${BOOT} boot.c)
target_link_libraries(${BOOT} pico_stdlib
hardware_pio
)
target_compile_options(${BOOT} PRIVATE
-Os
-Wall
-Werror
-Wno-unused-variable
-Wno-unused-function
)
pico_enable_stdio_usb(${BOOT} 0)
pico_enable_stdio_uart(${BOOT} 1)
pico_add_uf2_output(${BOOT})
target_link_libraries(${BOOT}
hardware_resets
cmsis_core
)
pico_set_binary_type(${BOOT} copy_to_ram)
add_custom_target(BUILT_${BOOT}
COMMENT "Record Build Details for '${BOOT}'"
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BOOT}.uf2
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/applink.py BUILT
${CMAKE_CURRENT_BINARY_DIR}
${BOOT}
)
# ***************************************************************************
# * Build the BOOT plus all the APPS *
# ***************************************************************************
add_dependencies(BUILT_boot boot)
add_dependencies(PREPARE_picomite BUILT_boot)
add_dependencies(picomite PREPARE_picomite)
add_dependencies(BUILT_picomite picomite)
add_dependencies(PREPARE_sd_boot BUILT_picomite)
add_dependencies(sd_boot PREPARE_sd_boot)
add_dependencies(BUILT_sd_boot sd_boot)
# ***************************************************************************
# * Join the BOOT and all APP '.uf2' files together *
# ***************************************************************************
set(UF2S boot.uf2 picomite.uf2 sd_boot.uf2)
add_custom_target(JOIN
COMMENT "Combine the '.uf2' files"
COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/applink.py JOIN
${CMAKE_CURRENT_BINARY_DIR}
${OUTPUT}
${UF2S}
)
add_dependencies(JOIN BUILT_sd_boot)
add_custom_target(${PROJECT} ALL DEPENDS JOIN)
# ***************************************************************************
# * Finished *
# ***************************************************************************

View File

@ -0,0 +1,87 @@
# PicoCalc multi booter
Here is a bootloader for PicoCalc combined slightly modified [PicoMite](https://github.com/madcock/PicoMiteAllVersions) and [SD boot](https://github.com/adwuard/Picocalc_SD_Boot)
- Pico1
- No sdcard inserted ,PicoMite will show up.
- Sdcard inserted, SD boot menu will show up, load third pico app bin to run at FLASH TARGET OFFSET 2048k-940k
## How to compile
```
export PICO_SDK_PATH=/where/picosdk/is
mkdir build
cd build
cmake ..
make
```
## How to run
Just copy **combined.uf2** into PicoCalc
## PicoMite
configuration.h
```
#define FLASH_TARGET_OFFSET (920 * 1024)
```
## sd_boot
config.h
```
#define SD_BOOT_FLASH_OFFSET (940 * 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(940k) address.
Applications intended for SD card boot is in **bin** format, not uf2.
```
---
This section explains how to build and deploy applications on an SD card. Below is a simple example of a CMakeLists.txt for an application.
#### Step 1 Copy Custom Link Script
Copy `memmap_sdcard_app.ld` to your project repository.
#### Step 2 Add Custom Link Script to CMakeList.txt
In the project for multi boot, add custom link script to CMakeList.txt,usually at bottom.
We also need to use `pico_add_extra_outputs` to sure that there will .bin file generated.
```
...
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")
pico_set_linker_script(${CMAKE_PROJECT_NAME} ${CMAKE_SOURCE_DIR}/memmap_default_rp2350.ld)
endif()
endfunction()
enable_sdcard_app(${CMAKE_PROJECT_NAME})
```
#### Build and Deployment Process
1. Build the project using the above CMakeLists.txt.
```bash
mkdir build;
cd build
export PICO_SDK_PATH=/path/to/pico-sdk
cmake ..
make
```
#### Step 3 Your Custom Application Is Ready For SD Card Boot
Once the build is complete, copy the generated `.bin` file to the `/sd` directory of the SD card.

View File

@ -0,0 +1,630 @@
#!/usr/bin/python3
# ****************************************************************************
# * *
# * App linking Tool *
# * *
# ****************************************************************************
PRODUCT = "App Linking Tool"
PACKAGE = "uf2"
PROGRAM = "applink.py"
VERSION = "0.01"
CHANGES = "0000"
TOUCHED = "2022-03-06 18:42:21"
LICENSE = "MIT Licensed"
DETAILS = "https://opensource.org/licenses/MIT"
# .--------------------------------------------------------------------------.
# | MIT Licence |
# `--------------------------------------------------------------------------'
# Copyright 2022, "Hippy"
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
# .--------------------------------------------------------------------------.
# | Satandard libraries |
# `--------------------------------------------------------------------------'
import os
import sys; python3 = sys.version_info[0] == 3
import time; today = time.strftime("%Y-%m-%d %H:%M:%S")
# .--------------------------------------------------------------------------.
# | Configuration |
# `--------------------------------------------------------------------------'
SHOW_INVOCATIONS = True
LOG_INVOCATIONS = True
IGNORE_ERRORS = False
REMOVE_STAGE_2_BOOLOADER = True
EMIT_INDIVIDUAL_MAP_FILES = False
# .--------------------------------------------------------------------------.
# | Utility code |
# `--------------------------------------------------------------------------'
def Pad(s, w, c=" "):
if len(s) < w:
s += c * (w-len(s))
return s
# .--------------------------------------------------------------------------.
# | UF2 Read Handling |
# `--------------------------------------------------------------------------'
def Uf2Block(f):
if python3:
b = f.read(512)
else:
s = f.read(512)
b = bytearray()
for c in s:
b.append(ord(c))
return b
def Expand(b):
def Field(b, n, w=4):
val = 0
shf = 0
for count in range(w):
val = val | (b[n + count] << shf)
shf = shf + 8
return val, n + w
def Bytes(b, n, w):
return b[n:n+w], n + w
n = 0
head, n = Field(b, n, 8)
flags, n = Field(b, n)
adr, n = Field(b, n)
length, n = Field(b, n)
seq, n = Field(b, n)
tot, n = Field(b, n)
family, n = Field(b, n)
data, n = Bytes(b, n, 476)
tail, n = Field(b, n)
return head, flags, adr, length, seq, tot, family, data, tail
# .--------------------------------------------------------------------------.
# | UF2 Write Handling |
# `--------------------------------------------------------------------------'
def Encode(fDst, head, flags, adr, length, seq, tot, family, data, tail):
def Field(b, n, w=4):
for count in range(w):
b.append(n & 0xFF)
n = n >> 8
def Bytes(b, data, w):
for n in range(w):
if n >= len(data) : b.append(0)
else : b.append(data[n])
b = bytearray()
Field(b, head, 8)
Field(b, flags)
Field(b, adr)
Field(b, length)
Field(b, seq)
Field(b, tot)
Field(b, family)
Bytes(b, data, 476)
Field(b, tail)
fDst.write(b)
return adr + length, seq + 1
# .--------------------------------------------------------------------------.
# | Create a linker script for an APP build |
# `--------------------------------------------------------------------------'
def Align(n, mask):
if (n & (mask-1)) != 0:
n = (n | (mask-1)) + 1
return n
def Size(n, mask):
return int(Align(n & 0x0FFFFFFF, mask) / 1024)
def Prepare(dir, app):
# dir = "./build"
# app = "app"
if REMOVE_STAGE_2_BOOLOADER : stage2 = " Removed "
else : stage2 = "*"
mapFile = os.path.join(dir, "applink.map")
if not os.path.isfile(mapFile):
print("LINK {} - '{}' not found".format(app, mapFile))
if IGNORE_ERRORS : sys.exit()
else : sys.exit(1)
last = 0
with open(mapFile, "r") as f:
for s in f:
if s[0] != "S":
a = s.strip().split()
this = int(a[1], 16)
if this > last:
last = this
used = "{:>3}k".format(Size(last, 4 * 1024))
dstFile = os.path.join(dir, app + ".ld")
with open(dstFile, "w") as f:
f.write(
"""
/* 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)
*/
/*
Increased the FLASH-ORIGIN by 64KB to not overwrite the bootloader
(reduce LENGTH accordingly)
*/
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 +###k, LENGTH = 2048k -###k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
}
ENTRY(_entry_point)
SECTIONS
{
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
and checksummed. It is usually built by the boot_stage2 target
in the Raspberry Pi Pico SDK
*/
.flash_begin : {
__flash_binary_start = .;
} > FLASH
/*###/
.boot2 : {
__boot2_start__ = .;
KEEP (*(.boot2))
__boot2_end__ = .;
} > FLASH
ASSERT(__boot2_end__ - __boot2_start__ == 256,
"ERROR: Pico second stage bootloader must be 256 bytes in size")
/###*/
/* The second stage will always enter the image at the start of .text.
The debugger will use the ELF entry point, which is the _entry_point
symbol if present, otherwise defaults to start of .text.
This can be used to transfer control back to the bootrom on debugger
launches only, to perform proper flash setup.
*/
.text : {
__logical_binary_start = .;
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_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 */
/*
. = ALIGN(4);
} > FLASH
.text2 0x10010000 : {
*/
*(.init)
*(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)
*(.eh_frame*)
. = ALIGN(4);
} > FLASH
.rodata : {
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
. = 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);
/* End of .text-like segments */
__etext = .;
.ram_vector_table (COPY): {
*(.ram_vector_table)
} > 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*)
. = 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 = .);
. = 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 = .);
*(.jcr)
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM AT> FLASH
.uninitialized_data (COPY): {
. = ALIGN(4);
*(.uninitialized_data*)
} > 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);
.bss : {
. = ALIGN(4);
__bss_start__ = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .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 (COPY):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (COPY):
{
*(.stack*)
} > SCRATCH_Y
.flash_end : {
__flash_binary_end = .;
} > FLASH
/* 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);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
/* todo assert on extra code */
}
"""
.strip()
.replace("###k", used)
.replace("###", stage2))
# .--------------------------------------------------------------------------.
# | Post UF2 build Handling |
# `--------------------------------------------------------------------------'
def Built(dir, app):
# dir = "./build"
# app = "app"
uf2File = os.path.join(dir, app + ".uf2")
if not os.path.isfile(uf2File):
print("BUILT {} - '{}' not found".format(app, uf2File))
if IGNORE_ERRORS : sys.exit()
else : sys.exit(1)
strt = -1
last = -1
with open(uf2File, "rb") as f:
block = Uf2Block(f)
while block:
head, flags, adr, length, seq, tot, family, data, tail = Expand(block)
if head == 0x9E5D51570A324655 \
and tail == 0xAB16F30 \
and family == 0xE48BFF56:
if strt < 0 : strt = adr
if adr + length - 1 > last : last = adr + length - 1
block = Uf2Block(f)
size = "{:>3}k".format(Size(last-strt, 1024))
used = "{:>3}k".format(Size(last, 4*1024))
print(last,strt)
print(size,used)
mapfile = os.path.join(dir, "applink.map")
if (strt & 0x0FFFFFFF) == 0:
with open(mapfile, "w") as f:
# 12345678 12345678 ###k ###k
f.write("Start Last Size Used\n")
f.write("{:>08X} {:>08X} {} {} {}\n".format(strt, last,
size, used, app))
info = Align(last, 256)
f.write("{:>08X} {:>08X} 256 {:>3}k {}\n".format(info, info | 0xFF,
Size(info | 0XFF, 4*1024),
"Info Table"))
else:
with open(mapfile, "a") as f:
f.write("{:>08X} {:>08X} {} {} {}\n".format(strt, last,
size, used, app))
mapFile = os.path.join(dir, app + ".map")
if EMIT_INDIVIDUAL_MAP_FILES:
with open(mapFile, "w") as f:
# 12345678 12345678 ###k ###k
f.write("Start Last Size Used\n")
f.write("{:>08X} {:>08X} {} {} {}\n".format(strt, last,
size, used, app))
if (strt & 0x0FFFFFFF) == 0:
info = Align(last, 256)
f.write("{:>08X} {:>08X} 256 {:>3}k {}\n".format(info, info | 0xFF,
Size(info | 0XFF, 4*1024),
"Info Table"))
elif os.path.isfile(mapFile):
os.remove(mapFile)
# .--------------------------------------------------------------------------.
# | Combining UF2 files |
# `--------------------------------------------------------------------------'
def ToBytes(s):
b = bytearray()
for c in s:
b.append(ord(c))
return b
def Join(dir, dst, uf2):
# dir = "./build"
# dst = "out.uf2"
# uf2 = [ "boot.uf2", "app1.uf2", "app2.uf2", ... ]
# Check the files exist
for src in uf2:
uf2File = os.path.join(dir, src)
if not os.path.isfile(uf2File):
print("JOIN {} - '{}' not found".format(dst, uf2File))
if IGNORE_ERRORS : sys.exit()
else : sys.exit(1)
# Determine how many blocks in output including padding and info block
adr = -1
tot = 0
for src in uf2:
uf2File = os.path.join(dir, src)
with open(uf2File, "rb") as fSrc:
block = Uf2Block(fSrc)
while block:
head, flags, Xadr, length, seq, Xtot, family, data, tail = Expand(block)
if adr < 0:
adr = Xadr
else:
while adr < Xadr:
adr = adr + 256
tot = tot + 1
adr = adr + length
tot = tot + 1
block = Uf2Block(fSrc)
# Build the info table
info = ""
mapFile = os.path.join(dir, "applink.map")
with open(mapFile, "r") as f:
line = 0
for s in f:
line = line + 1
if line > 3:
a = s.strip().split()
strt = int(a[0], 16)
info += chr((strt >> 0) & 0xFF)
info += chr((strt >> 8) & 0xFF)
info += chr((strt >> 16) & 0xFF)
info += chr((strt >> 24) & 0xFF)
info += Pad(a[-1][:12], 12, chr(0))
# Concatenate the files
dstFile = os.path.join(dir, dst)
adr = -1
seq = 0
with open(dstFile, "wb") as fDst:
for n in range(len(uf2)):
uf2File = os.path.join(dir, uf2[n])
with open(uf2File, "rb") as fSrc:
block = Uf2Block(fSrc)
while block:
head, flags, Xadr, length, Xseq, Xtot, family, data, tail = Expand(block)
if adr < 0:
adr = Xadr
else:
while adr < Xadr:
# 123456789-123456
pads = ToBytes("Padding before {}".format(uf2[n]))
adr, seq = Encode(fDst, head, flags, adr, 256, seq, tot, family,
pads, tail)
adr, seq = Encode(fDst, head, flags, adr, 256, seq, tot, family,
data[:256], tail)
block = Uf2Block(fSrc)
if n == 0:
# Add info block
adr, seq = Encode(fDst, head, flags, adr, 256, seq, tot, family,
ToBytes(info)[:256], tail)
# .--------------------------------------------------------------------------.
# | Main program and command dispatcher |
# `--------------------------------------------------------------------------'
def GetArgv(n):
if n < 0 : return sys.argv[-n:]
elif n < len(sys.argv) : return sys.argv[n]
else : return ""
def Main():
# 0 1 2 3 4
# ./applink.py PREPARE ./build app
# ./applink.py BUILT ./build app
# ./applink.py JOIN ./build out.uf2 boot.uf2 app1.uf2 app2.uf2 ...
cmd = GetArgv(1)
dir = GetArgv(2)
app = GetArgv(3)
uf2 = GetArgv(-4)
if SHOW_INVOCATIONS:
for n in range(1, len(sys.argv)):
print("****** applink.py : [{}] {}".format(n, GetArgv(n)))
logFile = os.path.join(dir, "applink.log")
if LOG_INVOCATIONS:
s = " ".join(sys.argv[2:]).replace("/home/pi/", "~/")
with open(logFile, "a") as f:
f.write("{} {:<5} {}\n".format(today, cmd, s))
elif os.path.isfile(logFile):
os.remove(logFile)
if cmd == "PREPARE" : Prepare (dir, app)
elif cmd == "BUILT" : Built (dir, app)
elif cmd == "JOIN" : Join (dir, app, uf2)
else:
print("Unknown '{}' command".format(cmd))
sys.exit(1)
if __name__ == "__main__":
Main()

View File

@ -0,0 +1,196 @@
// .------------------------------------------------------------------------.
// | MIT Licensed : Copyright 2022, "Hippy" |
// `------------------------------------------------------------------------'
// **************************************************************************
// * Check we did build booter with 'Copy to RAM' option *
// **************************************************************************
#if !PICO_COPY_TO_RAM
#error "The booter must use: pico_set_binary_type(${BOOT} copy_to_ram)"
#endif
// **************************************************************************
// * Pico SDK integration *
// **************************************************************************
#include <stdio.h>
#include "RP2040.h"
#include "pico/stdlib.h"
#include "hardware/resets.h"
#include "hardware/gpio.h"
// **************************************************************************
// * Utility code *
// **************************************************************************
#define PEEK32(adr) *((uint32_t *) (adr))
#define POKE32(adr, n) *((uint32_t *) (adr)) = n
#define PEEK8(adr) *((uint8_t *) (adr))
uint32_t Align(uint32_t n, uint32_t mask) {
if ((n & (mask-1)) != 0) {
n = (n | (mask-1)) + 1;
}
return n;
}
uint32_t Size(uint32_t n, uint32_t mask) {
return (((n & 0x0FFFFFFF) | (mask-1)) + 1) / 1024;
}
uint32_t Crc32(uint32_t crc, uint8_t byt) {
for (uint32_t n = 8; n-- ;
crc = (crc << 1) ^ (((crc >> 31) ^ (byt >> 7)) * 0x04C11DB7),
byt <<= 1
);
return crc;
}
// **************************************************************************
// * Low-level interfacing *
// **************************************************************************
extern char __flash_binary_end;
// Credit : https://github.com/usedbytes/rp2040-serial-bootloader
// Copyright (c) 2021 Brian Starkey <stark3y@gmail.com>
// SPDX-License-Identifier: BSD-3-Clause
static void disable_interrupts(void) {
SysTick->CTRL &= ~1;
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICPR[0] = 0xFFFFFFFF;
}
static void reset_peripherals(void) {
reset_block(~(
RESETS_RESET_IO_QSPI_BITS |
RESETS_RESET_PADS_QSPI_BITS |
RESETS_RESET_SYSCFG_BITS |
RESETS_RESET_PLL_SYS_BITS
));
}
static void jump_to_vtor(uint32_t vtor) {
// Derived from the Leaf Labs Cortex-M3 bootloader.
// Copyright (c) 2010 LeafLabs LLC.
// Modified 2021 Brian Starkey <stark3y@gmail.com>
// Originally under The MIT License
uint32_t reset_vector = *(volatile uint32_t *)(vtor + 0x04);
SCB->VTOR = (volatile uint32_t)(vtor);
asm volatile("msr msp, %0"::"g" (*(volatile uint32_t *)vtor));
asm volatile("bx %0"::"r" (reset_vector));
}
#define LEDPIN 25
#define SD_DET_PIN 22
bool sd_card_inserted(void)
{
// Active low detection - returns true when pin is low
return !gpio_get(SD_DET_PIN);
}
// **************************************************************************
// * Main booter program *
// **************************************************************************
int main(void) {
while (true) {
stdio_init_all();
sleep_ms(1000);
gpio_init(SD_DET_PIN);
gpio_set_dir(SD_DET_PIN, GPIO_IN);
gpio_pull_up(SD_DET_PIN); // Enable pull-up resistor
gpio_init(LEDPIN);
gpio_set_dir(LEDPIN,GPIO_OUT);
gpio_put(LEDPIN,1);
// Determine where the boot binary ends
uintptr_t last = (uintptr_t) &__flash_binary_end;
printf("Booter ends at %08X\n", last);
// Determine the size in 1K blocks
printf("Booter size is %luk\n", Size(last, 1024));
// Determine the size in 4K blocks
printf("Booter used is %luk\n", Size(last, 4 * 1024));
// Determine the start of the next 256 byte block
printf("App info table %08lX\n", Align(last, 256));
// Determine the start of the next 4K block
printf("App base is at %08lX\n", Align(last, 4 * 1024));
printf("\n");
// Find the start of the next 256 byte block, the info table
uint32_t info = Align(last, 256);
uint32_t addr;
// Report items in the info table
int max = 0;
for (uint32_t item=0; item < 16; item++) {
addr = PEEK32(info + (item * 16));
if (addr != 0) {
printf("%lu : %08lX ", item+1, addr);
for (uint32_t cptr=4; cptr < 16; cptr++) {
char c = PEEK8(info + (item * 16 ) + cptr);
if (c != 0) {
printf("%c", c);
}
}
printf("\n");
max++;
}
}
printf("max %d \n",max);
// Choose an app to launch
int chosen;
if(!sd_card_inserted()){
printf("No sd card\n");
chosen = 0;
}else{
printf("Has SD card\n");
chosen = max-1;
if(chosen <0 ) chosen = 0;
}
// Get start address of app
addr = PEEK32( info + ((chosen * 16)));
printf("Application at %08lX\n", addr);
// Determine if the start of the application is actually
// the second stage bootloader. if so we need to skip
// beyond that.
uint32_t crc = 0xFFFFFFFF;
for(uint32_t pc = 0; pc < 0xFC; pc += 4) {
uint32_t u32 = PEEK32(addr + pc);
crc = Crc32(crc, (u32 >> 0 ) & 0xFF);
crc = Crc32(crc, (u32 >> 8 ) & 0xFF);
crc = Crc32(crc, (u32 >> 16 ) & 0xFF);
crc = Crc32(crc, (u32 >> 24 ) & 0xFF);
}
if (crc == PEEK32(addr + 0xFC)) {
printf("Stage 2 adjust\n");
addr += 256;
printf("Application at %08lX\n", addr);
}
printf("\n");
printf("Launching application code ...\n");
printf("\n");
sleep_ms(1000);
disable_interrupts();
reset_peripherals();
jump_to_vtor(addr);
}
}

View File

@ -0,0 +1,219 @@
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000 + 940k, LENGTH = 2048k - 940k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
}
ENTRY(_entry_point)
SECTIONS
{
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
and checksummed. It is usually built by the boot_stage2 target
in the Raspberry Pi Pico SDK
*/
.flash_begin : {
__flash_binary_start = .;
} > FLASH
/* The second stage will always enter the image at the start of .text.
The debugger will use the ELF entry point, which is the _entry_point
symbol if present, otherwise defaults to start of .text.
This can be used to transfer control back to the bootrom on debugger
launches only, to perform proper flash setup.
*/
.text : {
__logical_binary_start = .;
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_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)
*(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)
*(.eh_frame*)
. = ALIGN(4);
} > FLASH
.rodata : {
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
. = 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
.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*)
. = 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 = .);
. = 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 = .);
*(.jcr)
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM AT> FLASH
/* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */
__etext = LOADADDR(.data);
.uninitialized_data (NOLOAD): {
. = ALIGN(4);
*(.uninitialized_data*)
} > 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);
.bss : {
. = ALIGN(4);
__bss_start__ = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (NOLOAD):
{
__end__ = .;
end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM
/* .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 : {
PROVIDE(__flash_binary_end = .);
} > FLASH
/* 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);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
/* todo assert on extra code */
}

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 + 940k, LENGTH = 4096k - 940k
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

@ -0,0 +1,3 @@
https://github.com/madcock/PicoMiteAllVersions
6c312cc754c4347db0a2aba91bd63203cab7a21b

View File

@ -0,0 +1,713 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* ********************************************************************************
the C language function associated with commands, functions or operators should be
declared here
**********************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// format:
// void cmd_???(void)
// void fun_???(void)
// void op_???(void)
void cmd_clear(void);
void cmd_continue(void);
void cmd_delete(void);
void cmd_dim(void);
void cmd_do(void);
void cmd_else(void);
void cmd_end(void);
void cmd_endfun(void);
void cmd_endsub(void);
void cmd_erase(void);
void cmd_error(void);
void cmd_exit(void);
void cmd_exitfor(void);
void cmd_for(void);
void cmd_subfun(void);
void cmd_gosub(void);
void cmd_goto(void);
void cmd_if(void);
void cmd_inc(void);
void cmd_input(void);
void cmd_let(void);
void cmd_lineinput(void);
void cmd_list(void);
void cmd_load(void);
void cmd_loop(void);
void cmd_merge(void);
void cmd_chain(void);
void cmd_new(void);
void cmd_next(void);
void cmd_null(void);
void cmd_on(void);
void cmd_print(void);
void cmd_randomize(void);
void cmd_read(void);
void cmd_restore(void);
void cmd_return(void);
void cmd_run(void);
void cmd_save(void);
void cmd_troff(void);
void cmd_tron(void);
void cmd_trace(void);
void cmd_const(void);
void cmd_select(void);
void cmd_case(void);
void cmd_option(void);
void cmd_dump(void);
void cmd_call(void);
void cmd_execute(void);
void cmd_mid(void);
void cmd_null(void);
void cmd_open(void);
void cmd_close(void);
void cmd_files(void);
void cmd_mkdir(void);
void cmd_rmdir(void);
void cmd_chdir(void);
void cmd_kill(void);
void cmd_copy(void);
void cmd_name(void);
void cmd_exitmmb(void);
void cmd_pause(void);
void cmd_timer(void);
void cmd_copyright(void);
void cmd_seek(void);
void cmd_library(void);
void cmd_pio(void);
void cmd_date(void);
void cmd_time(void);
void cmd_flash(void);
void cmd_var(void);
void cmd_flush(void);
void cmd_disk(void);
void cmd_play(void);
void cmd_text(void);
void cmd_pixel(void);
void cmd_circle(void);
void cmd_line(void);
void cmd_box(void);
void cmd_rbox(void);
void cmd_arc(void) ;
void cmd_triangle(void);
void cmd_blit(void);
void cmd_cls(void);
void cmd_font(void);
void cmd_colour(void);
void cmd_refresh(void);
void cmd_polygon(void);
void cmd_gui(void);
void cmd_tile(void);
void cmd_mode(void);
void cmd_3D(void);
void cmd_framebuffer(void);
void cmd_edit(void);
void cmd_editfile(void);
void cmd_port(void);
void cmd_adc(void);
void cmd_ir(void);
void cmd_lcd(void);
void cmd_keypad();
void cmd_backlight(void);
void cmd_device(void);
void cmd_sync(void);
void cmd_setpin(void);
void cmd_pulse(void);
void cmd_pwm(void);
void cmd_pin(void);
void cmd_i2c(void);
void cmd_i2c2(void);
void cmd_rtc(void);
void cmd_math(void);
void cmd_memory(void);
void cmd_autosave(void);
void cmd_option(void);
void cmd_pause(void);
void cmd_timer(void);
void cmd_date(void);
void cmd_time(void);
void cmd_ireturn(void);
void cmd_poke(void);
void cmd_settick(void);
void cmd_watchdog(void);
void cmd_cpu(void);
void cmd_cfunction(void);
void cmd_longString(void);
void cmd_sort(void);
void cmd_csubinterrupt(void);
void cmd_library(void);
void cmd_onewire(void);
void cmd_ds18b20(void);
void cmd_spi(void);
void cmd_spi2(void);
void cmd_xmodem(void);
void cmd_ctrlval(void);
void cmd_GUIpage(unsigned char *p);
void cmd_gamepad(void);
void cmd_sprite(void);
void cmd_comment(void);
void cmd_endcomment(void);
void cmd_blitmemory(void);
void cmd_configure(void);
void cmd_colourmap(void);
void cmd_map(void);
void cmd_WS2812(void);
void cmd_DHT22(void);
void cmd_Classic(void);
void cmd_Nunchuck(void);
void cmd_mouse(void);
void cmd_camera(void);
void cmd_Servo(void);
void cmd_chain(void);
void cmd_psram(void);
void cmd_wrap(void);
void cmd_wraptarget(void);
void cmd_sideset(void);
void cmd_PIOline(void);
void cmd_program(void);
void cmd_endprogram(void);
void cmd_label(void);
void cmd_jmp(void);
void cmd_wait(void);
void cmd_in(void);
void cmd_out(void);
void cmd_push(void);
void cmd_pull(void);
void cmd_mov(void);
void cmd_nop(void);
void cmd_irqset(void);
void cmd_irqwait(void);
void cmd_irqclear(void);
void cmd_irqnowait(void);
void cmd_irq(void);
void cmd_set(void);
void cmd_byte(void);
void cmd_bit(void);
void cmd_flag(void);
void cmd_flags(void);
void cmd_frame(void);
void cmd_help(void);
void cmd_slice(void);
void cmd_insert(void);
void cmd_add(void);
void cmd_arrayset(void);
#ifdef PICOMITEWEB
void cmd_web(void);
#endif
#ifdef rp2350
void cmd_loadCMM2(void);
void cmd_RunCMM2(void);
#endif
void op_invalid(void);
void op_exp(void);
void op_mul(void);
void op_div(void);
void op_divint(void);
void op_add(void);
void op_subtract(void);
void op_mod(void);
void op_ne(void);
void op_gte(void);
void op_lte(void);
void op_lt(void);
void op_gt(void);
void op_equal(void);
void op_and(void);
void op_or(void);
void op_xor(void);
void op_not(void);
void op_shiftleft(void);
void op_shiftright(void);
void op_inv(void);
void fun_pin(void);
void fun_port(void);
void fun_distance(void);
void fun_pulsin(void);
void fun_rgb(void);
void fun_mmhres(void);
void fun_mmvres(void);
void fun_mmcharwidth(void);
void fun_mmcharheight(void);
void fun_at(void);
void fun_pixel(void);
void fun_getscanline(void);
void fun_3D(void);
void fun_sprite(void);
void fun_eof(void);
void fun_loc(void);
void fun_lof(void);
void fun_cwd(void);
void fun_inputstr(void);
void fun_mmfname(void);
void fun_dir(void);
void fun_date(void);
void fun_time(void);
void fun_timer(void);
void fun_device(void);
void fun_pio(void);
void fun_abs(void);
void fun_asc(void);
void fun_atn(void);
void fun_atan2(void);
void fun_bin(void);
void fun_chr(void);
void fun_cint(void);
void fun_cos(void);
void fun_deg(void);
void fun_exp(void);
void fun_fix(void);
void fun_hex(void);
void fun_inkey(void);
void fun_instr(void);
void fun_int(void);
void fun_lcase(void);
void fun_left(void);
void fun_len(void);
void fun_log(void);
void fun_errno(void);
void fun_errmsg(void);
void fun_mid(void);
void fun_oct(void);
void fun_peek(void);
void fun_pi(void);
void fun_pos(void);
void fun_rad(void);
void fun_right(void);
void fun_rnd(void);
void fun_sgn(void);
void fun_sin(void);
void fun_space(void);
void fun_sqr(void);
void fun_str(void);
void fun_string(void);
void fun_tab(void);
void fun_tan(void);
void fun_ucase(void);
void fun_val(void);
void fun_eval(void);
void fun_version(void);
void fun_asin(void);
void fun_acos(void);
void fun_field(void);
void fun_max(void);
void fun_min(void);
void fun_bin2str(void);
void fun_str2bin(void);
void fun_test(void);
void fun_bound(void);
void fun_ternary(void);
void fun_call(void);
void fun_GPS(void);
void fun_mmi2c(void);
void fun_math(void);
void fun_timer(void);
void fun_date(void);
void fun_time(void);
void fun_keydown(void);
void fun_peek(void);
void fun_restart(void);
void fun_day(void);
void fun_info(void);
void fun_LLen(void);
void fun_LGetByte(void);
void fun_LGetStr(void);
void fun_LCompare(void);
void fun_LInstr(void);
void fun_epoch(void);
void fun_datetime(void);
void fun_json(void);
void cmd_update(void);
void fun_format(void);
void fun_mmOW(void);
void fun_ds18b20(void);
void fun_pixel(void);
void fun_getscanline(void);
void fun_spi(void);
void fun_spi2(void);
void fun_msgbox(void);
void fun_ctrlval(void);
void fun_mmhpos(void);
void fun_mmvpos(void);
void fun_tilde(void);
void fun_byte(void);
void fun_bit(void);
void fun_flag(void);
#ifdef PICOMITEWEB
void fun_json(void);
#endif
void fun_dev(void);
void fun_map(void);
#endif
/* ********************************************************************************
All command tokens tokens (eg, PRINT, FOR, etc) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_COMMAND_TABLE
{ (unsigned char *)"Call", T_CMD, 0, cmd_call },
{ (unsigned char *)"Clear", T_CMD, 0, cmd_clear },
{ (unsigned char *)"Continue", T_CMD, 0, cmd_continue },
{ (unsigned char *)"Data", T_CMD, 0, cmd_null },
{ (unsigned char *)"Dim", T_CMD, 0, cmd_dim },
{ (unsigned char *)"Do", T_CMD, 0, cmd_do },
{ (unsigned char *)"Else If", T_CMD, 0, cmd_else },
{ (unsigned char *)"End If", T_CMD, 0, cmd_null },
{ (unsigned char *)"Exit Do", T_CMD, 0, cmd_exit },
{ (unsigned char *)"ElseIf", T_CMD, 0, cmd_else },
{ (unsigned char *)"Case Else", T_CMD, 0, cmd_case },
{ (unsigned char *)"Else", T_CMD, 0, cmd_else },
{ (unsigned char *)"Select Case", T_CMD, 0, cmd_select },
{ (unsigned char *)"End Select", T_CMD, 0, cmd_null },
{ (unsigned char *)"Case", T_CMD, 0, cmd_case },
{ (unsigned char *)"EndIf", T_CMD, 0, cmd_null },
{ (unsigned char *)"End Function", T_CMD, 0, cmd_endfun }, // this entry must come before END and FUNCTION
{ (unsigned char *)"End Sub", T_CMD, 0, cmd_return }, // this entry must come before END and SUB
{ (unsigned char *)"End", T_CMD, 0, cmd_end },
{ (unsigned char *)"Erase", T_CMD, 0, cmd_erase },
{ (unsigned char *)"Error", T_CMD, 0, cmd_error },
{ (unsigned char *)"Exit For", T_CMD, 0, cmd_exitfor }, // this entry must come before EXIT and FOR
{ (unsigned char *)"Exit Sub", T_CMD, 0, cmd_return }, // this entry must come before EXIT and SUB
{ (unsigned char *)"Exit Function", T_CMD, 0, cmd_endfun }, // this entry must come before EXIT and FUNCTION
{ (unsigned char *)"Exit", T_CMD, 0, cmd_exit },
{ (unsigned char *)"For", T_CMD, 0, cmd_for },
{ (unsigned char *)"Function", T_CMD, 0, cmd_subfun },
{ (unsigned char *)"GoSub", T_CMD, 0, cmd_gosub },
{ (unsigned char *)"GoTo", T_CMD, 0, cmd_goto },
{ (unsigned char *)"Inc", T_CMD, 0, cmd_inc },
{ (unsigned char *)"If", T_CMD, 0, cmd_if },
{ (unsigned char *)"Line Input", T_CMD, 0, cmd_lineinput}, // this entry must come before INPUT
{ (unsigned char *)"Input", T_CMD, 0, cmd_input },
{ (unsigned char *)"Let", T_CMD, 0, cmd_let },
{ (unsigned char *)"List", T_CMD, 0, cmd_list },
{ (unsigned char *)"Load", T_CMD, 0, cmd_load },
{ (unsigned char *)"Local", T_CMD, 0, cmd_dim },
{ (unsigned char *)"Loop", T_CMD, 0, cmd_loop },
{ (unsigned char *)"Next", T_CMD, 0, cmd_next },
{ (unsigned char *)"On", T_CMD, 0, cmd_on },
{ (unsigned char *)"Print", T_CMD, 0, cmd_print },
{ (unsigned char *)"Read", T_CMD, 0, cmd_read },
{ (unsigned char *)"Rem", T_CMD, 0, cmd_null, },
{ (unsigned char *)"Restore", T_CMD, 0, cmd_restore },
{ (unsigned char *)"Return", T_CMD, 0, cmd_return, },
{ (unsigned char *)"Run", T_CMD, 0, cmd_run },
{ (unsigned char *)"Save", T_CMD, 0, cmd_save },
{ (unsigned char *)"Static", T_CMD, 0, cmd_dim },
{ (unsigned char *)"Sub", T_CMD, 0, cmd_subfun },
{ (unsigned char *)"Trace", T_CMD, 0, cmd_trace },
{ (unsigned char *)"While", T_CMD, 0, cmd_do },
{ (unsigned char *)"Const", T_CMD, 0, cmd_const },
{ (unsigned char *)"Execute", T_CMD, 0, cmd_execute },
{ (unsigned char *)"MID$(", T_CMD | T_FUN, 0, cmd_mid },
{ (unsigned char *)"/*", T_CMD, 0, cmd_comment },
{ (unsigned char *)"*/", T_CMD, 0, cmd_endcomment },
{ (unsigned char *)"Open", T_CMD, 0, cmd_open },
{ (unsigned char *)"Close", T_CMD, 0, cmd_close },
{ (unsigned char *)"Kill", T_CMD, 0, cmd_kill },
{ (unsigned char *)"Rmdir", T_CMD, 0, cmd_rmdir },
{ (unsigned char *)"Chdir", T_CMD, 0, cmd_chdir },
{ (unsigned char *)"Mkdir", T_CMD, 0, cmd_mkdir },
{ (unsigned char *)"Copy", T_CMD, 0, cmd_copy },
{ (unsigned char *)"Rename", T_CMD, 0, cmd_name },
{ (unsigned char *)"Seek", T_CMD, 0, cmd_seek },
{ (unsigned char *)"Flash", T_CMD, 0, cmd_flash },
{ (unsigned char *)"VAR", T_CMD, 0, cmd_var },
{ (unsigned char *)"Flush", T_CMD, 0, cmd_flush },
{ (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 *)"Pixel", T_CMD, 0, cmd_pixel },
{ (unsigned char *)"Circle", T_CMD, 0, cmd_circle },
{ (unsigned char *)"Line", T_CMD, 0, cmd_line },
{ (unsigned char *)"Box", T_CMD, 0, cmd_box },
{ (unsigned char *)"RBox", T_CMD, 0, cmd_rbox },
{ (unsigned char *)"CLS", T_CMD, 0, cmd_cls },
{ (unsigned char *)"Font", T_CMD, 0, cmd_font },
{ (unsigned char *)"Triangle", T_CMD, 0, cmd_triangle },
{ (unsigned char *)"Arc", T_CMD, 0, cmd_arc },
{ (unsigned char *)"Polygon", T_CMD, 0, cmd_polygon },
{ (unsigned char *)"FRAMEBUFFER", T_CMD, 0, cmd_framebuffer },
{ (unsigned char *)"Sprite", T_CMD, 0, cmd_sprite },
{ (unsigned char *)"Blit", T_CMD, 0, cmd_blit },
{ (unsigned char *)"Edit File", T_CMD, 0, cmd_editfile },
{ (unsigned char *)"Edit", T_CMD, 0, cmd_edit },
{ (unsigned char *)"ADC", T_CMD, 0, cmd_adc },
{ (unsigned char *)"Pin(", T_CMD | T_FUN, 0, cmd_pin },
{ (unsigned char *)"SetPin", T_CMD, 0, cmd_setpin },
{ (unsigned char *)"Pulse", T_CMD, 0, cmd_pulse },
{ (unsigned char *)"Port(", T_CMD | T_FUN, 0, cmd_port },
{ (unsigned char *)"IR", T_CMD, 0, cmd_ir },
{ (unsigned char *)"Blit Memory", T_CMD, 0, cmd_blitmemory },
#ifdef GUICONTROLS
{ (unsigned char *)"GUI", T_CMD, 0, cmd_gui },
#else
{ (unsigned char *)"GUI", T_CMD, 0, cmd_guiMX170 },
#endif
{ (unsigned char *)"Device", T_CMD, 0, cmd_device },
{ (unsigned char *)"PWM", T_CMD, 0, cmd_pwm },
{ (unsigned char *)"CSub", T_CMD, 0, cmd_cfunction},
{ (unsigned char *)"End CSub", T_CMD, 0, cmd_null },
{ (unsigned char *)"SYNC", T_CMD, 0, cmd_sync },
{ (unsigned char *)"I2C", T_CMD, 0, cmd_i2c },
{ (unsigned char *)"I2C2", T_CMD, 0, cmd_i2c2 },
{ (unsigned char *)"RTC", T_CMD, 0, cmd_rtc },
{ (unsigned char *)"Math", T_CMD, 0, cmd_math },
{ (unsigned char *)"Memory", T_CMD, 0, cmd_memory },
{ (unsigned char *)"Option", T_CMD, 0, cmd_option },
{ (unsigned char *)"Pause", T_CMD, 0, cmd_pause },
{ (unsigned char *)"Timer", T_CMD | T_FUN, 0, cmd_timer },
{ (unsigned char *)"Date$", T_CMD | T_FUN, 0, cmd_date },
{ (unsigned char *)"Time$", T_CMD | T_FUN, 0, cmd_time },
{ (unsigned char *)"IReturn", T_CMD, 0, cmd_ireturn },
{ (unsigned char *)"Poke", T_CMD, 0, cmd_poke },
{ (unsigned char *)"SetTick", T_CMD, 0, cmd_settick },
{ (unsigned char *)"WatchDog", T_CMD, 0, cmd_watchdog },
{ (unsigned char *)"CPU", T_CMD, 0, cmd_cpu },
{ (unsigned char *)"Sort", T_CMD, 0, cmd_sort },
{ (unsigned char *)"DefineFont", T_CMD, 0, cmd_cfunction},
{ (unsigned char *)"End DefineFont", T_CMD, 0, cmd_null },
{ (unsigned char *)"LongString", T_CMD, 0, cmd_longString },
{ (unsigned char *)"Interrupt", T_CMD, 0, cmd_csubinterrupt},
{ (unsigned char *)"Library", T_CMD, 0, cmd_library },
{ (unsigned char *)"OneWire", T_CMD, 0, cmd_onewire },
{ (unsigned char *)"TEMPR START", T_CMD, 0, cmd_ds18b20 },
{ (unsigned char *)"SPI", T_CMD, 0, cmd_spi },
{ (unsigned char *)"SPI2", T_CMD, 0, cmd_spi2 },
{ (unsigned char *)"XModem", T_CMD, 0, cmd_xmodem },
{ (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 *)"Autosave", T_CMD, 0, cmd_autosave },
{ (unsigned char *)"WS2812", T_CMD, 0, cmd_WS2812 },
{ (unsigned char *)"Keypad", T_CMD, 0, cmd_keypad },
{ (unsigned char *)"Humid", T_CMD, 0, cmd_DHT22 },
{ (unsigned char *)"LCD", T_CMD, 0, cmd_lcd },
{ (unsigned char *)"Wii Classic", T_CMD, 0, cmd_Classic },
{ (unsigned char *)"Wii Nunchuck", T_CMD, 0, cmd_Nunchuck },
{ (unsigned char *)"Wii", T_CMD, 0, cmd_Classic },
{ (unsigned char *)"Servo", T_CMD, 0, cmd_Servo },
{ (unsigned char *)"Mouse", T_CMD, 0, cmd_mouse },
{ (unsigned char *)"Chain", T_CMD, 0, cmd_chain },
{ (unsigned char *)"_wrap target", T_CMD, 0, cmd_wraptarget },
{ (unsigned char *)"_wrap", T_CMD, 0, cmd_wrap },
{ (unsigned char *)"_line", T_CMD, 0, cmd_PIOline },
{ (unsigned char *)"_program", T_CMD, 0, cmd_program },
{ (unsigned char *)"_end program", T_CMD, 0, cmd_endprogram },
{ (unsigned char *)"_side set", T_CMD, 0, cmd_sideset },
{ (unsigned char *)"_label", T_CMD, 0, cmd_label },
{ (unsigned char *)"Jmp", T_CMD, 0, cmd_jmp },
{ (unsigned char *)"Wait", T_CMD, 0, cmd_wait },
{ (unsigned char *)"In", T_CMD, 0, cmd_in },
{ (unsigned char *)"Out", T_CMD, 0, cmd_out },
{ (unsigned char *)"Push", T_CMD, 0, cmd_push },
{ (unsigned char *)"Pull", T_CMD, 0, cmd_pull },
{ (unsigned char *)"Mov", T_CMD, 0, cmd_mov },
{ (unsigned char *)"Nop", T_CMD, 0, cmd_nop },
{ (unsigned char *)"IRQ SET", T_CMD, 0, cmd_irqset },
{ (unsigned char *)"IRQ WAIT", T_CMD, 0, cmd_irqwait },
{ (unsigned char *)"IRQ CLEAR", T_CMD, 0, cmd_irqclear },
{ (unsigned char *)"IRQ NOWAIT",T_CMD, 0, cmd_irqnowait },
{ (unsigned char *)"IRQ", T_CMD, 0, cmd_irq },
{ (unsigned char *)"Set", T_CMD, 0, cmd_set },
{ (unsigned char *)"Byte(", T_CMD | T_FUN, 0, cmd_byte },
{ (unsigned char *)"Flag(", T_CMD | T_FUN, 0, cmd_flag },
/*frame
{ (unsigned char *)"Frame", T_CMD | T_FUN, 0, cmd_frame },
*/
#ifdef PICOMITEVGA
{ (unsigned char *)"TILE", T_CMD, 0, cmd_tile },
{ (unsigned char *)"MODE", T_CMD, 0, cmd_mode },
{ (unsigned char *)"Map(", T_CMD | T_FUN , 0, cmd_map },
{ (unsigned char *)"Map", T_CMD, 0, cmd_map },
{ (unsigned char *)"Colour Map", T_CMD, 0, cmd_colourmap },
#else
{ (unsigned char *)"Camera", T_CMD, 0, cmd_camera },
{ (unsigned char *)"Refresh", T_CMD, 0, cmd_refresh },
#endif
#ifdef GUICONTROLS
{ (unsigned char *)"CtrlVal(", T_CMD | T_FUN, 0, cmd_ctrlval },
#endif
#ifdef PICOMITE
{ (unsigned char *)"Backlight", T_CMD, 0, cmd_backlight },
#endif
#ifdef PICOMITEWEB
{ (unsigned char *)"Backlight", T_CMD, 0, cmd_backlight },
{ (unsigned char *)"WEB", T_CMD, 0, cmd_web },
#else
{ (unsigned char *)"Draw3D", T_CMD, 0, cmd_3D },
#endif
#ifndef USBKEYBOARD
{ (unsigned char *)"Update Firmware", T_CMD, 0, cmd_update},
#else
{ (unsigned char *)"Gamepad", T_CMD, 0, cmd_gamepad },
#endif
{ (unsigned char *)"Configure", T_CMD, 0, cmd_configure },
{ (unsigned char *)"Colour", T_CMD, 0, cmd_colour },
#ifdef rp2350
{ (unsigned char *)"CMM2 Load", T_CMD, 0, cmd_loadCMM2 },
{ (unsigned char *)"CMM2 Run", T_CMD, 0, cmd_RunCMM2 },
{ (unsigned char *)"Randomize", T_CMD, 0, cmd_null},
#ifndef PICOMITEWEB
{ (unsigned char *)"Ram", T_CMD, 0, cmd_psram },
#endif
#else
{ (unsigned char *)"Randomize", T_CMD, 0, cmd_randomize},
#endif
{ (unsigned char *)"Bit(", T_CMD | T_FUN, 0, cmd_bit },
{ (unsigned char *)"Flags", T_CMD | T_FUN, 0, cmd_flags },
{ (unsigned char *)"Help", T_CMD | T_FUN, 0, cmd_help },
{ (unsigned char *)"Array Slice", T_CMD, 0, cmd_slice },
{ (unsigned char *)"Array Insert", T_CMD, 0, cmd_insert },
{ (unsigned char *)"Array Add", T_CMD, 0, cmd_add },
{ (unsigned char *)"Array Set", T_CMD, 0, cmd_arrayset },
{ (unsigned char *)"", 0, 0, cmd_null, } // this dummy entry is always at the end
#endif
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
// These 4 operators mustn't be moved
{ (unsigned char *)"Not", T_OPER | T_NBR | T_INT, 3, op_not },
{ (unsigned char *)"INV", T_OPER | T_NBR | T_INT, 3, op_inv },
{ (unsigned char *)"+", T_OPER | T_NBR | T_INT | T_STR, 2, op_add },
{ (unsigned char *)"-", T_OPER | T_NBR | T_INT, 2, op_subtract },
//
{ (unsigned char *)"^", T_OPER | T_NBR | T_INT, 0, op_exp },
{ (unsigned char *)"*", T_OPER | T_NBR | T_INT, 1, op_mul },
{ (unsigned char *)"/", T_OPER | T_NBR, 1, op_div },
{ (unsigned char *)"\\", T_OPER | T_INT, 1, op_divint },
{ (unsigned char *)"Mod", T_OPER | T_INT, 1, op_mod },
{ (unsigned char *)"<<", T_OPER | T_INT, 4, op_shiftleft },
{ (unsigned char *)">>", T_OPER | T_INT, 4, op_shiftright },
{ (unsigned char *)"<>", T_OPER | T_NBR | T_INT | T_STR, 5, op_ne },
{ (unsigned char *)">=", T_OPER | T_NBR | T_INT | T_STR, 5, op_gte },
{ (unsigned char *)"<=", T_OPER | T_NBR | T_INT | T_STR, 5, op_lte },
{ (unsigned char *)"<", T_OPER | T_NBR | T_INT | T_STR, 5, op_lt },
{ (unsigned char *)">", T_OPER | T_NBR | T_INT | T_STR, 5, op_gt },
{ (unsigned char *)"=", T_OPER | T_NBR | T_INT | T_STR, 6, op_equal },
{ (unsigned char *)"And", T_OPER | T_INT, 7, op_and },
{ (unsigned char *)"Or", T_OPER | T_INT, 7, op_or },
{ (unsigned char *)"Xor", T_OPER | T_INT, 7, op_xor },
{ (unsigned char *)"ACos(", T_FUN | T_NBR, 0, fun_acos },
{ (unsigned char *)"Abs(", T_FUN | T_NBR | T_INT, 0, fun_abs },
{ (unsigned char *)"Asc(", T_FUN | T_INT, 0, fun_asc },
{ (unsigned char *)"ASin(", T_FUN | T_NBR, 0, fun_asin },
{ (unsigned char *)"Atn(", T_FUN | T_NBR, 0, fun_atn },
{ (unsigned char *)"Atan2(", T_FUN | T_NBR, 0, fun_atan2 },
{ (unsigned char *)"Bin$(", T_FUN | T_STR, 0, fun_bin },
{ (unsigned char *)"Bound(", T_FUN | T_INT, 0, fun_bound },
{ (unsigned char *)"Choice(", T_FUN | T_STR | T_INT | T_NBR, 0, fun_ternary },
{ (unsigned char *)"Chr$(", T_FUN | T_STR, 0, fun_chr, },
{ (unsigned char *)"Cint(", T_FUN | T_INT, 0, fun_cint },
{ (unsigned char *)"Cos(", T_FUN | T_NBR, 0, fun_cos },
{ (unsigned char *)"Deg(", T_FUN | T_NBR, 0, fun_deg },
{ (unsigned char *)"Exp(", T_FUN | T_NBR, 0, fun_exp },
{ (unsigned char *)"Field$(", T_FUN | T_STR, 0, fun_field },
{ (unsigned char *)"Fix(", T_FUN | T_INT, 0, fun_fix },
{ (unsigned char *)"Hex$(", T_FUN | T_STR, 0, fun_hex },
{ (unsigned char *)"Inkey$", T_FNA | T_STR, 0, fun_inkey },
{ (unsigned char *)"Instr(", T_FUN | T_INT, 0, fun_instr},
{ (unsigned char *)"Int(", T_FUN | T_INT, 0, fun_int },
{ (unsigned char *)"LCase$(", T_FUN | T_STR, 0, fun_lcase },
{ (unsigned char *)"Left$(", T_FUN | T_STR, 0, fun_left },
{ (unsigned char *)"Len(", T_FUN | T_INT, 0, fun_len },
{ (unsigned char *)"Log(", T_FUN | T_NBR, 0, fun_log },
{ (unsigned char *)"Mid$(", T_FUN | T_STR, 0, fun_mid },
{ (unsigned char *)"TEMPR(", T_FUN | T_NBR, 0, fun_ds18b20 },
{ (unsigned char *)"SPI(", T_FUN | T_INT, 0, fun_spi, },
{ (unsigned char *)"Oct$(", T_FUN | T_STR, 0, fun_oct },
{ (unsigned char *)"Pi", T_FNA | T_NBR, 0, fun_pi },
{ (unsigned char *)"Pos", T_FNA | T_INT, 0, fun_pos },
{ (unsigned char *)"Rad(", T_FUN | T_NBR, 0, fun_rad },
{ (unsigned char *)"Right$(", T_FUN | T_STR, 0, fun_right },
{ (unsigned char *)"Rnd(", T_FUN | T_NBR, 0, fun_rnd }, // this must come before Rnd - without bracket
{ (unsigned char *)"Rnd", T_FNA | T_NBR, 0, fun_rnd }, // this must come after Rnd(
{ (unsigned char *)"Sgn(", T_FUN | T_INT, 0, fun_sgn },
{ (unsigned char *)"Sin(", T_FUN | T_NBR, 0, fun_sin },
{ (unsigned char *)"Space$(", T_FUN | T_STR, 0, fun_space },
{ (unsigned char *)"Sqr(", T_FUN | T_NBR, 0, fun_sqr },
{ (unsigned char *)"Str$(", T_FUN | T_STR, 0, fun_str },
{ (unsigned char *)"String$(", T_FUN | T_STR, 0, fun_string },
{ (unsigned char *)"Tab(", T_FUN | T_STR, 0, fun_tab, },
{ (unsigned char *)"Tan(", T_FUN | T_NBR, 0, fun_tan },
{ (unsigned char *)"UCase$(", T_FUN | T_STR, 0, fun_ucase },
{ (unsigned char *)"Val(", T_FUN | T_NBR | T_INT, 0, fun_val },
{ (unsigned char *)"Eval(", T_FUN | T_NBR | T_INT | T_STR, 0, fun_eval },
{ (unsigned char *)"Max(", T_FUN | T_NBR, 0, fun_max },
{ (unsigned char *)"Min(", T_FUN | T_NBR, 0, fun_min },
{ (unsigned char *)"Bin2str$(", T_FUN | T_STR, 0, fun_bin2str },
{ (unsigned char *)"Str2bin(", T_FUN | T_NBR | T_INT, 0, fun_str2bin },
{ (unsigned char *)"Call(", T_FUN | T_STR | T_INT | T_NBR, 0, fun_call },
{ (unsigned char *)"For", T_NA, 0, op_invalid },
{ (unsigned char *)"Else", T_NA, 0, op_invalid },
{ (unsigned char *)"GoSub", T_NA, 0, op_invalid },
{ (unsigned char *)"GoTo", T_NA, 0, op_invalid },
{ (unsigned char *)"Step", T_NA, 0, op_invalid },
{ (unsigned char *)"Then", T_NA, 0, op_invalid },
{ (unsigned char *)"To", T_NA, 0, op_invalid },
{ (unsigned char *)"Until", T_NA, 0, op_invalid },
{ (unsigned char *)"While", T_NA, 0, op_invalid },
{ (unsigned char *)"Eof(", T_FUN | T_INT, 0, fun_eof },
{ (unsigned char *)"Loc(", T_FUN | T_INT, 0, fun_loc },
{ (unsigned char *)"Lof(", T_FUN | T_INT, 0, fun_lof },
{ (unsigned char *)"Cwd$", T_FNA | T_STR, 0, fun_cwd },
{ (unsigned char *)"As", T_NA, 0, op_invalid },
{ (unsigned char *)"Input$(", T_FUN | T_STR, 0, fun_inputstr },
{ (unsigned char *)"Dir$(", T_FUN | T_STR, 0, fun_dir },
{ (unsigned char *)"Pio(", T_FUN | T_INT, 0, fun_pio },
{ (unsigned char *)"RGB(", T_FUN | T_INT, 0, fun_rgb },
{ (unsigned char *)"Pixel(", T_FUN | T_INT, 0, fun_pixel },
{ (unsigned char *)"SPI2(", T_FUN | T_INT, 0, fun_spi2, },
{ (unsigned char *)"DEVICE(", T_FUN | T_INT| T_NBR | T_STR, 0, fun_dev, },
{ (unsigned char *)"@(", T_FUN | T_STR, 0, fun_at },
{ (unsigned char *)"Pin(", T_FUN | T_NBR | T_INT, 0, fun_pin },
{ (unsigned char *)"Port(", T_FUN | T_INT, 0, fun_port },
{ (unsigned char *)"Distance(", T_FUN | T_NBR, 0, fun_distance },
{ (unsigned char *)"Pulsin(", T_FUN | T_INT, 0, fun_pulsin },
{ (unsigned char *)"GPS(", T_FUN | T_NBR | T_INT| T_STR, 0, fun_GPS },
{ (unsigned char *)"Byte(", T_FUN | T_INT, 0, fun_byte, },
{ (unsigned char *)"Math(", T_FUN | T_NBR | T_INT, 0, fun_math },
{ (unsigned char *)"Timer", T_FNA | T_NBR , 0, fun_timer },
{ (unsigned char *)"LInStr(", T_FUN | T_INT, 0, fun_LInstr },
{ (unsigned char *)"LCompare(", T_FUN | T_INT, 0, fun_LCompare },
{ (unsigned char *)"LLen(", T_FUN | T_INT, 0, fun_LLen },
{ (unsigned char *)"LGetStr$(", T_FUN | T_STR, 0, fun_LGetStr },
{ (unsigned char *)"LGetByte(", T_FUN | T_INT, 0, fun_LGetByte },
{ (unsigned char *)"Date$", T_FNA | T_STR, 0, fun_date },
{ (unsigned char *)"Day$(", T_FUN | T_STR, 0, fun_day },
{ (unsigned char *)"Peek(", T_FUN | T_INT | T_STR | T_NBR, 0, fun_peek },
{ (unsigned char *)"Time$", T_FNA | T_STR, 0, fun_time },
{ (unsigned char *)"sprite(", T_FUN | T_INT | T_NBR, 0, fun_sprite },
{ (unsigned char *)"Flag(", T_FUN | T_INT, 0, fun_flag, },
{ (unsigned char *)"Epoch(", T_FUN | T_INT, 0, fun_epoch },
{ (unsigned char *)"DateTime$(", T_FUN | T_STR, 0, fun_datetime },
{ (unsigned char *)"MM.Info(", T_FUN | T_INT | T_NBR| T_STR, 0, fun_info },
{ (unsigned char *)"Format$(", T_FUN | T_STR, 0, fun_format },
{ (unsigned char*)"~(", T_FUN | T_INT | T_NBR | T_STR , 0, fun_tilde },
#ifdef USBKEYBOARD
{ (unsigned char*)"KeyDown(", T_FUN | T_INT, 0, fun_keydown },
#endif
#ifdef PICOMITEVGA
{ (unsigned char*)"DRAW3D(", T_FUN | T_INT, 0, fun_3D, },
{ (unsigned char *)"GetScanLine", T_FNA | T_INT, 0, fun_getscanline },
{ (unsigned char*)"Map(", T_FUN | T_INT, 0, fun_map, },
#else
{ (unsigned char *)"Touch(", T_FUN | T_INT, 0, fun_touch },
#endif
#ifdef PICOMITEWEB
{ (unsigned char *)"Json$(", T_FUN | T_STR, 0, fun_json },
#endif
#ifdef GUICONTROLS
{ (unsigned char *)"MsgBox(", T_FUN | T_INT, 0, fun_msgbox },
{ (unsigned char *)"CtrlVal(", T_FUN | T_NBR | T_STR, 0, fun_ctrlval },
#endif
{ (unsigned char *)"Bit(", T_FUN | T_INT, 0, fun_bit, },
{ (unsigned char *)"", 0, 0, cmd_null, } // this dummy entry is always at the end
#endif
/* @endcond */

View File

@ -0,0 +1,27 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// ArialNumFontPlus.c
// Font type : Special (SubSet)
// Font size : 32x50 pixels
// Memory usage : 2204 bytes
#define PROGMEM
#define fontdatatype const unsigned char
fontdatatype ArialNumFontPlus[2204] PROGMEM={
0x20,0x32,0x30,0x0B,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x1F,0xF8,0x00,0x00,0x7F,0xFE,0x00,0x00,0xFF,0xFF,0x00,0x01,0xFF,0xFF,0x00,0x03,0xF8,0x1F,0x80,0x03,0xF0,0x0F,0xC0,0x07,0xE0,0x07,0xC0,0x07,0xC0,0x03,0xE0,0x0F,0xC0,0x03,0xE0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x1F,0x80,0x01,0xF0,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xFC,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3F,0x00,0x00,0x7C,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x07,0xC0,0x03,0xE0,0x07,0xC0,0x03,0xE0,0x03,0xE0,0x07,0xC0,0x03,0xF0,0x0F,0xC0,0x01,0xF8,0x1F,0x80,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFE,0x00,0x00,0x7F,0xFC,0x00,0x00,0x1F,0xF8,0x00,0x00,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x0F,0xF0,0x00,0x00,0x1F,0xF0,0x00,0x00,0x3F,0xF0,0x00,0x00,0x7F,0xF0,0x00,0x01,0xFF,0xF0,0x00,0x03,0xFD,0xF0,0x00,0x0F,0xF1,0xF0,0x00,0x0F,0xE1,0xF0,0x00,0x0F,0x81,0xF0,0x00,0x0F,0x01,0xF0,0x00,0x0C,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //1 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x7F,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xC0,0x03,0xFF,0xFF,0xE0,0x07,0xE0,0x0F,0xF0,0x0F,0xC0,0x03,0xF0,0x0F,0x80,0x01,0xF0,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x3E,0x00,0x00,0xF8,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0xF8,0x00,0x00,0x01,0xF8,0x00,0x00,0x03,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x1F,0xC0,0x00,0x00,0x3F,0x80,0x00,0x00,0x7F,0x00,0x00,0x00,0xFE,0x00,0x00,0x01,0xFC,0x00,0x00,0x03,0xF8,0x00,0x00,0x07,0xF0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x1F,0xC0,0x00,0x00,0x3F,0x80,0x00,0x00,0x7F,0x00,0x00,0x00,0xFE,0x00,0x00,0x01,0xFC,0x00,0x00,0x03,0xF8,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xC0,0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x80,0x00,0x00,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x7F,0xFF,0xFF,0xFC,0x7F,0xFF,0xFF,0xFC,0x7F,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x3F,0xFC,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0x80,0x03,0xE0,0x1F,0xC0,0x07,0xC0,0x0F,0xC0,0x07,0x80,0x07,0xE0,0x0F,0x80,0x03,0xE0,0x0F,0x00,0x03,0xE0,0x0F,0x00,0x03,0xF0,0x0F,0x00,0x01,0xF0,0x00,0x00,0x03,0xF0,0x00,0x00,0x03,0xE0,0x00,0x00,0x03,0xE0,0x00,0x00,0x07,0xE0,0x00,0x00,0x0F,0xC0,0x00,0x00,0x1F,0xC0,0x00,0x00,0x3F,0x80,0x00,0x07,0xFF,0x00,0x00,0x07,0xFF,0x00,0x00,0x07,0xFF,0x00,0x00,0x07,0xFF,0x80,0x00,0x00,0x1F,0xC0,0x00,0x00,0x0F,0xE0,0x00,0x00,0x03,0xE0,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x01,0xF8,0x0F,0x80,0x01,0xF8,0x0F,0x80,0x03,0xF0,0x0F,0xC0,0x07,0xF0,0x07,0xE0,0x0F,0xE0,0x03,0xFC,0x3F,0xC0,0x01,0xFF,0xFF,0x80,0x00,0xFF,0xFF,0x00,0x00,0x7F,0xFC,0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 3 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0xFF,0x00,0x00,0x01,0xFF,0x00,0x00,0x01,0xFF,0x00,0x00,0x03,0xFF,0x00,0x00,0x07,0xDF,0x00,0x00,0x07,0xDF,0x00,0x00,0x0F,0x9F,0x00,0x00,0x0F,0x9F,0x00,0x00,0x1F,0x1F,0x00,0x00,0x3E,0x1F,0x00,0x00,0x7E,0x1F,0x00,0x00,0x7C,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x01,0xF0,0x1F,0x00,0x03,0xE0,0x1F,0x00,0x03,0xE0,0x1F,0x00,0x07,0xC0,0x1F,0x00,0x07,0xC0,0x1F,0x00,0x0F,0x80,0x1F,0x00,0x1F,0x80,0x1F,0x00,0x1F,0x00,0x1F,0x00,0x3E,0x00,0x1F,0x00,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //4 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0xFF,0xF0,0x01,0xFF,0xFF,0xF0,0x01,0xFF,0xFF,0xF0,0x01,0xFF,0xFF,0xF0,0x01,0xFF,0xFF,0xF0,0x03,0xE0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0x80,0x00,0x00,0x0F,0x80,0x00,0x00,0x0F,0x80,0xF0,0x00,0x0F,0x8F,0xFE,0x00,0x0F,0xBF,0xFF,0x80,0x0F,0xFF,0xFF,0xC0,0x0F,0xFF,0xFF,0xE0,0x1F,0xFF,0x07,0xF0,0x1F,0xE0,0x03,0xF0,0x1F,0xC0,0x01,0xF8,0x1F,0x00,0x00,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x3F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x3F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF0,0x1F,0x00,0x01,0xF0,0x1F,0x80,0x03,0xE0,0x0F,0xC0,0x07,0xE0,0x07,0xE0,0x1F,0xC0,0x03,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0x00,0x01,0xFF,0xFE,0x00,0x00,0x7F,0xF8,0x00,0x00,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 5 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x3F,0xFE,0x00,0x00,0xFF,0xFF,0x00,0x01,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xC0,0x07,0xE0,0x07,0xE0,0x07,0xC0,0x03,0xF0,0x0F,0xC0,0x01,0xF0,0x0F,0x80,0x00,0xF8,0x1F,0x80,0x00,0xF8,0x1F,0x80,0x00,0xF8,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x3F,0x03,0xF0,0x00,0x3F,0x1F,0xFC,0x00,0x3F,0x7F,0xFE,0x00,0x3F,0xFF,0xFF,0x80,0x3F,0xFF,0xFF,0xC0,0x3F,0xF8,0x0F,0xE0,0x3F,0xE0,0x03,0xF0,0x3F,0xE0,0x03,0xF0,0x3F,0xC0,0x01,0xF8,0x3F,0x80,0x00,0xF8,0x3F,0x80,0x00,0xF8,0x3F,0x00,0x00,0x7C,0x3F,0x00,0x00,0x7C,0x3F,0x00,0x00,0x7C,0x3F,0x00,0x00,0x7C,0x3F,0x00,0x00,0x7C,0x3F,0x00,0x00,0x7C,0x1F,0x00,0x00,0x7C,0x1F,0x80,0x00,0x78,0x1F,0x80,0x00,0xF8,0x1F,0x80,0x00,0xF8,0x0F,0x80,0x00,0xF8,0x0F,0xC0,0x01,0xF0,0x07,0xF0,0x03,0xF0,0x03,0xF8,0x0F,0xE0,0x01,0xFF,0xFF,0xC0,0x00,0xFF,0xFF,0x80,0x00,0x7F,0xFF,0x00,0x00,0x1F,0xFC,0x00,0x00,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 6 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x3F,0xFF,0xFF,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x01,0xF8,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xE0,0x00,0x00,0x03,0xE0,0x00,0x00,0x07,0xC0,0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xE0,0x00,0x00,0x03,0xE0,0x00,0x00,0x03,0xE0,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xC0,0x00,0x00,0x0F,0x80,0x00,0x00,0x0F,0x80,0x00,0x00,0x0F,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 7 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x7F,0xFE,0x00,0x00,0xFF,0xFF,0x80,0x01,0xFF,0xFF,0x80,0x03,0xF8,0x1F,0xC0,0x07,0xE0,0x07,0xE0,0x07,0xC0,0x03,0xE0,0x0F,0xC0,0x03,0xF0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x01,0xF0,0x07,0xC0,0x03,0xE0,0x07,0xC0,0x03,0xE0,0x03,0xE0,0x07,0xC0,0x01,0xF0,0x07,0x80,0x00,0xFC,0x3F,0x00,0x00,0x7F,0xFF,0x00,0x00,0x3F,0xFC,0x00,0x00,0x7F,0xFE,0x00,0x00,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xC0,0x07,0xF0,0x0F,0xE0,0x0F,0xC0,0x03,0xF0,0x0F,0x80,0x01,0xF0,0x1F,0x80,0x01,0xF8,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x3E,0x00,0x00,0x7C,0x1F,0x00,0x00,0xF8,0x1F,0x00,0x00,0xF8,0x0F,0x80,0x01,0xF0,0x0F,0x80,0x03,0xF0,0x07,0xC0,0x07,0xE0,0x03,0xF0,0x0F,0xC0,0x01,0xFF,0xFF,0x80,0x00,0xFF,0xFF,0x00,0x00,0x3F,0xFC,0x00,0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x00,0x00,0x3F,0xFC,0x00,0x00,0xFF,0xFF,0x00,0x01,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0xC0,0x03,0xF8,0x1F,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xE0,0x07,0xF0,0x0F,0xC0,0x03,0xF0,0x0F,0xC0,0x03,0xF8,0x1F,0x80,0x01,0xF8,0x1F,0x80,0x01,0xF8,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x80,0x01,0xFC,0x1F,0x80,0x01,0xFC,0x0F,0xC0,0x03,0xFC,0x0F,0xC0,0x03,0xFC,0x07,0xE0,0x07,0xFC,0x07,0xE0,0x07,0xFC,0x03,0xF8,0x1F,0xFC,0x01,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFC,0x00,0xFF,0xFE,0xFC,0x00,0x7F,0xF8,0xFC,0x00,0x1F,0xE0,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0xFC,0x00,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF8,0x3F,0x00,0x01,0xF0,0x1F,0x00,0x03,0xF0,0x1F,0x80,0x07,0xE0,0x0F,0xC0,0x0F,0xE0,0x0F,0xE0,0x3F,0xC0,0x07,0xFF,0xFF,0x80,0x03,0xFF,0xFF,0x00,0x01,0xFF,0xFE,0x00,0x00,0xFF,0xF8,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9 neu
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xF8,0x00,0x00,0x03,0xF8,0x00,0x00,0x03,0xF8,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x01,0xF0,0x00,0x00,0x03,0xF8,0x00,0x00,0x03,0xF8,0x00,0x00,0x03,0xF8,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // :
};
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
audio.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
the C language function associated with commands, functions or operators should be
declared here
**********************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// void cmd_tts(void);
void CloseAudio(int all);
void StopAudio(void);
void audioInterrupt(void);
void CheckAudio(void);
extern volatile int vol_left, vol_right;
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
#ifndef AUDIO_HEADER
#define AUDIO_HEADER
typedef enum {P_PAUSE_TONE, P_PAUSE_FLAC, P_PAUSE_MP3, P_PAUSE_SOUND, P_PAUSE_MOD, P_PAUSE_WAV, P_STOP,
P_NOTHING, P_TONE, P_SOUND, P_WAV, P_FLAC, P_MP3,
P_MIDI, P_SYNC, P_MOD, P_STREAM, P_WAVOPEN} e_CurrentlyPlaying;
extern const char* const PlayingStr[];
extern volatile e_CurrentlyPlaying CurrentlyPlaying;
extern char *WAVInterrupt;
extern bool WAVcomplete;
extern int WAV_fnbr;
extern int PWM_FREQ;
extern char *sbuff1, *sbuff2, *modbuff;
extern int16_t *g_buff1, *g_buff2;
extern volatile uint32_t bcount[3];
extern volatile int wav_filesize; // head and tail of the ring buffer for com1
extern uint8_t trackplaying, trackstoplay;
extern void checkWAVinput(void);
extern volatile uint64_t SoundPlay;
extern void (*AudioOutput)(uint16_t left, uint16_t right);
#define WAV_BUFFER_SIZE 8192
extern const unsigned short SineTable[4096];
extern const unsigned short nulltable[];
extern const unsigned short squaretable[];
extern volatile float PhaseM_left, PhaseM_right;
extern volatile unsigned char PWM_count;
extern uint16_t *playbuff;
extern int16_t *uplaybuff;
extern uint16_t left,right;
extern volatile int sound_v_left[MAXSOUNDS];
extern volatile int sound_v_right[MAXSOUNDS];
extern volatile float sound_PhaseAC_left[MAXSOUNDS], sound_PhaseAC_right[MAXSOUNDS];
extern volatile float sound_PhaseM_left[MAXSOUNDS], sound_PhaseM_right[MAXSOUNDS];
extern volatile unsigned short * sound_mode_left[MAXSOUNDS];
extern volatile unsigned short * sound_mode_right[MAXSOUNDS];
extern volatile int ppos; // playing position for PLAY WAV
extern volatile float PhaseAC_left, PhaseAC_right;
extern volatile int swingbuf,nextbuf, playreadcomplete;
extern volatile uint8_t mono;
extern volatile uint8_t audiorepeat;
extern int PWM_FREQ;
extern void (*AudioOutput)(uint16_t left, uint16_t right);
extern uint16_t AUDIO_SPI, AUDIO_CLK_PIN,AUDIO_MOSI_PIN,AUDIO_MISO_PIN, AUDIO_CS_PIN, AUDIO_RESET_PIN, AUDIO_DREQ_PIN, AUDIO_DCS_PIN, AUDIO_LDAC_PIN;
extern int streamsize;
extern volatile int *streamwritepointer;
extern volatile int *streamreadpointer;
extern char *streambuffer;
extern char WAVfilename[FF_MAX_LFN];
typedef struct sa_flist {
char fn[FF_MAX_LFN];
} a_flist;
extern a_flist *alist;
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,526 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
#define __BMPDECODER_C__
/******************************************************************************
* FileName: BmpDecoder.c
* Dependencies: Image decoding library; project requires File System library
* Processor: PIC24/dsPIC30/dsPIC33/PIC32MX
* Compiler: C30 v2.01/C32 v0.00.18
* Company: Microchip Technology, Inc.
* Software License Agreement
*
* Copyright <EFBFBD> 2008 Microchip Technology Inc. All rights reserved.
* Microchip licenses to you the right to use, modify, copy and distribute
* Software only when embedded on a Microchip microcontroller or digital
* signal controller, which is integrated into your product or third party
* product (pursuant to the sublicense terms in the accompanying license
* agreement).
*
* You should refer to the license agreement accompanying this Software
* for additional information regarding your rights and obligations.
*
* SOFTWARE AND DOCUMENTATION ARE PROVIDED <EFBFBD>AS IS<EFBFBD> WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
* OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR
* PURPOSE. IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR
* OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION,
* BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT
* DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
* INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA,
* COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY
* CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF),
* OR OTHER SIMILAR COSTS.
Author Date Comments
--------------------------------------------------------------------------------
Pradeep Budagutta 03-Mar-2008 First release
*******************************************************************************/
//#include "GenericTypeDefs.h"
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
//** SD CARD INCLUDES ***********************************************************
#include "ff.h"
#define IMG_FILE fnbr
int IMG_FREAD(int fnbr, void *buff, int count, unsigned int *read){
if(filesource[IMG_FILE]==FATFSFILE){
return f_read(FileTable[IMG_FILE].fptr, buff, count, (UINT *)read);
} else {
int n=lfs_file_read(&lfs, FileTable[IMG_FILE].lfsptr, buff, count);
if(n>=0)return 0;
else return n;
}
}
#define IMG_vSetboundaries()
#define IMG_vLoopCallback()
#define IMG_vCheckAndAbort() CheckAbort()
union colourmap
{
char rgbbytes[4];
unsigned int rgb;
} colour, colour2;
#define IMG_vSetColor(red, green, blue) {colour.rgbbytes[2] = red; colour.rgbbytes[1] = green; colour.rgbbytes[0] = blue;}
#define IMG_vSetColor2(red, green, blue) {colour2.rgbbytes[2] = red; colour2.rgbbytes[1] = green; colour2.rgbbytes[0] = blue;}
#define IMG_vPutPixel(xx, yy) DrawPixel(xx + x, yy + y, colour.rgb)
#define IMG_vPutPixel2(xx, yy) DrawPixel(xx + x, yy + y, colour2.rgb)
#define LONG long
int IMG_wImageWidth, IMG_wImageHeight;
int bufpos;
/*************************/
/**** DATA STRUCTURES ****/
/*************************/
typedef struct _BMPDECODER
{
LONG lWidth;
LONG lHeight;
LONG lImageOffset;
WORD wPaletteEntries;
BYTE bBitsPerPixel;
BYTE bHeaderType;
BYTE blBmMarkerFlag : 1;
BYTE blCompressionType : 3;
BYTE bNumOfPlanes : 3;
BYTE b16bit565flag : 1;
BYTE aPalette[256][3]; /* Each palette entry has RGB */
} BMPDECODER;
/**************************/
/******* FUNCTIONS *******/
/**************************/
/*******************************************************************************
Function: void BDEC_vResetData(BMPDECODER *pBmpDec)
Precondition: None
Overview: This function resets the variables so that new Bitmap image
can be decoded
Input: Bitmap decoder's data structure
Output: None
*******************************************************************************/
void BDEC_vResetData(BMPDECODER *pBmpDec)
{
pBmpDec->lWidth = 0;
pBmpDec->lHeight = 0;
pBmpDec->lImageOffset = 0;
pBmpDec->wPaletteEntries = 0;
pBmpDec->bBitsPerPixel = 0;
pBmpDec->bHeaderType = 0;
pBmpDec->blBmMarkerFlag = 0;
pBmpDec->blCompressionType = 0;
pBmpDec->bNumOfPlanes = 0;
pBmpDec->b16bit565flag = 0;
}
/*******************************************************************************
Function: BYTE BDEC_bReadHeader(BMPDECODER *pBmpDec)
Precondition: None
Overview: This function reads the Bitmap file header and
fills the data structure
Input: Bitmap decoder's data structure
Output: Error code - '0' means no error
*******************************************************************************/
BYTE BDEC_bReadHeader(BMPDECODER *pBmpDec, int fnbr)
{
BYTE bByte1, bByte2;
WORD wWord;
LONG lLong;
unsigned int nbr;
FSerror = IMG_FREAD(IMG_FILE, &bByte1, 1, &nbr); /* Marker */
FSerror = IMG_FREAD(IMG_FILE, &bByte2, 1, &nbr); /* Marker */
if(bByte1 == 'B' && bByte2 == 'M')
{
pBmpDec->blBmMarkerFlag = 1;
}
else
{
return(100);
}
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* File length */
FSerror = IMG_FREAD(IMG_FILE, &wWord, 2, &nbr); /* Reserved */
FSerror = IMG_FREAD(IMG_FILE, &wWord, 2, &nbr); /* Reserved */
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Image offset */
pBmpDec->lImageOffset = lLong;
FSerror = IMG_FREAD(IMG_FILE,&lLong, 4, &nbr); /* Header length */
pBmpDec->bHeaderType = (BYTE)lLong;
if(pBmpDec->bHeaderType >= 40)
{
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Image Width */
pBmpDec->lWidth = lLong;
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Image Height */
pBmpDec->lHeight = lLong;
FSerror = IMG_FREAD(IMG_FILE, &wWord, 2, &nbr); /* Number of Planes */
pBmpDec->bNumOfPlanes = (BYTE)wWord;
FSerror = IMG_FREAD(IMG_FILE, &wWord, 2, &nbr); /* Bits per Pixel */
pBmpDec->bBitsPerPixel = (BYTE)wWord;
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Compression info */
pBmpDec->blCompressionType = (BYTE)lLong;
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Image length */
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* xPixels per metre */
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* yPixels per metre */
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Palette entries */
pBmpDec->wPaletteEntries = (WORD)lLong;
if(pBmpDec->wPaletteEntries == 0)
{
WORD wTemp = (WORD)(pBmpDec->lImageOffset - 14 - 40)/4;
if(wTemp > 0)
{
pBmpDec->wPaletteEntries = wTemp; /* This is because of a bug in MSPAINT */
}
}
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Important colors */
if(pBmpDec->bBitsPerPixel == 16 && pBmpDec->bHeaderType > 40)
{
FSerror = IMG_FREAD(IMG_FILE, &lLong, 4, &nbr); /* Red mask */
if((WORD)lLong == 0xF800)
{
pBmpDec->b16bit565flag = 1;
}
}
// IMG_FSEEK(&nbr, pBmpDec->bHeaderType + 14, 0);
if(pBmpDec->wPaletteEntries <= 256)
{
WORD wCounter;
for(wCounter = 0; wCounter < pBmpDec->wPaletteEntries; wCounter++)
{
FSerror = IMG_FREAD(IMG_FILE, &pBmpDec->aPalette[wCounter][2], 1, &nbr); /* R */
FSerror = IMG_FREAD(IMG_FILE, &pBmpDec->aPalette[wCounter][1], 1, &nbr); /* G */
FSerror = IMG_FREAD(IMG_FILE, &pBmpDec->aPalette[wCounter][0], 1, &nbr); /* B */
FSerror = IMG_FREAD(IMG_FILE, &wWord, 1, &nbr); /* Dummy */
}
}
}
return(0);
}
/*******************************************************************************
Function: BYTE BMP_bDecode(IMG_FILE *pFile)
Precondition: None
Overview: This function decodes and displays a Bitmap image
Input: Image file
Output: Error code - '0' means no error
*******************************************************************************/
BYTE BMP_bDecode(int x, int y, int fnbr)
{
BMPDECODER BmpDec;
WORD wX, wY;
BYTE bPadding;
unsigned int nbr;
BDEC_vResetData(&BmpDec);
BDEC_bReadHeader(&BmpDec, fnbr);
if(BmpDec.blBmMarkerFlag == 0 || BmpDec.bHeaderType < 40 || (BmpDec.blCompressionType != 0 && BmpDec.blCompressionType != 2 && BmpDec.blCompressionType != 3))
{
return 100;
}
IMG_wImageWidth = (WORD)BmpDec.lWidth;
IMG_wImageHeight = (WORD)BmpDec.lHeight;
IMG_vSetboundaries();
char *linebuff=GetMemory(IMG_wImageWidth*3); //get a line buffer
// IMG_FSEEK(pFile, BmpDec.lImageOffset, 0);
if(BmpDec.wPaletteEntries == 0 && BmpDec.bBitsPerPixel == 8) /* Grayscale Image */
{
bPadding = (4 - (BmpDec.lWidth % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
IMG_vLoopCallback();
IMG_vCheckAndAbort();
for(wX = 0; wX < BmpDec.lWidth; wX++)
{
BYTE bY;
FSerror = IMG_FREAD(IMG_FILE, &bY, 1, &nbr); /* Y */
IMG_vSetColor(bY, bY, bY);
IMG_vPutPixel(wX, BmpDec.lHeight - wY - 1);
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
else if(BmpDec.bBitsPerPixel == 16) /* 16-bit Color Image */
{
bPadding = (4 - ((BmpDec.lWidth*2) % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
IMG_vLoopCallback();
IMG_vCheckAndAbort();
for(wX = 0; wX < BmpDec.lWidth; wX++)
{
WORD wColor;
BYTE bR, bG, bB;
FSerror = IMG_FREAD(IMG_FILE, &wColor, 2, &nbr); /* RGB */
if(BmpDec.b16bit565flag == 1)
{
bR = (wColor >> 11) << 3;
bG = ((wColor & 0x07E0) >> 5) << 2;
bB = (wColor & 0x001F) << 3;
}
else
{
bR = ((wColor & 0x7FFF) >> 10) << 3;
bG = ((wColor & 0x03E0) >> 5) << 3;
bB = (wColor & 0x001F) << 3;
}
IMG_vSetColor(bR, bG, bB);
IMG_vPutPixel(wX, BmpDec.lHeight - wY - 1);
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
else if(BmpDec.bBitsPerPixel == 24) /* True color Image */
{
int pp;
bPadding = (4 - ((BmpDec.lWidth*3) % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
IMG_vLoopCallback();
IMG_vCheckAndAbort();
FSerror = IMG_FREAD(IMG_FILE, linebuff, BmpDec.lWidth*3, &nbr); /* B */
pp=0;
for(wX = 0; wX < BmpDec.lWidth; wX++)
{
colour.rgbbytes[0]=linebuff[pp++];
colour.rgbbytes[1]=linebuff[pp++];
colour.rgbbytes[2]=linebuff[pp++];
IMG_vPutPixel(wX, BmpDec.lHeight - wY - 1);
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
else if(BmpDec.wPaletteEntries != 0 && BmpDec.bBitsPerPixel == 1) /* B/W Image */
{
WORD wBytesPerRow = BmpDec.lWidth/8;
BYTE bAdditionalBitsPerRow = BmpDec.lWidth % 8;
bPadding = (4 - ((wBytesPerRow + (bAdditionalBitsPerRow?1:0)) % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
BYTE bBits, bValue;
IMG_vLoopCallback();
IMG_vCheckAndAbort();
for(wX = 0; wX < wBytesPerRow; wX++)
{
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
for(bBits = 0; bBits < 8; bBits++)
{
BYTE bIndex = (bValue & (0x80 >> bBits))?1:0;
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
IMG_vPutPixel(wX*8+bBits, BmpDec.lHeight - wY - 1);
}
}
if(bAdditionalBitsPerRow > 0)
{
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
for(bBits = 0; bBits < bAdditionalBitsPerRow; bBits++)
{
BYTE bIndex = (bValue & (0x80 >> bBits))?1:0;
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
IMG_vPutPixel(wX*8+bBits, BmpDec.lHeight - wY - 1);
}
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
else if(BmpDec.wPaletteEntries != 0 && BmpDec.bBitsPerPixel == 4 && BmpDec.blCompressionType != 2) /* 16 colors Image */
{
WORD wBytesPerRow = BmpDec.lWidth/2;
BYTE bAdditionalNibblePerRow = BmpDec.lWidth % 2;
bPadding = (4 - ((wBytesPerRow + bAdditionalNibblePerRow) % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
IMG_vLoopCallback();
IMG_vCheckAndAbort();
for(wX = 0; wX < wBytesPerRow; wX++)
{
BYTE bIndex, bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
bIndex = bValue >> 4;
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
IMG_vPutPixel(wX*2, BmpDec.lHeight - wY - 1);
bIndex = bValue & 0x0F;
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
IMG_vPutPixel(wX*2+1, BmpDec.lHeight - wY - 1);
}
if(bAdditionalNibblePerRow)
{
BYTE bIndex, bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr); /* Bits8 */
bIndex = bValue >> 4;
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
IMG_vPutPixel(wX*2, BmpDec.lHeight - wY - 1);
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
else if(BmpDec.wPaletteEntries != 0 && BmpDec.bBitsPerPixel == 4 && BmpDec.blCompressionType==2) /* 16 colors Image */
{
BYTE bIndex;
int c;
unsigned char b[2];
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
IMG_vCheckAndAbort();
wX=0;
do {
FSerror = IMG_FREAD(IMG_FILE, b, 2, &nbr);
c=b[0];
bIndex = b[1] >> 4;
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
bIndex = b[1] & 0xf;
IMG_vSetColor2(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
while(c){
IMG_vPutPixel(wX++, BmpDec.lHeight - wY - 1);
IMG_vPutPixel2(wX++, BmpDec.lHeight - wY - 1);
c-=2;
}
} while(!(b[0]==0 && b[1]==0));
}
}
else if(BmpDec.wPaletteEntries != 0 && BmpDec.bBitsPerPixel == 8) /* 256 colors Image */
{
bPadding = (4 - (BmpDec.lWidth % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
IMG_vLoopCallback(); IMG_vCheckAndAbort();
for(wX = 0; wX < BmpDec.lWidth; wX++)
{
BYTE bIndex;
FSerror = IMG_FREAD(IMG_FILE, &bIndex, 1, &nbr);
IMG_vSetColor(BmpDec.aPalette[bIndex][0], BmpDec.aPalette[bIndex][1], BmpDec.aPalette[bIndex][2]);
IMG_vPutPixel(wX, BmpDec.lHeight - wY - 1);
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
FreeMemory((void *)linebuff);
return 0;
}
/*******************************************************************************
Function: BYTE BMP_bDecode(IMG_FILE *pFile)
Precondition: None
Overview: This function decodes and puts a section of an image into a memory array
Input: Image file
Output: Error code - '0' means no error
*******************************************************************************/
BYTE BMP_bDecode_memory(int x, int y, int xlen, int ylen, int fnbr, char *p)
{
BMPDECODER BmpDec;
WORD wX, wY;
BYTE bPadding;
unsigned int nbr;
BDEC_vResetData(&BmpDec);
BDEC_bReadHeader(&BmpDec, fnbr);
if(BmpDec.blBmMarkerFlag == 0 || BmpDec.bHeaderType < 40 || (BmpDec.blCompressionType != 0 && BmpDec.blCompressionType != 3))
{
return 100;
}
IMG_wImageWidth = (WORD)BmpDec.lWidth;
IMG_wImageHeight = (WORD)BmpDec.lHeight;
IMG_vSetboundaries();
char *linebuff=GetMemory(IMG_wImageWidth*3); //get a line buffer
// IMG_FSEEK(pFile, BmpDec.lImageOffset, 0);
if(BmpDec.bBitsPerPixel == 24) /* True color Image */
{
int pp;
bPadding = (4 - ((BmpDec.lWidth*3) % 4))%4;
for(wY = 0; wY < BmpDec.lHeight; wY++)
{
routinechecks();
IMG_vLoopCallback();
IMG_vCheckAndAbort();
FSerror = IMG_FREAD(IMG_FILE, linebuff, BmpDec.lWidth*3, &nbr); /* B */
/* if((void *)DrawBuffer != (void *)DisplayNotSet) {
PInt(linebuff[0]);PIntComma(linebuff[1]);PIntComma(linebuff[2]);PRet();
DrawBuffer(x, BmpDec.lHeight - wY - 1 + y, x+BmpDec.lWidth-1, BmpDec.lHeight - wY - 1 + y, linebuff);
} else */{ //must be a loadable driver so no helper function available
pp=0;
for(wX = 0; wX < BmpDec.lWidth; wX++)
{
colour.rgbbytes[0]=linebuff[pp++];
colour.rgbbytes[1]=linebuff[pp++];
colour.rgbbytes[2]=linebuff[pp++];
int px=wX-x;
int py=BmpDec.lHeight - wY - 1 - y;
if(px<xlen && px>=0 && py<ylen && py>=0){
char *q= p+(py*xlen+px)*3;
*q++=colour.rgbbytes[0];
*q++=colour.rgbbytes[1];
*q++=colour.rgbbytes[2];
}
}
}
for(wX = 0; wX < bPadding; wX++)
{
BYTE bValue;
FSerror = IMG_FREAD(IMG_FILE, &bValue, 1, &nbr);
}
}
}
else error("Only 24-bit colour images supported");
FreeMemory((void *)linebuff);
return 0;
}
/* @endcond */

View File

@ -0,0 +1,170 @@
/*
* CFunctions.c
*
* Created on: 3 Jul 2020
* Author: peter
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
//Vector to CFunction static RAM
//Vector to CFunction routine called every mSec
unsigned int CFuncmSec = (unsigned int)NULL;
extern volatile uint64_t uSecTimer;
extern volatile uint64_t FastTimer;
//extern TIM_HandleTypeDef htim2;
extern uint32_t ticks_per_microsecond;
void CallExecuteProgram(char *p);
void CallCFuncmSec(void);
extern const void * const CallTable[];
extern void routinechecksExternal(void);
//Vector to CFunction routine called every command (ie, from the BASIC interrupt checker)
unsigned int CFuncInt1 = (unsigned int)NULL;
//Vector to CFunction routine called by the interrupt 2 handler
unsigned int CFuncInt2 = (unsigned int)NULL;
unsigned int CFuncInt3 = (unsigned int)NULL;
unsigned int CFuncInt4 = (unsigned int)NULL;
unsigned int CFuncAudio = (unsigned int)NULL;
//static uint64_t timer(void){ return time_us_64();}
//static int64_t PinReadFunc(int a){return gpio_get(PinDef[a].GPno);}
// used by CallCFunction() below to find a CFunction or CSub in program flash or the library
unsigned int *FindCFunction(unsigned int *p, unsigned char *CmdPtr, unsigned char *offset) {
while(*p != 0xffffffff) {
//if(*p++ == (unsigned int)(CmdPtr-ProgMemory)) return p;
if(*p++ == (unsigned int)(CmdPtr-offset)) return p;
p += (*p + 4) / sizeof(unsigned int);
}
return p;
}
long long int MIPS16 CallCFunction(unsigned char *CmdPtr, unsigned char *ArgList, unsigned char *DefP, unsigned char *CallersLinePtr) {
void *arg[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
int typ[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
long long int ret, i64[10];
MMFLOAT ff[10];
unsigned char *pp;
int i,type;
uint32_t ii;
unsigned int *p=(void * const )CallTable;
MMFLOAT ftmp;
// if((uint32_t)p > 0x10000000)error("Internal error");
// find the C code in flash
if(*ArgList == '(') ArgList++; // and step over it
p = FindCFunction((unsigned int *)CFunctionFlash, CmdPtr,ProgMemory); // search through the program flash looking for a match to the function being called
if(*p == 0xffffffff && CFunctionLibrary != NULL)
p = FindCFunction((unsigned int *)CFunctionLibrary, CmdPtr,LibMemory);// if unsuccessful search the library area
if(*p == 0xffffffff) error("Internal fault 5(sorry)");
// next, get the argument types (if specified)
{ // first copy the type list to a buffer and trim the following closing bracket (if there)
char buf[MAXSTRLEN];
unsigned char *p = (unsigned char *)buf;
if(*DefP == '(') DefP++;
while(*DefP && *DefP != ')' && *DefP != '\'') *p++ = *DefP++;
*p = 0;
p = (unsigned char *)buf;
skipspace(p);
CheckIfTypeSpecified(p, &i, true);
if(i != DefaultType) {
// if there is a type list get each entry
getargs(&p, 19, (unsigned char *)",");
for(i = 0; i < argc; i+=2) { // get each definition
CheckIfTypeSpecified(argv[i], &typ[i/2], false);
typ[i/2] &= ~T_IMPLIED;
}
}
}
// we have found the CFunction or CSub and the types on its command line
CurrentLinePtr = CallersLinePtr; // report errors at the caller
if(*ArgList != ')') {
getargs(&ArgList, 19, (unsigned char *)","); // expand the command line of the caller
for(i = 0; i < argc; i += 2) {
// if this is a straight variable we want to pass a pointer to its value in RAM
if(isnamestart((uint8_t)*argv[i]) && (*skipvar(argv[i], false) == 0 || *skipvar(argv[i], false) == ')') && !(FindSubFun(argv[i], 1) >= 0 && strchr((const char *)argv[i], '(') != NULL)) {
arg[i/2] = findvar(argv[i], V_FIND | V_EMPTY_OK /* | V_NOFIND_ERR */ ); // if the argument
if(typ[i/2] != 0 && !(TypeMask(g_vartbl[g_VarIndex].type) & typ[i/2])) error("Incompatible type");
} else {
// else it must be an expression of some sort
// get the value based on the type specified in the definition
switch(typ[i/2]) {
case T_INT: i64[i/2] = getinteger(argv[i]);
arg[i/2] = &i64[i/2];
break;
case T_NBR: ftmp = getnumber(argv[i]);
ff[i/2] = ftmp;
arg[i/2] = &ff[i/2];
break;
case T_STR: arg[i/2] = GetTempMemory(STRINGSIZE);
Mstrcpy(arg[i/2], getstring(argv[i]));
break;
default: // the type has not been specified (old style CFunction)
type = T_NOTYPE;
evaluate(argv[i], &ftmp, &i64[i/2], &pp, &type, false);
ff[i/2] = ftmp;
if(type & T_NBR) {
arg[i/2] = &ff[i/2];
} else if(type & T_INT)
arg[i/2] = &i64[i/2];
else {
arg[i/2] = GetTempMemory(STRINGSIZE);
Mstrcpy(arg[i/2], pp);
}
break;
}
}
}
}
p++; // step over the size word
// run the function in flash
ii = *p++;
p = (unsigned int *)((unsigned int) p | 0x1);
ret = ((long long int (*)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *)) (p + ii)) (arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7], arg[8], arg[9]); // run the CFunction
return ret;
}
// If the CFuncmSec vector is set then call the CFunction
void CallCFuncmSec(void){
typedef void func(void);
func* f=(func*)(void *)CFuncmSec;
f();
}
// save the interpreter state if re entering it
void CallExecuteProgram(char *p) {
unsigned char *nextstmtSaved = nextstmt;
g_LocalIndex++;
ExecuteProgram((unsigned char *)p);
nextstmt = nextstmtSaved;
g_LocalIndex--;
g_TempMemoryIsChanged = true; // signal that temporary memory should be checked
}
// If the CFuncmInt1 vector is set then call the CFunction
void CallCFuncInt1(void){
typedef void func(void);
func* f=(func*)(void *)CFuncInt1;
f();
}
// If the CFuncmInt2 vector is set then call the CFunction
void CallCFuncInt2(void){
typedef void func(void);
func* f=(func*)(void *)CFuncInt2;
f();
}
void CallCFuncInt3(void){
typedef void func(void);
func* f=(func*)(void *)CFuncInt3;
f();
}
void CallCFuncInt4(void){
typedef void func(void);
func* f=(func*)(void *)CFuncInt4;
f();
}

View File

@ -0,0 +1,174 @@
set(APP_NAME picomite)
set(PICOCALC true)
#set(SDBOOT true)
# Compile for PICO 1 Board
set(COMPILE PICO)
set(PICO_PLATFORM rp2040)
set(PICO_BOARD pico)
add_executable(${APP_NAME}
PicoMite.c
Memory.c
regex.c
MMBasic.c
Operators.c
Custom.c
Functions.c
Commands.c
FileIO.c
ff.c
ffsystem.c
ffunicode.c
mmc_stm32.c
Draw.c
Editor.c
XModem.c
MM_Misc.c
External.c
MATHS.c
Onewire.c
I2C.c
SPI.c
Serial.c
SPI-LCD.c
BmpDecoder.c
GPS.c
Audio.c
CFunction.c
picojpeg.c
lfs.c
lfs_util.c
hxcmod.c
VS1053.c
aes.c
)
target_sources(${APP_NAME} PRIVATE
SSD1963.c
Touch.c
GUI.c)
target_sources(${APP_NAME} PRIVATE
Keyboard.c
mouse.c
)
if(PICOCALC STREQUAL "true")
target_sources(${APP_NAME} PRIVATE
picocalc/i2ckbd.c
)
endif()
set_source_files_properties(mmc_stm32.c PROPERTIES COMPILE_FLAGS -O2)
set_source_files_properties(ff.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(GUI.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(BmpDecoder.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(GPS.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(I2C.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(lfs.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(picojpeg.c PROPERTIES COMPILE_FLAGS -Os)
set_source_files_properties(regex.c PROPERTIES COMPILE_FLAGS -Os)
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_set_printf_implementation(${APP_NAME} compiler)
target_compile_options(${APP_NAME} PRIVATE -DNDEBUG
-DPICO_STDIO_USB_ENABLE_RESET_VIA_VENDOR_INTERFACE=0
-DPICO_ADC_CLKDIV_ROUND_NEAREST
-DPICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
-DPICO_CLOCK_AJDUST_PERI_CLOCK_WITH_SYS_CLOCK
-DPICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
-DPICO_FLASH_SIZE_BYTES=16777216
-DPICO_CORE1_STACK_SIZE=0x00
-DPICO_MALLOC_PANIC
-O2
-Wall)
target_compile_options(${APP_NAME} PRIVATE -DPICOMITE
-DPICO_HEAP_SIZE=0x1000
-DGUICONTROLS
-DPICO_CORE0_STACK_SIZE=0x1000
)
#set the PICOCALC flag
if(PICOCALC STREQUAL "true")
target_compile_options(${APP_NAME} PRIVATE -DPICOCALC
)
endif()
target_link_libraries(${APP_NAME}
pico_stdlib
hardware_flash
hardware_irq
hardware_adc
hardware_pwm
hardware_i2c
hardware_spi
hardware_dma
hardware_exception
hardware_pio
pico_multicore
pico_unique_id
)
set(UF2_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/${APP_NAME}.uf2)
set(UF2_DEST ${CMAKE_BINARY_DIR}/${APP_NAME}.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"
)
add_custom_target(PREPARE_${APP_NAME}
COMMENT "Create Linker Script for '${APP_NAME}'"
COMMAND ${Python3_EXECUTABLE}
${CMAKE_SOURCE_DIR}/applink.py PREPARE
${CMAKE_BINARY_DIR}
${APP_NAME})
add_custom_target(BUILT_${APP_NAME}
COMMENT "Record Build Details for '${APP_NAME}'"
DEPENDS ${UF2_DEST}
COMMAND ${Python3_EXECUTABLE}
${CMAKE_SOURCE_DIR}/applink.py BUILT
${CMAKE_BINARY_DIR}
${APP_NAME})
if(SDBOOT STREQUAL "true")
pico_set_linker_script(${APP_NAME} ${CMAKE_SOURCE_DIR}/memmap_sdcard_app.ld)
endif()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
commands.h
<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 <stdbool.h>
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
typedef struct s_forstack {
unsigned char *forptr; // pointer to the FOR command in program memory
unsigned char *nextptr; // pointer to the NEXT command in program memory
void *var; // value of the FOR variable
unsigned char vartype; // type of the variable
unsigned char level; // the sub/function level that the loop was created
union u_totype {
MMFLOAT f; // the TO value if it is a float
long long int i; // the TO value if it is an integer
} tovalue;
union u_steptype {
MMFLOAT f; // the STEP value if it is a float
long long int i; // the STEP value if it is an integer
} stepvalue;
}forstackval;
extern unsigned char topicbuff[STRINGSIZE];
extern unsigned char messagebuff[STRINGSIZE];
extern unsigned char addressbuff[20];
extern struct s_forstack g_forstack[MAXFORLOOPS + 1] ;
extern int g_forindex;
extern unsigned char cmdlinebuff[STRINGSIZE];
typedef struct s_dostack {
unsigned char *evalptr; // pointer to the expression to be evaluated
unsigned char *loopptr; // pointer to the loop statement
unsigned char *doptr; // pointer to the DO statement
unsigned char level; // the sub/function level that the loop was created
}dostackval;
extern struct s_dostack g_dostack[MAXDOLOOPS];
extern int g_doindex;
extern unsigned char *gosubstack[MAXGOSUB];
extern unsigned char *errorstack[MAXGOSUB];
extern int gosubindex;
extern unsigned char g_DimUsed;
//extern unsigned char *GetFileName(char* CmdLinePtr, unsigned char *LastFilePtr);
//extern void mergefile(unsigned char *fname, unsigned char *MemPtr);
extern void ListProgram(unsigned char *p, int all);
extern unsigned char *llist(unsigned char *b, unsigned char *p);
extern unsigned char *CheckIfTypeSpecified(unsigned char *p, int *type, int AllowDefaultType);
extern void MIPS16 ListNewLine(int *ListCnt, int all);
// definitions related to setting video off and on
extern const unsigned int CaseOption;
extern volatile bool Keycomplete;
extern char *KeyInterrupt;
extern int keyselect;
extern uint64_t g_flag;
#define TRACE_BUFF_SIZE 128
extern unsigned int BusSpeed;
extern unsigned char *OnKeyGOSUB;
extern unsigned char EchoOption;
extern unsigned char *GetFileName(unsigned char* CmdLinePtr, unsigned char *LastFilePtr);
extern void mergefile(unsigned char *fname, unsigned char *MemPtr);
extern volatile unsigned int ScrewUpTimer;
struct sa_data{
unsigned char* SaveNextDataLine;
int SaveNextData;
};
extern void SaveContext(void);
extern void RestoreContext(bool keep);
extern void do_end(bool ecmd);
extern struct sa_data datastore[MAXRESTORE];
extern int restorepointer;
extern unsigned short *frame, *outframe;
extern bool framecursor;
extern void array_slice(unsigned char *tp);
extern void array_insert(unsigned char *tp);
extern void array_add(unsigned char *tp);
extern void array_set(unsigned char *tp);
extern int format_string(char *c, int n);
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,144 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Custom.h
<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.
************************************************************************************************************************/
#ifdef PICOMITEWEB
#include "pico/cyw43_arch.h"
#include "lwip/dns.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/apps/mqtt.h"
#include "lwip/apps/mqtt_priv.h"
#include "lwip/timeouts.h"
#include "lwip/ip_addr.h"
#include "lwip/mem.h"
#include "lwip/err.h"
#endif
/* ********************************************************************************
the C language function associated with commands, functions or operators should be
declared here
**********************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// format:
// void cmd_???(void)
// void fun_???(void)
// void op_???(void)
extern uint8_t pioTXlast[4][3];
extern char *pioRXinterrupts[4][3];
extern char *pioTXinterrupts[4][3];
#ifdef PICOMITEWEB
extern void GetNTPTime(void);
extern void checkTCPOptions(void);
extern void open_tcp_server(void);
extern void open_udp_server(void);
extern volatile bool TCPreceived;
extern char *TCPreceiveInterrupt;
extern void TelnetPutC(int c,int flush);
extern int cmd_mqtt(void);
extern void cmd_ntp(unsigned char *tp);
extern void cmd_udp(unsigned char *tp);
extern int cmd_tcpclient(void);
extern int cmd_tcpserver(void);
extern int cmd_tftp_server_init(void);
extern int cmd_tls();
extern void closeMQTT(void);
typedef struct TCP_SERVER_T_ {
struct tcp_pcb *server_pcb;
struct tcp_pcb *telnet_pcb;
struct tcp_pcb* client_pcb[MaxPcb];
volatile int inttrig[MaxPcb];
uint8_t *buffer_sent[MaxPcb];
uint8_t* buffer_recv[MaxPcb];
volatile int sent_len[MaxPcb];
volatile int recv_len[MaxPcb];
volatile int total_sent[MaxPcb];
volatile int to_send[MaxPcb];
volatile uint64_t pcbopentime[MaxPcb];
volatile int keepalive[MaxPcb];
volatile int telnet_pcb_no;
volatile int telnet_init_sent;
} TCP_SERVER_T;
typedef struct NTP_T_ {
ip_addr_t ntp_server_address;
bool dns_request_sent;
struct udp_pcb *ntp_pcb;
absolute_time_t ntp_test_time;
alarm_id_t ntp_resend_alarm;
volatile bool complete;
} NTP_T;
typedef struct TCP_CLIENT_T_ {
volatile struct tcp_pcb *tcp_pcb;
ip_addr_t remote_addr;
volatile uint8_t *buffer;
volatile int buffer_len;
volatile bool complete;
volatile bool connected;
volatile int BUF_SIZE;
volatile int TCP_PORT;
volatile int *buffer_write;
volatile int *buffer_read;
volatile char *hostname;
} TCP_CLIENT_T;
extern TCP_SERVER_T *TCPstate;
extern void cleanserver(void);
extern err_t tcp_server_close(void *arg, int pcb);
extern err_t tcp_server_send_data(void *arg, struct tcp_pcb *tpcb, int pcb);
extern void checksent(void *arg, int fn, int pcb);
extern TCP_CLIENT_T *TCP_CLIENT;
extern TCP_CLIENT_T* tcp_client_init(void);
extern void tcp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg);
extern void starttelnet(struct tcp_pcb *client_pcb, int pcb, void *arg);
extern char *UDPinterrupt;
extern volatile bool UDPreceive;
#endif
extern int piointerrupt;
extern char *DMAinterruptRX;
extern char *DMAinterruptTX;
extern uint32_t dma_rx_chan;
extern uint32_t dma_tx_chan;
extern uint32_t dma_rx_chan2;
extern uint32_t dma_tx_chan2;
extern int dma_tx_pio;
extern int dma_tx_sm;
extern int dma_rx_pio;
extern int dma_rx_sm;
extern int dirOK;
extern bool PIO0;
extern bool PIO1;
extern bool PIO2;
extern uint64_t piomap[];
extern uint8_t nextline[4];
#define TCP_READ_BUFFER_SIZE 2048
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,258 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Draw.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
// { (unsigned char *)"MM.FontWidth", T_FNA | T_INT, 0, fun_mmcharwidth },
// { (unsigned char *)"MM.FontHeight", T_FNA | T_INT, 0, fun_mmcharheight },
// the format is:
// TEXT TYPE P FUNCTION TO CALL
// where type is T_NA, T_FUN, T_FNA or T_OPER augmented by the types T_STR and/or T_NBR
// and P is the precedence (which is only used for operators)
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#ifndef DRAW_H_INCL
#define RGB(red, green, blue) (unsigned int) (((red & 0b11111111) << 16) | ((green & 0b11111111) << 8) | (blue & 0b11111111))
#define swap(a, b) {int t = a; a = b; b = t;}
#define DRAW_H_INCL
#define WHITE RGB(255, 255, 255) //0b1111
#define YELLOW RGB(255, 255, 0) //0b1110
#define LILAC RGB(255, 128, 255) //0b1101
#define BROWN RGB(255, 128, 0) //0b1100
#define FUCHSIA RGB(255, 64, 255) //0b1011
#define RUST RGB(255, 64, 0) //0b1010
#define MAGENTA RGB(255, 0, 255) //0b1001
#define RED RGB(255, 0, 0) //0b1000
#define CYAN RGB(0, 255, 255) //0b0111
#define GREEN RGB(0, 255, 0) //0b0110
#define CERULEAN RGB(0, 128, 255) //0b0101
#define MIDGREEN RGB(0, 128, 0) //0b0100
#define COBALT RGB(0, 64, 255) //0b0011
#define MYRTLE RGB(0, 64, 0) //0b0010
#define BLUE RGB(0, 0, 255) //0b0001
#define BLACK RGB(0, 0, 0) //0b0000
#define BROWN RGB(255, 128, 0)
#define GRAY RGB(128, 128, 128)
#define LITEGRAY RGB(210, 210, 210)
#define ORANGE RGB(0xff, 0xA5, 0)
#define PINK RGB(0xFF, 0xA0, 0xAB)
#define GOLD RGB(0xFF, 0xD7, 0x00)
#define SALMON RGB(0xFA, 0x80, 0x72)
#define BEIGE RGB(0xF5, 0xF5, 0xDC)
#define JUSTIFY_LEFT 0
#define JUSTIFY_CENTER 1
#define JUSTIFY_RIGHT 2
#define JUSTIFY_TOP 0
#define JUSTIFY_MIDDLE 1
#define JUSTIFY_BOTTOM 2
#define ORIENT_NORMAL 0
#define ORIENT_VERT 1
#define ORIENT_INVERTED 2
#define ORIENT_CCW90DEG 3
#define ORIENT_CW90DEG 4
extern short gui_font;
extern short gui_font_width, gui_font_height;
extern int gui_fcolour;
extern int gui_bcolour;
extern short DisplayHRes, DisplayVRes; // resolution of the display
extern short HRes, VRes; // the programming charteristics of the display
extern short low_y, high_y, low_x, high_x;
#define LANDSCAPE 1
#define PORTRAIT 2
#define RLANDSCAPE 3
#define RPORTRAIT 4
#define DISPLAY_LANDSCAPE (Option.DISPLAY_ORIENTATION & 1)
#define TOUCH_NOT_CALIBRATED -999999
#define RESET_COMMAND 9999 // indicates that the reset was caused by the RESET command
#define WATCHDOG_TIMEOUT 9998 // reset caused by the watchdog timer
#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);
extern void cmd_guiBasic(void);
extern void DrawLine(int x1, int y1, int x2, int y2, int w, int c);
extern void DrawBox(int x1, int y1, int x2, int y2, int w, int c, int fill);
extern void DrawRBox(int x1, int y1, int x2, int y2, int radius, int c, int fill);
extern void DrawCircle(int x, int y, int radius, int w, int c, int fill, MMFLOAT aspect);
extern void ClearScreen(int c);
extern void SetFont(int fnt);
extern void ResetDisplay(void);
extern int GetFontWidth(int fnt);
extern int GetFontHeight(int fnt);
//extern char * spritebuffptr[MAXBLITBUF]; //Buffer pointers for the BLIT command
extern int rgb(int r, int g, int b);
extern void (*DrawRectangle)(int x1, int y1, int x2, int y2, int c);
extern void (*DrawBitmap)(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap);
extern void (*ScrollLCD) (int lines);
extern void (*DrawBuffer)(int x1, int y1, int x2, int y2, unsigned char *c);
extern void (*ReadBuffer)(int x1, int y1, int x2, int y2, unsigned char *c);
extern void (*DrawBLITBuffer)(int x1, int y1, int x2, int y2, unsigned char *c);
extern void (*ReadBLITBuffer)(int x1, int y1, int x2, int y2, unsigned char *c);
void DrawPixel16(int x, int y, int c);
void DrawRectangle16(int x1, int y1, int x2, int y2, int c);
void DrawBitmap16(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap);
void ScrollLCD16(int lines);
void DrawBuffer16(int x1, int y1, int x2, int y2, unsigned char *p);
void DrawBuffer16Fast(int x1, int y1, int x2, int y2, int blank, unsigned char *p);
void ReadBuffer16(int x1, int y1, int x2, int y2, unsigned char *c);
void ReadBuffer16Fast(int x1, int y1, int x2, int y2, unsigned char *c);
void DrawPixelNormal(int x, int y, int c) ;
void ReadBuffer2(int x1, int y1, int x2, int y2, unsigned char *c);
void copyframetoscreen(uint8_t *s,int xstart, int xend, int ystart, int yend, int odd);
void restorepanel(void);
#define FONT_BUILTIN_NBR 8
#define FONT_TABLE_SIZE 16
extern void (*DrawPixel)(int x1, int y1, int c);
extern void (*ReadBufferFast)(int x1, int y1, int x2, int y2, unsigned char *c);
extern uint8_t sprite_transparent;
#ifndef PICOMITEVGA
extern void DrawRectangleUser(int x1, int y1, int x2, int y2, int c);
extern void DrawBitmapUser(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap);
#endif
extern void DisplayPutC(char c);
extern void GUIPrintString(int x, int y, int fnt, int jh, int jv, int jo, int fc, int bc, char *str);
extern void DrawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, int c, int fill) ;
extern void cmd_guiMX170(void);
extern void initFonts(void);
extern void ShowCursor(int show);
extern unsigned char *FontTable[16];
extern short CurrentX, CurrentY;
extern int PrintPixelMode;
extern char CMM1;
extern int ScreenSize;
extern char LCDAttrib;
extern uint32_t remap[];
extern void setmode(int mode, bool clear);
typedef struct SVD {
FLOAT3D x;
FLOAT3D y;
FLOAT3D z;
}s_vector;
typedef struct t_quaternion {
FLOAT3D w;
FLOAT3D x;
FLOAT3D y;
FLOAT3D z;
FLOAT3D m;
}s_quaternion;
struct D3D {
s_quaternion* q_vertices;//array of original vertices
s_quaternion* r_vertices; //array of rotated vertices
s_quaternion* q_centroids;//array of original vertices
s_quaternion* r_centroids; //array of rotated vertices
s_vector* normals;
uint8_t* facecount; //number of vertices for each face
uint16_t* facestart; //index into the face_x_vert table of the start of a given face
int32_t* fill; //fill colours
int32_t* line; //line colours
int32_t* colours;
uint16_t* face_x_vert; //list of vertices for each face
uint8_t* flags;
FLOAT3D* dots;
FLOAT3D* depth;
FLOAT3D distance;
FLOAT3D ambient;
int* depthindex;
s_vector light;
s_vector current;
short tot_face_x_vert;
short xmin, xmax, ymin, ymax;
uint16_t nv; //number of vertices to describe the object
uint16_t nf; // number of faces in the object
uint8_t dummy;
uint8_t vmax; // maximum verticies for any face on the object
uint8_t camera; // camera to use for the object
uint8_t nonormals;
};
typedef struct {
FLOAT3D x;
FLOAT3D y;
FLOAT3D z;
FLOAT3D viewplane;
FLOAT3D panx;
FLOAT3D pany;
}s_camera;
extern struct D3D* struct3d[MAX3D + 1];
extern s_camera camera[MAXCAM + 1];
struct spritebuffer {
char* spritebuffptr; //points to the sprite image, set to NULL if not in use
short w;
short h;
char* blitstoreptr; //points to the stored background, set to NULL if not in use
char collisions[MAXCOLLISIONS + 1]; //set to NULL if not in use, otherwise contains current collisions
int64_t master; //bitmask of which sprites are copies
uint64_t lastcollisions;
short x; //set to 1000 if not in use
short y;
short next_x; //set to 1000 if not in use
short next_y;
signed char layer; //defaults to 1 if not specified. If zero then scrolls with background
signed char mymaster; //number of master if this is a copy
char rotation;
char active;
char edges;
};
struct blitbuffer {
char* blitbuffptr; //points to the sprite image, set to NULL if not in use
short w;
short h;
};
extern struct spritebuffer spritebuff[MAXBLITBUF+1];
extern struct blitbuffer blitbuff[MAXBLITBUF+1];
//extern int layer_in_use[MAXLAYER + 1];
extern void closeall3d(void);
extern void closeframebuffer(char layer);
extern void closeallsprites(void);
extern char* COLLISIONInterrupt;
extern bool CollisionFound;
extern void InitDisplayVirtual(void);
extern void ConfigDisplayVirtual(unsigned char *p);
extern void merge(uint8_t colour);
extern void blitmerge (int x0, int y0, int w, int h, uint8_t colour);
extern bool mergerunning;
extern uint32_t mergetimer;
extern int RGB121map[16];
#endif
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,86 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Editor.h
<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.
************************************************************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
void EditInputLine(void);
// General definitions used by other modules
extern unsigned char *StartEditPoint;
extern int StartEditChar;
extern unsigned char *EdBuff; // the buffer used for editing the text
extern int EdBuffSize; // size of the buffer in characters
extern int editactive;
extern int find_longest_line_length(const char *text ,int *linein);
// the values returned by the standard control keys
#define TAB 0x9
#define BKSP 0x8
#define ENTER 0xd
#define ESC 0x1b
// the values returned by the function keys
#define F1 0x91
#define F2 0x92
#define F3 0x93
#define F4 0x94
#define F5 0x95
#define F6 0x96
#define F7 0x97
#define F8 0x98
#define F9 0x99
#define F10 0x9a
#define F11 0x9b
#define F12 0x9c
// the values returned by special control keys
#define UP 0x80
#define DOWN 0x81
#define LEFT 0x82
#define RIGHT 0x83
#define INSERT 0x84
#define DEL 0x7f
#define HOME 0x86
#define END 0x87
#define PUP 0x88
#define PDOWN 0x89
#define NUM_ENT ENTER
#define SLOCK 0x8c
#define ALT 0x8b
// definitions related to setting the tab spacing
#define CONFIG_TAB2 0b111
#define CONFIG_TAB4 0b001
#define CONFIG_TAB8 0b010
//extern const unsigned int TabOption;
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,339 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
External.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
// the format is:
// TEXT TYPE P FUNCTION TO CALL
// where type is T_NA, T_FUN, T_FNA or T_OPER argumented by the types T_STR and/or T_NBR
// and P is the precedence (which is only used for operators)
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
#ifndef EXTERNAL_HEADER
#define EXTERNAL_HEADER
#define NBR_PULSE_SLOTS 5 // number of concurrent pulse commands, each entry is 8 bytes
extern unsigned char *InterruptReturn;
extern int check_interrupt(void);
extern void ClearExternalIO(void);
/* **************************************************************************************************************************
New, more portable, method of manipulating an I/O pin
*****************************************************************************************************************************/
// the basic functions
// set or clear bits in the pin's sfr registers
// some useful defines
////#define PinOpenCollectorOn(x) PinSetBit(x, ODCSET)
#define PinOpenCollectorOff(x) PinSetBit(x, ODCCLR)
#define PinHigh(x) PinSetBit(x, LATSET)
#define PinLow(x) PinSetBit(x, LATCLR)
#define PinSetOutput(x) PinSetBit(x, TRISCLR)
#define PinSetInput(x) PinSetBit(x, TRISSET)
// Define the offsets from the PORT address
#define ANSEL -8
#define ANSELCLR -7
#define ANSELSET -6
#define ANSELINV -5
#define TRIS -4
#define TRISCLR -3
#define TRISSET -2
#define TRISINV -1
//#define PORT 0
#define PORTCLR 1
#define PORTSET 2
#define PORTINV 3
#define LAT 4
#define LATCLR 5
#define LATSET 6
#define LATINV 7
#define ODC 8
#define ODCCLR 9
#define ODCSET 10
#define ODCINV 11
#define CNPU 12
#define CNPUCLR 13
#define CNPUSET 14
#define CNPUINV 15
#define CNPD 16
#define CNPDCLR 17
#define CNPDSET 18
#define CNPDINV 19
#define CNCON 20
#define CNCONCLR 21
#define CNCONSET 22
#define CNCONINV 23
#define CNEN 24
#define CNENCLR 25
#define CNENSET 26
#define CNENINV 27
#define CNSTAT 28
#define CNSTATCLR 29
#define CNSTATSET 30
#define CNSTATINV 31
#define EXT_NOT_CONFIG 0
#define EXT_ANA_IN 1
#define EXT_DIG_IN 2
#define EXT_FREQ_IN 3
#define EXT_PER_IN 4
#define EXT_CNT_IN 5
#define EXT_INT_HI 6
#define EXT_INT_LO 7
#define EXT_DIG_OUT 8
#define EXT_HEARTBEAT 9
#define EXT_INT_BOTH 10
#define EXT_UART0TX 11
#define EXT_UART0RX 12
#define EXT_UART1TX 13
#define EXT_UART1RX 14
#define EXT_I2C0SDA 15
#define EXT_I2C0SCL 16
#define EXT_I2C1SDA 17
#define EXT_I2C1SCL 18
#define EXT_SPI0RX 19
#define EXT_SPI0TX 20
#define EXT_SPI0SCK 21
#define EXT_SPI1RX 22
#define EXT_SPI1TX 23
#define EXT_SPI1SCK 24
#define EXT_IR 25
#define EXT_INT1 26
#define EXT_INT2 27
#define EXT_INT3 28
#define EXT_INT4 29
#define EXT_PWM0A 30
#define EXT_PWM0B 31
#define EXT_PWM1A 32
#define EXT_PWM1B 33
#define EXT_PWM2A 34
#define EXT_PWM2B 35
#define EXT_PWM3A 36
#define EXT_PWM3B 37
#define EXT_PWM4A 38
#define EXT_PWM4B 39
#define EXT_PWM5A 40
#define EXT_PWM5B 41
#define EXT_PWM6A 42
#define EXT_PWM6B 43
#define EXT_PWM7A 44
#define EXT_PWM7B 45
#define EXT_ADCRAW 46
#ifdef rp2350
#define EXT_PWM8A 47
#define EXT_PWM8B 48
#define EXT_PWM9A 49
#define EXT_PWM9B 50
#define EXT_PWM10A 51
#define EXT_PWM10B 52
#define EXT_PWM11A 53
#define EXT_PWM11B 54
#define EXT_PIO0_OUT 55
#define EXT_PIO1_OUT 56
#define EXT_PIO2_OUT 57
#define EXT_FAST_TIMER 58
#else
#define EXT_PIO0_OUT 47
#define EXT_PIO1_OUT 48
#endif
#define EXT_DS18B20_RESERVED 0x100 // this pin is reserved for DS18B20 and cannot be used
#define EXT_COM_RESERVED 0x200 // this pin is reserved and SETPIN and PIN cannot be used
#define EXT_BOOT_RESERVED 0x400 // this pin is reserved at bootup and cannot be used
extern const char *PinFunction[];
extern volatile int ExtCurrentConfig[NBRPINS + 1];
extern volatile int INT0Value, INT0InitTimer, INT0Timer;
extern volatile int INT1Value, INT1InitTimer, INT1Timer;
extern volatile int INT2Value, INT2InitTimer, INT2Timer;
extern volatile int INT3Value, INT3InitTimer, INT3Timer;
extern volatile int INT4Value, INT4InitTimer, INT4Timer;
extern volatile int64_t INT1Count,INT2Count,INT3Count, INT4Count;
extern volatile uint64_t INT5Count, INT5Value, INT5InitTimer, INT5Timer;
extern void PinSetBit(int pin, unsigned int offset);
extern int PinRead(int pin);
extern volatile unsigned int GetPinStatus(int pin);
extern int GetPinBit(int pin);
extern void WriteCoreTimer(unsigned long timeset);
extern unsigned long ReadCoreTimer(void);
extern uint64_t readusclock(void);
extern void writeusclock(uint64_t timeset);
extern uint64_t readIRclock(void);
extern void writeIRclock(uint64_t timeset);
extern void initExtIO(void);
extern void ExtCfg(int pin, int cfg, int option) ;
extern void ExtSet(int pin, int val);
extern int64_t ExtInp(int pin);
extern int IsInvalidPin(int pin);
extern int p100interrupts[];
extern unsigned long ReadCount5(void);
extern void WriteCount5(unsigned long timeset);
extern void SoftReset(void);
extern volatile uint64_t IRoffset;
extern int BacklightSlice,BacklightChannel;
extern void SetADCFreq(float frequency);
#ifndef PICOCALC
extern void setBacklight(int level, int frequency);
#else
extern void setBacklight(int level);
#endif
#ifdef rp2350
extern const uint8_t PINMAP[48];
#else
extern const uint8_t PINMAP[30];
#endif
void gpio_callback(uint gpio, uint32_t events);
// for CheckPin() action can be set to:
#define CP_CHECKALL 0b0000 // abort with an error if invalid, in use or reserved
#define CP_NOABORT 0b0001 // the function will not abort with an error
#define CP_IGNORE_INUSE 0b0010 // the function will ignore pins that are in use (but not including reserved pins)
#define CP_IGNORE_RESERVED 0b0100 // the function will ignore reserved pins (EXT_COM_RESERVED and EXT_BOOT_RESERVED)
#define CP_IGNORE_BOOTRES 0b1000 // the function will ignore the boot reserved pins (EXT_BOOT_RESERVED)
#define setuptime (12-(Option.CPU_Speed-250000)/50000)
#define shortpause(a){systick_hw->cvr=0;asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");while(systick_hw->cvr>a){};}
extern int CheckPin(int pin, int action);
extern unsigned int CFuncInt1;
extern unsigned int CFuncInt2;
extern unsigned int CFuncInt3;
extern unsigned int CFuncInt4;
extern void CallCFuncInt1(void);
extern void CallCFuncInt2(void);
extern void CallCFuncInt3(void);
extern void CallCFuncInt4(void);
extern int InterruptUsed;
typedef enum
{
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;
typedef enum
{
GPIO_PuPd_NOPULL = 0x00,
GPIO_PuPd_UP = 0x01,
GPIO_PuPd_DOWN = 0x02
}GPIOPuPd_TypeDef;
typedef enum
{
GPIO_OType_PP = 0x0,
GPIO_OType_OD = 0x1
}GPIOOType_TypeDef;
// IR related stuff
extern void *IrDev, *IrCmd;
extern volatile char IrVarType, IrState, IrGotMsg;
extern int IrBits, IrCount;
extern unsigned char *IrInterrupt;
extern int codemap(int pin);
extern int codecheck(unsigned char *line);
extern uint8_t PWM0Apin;
extern uint8_t PWM1Apin;
extern uint8_t PWM2Apin;
extern uint8_t PWM3Apin;
extern uint8_t PWM4Apin;
extern uint8_t PWM5Apin;
extern uint8_t PWM6Apin;
extern uint8_t PWM7Apin;
extern uint8_t PWM0Bpin;
extern uint8_t PWM1Bpin;
extern uint8_t PWM2Bpin;
extern uint8_t PWM3Bpin;
extern uint8_t PWM4Bpin;
extern uint8_t PWM5Bpin;
extern uint8_t PWM6Bpin;
extern uint8_t PWM7Bpin;
extern uint8_t UART1RXpin;
extern uint8_t UART1TXpin;
extern uint8_t UART0TXpin;
extern uint8_t UART0RXpin;
extern uint8_t SPI1TXpin;
extern uint8_t SPI1RXpin;
extern uint8_t SPI1SCKpin;
extern uint8_t SPI0TXpin;
extern uint8_t SPI0RXpin;
extern uint8_t SPI0SCKpin;
extern uint8_t I2C1SDApin;
extern uint8_t I2C1SCLpin;
extern uint8_t I2C0SDApin;
extern uint8_t I2C0SCLpin;
extern uint8_t slice0,slice1,slice2,slice3,slice4,slice5,slice6,slice7;
extern uint8_t SPI0locked;
extern uint8_t SPI1locked;
extern uint8_t I2C0locked;
extern uint8_t I2C1locked;
extern volatile int CallBackEnabled;
extern int ADCopen;
extern volatile MMFLOAT * volatile a1float, * volatile a2float, * volatile a3float, * volatile a4float;
extern uint32_t ADCmax;
extern bool dmarunning;
extern bool ADCDualBuffering;
extern char *ADCInterrupt;
extern uint32_t ADC_dma_chan;
extern uint32_t ADC_dma_chan2;
extern short *ADCbuffer;
extern volatile uint8_t *adcint;
extern uint8_t *adcint1;
extern uint8_t *adcint2;
void IrInit(void);
void IrReset(void);
void IRSendSignal(int pin, int half_cycles);
void TM_EXTI_Handler_5(char *buf, uint32_t events);
// numpad declares
extern unsigned char *KeypadInterrupt;
int KeypadCheck(void);
extern MMFLOAT ADCscale[4], ADCbottom[4];
#define IR_CLOSED 0
#define IR_WAIT_START 1
#define IR_WAIT_START_END 2
#define SONY_WAIT_BIT_START 3
#define SONY_WAIT_BIT_END 4
#define NEC_WAIT_FIRST_BIT_START 5
#define NEC_WAIT_BIT_START 7
#define NEC_WAIT_BIT_END 8
#define elapsed readusclock()
#endif
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
FileIO.h
<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.
************************************************************************************************************************/#ifndef __FILEIO_H
#define __FILEIO_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ff.h"
#ifdef rp2350
#include "upng.h"
#endif
// File related I/O
unsigned char MMfputc(unsigned char c, int fnbr);
int MMfgetc(int filenbr);
void MMfopen(unsigned char *fname, unsigned char *mode, int fnbr);
int MMfeof(int filenbr);
void MMfclose(int fnbr);
int FindFreeFileNbr(void);
void CloseAllFiles(void);
void MMgetline(int filenbr, char *p);
void MMPrintString(char *s);
void CheckAbort(void);
char FileGetChar(int fnbr);
void FilePutStr(int count, char *c, int fnbr);
char FilePutChar(char c, int fnbr);
void CheckSDCard(void);
void LoadOptions(void);
void CrunchData(unsigned char **p, int c);
int FileEOF(int fnbr);
void ClearSavedVars(void);
int FileLoadProgram(unsigned char *fname, bool chain);
int FileLoadCMM2Program(char *fname, bool message);
void SaveOptions(void);
void ResetAllFlash(void);
void disable_interrupts_pico(void);
void enable_interrupts_pico(void);
int ForceFileClose(int fnbr);
void ErrorCheck(int fnbr);
extern int OptionFileErrorAbort;
extern unsigned char filesource[MAXOPENFILES + 1];
extern int FatFSFileSystemSave;
extern void positionfile(int fnbr, int idx);
struct option_s {
int Magic;
char Autorun;
char Tab;
char Invert;
char Listcase; //8
//
unsigned int PROG_FLASH_SIZE;
unsigned int HEAP_SIZE;
#ifndef PICOMITEVGA
char Height;
char Width;
#else
short d2;
#endif
unsigned char DISPLAY_TYPE;
char DISPLAY_ORIENTATION; //12=20
//
int PIN;
int Baudrate;
int8_t ColourCode;
unsigned char MOUSE_CLOCK;
unsigned char MOUSE_DATA;
char spare;
int CPU_Speed;
unsigned int Telnet; // used to store the size of the program flash (also start of the LIBRARY code)
int DefaultFC, DefaultBC; // the default colours
short DefaultBrightness; // default backlight brightness //40
unsigned char KEYBOARD_CLOCK;
unsigned char KEYBOARD_DATA;
unsigned char continuation;
unsigned char D1; // dummy
uint16_t D2; // dummy
//
// display related
unsigned char DefaultFont;
unsigned char KeyboardConfig;
unsigned char RTC_Clock;
unsigned char RTC_Data; //4=60
//
#ifdef PICOCALC
uint8_t KEYBOARDBL;
#endif
#ifdef PICOMITE
char dummy[4]; // maximum number of controls allowed //64
#endif
#ifdef PICOMITEWEB
uint16_t TCP_PORT; // maximum number of controls allowed //64
uint16_t ServerResponceTime;
#endif
#ifdef PICOMITEVGA
int16_t X_TILE; // maximum number of controls allowed //64
int16_t Y_TILE; // maximum number of controls allowed //64
#endif
// for the SPI LCDs 4=64
unsigned char LCD_CD;
unsigned char LCD_CS;
unsigned char LCD_Reset;
// touch related
unsigned char TOUCH_CS;
unsigned char TOUCH_IRQ;
char TOUCH_SWAPXY;
unsigned char repeat;
char disabletftp;//56 8=72
#ifndef PICOMITEVGA
int TOUCH_XZERO;
int TOUCH_YZERO;
float TOUCH_XSCALE;
float TOUCH_YSCALE; //72 16=88
#else
short Height;
short Width;
char dummy[12];
#endif
#ifdef GUICONTROLS
int MaxCtrls;
#else
uint8_t HDMIclock;
uint8_t HDMId0;
uint8_t HDMId1;
uint8_t HDMId2;
#endif
unsigned int FlashSize; //8=96
unsigned char SD_CS;
unsigned char SYSTEM_MOSI;
unsigned char SYSTEM_MISO;
unsigned char SYSTEM_CLK;
unsigned char DISPLAY_BL;
unsigned char DISPLAY_CONSOLE;
unsigned char TOUCH_Click;
char LCD_RD; // used for the RD pin for SSD1963 //8=104
unsigned char AUDIO_L;
unsigned char AUDIO_R;
unsigned char AUDIO_SLICE;
unsigned char SDspeed;
unsigned char pins[3]; //20=116 // general use storage for CFunctions written by PeterM //86
unsigned char TOUCH_CAP;
unsigned char SSD_DATA;
unsigned char THRESHOLD_CAP;
unsigned char audio_i2s_data;
unsigned char audio_i2s_bclk;
char LCDVOP;
char I2Coffset;
unsigned char NoHeartbeat;
char Refresh;
unsigned char SYSTEM_I2C_SDA;
unsigned char SYSTEM_I2C_SCL;
unsigned char RTC;
char PWM; //8=124
unsigned char INT1pin;
unsigned char INT2pin;
unsigned char INT3pin;
unsigned char INT4pin;
unsigned char SD_CLK_PIN;
unsigned char SD_MOSI_PIN;
unsigned char SD_MISO_PIN;
unsigned char SerialConsole; //8=132
unsigned char SerialTX;
unsigned char SerialRX;
unsigned char numlock;
unsigned char capslock; //4=136
unsigned int LIBRARY_FLASH_SIZE; // 4=140
unsigned char AUDIO_CLK_PIN;
unsigned char AUDIO_MOSI_PIN;
unsigned char SYSTEM_I2C_SLOW;
unsigned char AUDIO_CS_PIN; //4=144
#ifdef PICOMITEWEB
uint16_t UDP_PORT; // maximum number of controls allowed //48
uint16_t UDPServerResponceTime;
char hostname[32];
char ipaddress[16];
char mask[16];
char gateway[16];
#else
unsigned char x[84]; //85=229
#endif
unsigned char heartbeatpin;
unsigned char PSRAM_CS_PIN;
unsigned char BGR;
unsigned char NoScroll;
unsigned char CombinedCS;
unsigned char USBKeyboard;
unsigned char VGA_HSYNC;
unsigned char VGA_BLUE; //7=236
unsigned char AUDIO_MISO_PIN;
unsigned char AUDIO_DCS_PIN;
unsigned char AUDIO_DREQ_PIN;
unsigned char AUDIO_RESET_PIN;
unsigned char SSD_DC;
unsigned char SSD_WR;
unsigned char SSD_RD;
signed char SSD_RESET; //8=244
unsigned char BackLightLevel;
unsigned char NoReset;
unsigned char AllPins;
unsigned char modbuff; //4=248
short RepeatStart;
short RepeatRate;
int modbuffsize; //8=256
unsigned char F1key[MAXKEYLEN];
unsigned char F5key[MAXKEYLEN];
unsigned char F6key[MAXKEYLEN];
unsigned char F7key[MAXKEYLEN];
unsigned char F8key[MAXKEYLEN];
unsigned char F9key[MAXKEYLEN];
unsigned char SSID[MAXKEYLEN];
unsigned char PASSWORD[MAXKEYLEN]; //512=768
unsigned char platform[32];
unsigned char extensions[96]; //128=896 == 7 XMODEM blocks
// To enable older CFunctions to run any new options *MUST* be added at the end of the list
} __attribute__((packed));
extern unsigned char *CFunctionFlash, *CFunctionLibrary;
extern struct option_s Option;
extern int FlashLoad;
extern void ResetOptions(bool startup);
extern void FlashWriteBlock(void);
extern void FlashWriteWord(unsigned int i);
extern void FlashWriteByte(unsigned char b);
extern void FlashWriteAlign(void);
extern void FlashWriteClose(void);
extern void FlashWriteInit(int region);
void FlashSetAddress(int address); //new
extern void FlashWriteAlignWord(void); //new
extern void ResetFlashStorage(int umount);
extern volatile uint32_t realflashpointer;
extern int drivecheck(char *p, int *waste);
extern void getfullfilename(char *fname, char *q);
extern char *GetCWD(void);
extern int FSerror;
extern int lfs_FileFnbr;
extern struct lfs_config pico_lfs_cfg;
#define SAVED_OPTIONS_FLASH 5
#define LIBRARY_FLASH 6
#define SAVED_VARS_FLASH 7
#define PROGRAM_FLASH 8
typedef union uFileTable
{
unsigned int com;
FIL *fptr;
lfs_file_t *lfsptr;
}u_file;
enum {
NONEFILE,
FLASHFILE,
FATFSFILE
};
extern union uFileTable FileTable[MAXOPENFILES + 1];
#ifdef __cplusplus
}
#endif
#endif /* __FILEIO_H */
/* @endcond */

View File

@ -0,0 +1,238 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// Fnt_10x16.c
// Font type : Full (224 characters)
// Font size : 10x16 pixels
// Memory usage : 4484 bytes
//const unsigned char Fnt_10x16[4564] = {
const unsigned char Fnt_10x16[4484] ={
0x0A,0x10,0x20,0xE0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(32)
0x00,0x00,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x08,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(33) !
0x00,0x04,0x81,0x20,0x48,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(34) "
0x00,0x00,0x00,0x00,0x88,0x22,0x1F,0xC2,0x20,0x88,0x22,0x1F,0xC2,0x20,0x88,0x00,0x00,0x00,0x00,0x00, // Chr$(35) #
0x00,0x02,0x00,0x80,0xF8,0x49,0x12,0x04,0x00,0xF8,0x01,0x02,0x44,0x90,0xF8,0x08,0x02,0x00,0x00,0x00, // Chr$(36) $
0x00,0x00,0x00,0x00,0xC0,0x79,0x0C,0x80,0x40,0x20,0x10,0x09,0x84,0xF0,0x18,0x00,0x00,0x00,0x00,0x00, // Chr$(37) %
0x00,0x00,0x01,0x80,0x90,0x24,0x09,0x01,0x90,0x94,0x42,0x10,0x84,0x20,0xF4,0x00,0x00,0x00,0x00,0x00, // Chr$(38) &
0x00,0x01,0x00,0x40,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(39) '
0x00,0x00,0x00,0x40,0x20,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x00, // Chr$(40) (
0x00,0x00,0x01,0x00,0x20,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x80,0x40,0x00,0x00,0x00,0x00,0x00, // Chr$(41) )
0x00,0x00,0x00,0x00,0x00,0x08,0x0A,0x81,0xC1,0xFC,0x1C,0x0A,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(42) *
0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x81,0xFC,0x08,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(43) +
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x10,0x04,0x02,0x00,0x00,0x00, // Chr$(44) ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(45) -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x00,0x00,0x00,0x00,0x00, // Chr$(46) .
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(47) /
0x00,0x00,0x01,0xC0,0x88,0x41,0x10,0x44,0x91,0x24,0x41,0x10,0x42,0x20,0x70,0x00,0x00,0x00,0x00,0x00, // Chr$(48) 0
0x00,0x00,0x00,0x80,0x60,0x28,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(49) 1
0x00,0x00,0x03,0xE1,0x04,0x01,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(50) 2
0x00,0x00,0x03,0xE1,0x04,0x01,0x00,0x41,0xE0,0x04,0x01,0x00,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(51) 3
0x00,0x00,0x00,0x20,0x18,0x0A,0x04,0x82,0x21,0x08,0x7F,0x00,0x80,0x20,0x08,0x00,0x00,0x00,0x00,0x00, // Chr$(52) 4
0x00,0x00,0x07,0xF1,0x00,0x40,0x10,0x07,0xE1,0x04,0x01,0x00,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(53) 5
0x00,0x00,0x03,0xE1,0x00,0x40,0x10,0x07,0xE1,0x04,0x41,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(54) 6
0x00,0x00,0x07,0xF0,0x04,0x01,0x00,0x80,0x40,0x20,0x08,0x02,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(55) 7
0x00,0x00,0x03,0xE1,0x04,0x41,0x08,0x83,0xE1,0x04,0x41,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(56) 8
0x00,0x00,0x03,0xE1,0x04,0x41,0x10,0x44,0x10,0xFC,0x01,0x00,0x40,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(57) 9
0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(58) :
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x00,0x40,0x10,0x04,0x02,0x00,0x00,0x00, // Chr$(59) ;
0x00,0x00,0x00,0x00,0x08,0x04,0x02,0x01,0x00,0x80,0x10,0x02,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0x00, // Chr$(60) <
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC0,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(61) =
0x00,0x00,0x00,0x00,0x80,0x10,0x02,0x00,0x40,0x08,0x04,0x02,0x01,0x00,0x80,0x00,0x00,0x00,0x00,0x00, // Chr$(62) >
0x00,0x00,0x03,0xE1,0x04,0x41,0x00,0x40,0x60,0x20,0x08,0x00,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(63) ?
0x00,0x00,0x03,0xE1,0x04,0x41,0x17,0x45,0x51,0x54,0x4E,0x10,0x04,0x00,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(64) @
0x00,0x00,0x01,0xC0,0x88,0x41,0x10,0x44,0x11,0xFC,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(65) A
0x00,0x00,0x07,0xE1,0x04,0x41,0x10,0x47,0xE1,0x04,0x41,0x10,0x44,0x11,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(66) B
0x00,0x00,0x03,0xE1,0x04,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(67) C
0x00,0x00,0x07,0xC1,0x08,0x41,0x10,0x44,0x11,0x04,0x41,0x10,0x44,0x21,0xF0,0x00,0x00,0x00,0x00,0x00, // Chr$(68) D
0x00,0x00,0x07,0xF1,0x00,0x40,0x10,0x07,0xE1,0x00,0x40,0x10,0x04,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(69) E
0x00,0x00,0x07,0xF1,0x00,0x40,0x10,0x07,0xE1,0x00,0x40,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(70) F
0x00,0x00,0x03,0xE1,0x04,0x40,0x10,0x04,0xF1,0x04,0x41,0x10,0x44,0x10,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(71) G
0x00,0x00,0x04,0x11,0x04,0x41,0x10,0x47,0xF1,0x04,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(72) H
0x00,0x00,0x03,0xE0,0x20,0x08,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(73) I
0x00,0x00,0x01,0xF0,0x08,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x84,0x20,0xF0,0x00,0x00,0x00,0x00,0x00, // Chr$(74) J
0x00,0x00,0x04,0x21,0x10,0x48,0x14,0x06,0x01,0x40,0x48,0x11,0x04,0x21,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(75) K
0x00,0x00,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(76) L
0x00,0x00,0x04,0x11,0x8C,0x55,0x12,0x44,0x91,0x04,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(77) M
0x00,0x00,0x04,0x11,0x84,0x51,0x12,0x44,0x51,0x0C,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(78) N
0x00,0x00,0x03,0xE1,0x04,0x41,0x10,0x44,0x11,0x04,0x41,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(79) O
0x00,0x00,0x07,0xE1,0x04,0x41,0x10,0x47,0xE1,0x00,0x40,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(80) P
0x00,0x00,0x03,0xE1,0x04,0x41,0x10,0x44,0x11,0x04,0x49,0x12,0x44,0x90,0xF8,0x04,0x00,0x80,0x00,0x00, // Chr$(81) Q
0x00,0x00,0x07,0xE1,0x04,0x41,0x10,0x47,0xE1,0x08,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(82) R
0x00,0x00,0x03,0xE1,0x04,0x40,0x0C,0x01,0x80,0x18,0x01,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(83) S
0x00,0x00,0x07,0xF0,0x20,0x08,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(84) T
0x00,0x00,0x04,0x11,0x04,0x41,0x10,0x44,0x11,0x04,0x41,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(85) U
0x00,0x00,0x04,0x11,0x04,0x41,0x10,0x44,0x11,0x04,0x41,0x08,0x81,0x40,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(86) V
0x00,0x00,0x04,0x11,0x04,0x41,0x10,0x44,0x11,0x24,0x49,0x12,0x45,0x50,0x88,0x00,0x00,0x00,0x00,0x00, // Chr$(87) W
0x00,0x00,0x04,0x11,0x04,0x22,0x05,0x00,0x80,0x50,0x22,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(88) X
0x00,0x00,0x04,0x11,0x04,0x41,0x08,0x81,0x40,0x20,0x08,0x02,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(89) Y
0x00,0x00,0x07,0xF0,0x04,0x02,0x01,0x00,0x80,0x40,0x20,0x10,0x04,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(90) Z
0x00,0x00,0x01,0xC0,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x70,0x00,0x00,0x00,0x00,0x00, // Chr$(91) [
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,0x00,0x40,0x08,0x01,0x00,0x20,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(92) backslash
0x00,0x00,0x01,0xC0,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x70,0x00,0x00,0x00,0x00,0x00, // Chr$(93) ]
0x08,0x05,0x02,0x21,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(94) ^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC0,0x00,0x00, // Chr$(95) _
0x00,0x07,0x02,0x20,0x88,0x22,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(96) `
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x20,0x08,0x3E,0x10,0x84,0x20,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(97) a
0x00,0x00,0x04,0x01,0x00,0x40,0x17,0x86,0x11,0x04,0x41,0x10,0x44,0x11,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(98) b
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x84,0x11,0x00,0x40,0x10,0x04,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(99) c
0x00,0x00,0x00,0x10,0x04,0x01,0x0F,0x44,0x31,0x04,0x41,0x10,0x44,0x10,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(100) d
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x84,0x11,0x04,0x7F,0x10,0x04,0x00,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(101) e
0x00,0x00,0x00,0x70,0x20,0x08,0x0F,0x80,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(102) f
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC4,0x11,0x04,0x41,0x10,0x44,0x30,0xF4,0x01,0x00,0x43,0xE0,0x00, // Chr$(103) g
0x00,0x00,0x04,0x01,0x00,0x40,0x17,0x86,0x11,0x04,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(104) h
0x00,0x00,0x00,0x80,0x20,0x00,0x0E,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(105) i
0x00,0x00,0x00,0x20,0x08,0x00,0x03,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x81,0xC0,0x00, // Chr$(106) j
0x00,0x00,0x04,0x01,0x00,0x40,0x10,0xC4,0xC1,0xC0,0x48,0x11,0x04,0x21,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(107) k
0x00,0x00,0x03,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x38,0x00,0x00,0x00,0x00,0x00, // Chr$(108) l
0x00,0x00,0x00,0x00,0x00,0x00,0x1D,0x84,0x91,0x24,0x49,0x12,0x44,0x91,0x24,0x00,0x00,0x00,0x00,0x00, // Chr$(109) m
0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x86,0x11,0x04,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(110) n
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x84,0x11,0x04,0x41,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(111) o
0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x86,0x11,0x04,0x41,0x10,0x46,0x11,0x78,0x40,0x10,0x04,0x00,0x00, // Chr$(112) p
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC4,0x11,0x04,0x41,0x10,0x44,0x30,0xF4,0x01,0x00,0x40,0x10,0x00, // Chr$(113) q
0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x86,0x11,0x00,0x40,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(114) r
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC4,0x01,0x00,0x3E,0x00,0x40,0x11,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(115) s
0x00,0x00,0x00,0x00,0x20,0x08,0x0F,0xC0,0x80,0x20,0x08,0x02,0x00,0x80,0x1C,0x00,0x00,0x00,0x00,0x00, // Chr$(116) t
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x44,0x11,0x04,0x41,0x10,0x44,0x30,0xF4,0x00,0x00,0x00,0x00,0x00, // Chr$(117) u
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x44,0x11,0x04,0x41,0x08,0x81,0x40,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(118) v
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x44,0x11,0x04,0x49,0x12,0x44,0x90,0xD8,0x00,0x00,0x00,0x00,0x00, // Chr$(119) w
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x42,0x20,0x50,0x08,0x05,0x02,0x21,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(120) x
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x44,0x11,0x04,0x41,0x10,0x44,0x30,0xF4,0x01,0x00,0x43,0xE0,0x00, // Chr$(121) y
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC0,0x20,0x10,0x08,0x04,0x02,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(122) z
0x00,0x00,0x00,0x60,0x20,0x08,0x02,0x03,0x00,0x20,0x08,0x02,0x00,0x80,0x18,0x00,0x00,0x00,0x00,0x00, // Chr$(123) {
0x00,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0x00, // Chr$(124) |
0x00,0x00,0x03,0x00,0x20,0x08,0x02,0x00,0x60,0x20,0x08,0x02,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0x00, // Chr$(125) }
0x00,0x00,0x03,0x11,0x24,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(126) ~
0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x40,0x88,0x41,0x10,0x44,0x11,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(127)
0x00,0x00,0x0F,0xFE,0x01,0x80,0x60,0x18,0x06,0x01,0x80,0x60,0x18,0x06,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(128)
0x00,0x00,0x0F,0xFE,0x01,0x80,0x60,0x58,0x16,0x09,0x94,0x62,0x18,0x06,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(129)
0x00,0x00,0x0F,0xFE,0x01,0xA1,0x64,0x98,0xC6,0x31,0x8C,0x64,0x9A,0x16,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(130)
0x00,0x00,0x0F,0xFE,0x01,0x80,0x60,0x18,0xC6,0x31,0x8C,0x60,0x18,0x06,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(131)
0x00,0x00,0x0F,0xFE,0x01,0x80,0x60,0x18,0x06,0x01,0x80,0x6F,0xD8,0x06,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(132)
0x00,0x00,0x0F,0xFE,0x01,0x8C,0x63,0x18,0xC6,0x31,0x8C,0x60,0x18,0xC6,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(133)
0x00,0x00,0x0F,0xFE,0x01,0x8C,0x64,0x98,0x26,0x11,0x84,0x60,0x18,0x46,0x01,0xFF,0xC0,0x00,0x00,0x00, // Chr$(134)
0x00,0x00,0x03,0xE1,0xFC,0x7F,0x1A,0xC7,0xF1,0xFC,0x63,0x1D,0xC7,0xF0,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(135)
0x00,0x00,0x03,0xE1,0x04,0x41,0x15,0x44,0x11,0x04,0x5D,0x12,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(136)
0x00,0x00,0x00,0x00,0x00,0x08,0x07,0x03,0xE1,0xFC,0x3E,0x07,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(137)
0x00,0x00,0x00,0x00,0x00,0x1C,0x07,0x01,0xC1,0xDC,0x77,0x1D,0xC0,0x80,0x70,0x00,0x00,0x00,0x00,0x00, // Chr$(138)
0x00,0x00,0x00,0x00,0x00,0x08,0x07,0x03,0xE1,0xFC,0x7F,0x0A,0x80,0x80,0x70,0x00,0x00,0x00,0x00,0x00, // Chr$(139)
0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x87,0xF1,0xFC,0x3E,0x07,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(140)
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x7C,0xCF,0x7B,0xDE,0xF3,0x3E,0x1F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // Chr$(141)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x78,0x1E,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(142)
0x00,0x00,0x00,0xF0,0x24,0x0F,0x02,0x00,0x80,0x20,0x08,0x1E,0x07,0x81,0xC0,0x00,0x00,0x00,0x00,0x00, // Chr$(143)
0x00,0x00,0x00,0x80,0x70,0x2A,0x12,0x40,0x80,0x20,0x49,0x0A,0x81,0xC0,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(144)
0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x82,0x11,0xFE,0x21,0x04,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(145)
0x00,0x00,0x00,0x80,0x70,0x2A,0x12,0x40,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(146)
0x00,0x00,0x00,0x80,0x20,0x08,0x02,0x00,0x80,0x20,0x49,0x0A,0x81,0xC0,0x20,0x00,0x00,0x00,0x00,0x00, // Chr$(147)
0x00,0x00,0x00,0x00,0x00,0x08,0x01,0x00,0x21,0xFC,0x02,0x01,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(148)
0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x02,0x01,0xFC,0x20,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(149)
0x00,0x00,0x00,0x80,0x20,0x2A,0x12,0x44,0x91,0x24,0x49,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(150)
0x00,0x07,0x82,0x11,0x02,0x5E,0x93,0x24,0xC8,0xB4,0x1E,0x00,0x01,0xE0,0x00,0x1E,0x00,0x00,0x00,0x00, // Chr$(151)
0x00,0x03,0x00,0xC0,0x00,0x1E,0x07,0x81,0xE0,0x78,0x0C,0x03,0x00,0xC0,0x30,0x0C,0x00,0x00,0x00,0x00, // Chr$(152)
0x00,0x1F,0x04,0x61,0x7C,0x47,0x9D,0xE4,0x19,0xEA,0x7A,0x9E,0xA7,0x99,0xFE,0x00,0x00,0x00,0x00,0x00, // Chr$(153)
0x00,0x03,0x01,0x20,0x84,0x21,0x08,0x42,0x10,0xFC,0x3F,0x04,0x81,0x20,0x48,0x12,0x00,0x00,0x00,0x00, // Chr$(154)
0x00,0x03,0x01,0xE0,0xFC,0x3F,0x0F,0xC3,0xF0,0xFC,0x3F,0x04,0x81,0x20,0x48,0x12,0x00,0x00,0x00,0x00, // Chr$(155)
0x00,0x00,0x01,0x00,0xC8,0x71,0x1D,0x27,0x29,0xCA,0x74,0x9C,0x43,0x20,0x40,0x00,0x00,0x00,0x00,0x00, // Chr$(156)
0x00,0x00,0x03,0xF1,0x2C,0x4B,0x12,0xC4,0xB0,0xEC,0x0B,0x02,0xC0,0xB0,0x2C,0x00,0x00,0x00,0x00,0x00, // Chr$(157)
0x00,0x00,0x03,0xF0,0x88,0x24,0x0D,0xC1,0x20,0x50,0x28,0x0C,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(158)
0x00,0x00,0x00,0x00,0x42,0x1B,0x03,0xC1,0xE1,0xFC,0x0D,0x82,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(159)
0x00,0x00,0x01,0xE0,0x84,0x40,0x94,0xA5,0x29,0x4A,0x52,0x90,0x22,0x10,0x78,0x00,0x00,0x00,0x00,0x00, // Chr$(160)
0x00,0x00,0x01,0xE0,0x84,0x48,0x93,0x24,0xE9,0x32,0x48,0x90,0x22,0x10,0x78,0x00,0x00,0x00,0x00,0x00, // Chr$(161)
0x00,0x00,0x01,0xE0,0x84,0x40,0x97,0xA5,0xE9,0x7A,0x5E,0x90,0x22,0x10,0x78,0x00,0x00,0x00,0x00,0x00, // Chr$(162)
0x00,0x00,0x00,0x00,0xE0,0x44,0x11,0x04,0x40,0xF0,0x06,0x00,0xC0,0x18,0x02,0x00,0x00,0x00,0x00,0x00, // Chr$(163)
0x00,0x00,0x00,0x60,0x20,0x10,0x0F,0x81,0x00,0x40,0x3E,0x04,0x00,0x80,0x18,0x00,0x00,0x00,0x00,0x00, // Chr$(164)
0x00,0x00,0x00,0xD0,0x4C,0x21,0x10,0x22,0x10,0x84,0x21,0x08,0x42,0x10,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(165)
0x00,0x00,0x01,0xE0,0x48,0x7F,0x88,0x42,0x10,0x84,0x21,0x08,0x42,0x10,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(166)
0x00,0x00,0x01,0xC1,0x8C,0x41,0x20,0x28,0x0B,0x06,0xC1,0x90,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(167)
0x00,0x00,0x0F,0xFE,0x01,0x80,0x60,0x18,0x06,0x01,0x80,0x7F,0xF0,0xC0,0x30,0x1E,0x00,0x00,0x00,0x00, // Chr$(168)
0x00,0x00,0x00,0xC0,0x78,0x1E,0x07,0x81,0xE0,0x78,0x0C,0x03,0x00,0x00,0x30,0x0C,0x00,0x00,0x00,0x00, // Chr$(169)
0x00,0x05,0x02,0xB0,0x82,0x41,0x9F,0xC0,0x60,0x20,0x08,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(170)
0x00,0x00,0x01,0x80,0x90,0x24,0x09,0x02,0x50,0x64,0x01,0x00,0x40,0x10,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(171)
0x00,0x03,0x01,0x20,0xCC,0x6D,0x8C,0xC0,0xC0,0x30,0x1C,0x03,0x01,0xC0,0x30,0x1C,0x00,0x00,0x00,0x00, // Chr$(172)
0x00,0x3F,0xF0,0x03,0xFF,0x00,0x3F,0xF0,0x03,0xFF,0x00,0x3F,0xF0,0x03,0xFF,0x00,0x3F,0xF0,0x03,0xFF, // Chr$(173)
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55, // Chr$(174)
0xCC,0xF3,0x33,0x30,0xCC,0xCC,0xF3,0x33,0x30,0xCC,0xCC,0xF3,0x33,0x30,0xCC,0xCC,0xF3,0x33,0x30,0xCC, // Chr$(175)
0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11, // Chr$(176)
0xAA,0x95,0x5A,0xA9,0x55,0xAA,0x95,0x5A,0xA9,0x55,0xAA,0x95,0x5A,0xA9,0x55,0xAA,0x95,0x5A,0xA9,0x55, // Chr$(177)
0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // Chr$(178)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(179)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x43,0xF0,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(180)
0x04,0x01,0x00,0x40,0x10,0x04,0x3F,0x00,0x43,0xF0,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(181)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x23,0xC8,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(182)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF8,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(183)
0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x43,0xF0,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(184)
0x12,0x04,0x81,0x20,0x48,0x12,0x3C,0x80,0x23,0xC8,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(185)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(186)
0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x23,0xC8,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(187)
0x12,0x04,0x81,0x20,0x48,0x12,0x3C,0x80,0x23,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(188)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x23,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(189)
0x04,0x01,0x00,0x40,0x10,0x04,0x3F,0x00,0x43,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(190)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(191)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(192)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x43,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(193)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(194)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x1F,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(195)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(196)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x43,0xFF,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(197)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0xF0,0x40,0x1F,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(198)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x4F,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(199)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0xF1,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(200)
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF1,0x00,0x4F,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(201)
0x12,0x04,0x81,0x20,0x48,0x12,0x3C,0xF0,0x03,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(202)
0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x03,0xCF,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(203)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0xF1,0x00,0x4F,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(204)
0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x03,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(205)
0x12,0x04,0x81,0x20,0x48,0x12,0x3C,0xF0,0x03,0xCF,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(206)
0x04,0x01,0x00,0x40,0x10,0x04,0x3F,0xF0,0x03,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(207)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x23,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(208)
0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x03,0xFF,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(209)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(210)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(211)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0xF0,0x40,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(212)
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xF0,0x40,0x1F,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(213)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(214)
0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x23,0xFF,0x12,0x04,0x81,0x20,0x48,0x12,0x04,0x81,0x20,0x48, // Chr$(215)
0x04,0x01,0x00,0x40,0x10,0x04,0x3F,0xF0,0x43,0xFF,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(216)
0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x43,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(217)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10, // Chr$(218)
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // Chr$(219)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // Chr$(220)
0x1E,0x07,0x81,0xE0,0x78,0x1E,0x07,0x81,0xE0,0x78,0x1E,0x07,0x81,0xE0,0x78,0x1E,0x07,0x81,0xE0,0x78, // Chr$(221)
0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F,0x07,0xC1,0xF0,0x7C,0x1F, // Chr$(222)
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(223)
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x84,0x41,0x10,0x44,0x11,0x04,0x40,0xEC,0x00,0x00,0x00,0x00,0x00, // Chr$(224)
0x00,0x00,0x01,0xC0,0x88,0x42,0x10,0x84,0xC1,0x08,0x41,0x10,0x44,0x11,0x38,0x40,0x10,0x00,0x00,0x00, // Chr$(225)
0x00,0x00,0x07,0xF1,0x00,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(226)
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC2,0x20,0x88,0x22,0x08,0x82,0x20,0x84,0x00,0x00,0x00,0x00,0x00, // Chr$(227)
0x00,0x00,0x07,0xF0,0x80,0x10,0x02,0x00,0x40,0x20,0x10,0x08,0x04,0x01,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(228)
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC4,0x41,0x08,0x42,0x10,0x84,0x20,0xF0,0x00,0x00,0x00,0x00,0x00, // Chr$(229)
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0x21,0x08,0x42,0x10,0x86,0x21,0x74,0x40,0x10,0x04,0x00,0x00, // Chr$(230)
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC4,0x80,0x20,0x08,0x02,0x00,0x80,0x18,0x00,0x00,0x00,0x00,0x00, // Chr$(231)
0x00,0x00,0x03,0xF0,0x00,0x1E,0x08,0x42,0x10,0x84,0x21,0x07,0x80,0x00,0xFC,0x00,0x00,0x00,0x00,0x00, // Chr$(232)
0x00,0x00,0x01,0xC0,0x88,0x41,0x10,0x47,0xF1,0x04,0x41,0x10,0x42,0x20,0x70,0x00,0x00,0x00,0x00,0x00, // Chr$(233)
0x00,0x00,0x01,0xC0,0x88,0x41,0x10,0x44,0x11,0x04,0x41,0x08,0x81,0x41,0xDC,0x00,0x00,0x00,0x00,0x00, // Chr$(234)
0x00,0x00,0x03,0xE0,0x80,0x10,0x02,0x03,0xC1,0x08,0x41,0x10,0x44,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(235)
0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x84,0x91,0x24,0x49,0x0D,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(236)
0x00,0x00,0x00,0x00,0x04,0x02,0x0D,0x84,0xD1,0x24,0x59,0x0D,0x82,0x01,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(237)
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x84,0x11,0x00,0x3C,0x10,0x04,0x10,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(238)
0x00,0x00,0x00,0x00,0xF8,0x41,0x10,0x44,0x11,0x04,0x41,0x10,0x44,0x11,0x04,0x00,0x00,0x00,0x00,0x00, // Chr$(239)
0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x01,0xFC,0x00,0x00,0x07,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(240)
0x00,0x00,0x00,0x80,0x20,0x08,0x1F,0xC0,0x80,0x20,0x08,0x00,0x07,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(241)
0x00,0x00,0x00,0x00,0x40,0x08,0x01,0x00,0x20,0x10,0x08,0x04,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(242)
0x00,0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x00,0x40,0x08,0x01,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00, // Chr$(243)
0x00,0x08,0x02,0x00,0x84,0x22,0x09,0x00,0x80,0x40,0x20,0x03,0x80,0x10,0x08,0x04,0x03,0xC0,0x00,0x00, // Chr$(244)
0x00,0x08,0x02,0x00,0x80,0x21,0x08,0x80,0x40,0x20,0x11,0x08,0xC0,0x50,0x3C,0x01,0x00,0x40,0x00,0x00, // Chr$(245)
0x00,0x00,0x00,0x00,0x00,0x08,0x02,0x00,0x01,0xFC,0x00,0x02,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(246)
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x42,0x60,0x00,0x19,0x09,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(247)
0x00,0x04,0x01,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(248)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(249)
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(250)
0x00,0x01,0xC0,0x40,0x10,0x04,0x01,0x00,0x40,0x10,0x64,0x05,0x00,0xC0,0x10,0x00,0x00,0x00,0x00,0x00, // Chr$(251)
0x00,0x0B,0x81,0x10,0x44,0x11,0x04,0x41,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(252)
0x00,0x03,0x01,0x20,0x08,0x04,0x02,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(253)
0x00,0x00,0x00,0x00,0x00,0x3F,0x0F,0xC3,0xF0,0xFC,0x3F,0x0F,0xC3,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(254)
0x00,0x00,0x00,0x81,0x24,0x3E,0x08,0x84,0x11,0x04,0x41,0x08,0x83,0xE1,0x24,0x08,0x00,0x00,0x00,0x00 // Chr$(255)
};
/* @endcond */

View File

@ -0,0 +1,110 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
const unsigned char F_6x8_LE[580] = {
0x06,0x08,0x20,0x60,
0x00,0x00,0x00,0x00,0x00,0x00, // Chr$(32)
0x20,0x82,0x08,0x00,0x82,0x00, // Chr$(33) !
0x51,0x45,0x00,0x00,0x00,0x00, // Chr$(34) "
0x51,0x4F,0x94,0xF9,0x45,0x00, // Chr$(35) #
0x21,0xEA,0x1C,0x2B,0xC2,0x00, // Chr$(36) $
0x00,0x69,0x90,0x20,0x4C,0xB0, // Chr$(37) %
0x62,0x4A,0x10,0xAA,0x46,0x80, // Chr$(38) &
0x60,0x84,0x00,0x00,0x00,0x00, // Chr$(39) '
0x10,0x84,0x10,0x40,0x81,0x00, // Chr$(40) (
0x40,0x81,0x04,0x10,0x84,0x00, // Chr$(41) )
0x00,0x8A,0x9C,0xA8,0x80,0x00, // Chr$(42) *
0x00,0x82,0x3E,0x20,0x80,0x00, // Chr$(43) +
0x00,0x00,0x00,0x30,0x42,0x00, // Chr$(44) ,
0x00,0x00,0x3E,0x00,0x00,0x00, // Chr$(45) -
0x00,0x00,0x00,0x01,0x86,0x00, // Chr$(46) .
0x00,0x21,0x08,0x42,0x00,0x00, // Chr$(47) /
0x72,0x29,0xAA,0xCA,0x27,0x00, // Chr$(48) 0
0x21,0x82,0x08,0x20,0x87,0x00, // Chr$(49) 1
0x72,0x20,0x84,0x21,0x0F,0x80, // Chr$(50) 2
0xF8,0x42,0x04,0x0A,0x27,0x00, // Chr$(51) 3
0x10,0xC5,0x24,0xF8,0x41,0x00, // Chr$(52) 4
0xFA,0x0F,0x02,0x0A,0x27,0x00, // Chr$(53) 5
0x31,0x08,0x3C,0x8A,0x27,0x00, // Chr$(54) 6
0xF8,0x21,0x08,0x41,0x04,0x00, // Chr$(55) 7
0x72,0x28,0x9C,0x8A,0x27,0x00, // Chr$(56) 8
0x72,0x28,0x9E,0x08,0x27,0x00, // Chr$(57) 9
0x01,0x86,0x00,0x61,0x80,0x00, // Chr$(58) :
0x01,0x86,0x00,0x60,0x84,0x00, // Chr$(59) ;
0x10,0x84,0x20,0x40,0x81,0x00, // Chr$(60) <
0x00,0x0F,0x80,0xF8,0x00,0x00, // Chr$(61) =
0x40,0x81,0x02,0x10,0x84,0x00, // Chr$(62) >
0x72,0x20,0x84,0x20,0x02,0x00, // Chr$(63) ?
0x72,0x20,0x9A,0xBA,0x27,0x00, // Chr$(64) @
0x72,0x28,0xA2,0xFA,0x28,0x80, // Chr$(65) A
0xF2,0x28,0xBC,0x8A,0x2F,0x00, // Chr$(66) B
0x72,0x28,0x20,0x82,0x27,0x00, // Chr$(67) C
0xE2,0x48,0xA2,0x8A,0x4E,0x00, // Chr$(68) D
0xFA,0x08,0x3C,0x82,0x0F,0x80, // Chr$(69) E
0xFA,0x08,0x3C,0x82,0x08,0x00, // Chr$(70) F
0x72,0x28,0x2E,0x8A,0x27,0x80, // Chr$(71) G
0x8A,0x28,0xBE,0x8A,0x28,0x80, // Chr$(72) H
0x70,0x82,0x08,0x20,0x87,0x00, // Chr$(73) I
0x38,0x41,0x04,0x12,0x46,0x00, // Chr$(74) J
0x8A,0x4A,0x30,0xA2,0x48,0x80, // Chr$(75) K
0x82,0x08,0x20,0x82,0x0F,0x80, // Chr$(76) L
0x8B,0x6A,0xAA,0x8A,0x28,0x80, // Chr$(77) M
0x8A,0x2C,0xAA,0x9A,0x28,0x80, // Chr$(78) N
0x72,0x28,0xA2,0x8A,0x27,0x00, // Chr$(79) O
0xF2,0x28,0xBC,0x82,0x08,0x00, // Chr$(80) P
0x72,0x28,0xA2,0xAA,0x46,0x80, // Chr$(81) Q
0xF2,0x28,0xBC,0xA2,0x48,0x80, // Chr$(82) R
0x7A,0x08,0x1C,0x08,0x2F,0x00, // Chr$(83) S
0xF8,0x82,0x08,0x20,0x82,0x00, // Chr$(84) T
0x8A,0x28,0xA2,0x8A,0x27,0x00, // Chr$(85) U
0x8A,0x28,0xA2,0x89,0x42,0x00, // Chr$(86) V
0x8A,0x28,0xAA,0xAA,0xA5,0x00, // Chr$(87) W
0x8A,0x25,0x08,0x52,0x28,0x80, // Chr$(88) X
0x8A,0x28,0x94,0x20,0x82,0x00, // Chr$(89) Y
0xF8,0x21,0x08,0x42,0x0F,0x80, // Chr$(90) Z
0x71,0x04,0x10,0x41,0x07,0x00, // Chr$(91) [
0x02,0x04,0x08,0x10,0x20,0x00, // Chr$(92) backslash
0x70,0x41,0x04,0x10,0x47,0x00, // Chr$(93) ]
0x21,0x48,0x80,0x00,0x00,0x00, // Chr$(94) ^
0x00,0x00,0x00,0x00,0x0F,0x80, // Chr$(95) _
0x00,0xC4,0x8C,0x00,0x00,0x00, // Chr$(96) `
0x00,0x07,0x02,0x7A,0x27,0x80, // Chr$(97) a
0x82,0x0B,0x32,0x8A,0x2F,0x00, // Chr$(98) b
0x00,0x07,0x20,0x82,0x27,0x00, // Chr$(99) c
0x08,0x26,0xA6,0x8A,0x27,0x80, // Chr$(100) d
0x00,0x07,0x22,0xFA,0x07,0x00, // Chr$(101) e
0x31,0x24,0x38,0x41,0x04,0x00, // Chr$(102) f
0x01,0xE8,0xA2,0x78,0x27,0x00, // Chr$(103) g
0x82,0x0B,0x32,0x8A,0x28,0x80, // Chr$(104) h
0x20,0x06,0x08,0x20,0x87,0x00, // Chr$(105) i
0x10,0x03,0x04,0x12,0x46,0x00, // Chr$(106) j
0x82,0x09,0x28,0xC2,0x89,0x00, // Chr$(107) k
0x60,0x82,0x08,0x20,0x87,0x00, // Chr$(108) l
0x00,0x0D,0x2A,0xAA,0x28,0x80, // Chr$(109) m
0x00,0x0B,0x32,0x8A,0x28,0x80, // Chr$(110) n
0x00,0x07,0x22,0x8A,0x27,0x00, // Chr$(111) o
0x00,0x0F,0x22,0xF2,0x08,0x00, // Chr$(112) p
0x00,0x06,0xA6,0x78,0x20,0x80, // Chr$(113) q
0x00,0x0B,0x32,0x82,0x08,0x00, // Chr$(114) r
0x00,0x07,0x20,0x70,0x2F,0x00, // Chr$(115) s
0x41,0x0E,0x10,0x41,0x23,0x00, // Chr$(116) t
0x00,0x08,0xA2,0x8A,0x66,0x80, // Chr$(117) u
0x00,0x08,0xA2,0x89,0x42,0x00, // Chr$(118) v
0x00,0x08,0xA2,0xAA,0xA5,0x00, // Chr$(119) w
0x00,0x08,0x94,0x21,0x48,0x80, // Chr$(120) x
0x00,0x08,0xA2,0x78,0x27,0x00, // Chr$(121) y
0x00,0x0F,0x84,0x21,0x0F,0x80, // Chr$(122) z
0x10,0x82,0x10,0x40,0x82,0x04, // Chr$(123) {
0x20,0x82,0x00,0x20,0x82,0x00, // Chr$(124) |
0x20,0x41,0x02,0x08,0x41,0x08, // Chr$(125) }
0x00,0x04,0xAA,0x90,0x00,0x00, // Chr$(126) ~
0x00,0x02,0x14,0x8B,0xE0,0x00 // Chr$(127)
};
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Functions.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
the C language function associated with commands, functions or operators should be
declared here
**********************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#define RADCONV (MMFLOAT)57.2957795130823229 // Used when converting degrees -> radians and vice versa
#define Rad(a) (((MMFLOAT)a) / RADCONV)
#endif
/* @endcond */

View File

@ -0,0 +1,704 @@
/***********************************************************************************************************************
PicoMite MMBasic
GPS.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.
************************************************************************************************************************/
/**
* @file GPS.c
* @author Geoff Graham, Peter Mather
* @brief Source for GPS MMBasic function
*/
/**
* @cond
* The following section will be excluded from the documentation.
*/
/* ************************************************************************** */
/* ************************************************************************** */
/* Section: Included Files */
/* ************************************************************************** */
/* ************************************************************************** */
/* This section lists the other files that are included in this file.
*/
/* TODO: Include other files here if needed. */
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <time.h>
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
/* ************************************************************************** */
/* ************************************************************************** */
/* Section: File Scope or Global Data */
/* ************************************************************************** */
/* ************************************************************************** */
/* A brief description of a section can be given directly below the section
banner.
*/
/* ************************************************************************** */
/** Descriptive Data Item Name
@Summary
Brief one-line summary of the data item.
@Description
Full description, explaining the purpose and usage of data item.
<p>
Additional description in consecutive paragraphs separated by HTML
paragraph breaks, as necessary.
<p>
Type "JavaDoc" in the "How Do I?" IDE toolbar for more information on tags.
@Remarks
Any additional remarks
*/
//int global_data;
int GPSchannel=0;
volatile char gpsbuf1[128];
volatile char gpsbuf2[128];
volatile char * volatile gpsbuf;
volatile char *gpsready;
volatile char gpscount;
volatile int gpscurrent;
volatile int gpsmonitor;
MMFLOAT GPSlatitude=0;
MMFLOAT GPSlongitude=0;
MMFLOAT GPSspeed=0;
int GPSvalid=0;
char GPStime[9]="000:00:0";
char GPSdate[11]="000-00-200";
MMFLOAT GPStrack=0;
MMFLOAT GPSdop=0;
int GPSsatellites=0;
MMFLOAT GPSaltitude=0;
MMFLOAT GPSgeoid=0;
int GPSfix=0;
int GPSadjust=0;
void GPS_parse(char *nmea);
#define EPOCH_ADJUSTMENT_DAYS 719468L
/* year to which the adjustment was made */
#define ADJUSTED_EPOCH_YEAR 0
/* 1st March of year 0 is Wednesday */
#define ADJUSTED_EPOCH_WDAY 3
/* there are 97 leap years in 400-year periods. ((400 - 97) * 365 + 97 * 366) */
#define DAYS_PER_ERA 146097L
/* there are 24 leap years in 100-year periods. ((100 - 24) * 365 + 24 * 366) */
#define DAYS_PER_CENTURY 36524L
/* there is one leap year every 4 years */
#define DAYS_PER_4_YEARS (3 * 365 + 366)
/* number of days in a non-leap year */
#define DAYS_PER_YEAR 365
/* number of days in January */
#define DAYS_IN_JANUARY 31
/* number of days in non-leap February */
#define DAYS_IN_FEBRUARY 28
/* number of years per era */
#define YEARS_PER_ERA 400
#define SECSPERDAY 86400
#define SECSPERHOUR 3600
#define SECSPERMIN 60
#define DAYSPERWEEK 7
#define YEAR_BASE 1900
/* Number of days per month (except for February in leap years). */
static const int monoff[] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
static int
is_leap_year(int year)
{
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
static int
leap_days(int y1, int y2)
{
--y1;
--y2;
return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400);
}
struct tm *
gmtime_r (const time_t *__restrict tim_p,
struct tm *__restrict res)
{
long days, rem;
const time_t lcltime = *tim_p;
int era, weekday, year;
unsigned erayear, yearday, month, day;
unsigned long eraday;
days = lcltime / SECSPERDAY + EPOCH_ADJUSTMENT_DAYS;
rem = lcltime % SECSPERDAY;
if (rem < 0)
{
rem += SECSPERDAY;
--days;
}
/* compute hour, min, and sec */
res->tm_hour = (int) (rem / SECSPERHOUR);
rem %= SECSPERHOUR;
res->tm_min = (int) (rem / SECSPERMIN);
res->tm_sec = (int) (rem % SECSPERMIN);
/* compute day of week */
if ((weekday = ((ADJUSTED_EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
weekday += DAYSPERWEEK;
res->tm_wday = weekday;
/* compute year, month, day & day of year */
/* for description of this algorithm see
* http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
era = (days >= 0 ? days : days - (DAYS_PER_ERA - 1)) / DAYS_PER_ERA;
eraday = days - era * DAYS_PER_ERA; /* [0, 146096] */
erayear = (eraday - eraday / (DAYS_PER_4_YEARS - 1) + eraday / DAYS_PER_CENTURY -
eraday / (DAYS_PER_ERA - 1)) / 365; /* [0, 399] */
yearday = eraday - (DAYS_PER_YEAR * erayear + erayear / 4 - erayear / 100); /* [0, 365] */
month = (5 * yearday + 2) / 153; /* [0, 11] */
day = yearday - (153 * month + 2) / 5 + 1; /* [1, 31] */
month += month < 10 ? 2 : -10;
year = ADJUSTED_EPOCH_YEAR + erayear + era * YEARS_PER_ERA + (month <= 1);
res->tm_yday = yearday >= DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY ?
yearday - (DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY) :
yearday + DAYS_IN_JANUARY + DAYS_IN_FEBRUARY + is_leap_year(erayear);
res->tm_year = year - YEAR_BASE;
res->tm_mon = month;
res->tm_mday = day;
res->tm_isdst = 0;
return (res);
}
struct tm *
gmtime (const time_t * tim_p)
{
struct _reent *reent = _REENT;
_REENT_CHECK_TM(reent);
return gmtime_r (tim_p, (struct tm *)_REENT_TM(reent));
}
time_t
timegm(const struct tm *tm)
{
int year;
time_t days;
time_t hours;
time_t minutes;
time_t seconds;
year = 1900 + tm->tm_year;
days = 365 * (year - 1970) + leap_days(1970, year);
days += monoff[tm->tm_mon];
if (tm->tm_mon > 1 && is_leap_year(year))
++days;
days += tm->tm_mday - 1;
hours = days * 24 + tm->tm_hour;
minutes = hours * 60 + tm->tm_min;
seconds = minutes * 60 + tm->tm_sec;
return seconds;
}
/* ************************************************************************** */
/* ************************************************************************** */
// Section: Local Functions */
/* ************************************************************************** */
/* ************************************************************************** */
/* A brief description of a section can be given directly below the section
banner.
*/
/* ************************************************************************** */
/**
@Function
int ExampleLocalFunctionName ( int param1, int param2 )
@Summary
Brief one-line description of the function.
@Description
Full description, explaining the purpose and usage of the function.
<p>
Additional description in consecutive paragraphs separated by HTML
paragraph breaks, as necessary.
<p>
Type "JavaDoc" in the "How Do I?" IDE toolbar for more information on tags.
@Precondition
List and describe any required preconditions. If there are no preconditions,
enter "None."
@Parameters
@param param1 Describe the first parameter to the function.
@param param2 Describe the second parameter to the function.
@Returns
List (if feasible) and describe the return values of the function.
<ul>
<li>1 Indicates an error occurred
<li>0 Indicates an error did not occur
</ul>
@Remarks
Describe any special behavior not described above.
<p>
Any additional remarks.
@Example
@code
if(ExampleFunctionName(1, 2) == 0)
{
return 3;
}
*/
//static int ExampleLocalFunction(int param1, int param2) {
// return 0;
//}
#define INDENT_SPACES " "
/* ************************************************************************** */
/* ************************************************************************** */
// Section: Interface Functions */
/* ************************************************************************** */
/* ************************************************************************** */
/* A brief description of a section can be given directly below the section
banner.
*/
// *****************************************************************************
/**
@Function
int ExampleInterfaceFunctionName ( int param1, int param2 )
@Summary
Brief one-line description of the function.
@Remarks
Refer to the example_file.h interface header for function usage details.
*/
//int ExampleInterfaceFunction(int param1, int param2) {
// return 0;
//}
/* @endcond */
void fun_GPS(void){
sret = GetTempMemory(STRINGSIZE); // this will last for the life of the command
if(!GPSchannel) error("GPS not activated");
if(checkstring(ep, (unsigned char *)"LATITUDE") != NULL) {
fret = GPSlatitude;
targ = T_NBR;
}
else if(checkstring(ep, (unsigned char *)"LONGITUDE") != NULL) {
fret = GPSlongitude;
targ = T_NBR;
}
else if(checkstring(ep, (unsigned char *)"SPEED") != NULL) {
fret = GPSspeed;
targ = T_NBR;
}
else if(checkstring(ep, (unsigned char *)"TRACK") != NULL) {
fret = GPStrack;
targ = T_NBR;
}
else if(checkstring(ep, (unsigned char *)"VALID") != NULL) {
iret = GPSvalid;
targ = T_INT;
}
else if(checkstring(ep, (unsigned char *)"TIME") != NULL) {
sret = (unsigned char *)GPStime;
targ = T_STR;
}
else if(checkstring(ep, (unsigned char *)"DATE") != NULL) {
sret = (unsigned char *)GPSdate;
targ = T_STR;
}
else if(checkstring(ep, (unsigned char *)"SATELLITES") != NULL) {
iret = GPSsatellites;
targ = T_INT;
}
else if(checkstring(ep, (unsigned char *)"ALTITUDE") != NULL) {
fret = GPSaltitude;
targ = T_NBR;
}
else if(checkstring(ep, (unsigned char *)"DOP") != NULL) {
fret = GPSdop;
targ = T_NBR;
}
else if(checkstring(ep, (unsigned char *)"FIX") != NULL) {
iret = GPSfix;
targ = T_INT;
}
else if(checkstring(ep, (unsigned char *)"GEOID") != NULL) {
fret = GPSgeoid;
targ = T_NBR;
}
else error("Invalid command");
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
void processgps(void){
if(GPSTimer>2000){
GPSvalid=0;
}
if(gpsready !=NULL){
GPS_parse((char *)gpsready);
GPSTimer=0;
gpsready=NULL;
}
}
uint8_t parseHex(char c) {
if (c < '0')
return 0;
if (c <= '9')
return c - '0';
if (c < 'A')
return 0;
if (c <= 'F')
return (c - 'A')+10;
// if (c > 'F')
return 0;
}
void GPS_parse(char *nmea) {
uint8_t hour, minute, seconds, year=0, month=0, day=0;
uint16_t __attribute__((unused)) milliseconds;
// Floating point latitude and longitude value in degrees.
MMFLOAT __attribute__((unused)) latitude, longitude;
// Fixed point latitude and longitude value with degrees stored in units of 1/100000 degrees,
// and minutes stored in units of 1/100000 degrees. See pull #13 for more details:
// https://github.com/adafruit/Adafruit-GPS-Library/pull/13
int32_t __attribute__((unused)) latitude_fixed, longitude_fixed;
MMFLOAT latitudeDegrees=0.0, longitudeDegrees=0.0;
MMFLOAT geoidheight, altitude;
MMFLOAT speed, angle, HDOP;
MMFLOAT __attribute__((unused)) magvariation;
char __attribute__((unused)) lat, lon;
uint8_t fixquality, satellites;
struct tm *tm;
struct tm tma;
tm=&tma;
if(gpsmonitor){
MMPrintString(nmea);
}
// do checksum check
// first look if we even have one
if (nmea[strlen(nmea)-4] == '*') {
uint16_t sum = parseHex(nmea[strlen(nmea)-3]) * 16;
sum += parseHex(nmea[strlen(nmea)-2]);
uint8_t i;
// check checksum
for (i=2; i < (strlen(nmea)-4); i++) {
sum ^= nmea[i];
}
if (sum != 0) {
// bad checksum :(
return;
}
}
int32_t degree;
long minutes;
char degreebuff[10];
// look for a few common sentences
if (strstr(nmea, "$GPGGA") || strstr(nmea, "$GNGGA")) {
// found GGA
char *p = nmea;
// get time
p = strchr((char *)p, ',')+1;
MMFLOAT timef = atof(p);
uint32_t time = timef;
hour = time / 10000;
minute = (time % 10000) / 100;
seconds = (time % 100);
milliseconds = fmod(timef, 1.0) * 1000;
// parse out latitude
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
strncpy(degreebuff, p, 2);
p += 2;
degreebuff[2] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
latitude_fixed = degree + minutes;
latitude = degree / 100000 + minutes * 0.000006F;
latitudeDegrees = (latitude-100*(MMFLOAT)((int)(latitude/100)))/60.0;
latitudeDegrees += (MMFLOAT)((int)(latitude/100));
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
if (p[0] == 'S') latitudeDegrees *= -1.0;
if (p[0] == 'N') lat = 'N';
else if (p[0] == 'S') lat = 'S';
else if (p[0] == ',') lat = 0;
else return;
}
GPSlatitude=(MMFLOAT)latitudeDegrees;
// parse out longitude
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
strncpy(degreebuff, p, 3);
p += 3;
degreebuff[3] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
longitude_fixed = degree + minutes;
longitude = degree / 100000 + minutes * 0.000006F;
longitudeDegrees = (longitude-100*(MMFLOAT)((int)(longitude/100)))/60.0;
longitudeDegrees += (MMFLOAT)((int)(longitude/100));
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
if (p[0] == 'W') longitudeDegrees *= -1.0;
if (p[0] == 'W') lon = 'W';
else if (p[0] == 'E') lon = 'E';
else if (p[0] == ',') lon = 0;
else return;
}
GPSlongitude=(MMFLOAT)longitudeDegrees;
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
fixquality = atoi(p);
GPSfix=(int)fixquality;
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
satellites = atoi(p);
GPSsatellites=(int)satellites;
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
HDOP = atof(p);
GPSdop=(MMFLOAT)HDOP;
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
altitude = atof(p);
GPSaltitude=(MMFLOAT)altitude;
}
p = strchr((char *)p, ',')+1;
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
geoidheight = atof(p);
GPSgeoid=(MMFLOAT)geoidheight;
}
return;
}
if (strstr(nmea, "$GPRMC") || strstr(nmea, "$GNRMC")) {
// found RMC
char *p = nmea;
int i, localGPSvalid=0;
// get time
p = strchr((char *)p, ',')+1;
MMFLOAT timef = atof(p);
uint32_t time = timef;
hour = time / 10000;
minute = (time % 10000) / 100;
seconds = (time % 100);
milliseconds = fmod(timef, 1.0) * 1000;
i=tm->tm_hour;
GPStime[1]=(hour/10) + 48;
GPStime[2]=(hour % 10) + 48;
i=tm->tm_min;
GPStime[4]=(minute/10) + 48;
GPStime[5]=(minute % 10) + 48;
i=tm->tm_sec;
GPStime[7]=(seconds/10) + 48;
GPStime[8]=(seconds % 10) + 48;
p = strchr((char *)p, ',')+1;
if (p[0] == 'A')
localGPSvalid = 1;
else if (p[0] == 'V')
localGPSvalid = 0;
else
{
GPSvalid=0;
return;
}
// parse out latitude
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
strncpy(degreebuff, p, 2);
p += 2;
degreebuff[2] = '\0';
long degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
long minutes = 50 * atol(degreebuff) / 3;
latitude_fixed = degree + minutes;
latitude = degree / 100000 + minutes * 0.000006F;
latitudeDegrees = (latitude-100*(MMFLOAT)((int)(latitude/100)))/60.0;
latitudeDegrees += (MMFLOAT)((int)(latitude/100));
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
if (p[0] == 'S') latitudeDegrees *= -1.0;
if (p[0] == 'N') lat = 'N';
else if (p[0] == 'S') lat = 'S';
else if (p[0] == ',') lat = 0;
else return;
}
GPSlatitude=(MMFLOAT)latitudeDegrees;
// parse out longitude
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
strncpy(degreebuff, p, 3);
p += 3;
degreebuff[3] = '\0';
degree = atol(degreebuff) * 10000000;
strncpy(degreebuff, p, 2); // minutes
p += 3; // skip decimal point
strncpy(degreebuff + 2, p, 4);
degreebuff[6] = '\0';
minutes = 50 * atol(degreebuff) / 3;
longitude_fixed = degree + minutes;
longitude = degree / 100000 + minutes * 0.000006F;
longitudeDegrees = (longitude-100*(MMFLOAT)((int)(longitude/100)))/60.0;
longitudeDegrees += (MMFLOAT)((int)(longitude/100));
}
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
if (p[0] == 'W') longitudeDegrees *= -1.0;
if (p[0] == 'W') lon = 'W';
else if (p[0] == 'E') lon = 'E';
else if (p[0] == ',') lon = 0;
else return;
}
GPSlongitude=(MMFLOAT)longitudeDegrees;
// speed
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
speed = atof(p);
GPSspeed=(MMFLOAT)speed;
}
// angle
p = strchr((char *)p, ',')+1;
if (',' != *p)
{
angle = atof(p);
GPStrack=(MMFLOAT)angle;
}
p = strchr((char *)p, ',')+1;
if (',' != *p && p[6]==',')
{
uint32_t fulldate = atoi(p);
day = fulldate / 10000;
month = (fulldate % 10000) / 100;
year = (fulldate % 100);
GPStime[0]=8;
tm->tm_year = year + 100;
tm->tm_mon = month - 1;
tm->tm_mday = day;
tm->tm_hour = hour;
tm->tm_min = minute;
tm->tm_sec = seconds;
time_t timestamp = timegm(tm); /* See README.md if your system lacks timegm(). */
timestamp+=GPSadjust;
tm=gmtime(&timestamp);
i=tm->tm_hour;
GPStime[1]=(i/10) + 48;
GPStime[2]=(i % 10) + 48;
i=tm->tm_min;
GPStime[4]=(i/10) + 48;
GPStime[5]=(i % 10) + 48;
i=tm->tm_sec;
GPStime[7]=(i/10) + 48;
GPStime[8]=(i % 10) + 48;
i=tm->tm_mday;
GPSdate[0]=10;
GPSdate[1]=(i/10) + 48;
GPSdate[2]=(i % 10) + 48;
i=tm->tm_mon+1;
GPSdate[4]=(i/10) + 48;
GPSdate[5]=(i % 10) + 48;
i=tm->tm_year % 100;
GPSdate[9]=(i/10) + 48;
GPSdate[10]=(i % 10) + 48;
// we don't parse the remaining, yet!
GPSvalid=localGPSvalid;
return;
}
}
return;
}
/* @endcond */

View File

@ -0,0 +1,275 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
GPS.h
<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 "configuration.h"
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
#ifndef MINMEA_H
#define MINMEA_H
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <time.h>
//#include <math.h>
#define YEAR0 1900 /* the first year */
#define EPOCH_YR 1970 /* EPOCH = Jan 1 1970 00:00:00 */
#define SECS_DAY (24L * 60L * 60L)
#define LEAPYEAR(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year) (LEAPYEAR(year) ? 366 : 365)
#define FIRSTSUNDAY(timp) (((timp)->tm_yday - (timp)->tm_wday + 420) % 7)
#define FIRSTDAYOF(timp) (((timp)->tm_wday - (timp)->tm_yday + 420) % 7)
#define TIME_MAX ULONG_MAX
#define ABB_LEN 3
#define MINMEA_MAX_LENGTH 80
extern volatile char gpsbuf1[128];
extern volatile char gpsbuf2[128];
extern volatile char * volatile gpsbuf;
extern volatile char gpscount;
extern volatile int gpscurrent;
extern volatile char *gpsready;
extern volatile int gpsmonitor;
extern MMFLOAT GPSlatitude;
extern MMFLOAT GPSlongitude;
extern MMFLOAT GPSspeed;
extern int GPSvalid;
extern char GPStime[9];
extern char GPSdate[11];
extern MMFLOAT GPStrack;
extern int GPSfix;
extern int GPSadjust;
extern MMFLOAT GPSdop;
extern int GPSsatellites;
extern MMFLOAT GPSaltitude;
extern int GPSfix;
extern int GPSadjust;
extern const int _ytab[2][12];
extern int GPSchannel;
extern time_t timegm(const struct tm *tm);
extern struct tm * gmtime(const time_t *timer);
enum minmea_sentence_id {
MINMEA_INVALID = -1,
MINMEA_UNKNOWN = 0,
MINMEA_SENTENCE_RMC,
MINMEA_SENTENCE_GGA,
MINMEA_SENTENCE_GSA,
MINMEA_SENTENCE_GLL,
MINMEA_SENTENCE_GST,
MINMEA_SENTENCE_GSV,
MINMEA_SENTENCE_VTG,
};
struct minmea_float {
int value;
int scale;
};
struct minmea_date {
int day;
int month;
int year;
};
struct minmea_time {
int hours;
int minutes;
int seconds;
int microseconds;
};
struct minmea_sentence_rmc {
struct minmea_time time;
bool valid;
struct minmea_float latitude;
struct minmea_float longitude;
struct minmea_float speed;
struct minmea_float course;
struct minmea_date date;
struct minmea_float variation;
};
struct minmea_sentence_gga {
struct minmea_time time;
struct minmea_float latitude;
struct minmea_float longitude;
int fix_quality;
int satellites_tracked;
struct minmea_float hdop;
struct minmea_float altitude; char altitude_units;
struct minmea_float height; char height_units;
int dgps_age;
};
enum minmea_gll_status {
MINMEA_GLL_STATUS_DATA_VALID = 'A',
MINMEA_GLL_STATUS_DATA_NOT_VALID = 'V',
};
// FAA mode added to some fields in NMEA 2.3.
enum minmea_faa_mode {
MINMEA_FAA_MODE_AUTONOMOUS = 'A',
MINMEA_FAA_MODE_DIFFERENTIAL = 'D',
MINMEA_FAA_MODE_ESTIMATED = 'E',
MINMEA_FAA_MODE_MANUAL = 'M',
MINMEA_FAA_MODE_SIMULATED = 'S',
MINMEA_FAA_MODE_NOT_VALID = 'N',
MINMEA_FAA_MODE_PRECISE = 'P',
};
struct minmea_sentence_gll {
struct minmea_float latitude;
struct minmea_float longitude;
struct minmea_time time;
char status;
char mode;
};
struct minmea_sentence_gst {
struct minmea_time time;
struct minmea_float rms_deviation;
struct minmea_float semi_major_deviation;
struct minmea_float semi_minor_deviation;
struct minmea_float semi_major_orientation;
struct minmea_float latitude_error_deviation;
struct minmea_float longitude_error_deviation;
struct minmea_float altitude_error_deviation;
};
enum minmea_gsa_mode {
MINMEA_GPGSA_MODE_AUTO = 'A',
MINMEA_GPGSA_MODE_FORCED = 'M',
};
enum minmea_gsa_fix_type {
MINMEA_GPGSA_FIX_NONE = 1,
MINMEA_GPGSA_FIX_2D = 2,
MINMEA_GPGSA_FIX_3D = 3,
};
struct minmea_sentence_gsa {
char mode;
int fix_type;
int sats[12];
struct minmea_float pdop;
struct minmea_float hdop;
struct minmea_float vdop;
};
struct minmea_sat_info {
int nr;
int elevation;
int azimuth;
int snr;
};
struct minmea_sentence_gsv {
int total_msgs;
int msg_nr;
int total_sats;
struct minmea_sat_info sats[4];
};
struct minmea_sentence_vtg {
struct minmea_float true_track_degrees;
struct minmea_float magnetic_track_degrees;
struct minmea_float speed_knots;
struct minmea_float speed_kph;
enum minmea_faa_mode faa_mode;
};
/*
* Calculate raw sentence checksum. Does not check sentence integrity.
*/
uint8_t minmea_checksum(const char *sentence);
/*
* Check sentence validity and checksum. Returns true for valid sentences.
*/
bool minmea_check(const char *sentence, bool strict);
/*
* Determine talker identifier.
*/
bool minmea_talker_id(char talker[3], const char *sentence);
/*
* Determine sentence identifier.
*/
void processgps(void);
enum minmea_sentence_id minmea_sentence_id(const char *sentence, bool strict);
/*
* Scanf-like processor for NMEA sentences. Supports the following formats:
* c - single character (char *)
* d - direction, returned as 1/-1, default 0 (int *)
* f - fractional, returned as value + scale (int *, int *)
* i - decimal, default zero (int *)
* s - string (char *)
* t - talker identifier and type (char *)
* T - date/time stamp (int *, int *, int *)
* Returns true on success. See library source code for details.
*/
bool minmea_scan(const char *sentence, const char *format, ...);
/*
* Parse a specific type of sentence. Return true on success.
*/
bool minmea_parse_rmc(struct minmea_sentence_rmc *frame, const char *sentence);
bool minmea_parse_gga(struct minmea_sentence_gga *frame, const char *sentence);
bool minmea_parse_gsa(struct minmea_sentence_gsa *frame, const char *sentence);
bool minmea_parse_gll(struct minmea_sentence_gll *frame, const char *sentence);
bool minmea_parse_gst(struct minmea_sentence_gst *frame, const char *sentence);
bool minmea_parse_gsv(struct minmea_sentence_gsv *frame, const char *sentence);
bool minmea_parse_vtg(struct minmea_sentence_vtg *frame, const char *sentence);
/*
* Convert GPS UTC date/time representation to a UNIX timestamp.
*/
int minmea_gettime(struct timespec *ts, const struct minmea_date *date, const struct minmea_time *time_);
/*
* Rescale a fixed-point value to a different scale. Rounds towards zero.
*/
#endif /* MINMEA_H */
#endif
/* vim: set ts=4 sw=4 et: */
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
GUI.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#ifndef GUI_H_INCL
#define GUI_H_INCL
extern void ConfigDisplaySSD(unsigned char *p);
extern void InitDisplaySSD(void);
extern void DrawRectangleSSD1963(int x1, int y1, int x2, int y2, int c);
extern void ProcessTouch(void);
extern void ResetGUI(void);
extern void DrawKeyboard(int);
extern void DrawFmtBox(int);
// define the blink rate for the cursor
#define CURSOR_OFF 350 // cursor off time in mS
#define CURSOR_ON 650 // cursor on time in mS
#define MAX_CAPTION_LINES 10 // maximum number of lines in a caption
extern void HideAllControls(void);
extern short gui_font, gui_font_width, gui_font_height;
extern int gui_fcolour, gui_bcolour;
extern int last_fcolour, last_bcolour;
extern int gui_click_pin; // the sound pin
extern int display_backlight; // the brightness of the backlight (1 to 100)
extern short CurrentX, CurrentY; // and the current default position
extern bool gui_int_down; // true if the touch down has triggered an interrupt
extern char *GuiIntDownVector; // address of the interrupt routine or NULL if no interrupt
extern bool gui_int_up; // true if the release of the touch has triggered an interrupt
extern char *GuiIntUpVector; // address of the interrupt routine or NULL if no interrupt
extern volatile bool DelayedDrawKeyboard; // a flag to indicate that the pop-up keyboard should be drawn AFTER the pen down interrupt
extern volatile bool DelayedDrawFmtBox; // a flag to indicate that the pop-up formatted keyboard should be drawn AFTER the pen down interrupt
extern short CurrentRef; // if the pen is down this is the control (or zero if not on a control)
extern short LastRef; // this is the last control touched
extern short LastX; // this is the x coord when the pen was lifted
extern short LastY; // ditto for y
extern MMFLOAT CtrlSavedVal; // a temporary place to save a control's value
extern int CheckGuiFlag; // used by Timer.c to tell if it has to call CheckGuiTimeouts()
extern void CheckGui(void);
extern void CheckGuiTimeouts(void);
extern volatile int ClickTimer; // used to time the click when touch occurs
extern volatile int TouchTimer; // used to time the response to touch
extern struct s_ctrl *Ctrl; // list of the controls
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,397 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Hardware_Includes.h
<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 "AllCommands.h"
#include "Memory.h"
#include "hardware/watchdog.h"
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "pico/stdlib.h"
#include "pico/util/datetime.h"
#ifdef PICOMITEVGA
#include "pico/multicore.h"
#endif
#include "lfs.h"
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#include <stdio.h>
#include <stddef.h>
#include "Version.h"
#include "configuration.h"
#include "FileIO.h"
#include "ff.h"
// global variables used in MMBasic but must be maintained outside of the interpreter
extern int MMerrno;
//extern int ListCnt;
extern int MMCharPos;
extern unsigned char *StartEditPoint;
extern int StartEditChar;
extern int OptionErrorSkip;
extern int ExitMMBasicFlag;
extern unsigned char *InterruptReturn;
extern unsigned int _excep_peek;
extern volatile long long int mSecTimer;
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 int ds18b20Timer;
extern volatile int CursorTimer;
extern volatile unsigned int I2CTimer;
#ifndef USBKEYBOARD
extern volatile unsigned int MouseTimer;
extern void initMouse0(int sensitivity);
extern bool mouse0;
extern int MOUSE_CLOCK,MOUSE_DATA;
#endif
//extern volatile int second;
//extern volatile int minute;
//extern volatile int hour;
//extern volatile int day;
//extern volatile int month;
//extern volatile int year;
extern volatile unsigned int SecondsTimer;
extern volatile int day_of_week;
extern unsigned char WatchdogSet;
extern unsigned char IgnorePIN;
extern MMFLOAT VCC;
extern volatile unsigned int WDTimer; // used for the watchdog timer
extern unsigned char PulsePin[];
extern unsigned char PulseDirection[];
extern int PulseCnt[];
extern int PulseActive;
extern volatile int ClickTimer;
extern int calibrate;
extern volatile unsigned int InkeyTimer; // used to delay on an escape character
extern volatile int DISPLAY_TYPE;
extern void routinechecks(void);
extern volatile char ConsoleRxBuf[CONSOLE_RX_BUF_SIZE];
extern volatile int ConsoleRxBufHead;
extern volatile int ConsoleRxBufTail;
extern volatile char ConsoleTxBuf[CONSOLE_TX_BUF_SIZE];
extern volatile int ConsoleTxBufHead;
extern volatile int ConsoleTxBufTail;
extern unsigned char SPIatRisk;
extern uint8_t RGB121(uint32_t c);
extern uint8_t RGB332(uint32_t c);
extern uint16_t RGB555(uint32_t c);
extern uint16_t RGB121pack(uint32_t c);
#ifndef rp2350
extern datetime_t rtc_t;
#else
extern bool rp2350a;
extern uint32_t PSRAMsize;
extern const uint32_t MAP16DEF[16];
extern void _Z10copy_wordsPKmPmm(uint32_t *s, uint32_t *d, int n);
#endif
#ifdef HDMI
extern uint16_t *tilefcols;
extern uint16_t *tilebcols;
extern uint8_t *tilefcols_w;
extern uint8_t *tilebcols_w;
extern void settiles(void);
extern uint16_t map256[256];
extern uint16_t map16[16];
extern uint16_t map16d[16];
extern uint8_t map16s[16];
extern uint32_t map16q[16];
extern uint32_t map16pairs[16];
extern const uint32_t MAP256DEF[256];
extern volatile int32_t v_scanline;
#else
#ifdef rp2350
extern uint16_t *tilefcols;
extern uint16_t *tilebcols;
#else
extern uint16_t tilefcols[];
extern uint16_t tilebcols[];
#endif
#endif
extern void __not_in_flash_func(QVgaCore)(void);
extern uint32_t core1stack[];
extern int QVGA_CLKDIV;
extern int getslice(int pin);
extern void setpwm(int pin, int *PWMChannel, int *PWMSlice, MMFLOAT frequency, MMFLOAT duty);
struct s_PinDef {
int pin;
int GPno;
char pinname[5];
uint64_t mode;
unsigned char ADCpin;
unsigned char slice;
};
typedef struct s_HID {
uint8_t Device_address;
uint8_t Device_instance;
uint8_t Device_type;
uint8_t report_rate;
int16_t report_timer;
uint16_t vid;
uint16_t pid;
bool active;
bool report_requested;
bool notfirsttime;
uint8_t motorleft;
uint8_t motorright;
uint8_t r,g,b;
uint8_t sendlights;
uint8_t report[65];
} a_HID;
extern volatile struct s_HID HID[4];
extern uint32_t _excep_code;
extern const struct s_PinDef PinDef[NBRPINS + 1];
#define VCHARS 25 // nbr of lines in the DOS box (used in LIST)
#define FILENAME_LENGTH 12
//extern unsigned char *ModuleTable[MAXMODULES]; // list of pointers to modules loaded in memory;
//extern int NbrModules; // the number of modules currently loaded
extern void mT4IntEnable(int status);
extern int BasicFileOpen(char *fname, int fnbr, int mode);
extern int kbhitConsole(void);
extern int InitSDCard(void);
extern void FileClose(int fnbr);
#define NBRERRMSG 17 // number of file error messages
extern void PRet(void);
extern void PInt(int64_t n);
extern void PIntComma(int64_t n);
extern void SRet(void);
extern void SInt(int64_t n);
extern void SPIClose(void);
extern void SPI2Close(void);
extern void SIntComma(int64_t n);
extern void PIntH(unsigned long long int n);
extern void PIntB(unsigned long long int n);
extern void PIntBC(unsigned long long int n);
extern void PIntHC(unsigned long long int n) ;
extern void PFlt(MMFLOAT flt);
extern void PFltComma(MMFLOAT n) ;
extern void putConsole(int c, int flush);
extern void MMPrintString(char* s);
extern void SSPrintString(char* s);
extern void myprintf(char *s);
extern int getConsole(void);
extern void InitReservedIO(void);
extern char SerialConsolePutC(char c, int flush);
extern void CallExecuteProgram(char *p);
extern long long int *GetReceiveDataBuffer(unsigned char *p, unsigned int *nbr);
extern int ticks_per_second;
extern volatile unsigned int GPSTimer;
extern uint16_t AUDIO_L_PIN, AUDIO_R_PIN, AUDIO_SLICE;
extern uint16_t AUDIO_WRAP;
extern int PromptFont, PromptFC, PromptBC; // the font and colours selected at the prompt
extern const uint8_t *flash_progmemory;
extern lfs_t lfs;
extern lfs_dir_t lfs_dir;
extern struct lfs_info lfs_info;
extern int FatFSFileSystem;
extern void uSec(int us);
extern int volatile ytileheight;
extern volatile int X_TILE, Y_TILE;
extern int CameraSlice;
extern int CameraChannel;
extern char id_out[];
extern uint8_t *buff320;
extern uint16_t SD_CLK_PIN,SD_MOSI_PIN,SD_MISO_PIN, SD_CS_PIN;
extern bool screen320;
extern void clear320(void);
#ifdef PICOMITEVGA
extern volatile uint8_t transparent;
extern volatile uint8_t transparents;
extern volatile int RGBtransparent;
extern uint16_t map16[16];
#ifndef HDMI
extern uint16_t __attribute__ ((aligned (256))) M_Foreground[16];
extern uint16_t __attribute__ ((aligned (256))) M_Background[16];
#ifdef rp2350
extern uint16_t *tilefcols;
extern uint16_t *tilebcols;
#else
extern uint16_t __attribute__ ((aligned (256))) tilefcols[80*40];
extern uint16_t __attribute__ ((aligned (256))) tilebcols[80*40];
#endif
extern void VGArecovery(int pin);
#else
extern int MODE_H_SYNC_POLARITY, MODE_V_TOTAL_LINES, MODE_ACTIVE_LINES, MODE_ACTIVE_PIXELS;
extern int MODE_H_ACTIVE_PIXELS, MODE_H_FRONT_PORCH, MODE_H_SYNC_WIDTH, MODE_H_BACK_PORCH;
extern int MODE_V_SYNC_POLARITY ,MODE_V_ACTIVE_LINES ,MODE_V_FRONT_PORCH, MODE_V_SYNC_WIDTH, MODE_V_BACK_PORCH;
#endif
extern int MODE1SIZE;
extern int MODE2SIZE;
extern int MODE3SIZE;
extern int MODE4SIZE;
extern int MODE5SIZE;
#endif
#ifdef PICOMITEWEB
extern volatile int WIFIconnected;
extern volatile int scantimer;
extern int startupcomplete;
extern void ProcessWeb(int mode);
extern void WebConnect(void);
extern void close_tcpclient(void);
#endif
// console related I/O
#ifdef USBKEYBOARD
extern void clearrepeat(void);
extern uint8_t Current_USB_devices;
extern void cmd_mouse(void);
extern bool USBenabled;
#endif
int __not_in_flash_func(MMInkey)(void);
int MMgetchar(void);
char MMputchar(char c, int flush);
void SaveProgramToFlash(unsigned char *pm, int msg);
void CheckAbort(void);
void EditInputLine(void);
// empty functions used in MMBasic but must be maintained outside of the interpreter
void UnloadFont(int);
#define NBRFONTS 0
#define STATE_VECTOR_LENGTH 624
#define STATE_VECTOR_M 397 /* changes to STATE_VECTOR_LENGTH also require changes to this */
typedef struct tagMTRand {
unsigned long mt[STATE_VECTOR_LENGTH];
int index;
} MTRand;
void seedRand(unsigned long seed);
unsigned long genRandLong(MTRand* rand);
MMFLOAT genRand(MTRand* rand);
extern struct tagMTRand *g_myrand;
#if defined(MSVCC)
#define mkdir _mkdir
#define rmdir _rmdir
#define chdir _chdir
#define getcwd _getcwd
#define kbhit _kbhit
#define getch _getch
#define ungetch _ungetch
#define putch _putch
#endif
#endif
#define CURSOR_OFF 350 // cursor off time in mS
#define CURSOR_ON 650 // cursor on time in mS
#define dp(...) {unsigned char s[140];sprintf((char *)s, __VA_ARGS__); MMPrintString((char *)s); MMPrintString((char *)"\r\n");}
#define TAB 0x9
#define BKSP 0x8
#define ENTER 0xd
#define ESC 0x1b
// the values returned by the function keys
#define F1 0x91
#define F2 0x92
#define F3 0x93
#define F4 0x94
#define F5 0x95
#define F6 0x96
#define F7 0x97
#define F8 0x98
#define F9 0x99
#define F10 0x9a
#define F11 0x9b
#define F12 0x9c
// the values returned by special control keys
#define UP 0x80
#define DOWN 0x81
#define LEFT 0x82
#define RIGHT 0x83
#define DOWNSEL 0xA1
#define RIGHTSEL 0xA3
#define INSERT 0x84
#define DEL 0x7f
#define HOME 0x86
#define END 0x87
#define PUP 0x88
#define PDOWN 0x89
#define NUM_ENT ENTER
#define SLOCK 0x8c
#define ALT 0x8b
#define SHIFT_TAB 0x9F
#define SHIFT_DEL 0xa0
#define CTRLKEY(a) (a & 0x1f)
#define DISPLAY_CLS 1
#define REVERSE_VIDEO 3
#define CLEAR_TO_EOL 4
#define CLEAR_TO_EOS 5
#define SCROLL_DOWN 6
#define DRAW_LINE 7
#define CONFIG_TAB2 0b111
#define CONFIG_TAB4 0b001
#define CONFIG_TAB8 0b010
#define WPN 65 //Framebuffer page no.
#define GPIO_PIN_SET 1
#define GPIO_PIN_RESET 0
#define SD_SLOW_SPI_SPEED 0
#define SD_FAST_SPI_SPEED 1
#define NONE_SPI_SPEED 4
#define RESET_COMMAND 9999 // indicates that the reset was caused by the RESET command
#define WATCHDOG_TIMEOUT 9998 // reset caused by the watchdog timer
#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 RESTART_DOAUTORUN 9995 // reset required by OPTION SET (ie, re runs the program)
#define KEYBOARDCLOCK 11
#define KEYBOARDDATA 12
#define ALARM_NUM 0
#define ALARM_IRQ TIMER_IRQ_0
#include "External.h"
#include "MM_Misc.h"
#include "Editor.h"
#include "Draw.h"
#include "XModem.h"
#include "MATHS.h"
#include "Onewire.h"
#include "I2C.h"
#include "SPI.h"
#include "Serial.h"
#include "SPI-LCD.h"
#ifndef PICOMITEVGA
#ifndef PICOMITEWEB
#include "SSD1963.h"
#include "Touch.h"
#include "GUI.h"
#endif
#endif
#ifdef PICOMITEWEB
#include "SSD1963.h"
#include "Touch.h"
#ifdef rp2350
#include "GUI.h"
#endif
#endif
#include "GPS.h"
#include "Audio.h"
#include "PS2Keyboard.h"
/* @endcond */

View File

@ -0,0 +1,116 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// Hom_16x24_LE.c
// Font type : Full (95 characters)
// Font size : 16x24 pixels
// Memory usage : 4564 bytes
#ifndef Hom_16x24_LE_h
#define Hom_16x24_LE_h
const unsigned char Hom_16x24_LE[4564] = {
0x10,0x18,0x20,0x5F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <space>
0x01,0x80,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x03,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0xC0,0x03,0xC0,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // !
0x00,0x00,0x00,0x00,0x06,0x30,0x06,0x30,0x0C,0x60,0x0C,0x60,0x0E,0x70,0x0E,0x70,0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
0x00,0x00,0x00,0x00,0x03,0x18,0x03,0x18,0x07,0x38,0x07,0x38,0x3F,0xFC,0x3F,0xFC,0x06,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x60,0x3F,0xFC,0x3F,0xFC,0x1C,0xE0,0x1C,0xE0,0x1C,0xC0,0x18,0xC0,0x18,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // #
0x01,0x80,0x01,0x80,0x07,0xC0,0x1F,0xF0,0x1F,0xF8,0x3D,0xB8,0x39,0xB8,0x39,0x98,0x3D,0x80,0x1F,0x80,0x0F,0xF0,0x03,0xF8,0x01,0xBC,0x31,0x9C,0x39,0x9C,0x39,0x9C,0x3D,0xB8,0x1F,0xF8,0x07,0xE0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00, // $
0x00,0x00,0x78,0x10,0xF8,0x30,0xCC,0x20,0xCC,0x60,0xCC,0x40,0xCC,0xC0,0xCC,0x80,0x79,0x80,0x01,0x3C,0x03,0x66,0x02,0x66,0x06,0x66,0x0C,0x66,0x0C,0x66,0x18,0x3C,0x10,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // %
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0F,0xC0,0x1C,0xE0,0x1C,0xE0,0x1C,0xE0,0x0F,0xC0,0x07,0x00,0x1F,0x08,0x3B,0x9C,0x71,0xD8,0x71,0xF8,0x70,0xF0,0x78,0xFC,0x3F,0xDE,0x0F,0x8C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // &
0x00,0xE0,0x00,0xC0,0x01,0xC0,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
0x00,0x40,0x00,0xC0,0x01,0xC0,0x01,0x80,0x03,0x80,0x03,0x80,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x03,0x80,0x03,0x80,0x01,0x80,0x01,0xC0,0x00,0xC0,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // (
0x02,0x00,0x03,0x00,0x03,0x80,0x01,0x80,0x01,0xC0,0x01,0xC0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x03,0x80,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // )
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x06,0xD8,0x07,0xF8,0x00,0xC0,0x01,0xE0,0x03,0x30,0x03,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // *
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0xF8,0x1F,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // +
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x80,0x03,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x00,0x00,0x00,0x00, // ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF0,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .
0x00,0x30,0x00,0x70,0x00,0x70,0x00,0x60,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x00,0x07,0x00,0x07,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // /
0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1F,0xF8,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x1C,0x38,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0
0x00,0x00,0x00,0x60,0x00,0xE0,0x01,0xE0,0x03,0xE0,0x07,0xE0,0x1F,0xE0,0x1C,0xE0,0x18,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 1
0x00,0x00,0x07,0xE0,0x1F,0xF8,0x1F,0xF8,0x3C,0x3C,0x38,0x1C,0x38,0x1C,0x00,0x1C,0x00,0x38,0x00,0x78,0x00,0xF0,0x03,0xE0,0x07,0x80,0x0F,0x00,0x1E,0x00,0x3C,0x00,0x3F,0xF8,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 2
0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1F,0xF8,0x3C,0x78,0x38,0x38,0x00,0x38,0x00,0x78,0x01,0xF0,0x01,0xF0,0x00,0xF8,0x00,0x3C,0x30,0x1C,0x38,0x1C,0x38,0x3C,0x3C,0x78,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 3
0x00,0x00,0x00,0x60,0x00,0xF0,0x00,0xF0,0x01,0xF0,0x03,0xF0,0x03,0x70,0x07,0x70,0x0E,0x70,0x0C,0x70,0x1C,0x70,0x38,0x70,0x38,0x70,0x3F,0xFC,0x3F,0xFC,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 4
0x00,0x00,0x1F,0xFC,0x1F,0xFC,0x1F,0xF8,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xE0,0x1F,0xF0,0x1F,0xF8,0x1C,0x3C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x38,0x1C,0x3C,0x38,0x3F,0xF8,0x1F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 5
0x00,0x00,0x03,0xE0,0x0F,0xF0,0x1F,0xF8,0x1C,0x38,0x3C,0x18,0x38,0x00,0x38,0x00,0x3B,0xE0,0x3F,0xF0,0x3F,0xF8,0x3C,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x1C,0x3C,0x1F,0xF8,0x0F,0xF0,0x03,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 6
0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x1F,0xFC,0x00,0x38,0x00,0x70,0x00,0x70,0x00,0xE0,0x01,0xC0,0x01,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x07,0x80,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 7
0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1F,0xF8,0x1E,0x78,0x1C,0x38,0x1C,0x38,0x1E,0x78,0x0F,0xF0,0x0F,0xF0,0x1C,0x38,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 8
0x00,0x00,0x07,0xC0,0x0F,0xF0,0x1F,0xF8,0x3C,0x38,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x3C,0x1F,0xFC,0x0F,0xFC,0x07,0xDC,0x00,0x1C,0x00,0x1C,0x18,0x3C,0x1C,0x38,0x1F,0xF8,0x0F,0xF0,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 9
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // :
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x80,0x03,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x02,0x00,0x00,0x00, // ;
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x38,0x00,0xF8,0x03,0xF8,0x0F,0xC0,0x1F,0x00,0x1C,0x00,0x1F,0x00,0x0F,0xC0,0x03,0xF8,0x00,0xF8,0x00,0x38,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x3F,0xFC,0x3F,0xFC,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // =
0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1C,0x00,0x1F,0x00,0x1F,0xC0,0x03,0xF0,0x00,0xF8,0x00,0x38,0x00,0xF8,0x03,0xF0,0x1F,0xC0,0x1F,0x00,0x1C,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // >
0x07,0xC0,0x0F,0xF0,0x1F,0xF0,0x3C,0x78,0x38,0x38,0x38,0x38,0x30,0x38,0x00,0x70,0x00,0xF0,0x01,0xE0,0x03,0xC0,0x03,0x80,0x03,0x80,0x01,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ?
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x0F,0xF8,0x1C,0x1C,0x10,0x04,0x23,0xB6,0x27,0xF2,0x4C,0x72,0x5C,0x62,0x58,0x62,0x58,0x62,0x58,0x64,0x58,0xEC,0x6F,0xF8,0x27,0x70,0x30,0x06,0x18,0x0C,0x0F,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00, // @
0x00,0x00,0x00,0x00,0x01,0x80,0x03,0xC0,0x03,0xC0,0x07,0xE0,0x07,0xE0,0x0E,0x60,0x0E,0x70,0x0E,0x70,0x1C,0x78,0x1C,0x38,0x1C,0x38,0x3F,0xFC,0x3F,0xFC,0x38,0x1C,0x70,0x0E,0x70,0x0E,0x60,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // A
0x00,0x00,0x00,0x00,0x3F,0xE0,0x3F,0xF0,0x38,0x78,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x3F,0xF0,0x3F,0xF0,0x38,0x38,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x3C,0x3F,0xF8,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // B
0x00,0x00,0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1E,0x78,0x3C,0x3C,0x38,0x1C,0x78,0x0C,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x00,0x70,0x0C,0x70,0x0C,0x38,0x1C,0x3C,0x3C,0x1E,0x78,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // C
0x00,0x00,0x00,0x00,0x3F,0xC0,0x3F,0xF0,0x38,0xF0,0x38,0x78,0x38,0x38,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x38,0x38,0x78,0x38,0xF0,0x3F,0xF0,0x3F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // D
0x00,0x00,0x00,0x00,0x1F,0xFC,0x1F,0xFC,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xF8,0x1F,0xF8,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xFC,0x1F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // E
0x00,0x00,0x00,0x00,0x0F,0xFC,0x0F,0xFC,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0F,0xF8,0x0F,0xF8,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // F
0x00,0x00,0x00,0x00,0x03,0xE0,0x0F,0xF8,0x1C,0x3C,0x38,0x1C,0x38,0x0E,0x70,0x0C,0x70,0x00,0x70,0x00,0x70,0xFE,0x70,0xFE,0x70,0x0E,0x70,0x0E,0x38,0x0E,0x38,0x0E,0x1C,0x3E,0x0F,0xFC,0x03,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // G
0x00,0x00,0x00,0x00,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3F,0xFC,0x3F,0xFC,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // H
0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // I
0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xE0,0x70,0xE0,0x70,0xE0,0x70,0xE0,0x79,0xE0,0x3F,0xC0,0x3F,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // J
0x00,0x00,0x00,0x00,0x38,0x0C,0x38,0x1C,0x38,0x3C,0x38,0x78,0x38,0xF0,0x39,0xE0,0x3B,0xC0,0x3F,0xC0,0x3F,0xE0,0x3E,0xF0,0x3C,0x70,0x38,0x78,0x38,0x3C,0x38,0x3C,0x38,0x1E,0x38,0x0E,0x38,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // K
0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1F,0xF8,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // L
0x00,0x00,0x00,0x00,0xF8,0x1F,0xF8,0x1F,0xFC,0x3F,0xFC,0x3F,0xFC,0x3F,0xEC,0x37,0xEE,0x77,0xEE,0x77,0xEE,0x77,0xE6,0x67,0xE7,0xE7,0xE7,0xE7,0xE7,0xE7,0xE3,0xC7,0xE3,0xC7,0xE3,0xC7,0xE1,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // M
0x00,0x00,0x00,0x00,0x18,0x1C,0x3C,0x1C,0x3C,0x1C,0x3E,0x1C,0x3E,0x1C,0x3F,0x1C,0x3B,0x1C,0x3B,0x9C,0x39,0x9C,0x39,0xDC,0x38,0xDC,0x38,0xFC,0x38,0x7C,0x38,0x7C,0x38,0x3C,0x38,0x3C,0x38,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // N
0x00,0x00,0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1F,0xF8,0x3C,0x3C,0x38,0x1C,0x78,0x1E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x78,0x1E,0x38,0x1C,0x3C,0x3C,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // O
0x00,0x00,0x00,0x00,0x3F,0xF0,0x3F,0xF8,0x38,0x3C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x38,0x3F,0xF8,0x3F,0xE0,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // P
0x00,0x00,0x00,0x00,0x07,0xE0,0x0F,0xF0,0x1F,0xF8,0x3C,0x3C,0x38,0x1C,0x78,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x70,0x0E,0x79,0x9E,0x38,0xFC,0x3C,0x7C,0x1F,0xF8,0x0F,0xFE,0x07,0xEF,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Q
0x00,0x00,0x00,0x00,0x3F,0xF8,0x3F,0xFC,0x38,0x1E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x1E,0x3F,0xFC,0x3F,0xF0,0x38,0xE0,0x38,0x70,0x38,0x78,0x38,0x3C,0x38,0x3C,0x38,0x1E,0x38,0x0E,0x38,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // R
0x00,0x00,0x00,0x00,0x07,0xE0,0x1F,0xF0,0x1C,0x38,0x38,0x38,0x38,0x18,0x3C,0x00,0x3F,0x00,0x1F,0xE0,0x0F,0xF8,0x01,0xF8,0x00,0x3C,0x30,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x38,0x1F,0xF8,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // S
0x00,0x00,0x00,0x00,0x7F,0xFC,0x7F,0xFC,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // T
0x00,0x00,0x00,0x00,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x3C,0x38,0x1F,0xF8,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // U
0x00,0x00,0x00,0x00,0x38,0x06,0x38,0x0E,0x38,0x0E,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x0E,0x18,0x0E,0x38,0x0E,0x38,0x0E,0x30,0x07,0x70,0x07,0x70,0x07,0x60,0x03,0xE0,0x03,0xE0,0x03,0xC0,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // V
0x00,0x00,0x00,0x00,0xC1,0x83,0xC3,0xC3,0xE3,0xC7,0xE3,0xC7,0xE3,0xC7,0x63,0xC6,0x66,0x66,0x66,0x66,0x76,0x6E,0x76,0x6E,0x36,0x6C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x1C,0x38,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // W
0x00,0x00,0x00,0x00,0x30,0x0C,0x38,0x1E,0x3C,0x1C,0x1C,0x3C,0x1E,0x78,0x0F,0xF0,0x07,0xF0,0x07,0xE0,0x03,0xC0,0x07,0xE0,0x0F,0xF0,0x1F,0xF8,0x1E,0x78,0x3C,0x3C,0x78,0x1E,0x78,0x1E,0x70,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // X
0x00,0x00,0x00,0x00,0x30,0x18,0x78,0x1C,0x38,0x38,0x3C,0x38,0x1C,0x70,0x1E,0xF0,0x0E,0xE0,0x07,0xC0,0x07,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Y
0x00,0x00,0x00,0x00,0x3F,0xF8,0x3F,0xF8,0x00,0x78,0x00,0x78,0x00,0xF0,0x01,0xF0,0x01,0xE0,0x03,0xC0,0x07,0x80,0x07,0x80,0x0F,0x00,0x1E,0x00,0x1E,0x00,0x3C,0x00,0x78,0x00,0x7F,0xFC,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Z
0x00,0x00,0x01,0xE0,0x01,0xE0,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0xE0,0x01,0xE0,0x00,0x00,0x00,0x00, // [
0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x0E,0x00,0x0F,0x00,0x07,0x00,0x07,0x00,0x07,0x80,0x03,0x80,0x03,0x80,0x03,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xE0,0x00,0xE0,0x00,0xE0,0x00,0xF0,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <backslash>
0x00,0x00,0x0F,0x80,0x0F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x0F,0x80,0x0F,0x80,0x00,0x00,0x00,0x00, // ]
0x00,0x00,0x00,0x00,0x03,0x80,0x07,0x80,0x07,0x80,0x07,0xC0,0x0E,0xC0,0x0C,0xE0,0x1C,0xE0,0x1C,0x60,0x38,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // _
0x00,0x00,0x00,0x00,0x1C,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // `
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x1F,0xE0,0x18,0x70,0x10,0x70,0x00,0xF0,0x0F,0xF0,0x1E,0x70,0x38,0x70,0x38,0x70,0x38,0xF0,0x1F,0xF0,0x0E,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // a
0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x1D,0xF0,0x1F,0xF8,0x1E,0x38,0x1E,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1E,0x1C,0x1E,0x38,0x1F,0xF8,0x1D,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // b
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0xF0,0x1C,0x70,0x3C,0x38,0x38,0x10,0x38,0x00,0x38,0x00,0x38,0x10,0x3C,0x38,0x1C,0x78,0x0F,0xF0,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // c
0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x0F,0xB8,0x1F,0xF8,0x1C,0x78,0x38,0x78,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x78,0x1C,0x78,0x1F,0xF8,0x07,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // d
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0xE0,0x1C,0x70,0x38,0x38,0x38,0x38,0x3F,0xF8,0x3F,0xF0,0x38,0x00,0x38,0x10,0x1C,0x38,0x0F,0xF0,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // e
0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0xE0,0x07,0x00,0x07,0x00,0x07,0x00,0x1F,0xC0,0x1F,0xC0,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // f
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xB8,0x1F,0xF8,0x1C,0x78,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x1C,0x78,0x1F,0xF8,0x07,0xB8,0x10,0x38,0x38,0x38,0x1C,0x70,0x1F,0xF0,0x07,0xC0, // g
0x00,0x00,0x00,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x3B,0xC0,0x3F,0xE0,0x3C,0xF0,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x38,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // h
0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // i
0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x1F,0x80,0x1F,0x00, // j
0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x18,0x0E,0x38,0x0E,0x70,0x0E,0xE0,0x0F,0xC0,0x0F,0xE0,0x0F,0x70,0x0E,0x70,0x0E,0x38,0x0E,0x38,0x0E,0x1C,0x0E,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // k
0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // l
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0x9E,0xFF,0xFF,0xF1,0xE7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0xE1,0xC7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // m
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1D,0xE0,0x1F,0xF0,0x1E,0x78,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // n
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x1F,0xC0,0x38,0xE0,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x38,0xE0,0x1F,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // o
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0xC0,0x3F,0xF0,0x3C,0x70,0x3C,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x3C,0x38,0x3C,0x70,0x3F,0xF0,0x3B,0xC0,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00, // p
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xB8,0x1F,0xF8,0x1C,0x78,0x38,0x78,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x78,0x1C,0x78,0x1F,0xF8,0x07,0xB8,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38, // q
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0xE0,0x0F,0xF0,0x0F,0x10,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // r
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0xF0,0x1C,0x70,0x1C,0x30,0x1F,0x00,0x0F,0xE0,0x03,0xF0,0x00,0x78,0x1C,0x38,0x1E,0x38,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // s
0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x07,0xE0,0x0F,0xE0,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0xF0,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // t
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x1E,0x78,0x0F,0xF8,0x07,0xB8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // u
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1C,0x38,0x1C,0x38,0x0C,0x30,0x0E,0x70,0x0E,0x70,0x06,0x60,0x07,0xE0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // v
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0x83,0xE3,0xC7,0xE3,0xC7,0x63,0xC6,0x67,0xE6,0x76,0x6E,0x36,0x6C,0x36,0x6C,0x3E,0x7C,0x1C,0x38,0x1C,0x38,0x1C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // w
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x3C,0x78,0x1E,0xF0,0x0F,0xE0,0x07,0xC0,0x07,0xC0,0x0F,0xE0,0x0E,0xE0,0x1E,0xF0,0x3C,0x78,0x38,0x38,0x30,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // x
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1C,0x38,0x1C,0x38,0x0C,0x30,0x0E,0x70,0x0E,0x70,0x06,0x60,0x07,0x60,0x07,0xE0,0x03,0xC0,0x03,0xC0,0x03,0xC0,0x01,0x80,0x03,0x80,0x03,0x80,0x1F,0x00,0x1E,0x00, // y
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x3F,0xF8,0x00,0x78,0x00,0xF0,0x01,0xE0,0x03,0xC0,0x07,0x80,0x07,0x00,0x0E,0x00,0x1E,0x00,0x3F,0xF8,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // z
0x00,0x70,0x00,0xF0,0x01,0xF0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x03,0x80,0x07,0x80,0x07,0x80,0x03,0x80,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x01,0xF0,0x00,0xF0,0x00,0x70,0x00,0x00,0x00,0x00, // {
0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00, // |
0x1C,0x00,0x1E,0x00,0x1F,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x03,0x80,0x03,0xC0,0x03,0xC0,0x03,0x80,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x07,0x00,0x1F,0x00,0x1E,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, // }
0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x08,0x3F,0xF8,0x3F,0xF8,0x20,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
};
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,499 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
I2C.h
<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.
************************************************************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#ifndef I2C_HEADER
#define I2C_HEADER
// states of the master state machine
#define I2C_State_Idle 0 // Bus Idle
#define I2C_State_Start 1 // Sending Start or Repeated Start
#define I2C_State_10Bit 2 // Sending a 10 bit address
#define I2C_State_10BitRcv 3 // 10 bit address receive
#define I2C_State_RcvAddr 4 // Receive address
#define I2C_State_Send 5 // Sending Data
#define I2C_State_Receive 6 // Receiving data
#define I2C_State_Ack 7 // Sending Acknowledgement
#define I2C_State_Stop 8 // Sending Stop
// defines for I2C_Status
#define I2C_Status_Enabled 0x00000001
#define I2C_Status_MasterCmd 0x00000002
#define I2C_Status_NoAck 0x00000010
#define I2C_Status_Timeout 0x00000020
#define I2C_Status_InProgress 0x00000040
#define I2C_Status_Completed 0x00000080
#define I2C_Status_Interrupt 0x00000100
#define I2C_Status_BusHold 0x00000200
#define I2C_Status_10BitAddr 0x00000400
#define I2C_Status_BusOwned 0x00000800
#define I2C_Status_Send 0x00001000
#define I2C_Status_Receive 0x00002000
#define I2C_Status_Disable 0x00004000
#define I2C_Status_Master 0x00008000
#define I2C_Status_Slave 0x00010000
#define I2C_Status_Slave_Send 0x00020000
#define I2C_Status_Slave_Receive 0x00040000
#define I2C_Status_Slave_Send_Rdy 0x00080000
#define I2C_Status_Slave_Receive_Rdy 0x00100000
#define I2C_Status_Slave_Receive_Full 0x00200000
#define SSD1306_I2C_Addr 0x3c
// 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
extern void i2c_disable(void);
extern void i2c2_disable(void);
extern void RtcGetTime(int noerror);
extern void ConfigDisplayI2C(unsigned char *p);
extern void InitDisplayI2C(int InitOnly);
extern bool I2C2_enabled; // I2C enable marker
extern bool I2C_enabled; // I2C enable marker
extern unsigned int I2C_Timeout; // master timeout value
extern unsigned int I2C2_Timeout; // master timeout value
extern volatile unsigned int I2C_Status; // status flags
extern volatile unsigned int I2C2_Status; // status flags
extern bool noRTC, noI2C;
extern char *I2C_Slave_Send_IntLine; // pointer to the slave send interrupt line number
extern char *I2C_Slave_Receive_IntLine; // pointer to the slave receive interrupt line number
extern char *I2C2_Slave_Send_IntLine; // pointer to the slave send interrupt line number
extern char *I2C2_Slave_Receive_IntLine; // pointer to the slave receive interrupt line number
#ifdef PICOCALC
extern void I2C_Send_RegData(int i2caddr,int reg,char command);
#endif
extern void I2C_Send_Command(char command);
extern void CheckI2CKeyboard(int noerror, int read);
extern void cmd_camera(void);
extern void cmd_Classic(void);
extern void cameraclose(void);
typedef struct {
uint8_t reg; ///< Register address
uint8_t value; ///< Value to store
} OV7670_command;
typedef enum {
OV7670_SIZE_DIV1 = 0, ///< 640 x 480
OV7670_SIZE_DIV2, ///< 320 x 240
OV7670_SIZE_DIV4, ///< 160 x 120
OV7670_SIZE_DIV8, ///< 80 x 60
OV7670_SIZE_DIV16, ///< 40 x 30
} OV7670_size;
typedef enum {
OV7670_TEST_PATTERN_NONE = 0, ///< Disable test pattern
OV7670_TEST_PATTERN_SHIFTING_1, ///< "Shifting 1" pattern
OV7670_TEST_PATTERN_COLOR_BAR, ///< 8 color bars
OV7670_TEST_PATTERN_COLOR_BAR_FADE, ///< Color bars w/fade to white
} OV7670_pattern;
typedef struct s_nunstruct {
char x;
char y;
int ax; //classic left x
int ay; //classic left y
int az; //classic centre
int Z; //classic right x
int C; //classic right y
int L; //classic left analog
int R; //classic right analog
unsigned short x0; //classic buttons
unsigned short y0;
unsigned short z0;
unsigned short x1;
unsigned short y1;
unsigned short z1;
uint64_t type;
uint8_t calib[16];
uint8_t classic[6];
int16_t gyro[3], accs[3];
} a_nunstruct;
extern volatile uint8_t classic1, nunchuck1;
extern char *nunInterruptc[];
extern bool nunfoundc[];
extern void classicproc(void);
extern void nunproc(void);
extern uint8_t nunbuff[];
extern const unsigned char readcontroller[1];
extern uint8_t readRegister8(unsigned int addr, uint8_t reg);
extern void WriteRegister8(unsigned int addr, uint8_t reg, uint8_t data);
extern uint32_t readRegister32(unsigned int addr, uint8_t reg);
extern void Write8Register16(unsigned int addr, uint16_t reg, uint8_t data);
extern uint8_t read8Register16(unsigned int addr, uint16_t reg);
extern volatile struct s_nunstruct nunstruct[6];
extern void WiiReceive(int nbr, char *p);
extern void WiiSend(int nbr, char *p);
extern int mmI2Cvalue;
extern unsigned char classicread, nunchuckread;
#define REG_GAIN 0x00 // Gain lower 8 bits (rest in vref
#define REG_BLUE 0x01 // blue gain
#define REG_RED 0x02 // red gain
#define REG_VREF 0x03 // Pieces of GAIN, VSTART, VSTOP
#define REG_COM1 0x04 // Control 1
#define COM1_CCIR656 0x40 // CCIR656 enable
#define REG_BAVE 0x05 // U/B Average level
#define REG_GbAVE 0x06 // Y/Gb Average level
#define REG_AECHH 0x07 // AEC MS 5 bits
#define REG_RAVE 0x08 // V/R Average level
#define REG_COM2 0x09 // Control 2
#define COM2_SSLEEP 0x10 // Soft sleep mode
#define REG_PID 0x0a // Product ID MSB
#define REG_VER 0x0b // Product ID LSB
#define REG_COM3 0x0c // Control 3
#define COM3_SWAP 0x40 // Byte swap
#define COM3_SCALEEN 0x08 // Enable scaling
#define COM3_DCWEN 0x04 // Enable downsamp/crop/window
#define REG_COM4 0x0d // Control 4
#define REG_COM5 0x0e // All "reserved"
#define REG_COM6 0x0f // Control 6
#define REG_AECH 0x10 // More bits of AEC value
#define REG_CLKRC 0x11 // Clocl control
#define CLK_EXT 0x40 // Use external clock directly
#define CLK_SCALE 0x3f // Mask for internal clock scale
#define REG_COM7 0x12 // Control 7
#define COM7_RESET 0x80 // Register reset
#define COM7_FMT_MASK 0x38 //
#define COM7_FMT_VGA 0x00 // VGA format
#define COM7_FMT_CIF 0x20 // CIF format
#define COM7_FMT_QVGA 0x10 // QVGA format
#define COM7_FMT_QCIF 0x08 // QCIF format
#define COM7_RGB 0x04 // bits 0 and 2 - RGB format
#define COM7_YUV 0x00 // YUV
#define COM7_BAYER 0x01 // Bayer format
#define COM7_PBAYER 0x05 // "Processed bayer"
#define COM7_COLOR_BAR 0x02 // Enable Color Bar
#define REG_COM8 0x13 // Control 8
#define COM8_FASTAEC 0x80 // Enable fast AGC/AEC
#define COM8_AECSTEP 0x40 // Unlimited AEC step size
#define COM8_BFILT 0x20 // Band filter enable
#define COM8_AGC 0x04 // Auto gain enable
#define COM8_AWB 0x02 // White balance enable
#define COM8_AEC 0x01 // Auto exposure enable
#define REG_COM9 0x14 // Control 9 - gain ceiling
#define REG_COM10 0x15 // Control 10
#define COM10_HSYNC 0x40 // HSYNC instead of HREF
#define COM10_PCLK_HB 0x20 // Suppress PCLK on horiz blank
#define COM10_HREF_REV 0x08 // Reverse HREF
#define COM10_VS_LEAD 0x04 // VSYNC on clock leading edge
#define COM10_VS_NEG 0x02 // VSYNC negative
#define COM10_HS_NEG 0x01 // HSYNC negative
#define REG_HSTART 0x17 // Horiz start high bits
#define REG_HSTOP 0x18 // Horiz stop high bits
#define REG_VSTART 0x19 // Vert start high bits
#define REG_VSTOP 0x1a // Vert stop high bits
#define REG_PSHFT 0x1b // Pixel delay after HREF
#define REG_MIDH 0x1c // Manuf. ID high
#define REG_MIDL 0x1d // Manuf. ID low
#define REG_MVFP 0x1e // Mirror / vflip
#define MVFP_MIRROR 0x20 // Mirror image
#define MVFP_FLIP 0x10 // Vertical flip
#define REG_AEW 0x24 // AGC upper limit
#define REG_AEB 0x25 // AGC lower limit
#define REG_VPT 0x26 // AGC/AEC fast mode op region
#define REG_HSYST 0x30 // HSYNC rising edge delay
#define REG_HSYEN 0x31 // HSYNC falling edge delay
#define REG_HREF 0x32 // HREF pieces
#define REG_TSLB 0x3a // lots of stuff
#define TSLB_YLAST 0x04 // UYVY or VYUY - see com13
#define TSLB_UV 0x10 // enable special effects
#define TSLB_NEGATIVE 0x20 // enable special effects
#define REG_COM11 0x3b // Control 11
#define COM11_NIGHT 0x80 // Night mode enable
#define COM11_NIGHT_FR2 0x20 // Night mode 1/2 of normal framerate
#define COM11_NIGHT_FR4 0x40 // Night mode 1/4 of normal framerate
#define COM11_NIGHT_FR8 0x60 // Night mode 1/8 of normal framerate
#define COM11_HZAUTO 0x10 // Auto detect 50/60 Hz
#define COM11_50HZ 0x08 // Manual 50Hz select
#define COM11_EXP 0x02 // Exposure timing can be less than limit
#define REG_COM12 0x3c // Control 12
#define COM12_HREF 0x80 // HREF always
#define REG_COM13 0x3d // Control 13
#define COM13_GAMMA 0x80 // Gamma enable
#define COM13_UVSAT 0x40 // UV saturation auto adjustment
#define COM13_UVSWAP 0x01 // V before U - w/TSLB
#define REG_COM14 0x3e // Control 14
#define COM14_DCWEN 0x10 // DCW/PCLK-scale enable
#define COM14_MAN_SCAL 0x08 // Manual scaling enable
#define COM14_PCLK_DIV1 0x00 // PCLK divided by 1
#define COM14_PCLK_DIV2 0x01 // PCLK divided by 2
#define COM14_PCLK_DIV4 0x02 // PCLK divided by 4
#define COM14_PCLK_DIV8 0x03 // PCLK divided by 8
#define COM14_PCLK_DIV16 0x04 // PCLK divided by 16
#define REG_EDGE 0x3f // Edge enhancement factor
#define REG_COM15 0x40 // Control 15
#define COM15_R10F0 0x00 // Data range 10 to F0
#define COM15_R01FE 0x80 // 01 to FE
#define COM15_R00FF 0xc0 // 00 to FF
#define COM15_RGB565 0x10 // RGB565 output
#define COM15_RGB555 0x30 // RGB555 output
#define COM15_RGB444 0x10 // RGB444 output
#define REG_COM16 0x41 // Control 16
#define COM16_AWBGAIN 0x08 // AWB gain enable
#define COM16_DENOISE 0x10 // Enable de-noise auto adjustment
#define COM16_EDGE 0x20 // Enable edge enhancement
#define REG_COM17 0x42 // Control 17
#define COM17_AECWIN 0xc0 // AEC window - must match COM4
#define COM17_CBAR 0x08 // DSP Color bar
#define REG_DENOISE_STRENGTH 0x4c // De-noise strength
#define REG_SCALING_XSC 0x70
#define REG_SCALING_YSC 0x71
#define REG_SCALING_DCWCTR 0x72
#define REG_SCALING_PCLK_DIV 0x73
#define REG_SCALING_PCLK_DELAY 0xa2
// QQVGA setting
#define HSTART_QQVGA 0x16
#define HSTOP_QQVGA 0x04
#define HREF_QQVGA 0xa4 //0x24? 0xa4?
#define VSTART_QQVGA 0x02
#define VSTOP_QQVGA 0x7a
#define VREF_QQVGA 0x0a
#define COM3_QQVGA 0x04
#define COM14_QQVGA 0x1A
#define SCALING_XSC_QQVGA 0x3a
#define SCALING_YSC_QQVGA 0x35
#define SCALING_DCWCTR_QQVGA 0x22
#define SCALING_PCLK_DIV_QQVGA 0xf2
#define SCALING_PCLK_DELAY_QQVGA 0x02
#define REG_CMATRIX_BASE 0x4f
#define REG_CMATRIX_1 0x4f
#define REG_CMATRIX_2 0x50
#define REG_CMATRIX_3 0x51
#define REG_CMATRIX_4 0x52
#define REG_CMATRIX_5 0x53
#define REG_CMATRIX_6 0x54
#define CMATRIX_LEN 6
#define REG_CMATRIX_SIGN 0x58
//
#define REG_BRIGHT 0x55 // Brightness
#define REG_CONTRAST 0x56 // Contrast control
#define REG_GFIX 0x69 // Fix gain control
#define REG_GGAIN 0x6a // G channel AWB gain
#define REG_DBLV 0x6b // PLL control
#define REG_REG76 0x76 // OV//s name
#define R76_BLKPCOR 0x80 // Black pixel correction enable
#define R76_WHTPCOR 0x40 // White pixel correction enable
#define REG_RGB444 0x8c // RGB 444 control
#define R444_ENABLE 0x02 // Turn on RGB444, overrides 5x5
#define R444_RGBX 0x01 // Empty nibble at end
#define R444_XBGR 0x00
#define REG_HAECC1 0x9f // Hist AEC/AGC control 1
#define REG_HAECC2 0xa0 // Hist AEC/AGC control 2
#define REG_BD50MAX 0xa5 // 50hz banding step limit
#define REG_HAECC3 0xa6 // Hist AEC/AGC control 3
#define REG_HAECC4 0xa7 // Hist AEC/AGC control 4
#define REG_HAECC5 0xa8 // Hist AEC/AGC control 5
#define REG_HAECC6 0xa9 // Hist AEC/AGC control 6
#define REG_HAECC7 0xaa // Hist AEC/AGC control 7
#define REG_BD60MAX 0xab // 60hz banding step limit
#define OV7670_REG_GAIN 0x00 //< AGC gain bits 7:0 (9:8 in VREF)
#define OV7670_REG_BLUE 0x01 //< AWB blue channel gain
#define OV7670_REG_RED 0x02 //< AWB red channel gain
#define OV7670_REG_VREF 0x03 //< Vert frame control bits
#define OV7670_REG_COM1 0x04 //< Common control 1
#define OV7670_COM1_R656 0x40 //< COM1 enable R656 format
#define OV7670_REG_BAVE 0x05 //< U/B average level
#define OV7670_REG_GbAVE 0x06 //< Y/Gb average level
#define OV7670_REG_AECHH 0x07 //< Exposure value - AEC 15:10 bits
#define OV7670_REG_RAVE 0x08 //< V/R average level
#define OV7670_REG_COM2 0x09 //< Common control 2
#define OV7670_COM2_SSLEEP 0x10 //< COM2 soft sleep mode
#define OV7670_REG_PID 0x0A //< Product ID MSB (read-only)
#define OV7670_REG_VER 0x0B //< Product ID LSB (read-only)
#define OV7670_REG_COM3 0x0C //< Common control 3
#define OV7670_COM3_SWAP 0x40 //< COM3 output data MSB/LSB swap
#define OV7670_COM3_SCALEEN 0x08 //< COM3 scale enable
#define OV7670_COM3_DCWEN 0x04 //< COM3 DCW enable
#define OV7670_REG_COM4 0x0D //< Common control 4
#define OV7670_REG_COM5 0x0E //< Common control 5
#define OV7670_REG_COM6 0x0F //< Common control 6
#define OV7670_REG_AECH 0x10 //< Exposure value 9:2
#define OV7670_REG_CLKRC 0x11 //< Internal clock
#define OV7670_CLK_EXT 0x40 //< CLKRC Use ext clock directly
#define OV7670_CLK_SCALE 0x3F //< CLKRC Int clock prescale mask
#define OV7670_REG_COM7 0x12 //< Common control 7
#define OV7670_COM7_RESET 0x80 //< COM7 SCCB register reset
#define OV7670_COM7_SIZE_MASK 0x38 //< COM7 output size mask
#define OV7670_COM7_PIXEL_MASK 0x05 //< COM7 output pixel format mask
#define OV7670_COM7_SIZE_VGA 0x00 //< COM7 output size VGA
#define OV7670_COM7_SIZE_CIF 0x20 //< COM7 output size CIF
#define OV7670_COM7_SIZE_QVGA 0x10 //< COM7 output size QVGA
#define OV7670_COM7_SIZE_QCIF 0x08 //< COM7 output size QCIF
#define OV7670_COM7_RGB 0x04 //< COM7 pixel format RGB
#define OV7670_COM7_YUV 0x00 //< COM7 pixel format YUV
#define OV7670_COM7_BAYER 0x01 //< COM7 pixel format Bayer RAW
#define OV7670_COM7_PBAYER 0x05 //< COM7 pixel fmt proc Bayer RAW
#define OV7670_COM7_COLORBAR 0x02 //< COM7 color bar enable
#define OV7670_REG_COM8 0x13 //< Common control 8
#define OV7670_COM8_FASTAEC 0x80 //< COM8 Enable fast AGC/AEC algo,
#define OV7670_COM8_AECSTEP 0x40 //< COM8 AEC step size unlimited
#define OV7670_COM8_BANDING 0x20 //< COM8 Banding filter enable
#define OV7670_COM8_AGC 0x04 //< COM8 AGC (auto gain) enable
#define OV7670_COM8_AWB 0x02 //< COM8 AWB (auto white balance)
#define OV7670_COM8_AEC 0x01 //< COM8 AEC (auto exposure) enable
#define OV7670_REG_COM9 0x14 //< Common control 9 - max AGC value
#define OV7670_REG_COM10 0x15 //< Common control 10
#define OV7670_COM10_HSYNC 0x40 //< COM10 HREF changes to HSYNC
#define OV7670_COM10_PCLK_HB 0x20 //< COM10 Suppress PCLK on hblank
#define OV7670_COM10_HREF_REV 0x08 //< COM10 HREF reverse
#define OV7670_COM10_VS_EDGE 0x04 //< COM10 VSYNC chg on PCLK rising
#define OV7670_COM10_VS_NEG 0x02 //< COM10 VSYNC negative
#define OV7670_COM10_HS_NEG 0x01 //< COM10 HSYNC negative
#define OV7670_REG_HSTART 0x17 //< Horiz frame start high bits
#define OV7670_REG_HSTOP 0x18 //< Horiz frame end high bits
#define OV7670_REG_VSTART 0x19 //< Vert frame start high bits
#define OV7670_REG_VSTOP 0x1A //< Vert frame end high bits
#define OV7670_REG_PSHFT 0x1B //< Pixel delay select
#define OV7670_REG_MIDH 0x1C //< Manufacturer ID high byte
#define OV7670_REG_MIDL 0x1D //< Manufacturer ID low byte
#define OV7670_REG_MVFP 0x1E //< Mirror / vert-flip enable
#define OV7670_MVFP_MIRROR 0x20 //< MVFP Mirror image
#define OV7670_MVFP_VFLIP 0x10 //< MVFP Vertical flip
#define OV7670_REG_LAEC 0x1F //< Reserved
#define OV7670_REG_ADCCTR0 0x20 //< ADC control
#define OV7670_REG_ADCCTR1 0x21 //< Reserved
#define OV7670_REG_ADCCTR2 0x22 //< Reserved
#define OV7670_REG_ADCCTR3 0x23 //< Reserved
#define OV7670_REG_AEW 0x24 //< AGC/AEC upper limit
#define OV7670_REG_AEB 0x25 //< AGC/AEC lower limit
#define OV7670_REG_VPT 0x26 //< AGC/AEC fast mode op region
#define OV7670_REG_BBIAS 0x27 //< B channel signal output bias
#define OV7670_REG_GbBIAS 0x28 //< Gb channel signal output bias
#define OV7670_REG_EXHCH 0x2A //< Dummy pixel insert MSB
#define OV7670_REG_EXHCL 0x2B //< Dummy pixel insert LSB
#define OV7670_REG_RBIAS 0x2C //< R channel signal output bias
#define OV7670_REG_ADVFL 0x2D //< Insert dummy lines MSB
#define OV7670_REG_ADVFH 0x2E //< Insert dummy lines LSB
#define OV7670_REG_YAVE 0x2F //< Y/G channel average value
#define OV7670_REG_HSYST 0x30 //< HSYNC rising edge delay
#define OV7670_REG_HSYEN 0x31 //< HSYNC falling edge delay
#define OV7670_REG_HREF 0x32 //< HREF control
#define OV7670_REG_CHLF 0x33 //< Array current control
#define OV7670_REG_ARBLM 0x34 //< Array ref control - reserved
#define OV7670_REG_ADC 0x37 //< ADC control - reserved
#define OV7670_REG_ACOM 0x38 //< ADC & analog common - reserved
#define OV7670_REG_OFON 0x39 //< ADC offset control - reserved
#define OV7670_REG_TSLB 0x3A //< Line buffer test option
#define OV7670_TSLB_NEG 0x20 //< TSLB Negative image enable
#define OV7670_TSLB_YLAST 0x04 //< TSLB UYVY or VYUY, see COM13
#define OV7670_TSLB_AOW 0x01 //< TSLB Auto output window
#define OV7670_REG_COM11 0x3B //< Common control 11
#define OV7670_COM11_NIGHT 0x80 //< COM11 Night mode
#define OV7670_COM11_NMFR 0x60 //< COM11 Night mode frame rate mask
#define OV7670_COM11_HZAUTO 0x10 //< COM11 Auto detect 50/60 Hz
#define OV7670_COM11_BAND 0x08 //< COM11 Banding filter val select
#define OV7670_COM11_EXP 0x02 //< COM11 Exposure timing control
#define OV7670_REG_COM12 0x3C //< Common control 12
#define OV7670_COM12_HREF 0x80 //< COM12 Always has HREF
#define OV7670_REG_COM13 0x3D //< Common control 13
#define OV7670_COM13_GAMMA 0x80 //< COM13 Gamma enable
#define OV7670_COM13_UVSAT 0x40 //< COM13 UV saturation auto adj
#define OV7670_COM13_UVSWAP 0x01 //< COM13 UV swap, use w TSLB[3]
#define OV7670_REG_COM14 0x3E //< Common control 14
#define OV7670_COM14_DCWEN 0x10 //< COM14 DCW & scaling PCLK enable
#define OV7670_REG_EDGE 0x3F //< Edge enhancement adjustment
#define OV7670_REG_COM15 0x40 //< Common control 15
#define OV7670_COM15_RMASK 0xC0 //< COM15 Output range mask
#define OV7670_COM15_R10F0 0x00 //< COM15 Output range 10 to F0
#define OV7670_COM15_R01FE 0x80 //< COM15 01 to FE
#define OV7670_COM15_R00FF 0xC0 //< COM15 00 to FF
#define OV7670_COM15_RGBMASK 0x30 //< COM15 RGB 555/565 option mask
#define OV7670_COM15_RGB 0x00 //< COM15 Normal RGB out
#define OV7670_COM15_RGB565 0x10 //< COM15 RGB 565 output
#define OV7670_COM15_RGB555 0x30 //< COM15 RGB 555 output
#define OV7670_REG_COM16 0x41 //< Common control 16
#define OV7670_COM16_AWBGAIN 0x08 //< COM16 AWB gain enable
#define OV7670_REG_COM17 0x42 //< Common control 17
#define OV7670_COM17_AECWIN 0xC0 //< COM17 AEC window must match COM4
#define OV7670_COM17_CBAR 0x08 //< COM17 DSP Color bar enable
#define OV7670_REG_AWBC1 0x43 //< Reserved
#define OV7670_REG_AWBC2 0x44 //< Reserved
#define OV7670_REG_AWBC3 0x45 //< Reserved
#define OV7670_REG_AWBC4 0x46 //< Reserved
#define OV7670_REG_AWBC5 0x47 //< Reserved
#define OV7670_REG_AWBC6 0x48 //< Reserved
#define OV7670_REG_REG4B 0x4B //< UV average enable
#define OV7670_REG_DNSTH 0x4C //< De-noise strength
#define OV7670_REG_MTX1 0x4F //< Matrix coefficient 1
#define OV7670_REG_MTX2 0x50 //< Matrix coefficient 2
#define OV7670_REG_MTX3 0x51 //< Matrix coefficient 3
#define OV7670_REG_MTX4 0x52 //< Matrix coefficient 4
#define OV7670_REG_MTX5 0x53 //< Matrix coefficient 5
#define OV7670_REG_MTX6 0x54 //< Matrix coefficient 6
#define OV7670_REG_BRIGHT 0x55 //< Brightness control
#define OV7670_REG_CONTRAS 0x56 //< Contrast control
#define OV7670_REG_CONTRAS_CENTER 0x57 //< Contrast center
#define OV7670_REG_MTXS 0x58 //< Matrix coefficient sign
#define OV7670_REG_LCC1 0x62 //< Lens correction option 1
#define OV7670_REG_LCC2 0x63 //< Lens correction option 2
#define OV7670_REG_LCC3 0x64 //< Lens correction option 3
#define OV7670_REG_LCC4 0x65 //< Lens correction option 4
#define OV7670_REG_LCC5 0x66 //< Lens correction option 5
#define OV7670_REG_MANU 0x67 //< Manual U value
#define OV7670_REG_MANV 0x68 //< Manual V value
#define OV7670_REG_GFIX 0x69 //< Fix gain control
#define OV7670_REG_GGAIN 0x6A //< G channel AWB gain
#define OV7670_REG_DBLV 0x6B //< PLL & regulator control
#define OV7670_REG_AWBCTR3 0x6C //< AWB control 3
#define OV7670_REG_AWBCTR2 0x6D //< AWB control 2
#define OV7670_REG_AWBCTR1 0x6E //< AWB control 1
#define OV7670_REG_AWBCTR0 0x6F //< AWB control 0
#define OV7670_REG_SCALING_XSC 0x70 //< Test pattern X scaling
#define OV7670_REG_SCALING_YSC 0x71 //< Test pattern Y scaling
#define OV7670_REG_SCALING_DCWCTR 0x72 //< DCW control
#define OV7670_REG_SCALING_PCLK_DIV 0x73 //< DSP scale control clock divide
#define OV7670_REG_REG74 0x74 //< Digital gain control
#define OV7670_REG_REG76 0x76 //< Pixel correction
#define OV7670_REG_SLOP 0x7A //< Gamma curve highest seg slope
#define OV7670_REG_GAM_BASE 0x7B //< Gamma register base (1 of 15)
#define OV7670_GAM_LEN 15 //< Number of gamma registers
#define OV7670_R76_BLKPCOR 0x80 //< REG76 black pixel corr enable
#define OV7670_R76_WHTPCOR 0x40 //< REG76 white pixel corr enable
#define OV7670_REG_RGB444 0x8C //< RGB 444 control
#define OV7670_R444_ENABLE 0x02 //< RGB444 enable
#define OV7670_R444_RGBX 0x01 //< RGB444 word format
#define OV7670_REG_DM_LNL 0x92 //< Dummy line LSB
#define OV7670_REG_LCC6 0x94 //< Lens correction option 6
#define OV7670_REG_LCC7 0x95 //< Lens correction option 7
#define OV7670_REG_HAECC1 0x9F //< Histogram-based AEC/AGC ctrl 1
#define OV7670_REG_HAECC2 0xA0 //< Histogram-based AEC/AGC ctrl 2
#define OV7670_REG_SCALING_PCLK_DELAY 0xA2 //< Scaling pixel clock delay
#define OV7670_REG_BD50MAX 0xA5 //< 50 Hz banding step limit
#define OV7670_REG_HAECC3 0xA6 //< Histogram-based AEC/AGC ctrl 3
#define OV7670_REG_HAECC4 0xA7 //< Histogram-based AEC/AGC ctrl 4
#define OV7670_REG_HAECC5 0xA8 //< Histogram-based AEC/AGC ctrl 5
#define OV7670_REG_HAECC6 0xA9 //< Histogram-based AEC/AGC ctrl 6
#define OV7670_REG_HAECC7 0xAA //< Histogram-based AEC/AGC ctrl 7
#define OV7670_REG_BD60MAX 0xAB //< 60 Hz banding step limit
#define OV7670_REG_ABLC1 0xB1 //< ABLC enable
#define OV7670_REG_THL_ST 0xB3 //< ABLC target
#define OV7670_REG_SATCTR 0xC9 //< Saturation control
#define OV7670_REG_LAST OV7670_REG_SATCTR //< Maximum register address
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,134 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// ****************************************************************************
//
// Main code
//
// ****************************************************************************
#ifndef _INCLUDE_H
#define _INCLUDE_H
typedef unsigned char Bool;
#define True 1
#define False 0
// NULL
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void*)0)
#endif
#endif
// I/O port prefix
#define __IO volatile
// request to use inline
#define INLINE __attribute__((always_inline)) inline
// avoid to use inline
#define NOINLINE __attribute__((noinline))
// weak function
#define WEAK __attribute__((weak))
// align array to 4-bytes
#define ALIGNED __attribute__((aligned(4)))
// default LED pin
#define LED_PIN 25
// nop instruction
INLINE void nop()
{ __asm volatile (" nop\n"); }
// compiler barrier
INLINE void cb()
{ __asm volatile ("" ::: "memory"); }
// ----------------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------------
#define BIT(pos) (1UL<<(pos))
// ----------------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------------
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/multicore.h"
#include <string.h>
#include "hardware/divider.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "hardware/gpio.h"
#include "pico/binary_info.h"
#include "configuration.h"
#include "hardware/watchdog.h"
#include "hardware/clocks.h"
#include "hardware/flash.h"
#include "hardware/adc.h"
#include "hardware/exception.h"
#include "hardware/structs/systick.h"
#include "hardware/structs/scb.h"
#include "hardware/vreg.h"
#include <pico/bootrom.h>
#include "hardware/irq.h"
#include "hardware/pio.h"
#ifndef HDMI
#include "PicoMiteVGA.pio.h"
#include "PicoMiteI2S.pio.h"
#endif
#ifndef USBKEYBOARD
#include "pico/unique_id.h"
#include "class/cdc/cdc_device.h"
#endif
// ****************************************************************************
//
// QVGA configuration
//
// ****************************************************************************
// port pins
// GP22... VGA
// GP16 ... VGA HSYNC/CSYNC synchronization (inverted: negative SYNC=LOW=0x80, BLACK=HIGH=0x00)
// GP17 ... VSYNC
// QVGA port pins
#define QVGA_GPIO_FIRST PinDef[Option.VGA_BLUE].GPno // first QVGA GPIO
#define QVGA_GPIO_NUM 4 // number of QVGA color GPIOs, without HSYNC and VSYNC
#define QVGA_GPIO_LAST (QVGA_GPIO_FIRST+QVGA_GPIO_NUM-1) // last QVGA GPIO
#define QVGA_GPIO_HSYNC PinDef[Option.VGA_HSYNC].GPno // QVGA HSYNC/CSYNC GPIO
#define QVGA_GPIO_VSYNC (QVGA_GPIO_HSYNC+1) // QVGA VSYNC GPIO
// QVGA display resolution
//#define FRAMESIZE (38400) // display frame size in bytes (=38400)
// 126 MHz timings
#define QVGA_TOTAL_F 4000// total clock ticks (= QVGA_HSYNC + QVGA_BP + WIDTH*QVGA_CPP[1600] + QVGA_FP)
#define QVGA_HSYNC_F 480 // horizontal sync clock ticks
#define QVGA_BP_F 240 // back porch clock ticks
#define QVGA_FP_F 80 // front porch clock ticks
// QVGA vertical timings
#define QVGA_VTOT_F 525 // total scanlines (= QVGA_VSYNC + QVGA_VBACK + QVGA_VACT + QVGA_VFRONT)
#define QVGA_VSYNC_F 2 // length of V sync (number of scanlines)
#define QVGA_VBACK_F 33 // V back porch
#define QVGA_VACT_F 480 // V active scanlines (= 2*HEIGHT)
#define QVGA_VFRONT_F 10 // V front porch
#endif // _MAIN_H
/* @endcond */

View File

@ -0,0 +1,297 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// Inconsola2.c
// Font type : Full (95 characters)
// Font size : 24x32 pixels
// Memory usage : 9124 bytes
const int Inconsola[2281] = {
0x5F202018,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x3C000018,0x003C0000,0x00003C00,0x3C00003C,0x003C0000,0x00001C00,0x1800001C,
0x00180000,0x00001800,0x18000018,0x00180000,0x00001800,0x18000018,0x00000000,0x00000000,
0x18000000,0x003C0000,0x00003C00,0x0000003C,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xE10180C0,0xE0E101E0,0x00E0F101,0x6000E0E0,0xC0E000E0,0x01C0C100,0x03038081,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xE1000000,0x80E10080,0x0080C100,0xC30080C3,0x00C30080,0x1FF0FF0F,0xC301F0FF,
0x00C30100,0x01008301,0x87010087,0x00860100,0x1FE0FF1F,0x8601E0FF,0x00860300,0x03000603,
0x0E030006,0x000E0300,0x00000C03,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x18000000,0x00180000,0x0100FE00,0x9B0380FF,0xC01807E0,0x07801807,0x18070018,
0x00980300,0x0000F803,0x7F0000FC,0xC01F0000,0x00C01900,0x1800E018,0x60180060,0x06601804,
0x190FE018,0x80FF03C0,0x0000FF01,0x18000018,0x00180000,0x00000000,0x00000000,0x00000000,
0x00000000,0xC0010000,0x70E00700,0x0E607007,0x300CE030,0x80310CC0,0x0680330E,0xE7070073,
0x00C60300,0x00000E00,0x1C00000C,0x00180000,0x00003000,0x6300E071,0x38E600F0,0x0118C600,
0x860118C6,0x38860318,0x06F00303,0x0000E001,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFC010020,0x00FE0300,0x03008E03,0x07070006,0x00060300,0x03008603,0xDC01008E,
0x00F80000,0x0300F000,0xB80700F0,0x601C0740,0x0E701C0E,0x070CE00E,0xC0031CC0,0x0E80030C,
0x1E0FC007,0xF0FC07E0,0x0060F803,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x3C000018,0x003C0000,0x00003C00,0x0C00001C,0x00180000,0x00001800,0x60000030,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000100,0x0F000007,0x001C0080,0x00003800,0x70000070,0x00E00000,0x0100C000,0xC00100C0,
0x00800100,0x03008001,0x80030080,0x00800300,0x03008003,0x80010080,0x00800100,0x0100C001,
0xE00000C0,0x00E00000,0x00007000,0x38000078,0x001C0000,0x00000F00,0x03008007,0x00000000,
0x00008000,0xF00000E0,0x00780000,0x00001C00,0x0700000E,0x00070000,0x00800300,0x01008003,
0xC00100C0,0x00C00000,0x0000C000,0xE00000C0,0x00E00000,0x0000C000,0xC00100C0,0x00C00100,
0x03008001,0x80030080,0x00000700,0x1E00000E,0x003C0000,0x00007800,0xC00000F0,0x00800000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x001C0000,0x00001C00,0x1C04001C,
0x70180710,0x01F0C907,0x3C00C0FF,0x003C0000,0x00007600,0xE3000063,0xC0C10180,0x00C08103,
0x00008080,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x1C000000,0x001C0000,0x00001C00,0x1C00001C,
0x001C0000,0x07001C00,0xFF07F0FF,0x001C00F0,0x00001C00,0x1C00001C,0x001C0000,0x00001C00,
0x0000001C,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00060000,0x00000F00,
0x0F00000F,0x00070000,0x00000300,0x06000006,0x000C0000,0x00001800,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x03000000,0xFF03E0FF,0x000000E0,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x1E00000C,0x001E0000,0x00001E00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00004000,0xE00000E0,0x00C00000,0x0100C001,0x80030080,0x00000300,0x07000007,
0x000E0000,0x00000E00,0x1C00001C,0x00380000,0x00003800,0x70000030,0x00600000,0x0000E000,
0xC00100C0,0x00800100,0x03008003,0x00070080,0x00000100,0x00000000,0x00000000,0x00000000,
0x00000000,0xFC000010,0x00FE0100,0x0300C703,0x01078083,0xC0010680,0x0EC00306,0x0E0EC007,
0xE01C0EC0,0x0CE0180C,0x700EE038,0xE0E00EE0,0x0FC0C00E,0x8007C0C0,0xC00107C0,0x03800107,
0xC7038083,0x00FE0000,0x00007C00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x0E000000,0x003E0000,0x0000FE01,0x060000C6,0x00060000,0x00000600,0x06000006,
0x00060000,0x00000600,0x06000006,0x00060000,0x00000600,0x06000006,0x00060000,0x00000600,
0x06000006,0x00060000,0x00000600,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFE000010,0x00FF0100,0x07808703,0x0102C001,0xC00100C0,0x00C00000,0x0100C001,
0x800300C0,0x00800300,0x0E000007,0x001C0000,0x00003800,0xE0000070,0x00C00100,0x03008003,
0x00070080,0xC0FF0720,0x00C0FF07,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFC000000,0x00FF0300,0x02000707,0x01008003,0x80010080,0x00800100,0x07008003,
0x001E0000,0x00007C00,0x0700007F,0x80030080,0x00C00100,0x0100C001,0xC00100C0,0x02C00102,
0x87078003,0x00FF0380,0x0000FC01,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x07000000,0x000F0000,0x00000F00,0x3F00001F,0x00370000,0x00006700,0xC7000067,
0x00C70100,0x03008701,0x07070007,0x00070600,0x0FE0FF0F,0xFF0FE0FF,0x000700E0,0x00000700,
0x07000007,0x00070000,0x00000700,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF030000,0xC0FF03C0,0x03000003,0x00030000,0x00000300,0x07000003,0xFE070000,
0x00FF0700,0x07808707,0x0100C001,0xC00000C0,0x00E00000,0x0000E000,0xC00000E0,0x0EC00102,
0x8707C001,0x00FF0380,0x0000FE01,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x7F000008,0xC0FF0000,0x0380C101,0x00038080,0x00000700,0x06000007,0x3E060000,
0x00FF0600,0x0780C707,0x01078081,0xC00006C0,0x06C00006,0x0006C000,0xC00007C0,0x03C00103,
0xC301C081,0x00FF0080,0x00007E00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF070000,0xC0FF07C0,0x00C00100,0x03008003,0x00030080,0x00000700,0x0E000007,
0x000E0000,0x00000C00,0x1C00001C,0x00380000,0x00003800,0x70000038,0x00700000,0x00007000,
0xE00000E0,0x00E00000,0x0000C001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFE000018,0x00FF0100,0x03808303,0x01078001,0xC00107C0,0x03C00103,0xC7018083,
0x00FE0000,0x01007C00,0xC70300FF,0x80030780,0x06C00107,0x000EC000,0xC0000EE0,0x07C00006,
0x8307C001,0x80FF0380,0x0000FE00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFE000010,0x00FF0100,0x07808703,0x01078003,0xC00106C0,0x06C00006,0x0006C000,
0xC00007C0,0x03C00107,0xFE03C083,0xC0FC00C0,0x00C02000,0x0100C001,0xC00100C0,0x02800300,
0x0F038003,0x00FE0700,0x0000F801,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00001800,0x3C00003C,0x003C0000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00001800,0x3C00003C,0x003C0000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000C00,0x1E00001E,0x001E0000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000C00,0x1E00001E,0x001E0000,0x00000E00,
0x0C000006,0x000C0000,0x00001800,0x00000030,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00002000,0xE00300E0,0x00800F00,0xF800003E,
0x00E00300,0x1E00800F,0x001E0000,0x00800F00,0x0000E003,0x7C0000F0,0x001F0000,0x00C00700,
0x0000E001,0x200000E0,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x07F0FF07,0x0000F0FF,
0x00000000,0x00000000,0x00000000,0xF0FF0700,0x07F0FF07,0x0000F0FF,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x08000000,0x000E0000,0x00800F00,0x0000E003,0x3E0000F8,
0x000F0000,0x00C00300,0x0000E000,0xC00300E0,0x00800F00,0x7800003E,0x00F00100,0x1F00C007,
0x001C0000,0x00001800,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x3E000000,0x80FF0000,0x07C0FF01,0x0003C081,0xE00001E0,0x00E00000,0x0000E000,
0xE00100E0,0x00C00300,0x07008007,0x000E0000,0x00000C00,0x1C00000C,0x001C0000,0x00000000,
0x00000000,0x000C0000,0x00001E00,0x1E00001E,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x1C000000,0x00FF0000,0x0380E701,0x0007C081,0x600006E0,0x0C60000E,0x1F0CE003,
0x603C1CE0,0x1860701C,0x60186060,0x60601C60,0x1CE0701C,0x3F0CE079,0x000E0CE0,0x0700000E,
0x80030000,0xC0C00300,0x00C0FF00,0x0000807F,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x30000020,0x00300000,0x00003000,0x78000078,0x00780000,0x0000FC00,0xCE0000CC,
0x00860100,0x01008601,0x03030087,0x80030300,0x0780FF03,0x010680FF,0xC0010EC0,0x0CC0000E,
0x001CE000,0x70001CE0,0x00700018,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFE0F0000,0x00FF0F00,0x0C80070C,0x010CC001,0xC0000CC0,0x0CC0010C,0x030CC001,
0x00FF0F80,0x0F00FE0F,0x030C80FF,0xC0010CC0,0x0CE0000C,0x000CE000,0xE0000CE0,0x0CE0000C,
0x070CC001,0x80FF0FC0,0x0000FC0F,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x7F000008,0xC0FF0100,0x07E0C103,0x0007E080,0x00000E70,0x0E00000E,0x000C0000,
0x00000C00,0x0C00000C,0x000C0000,0x00000C00,0x0E00000C,0x000E0000,0x00000700,0x03400007,
0xC103E080,0x80FF00C0,0x00007F00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFC0F0000,0x00FF0F00,0x0C800F0C,0x010C8003,0xC0010CC0,0x0CE0000C,0x000CE000,
0xE0000CE0,0x0CE0000C,0x000C6000,0xE0000C60,0x0CE0000C,0x000CE000,0xC0010CC0,0x0CC0010C,
0x0F0C8003,0x00FE0F00,0x0000F80F,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF0F0000,0xE0FF0FE0,0x0E00000E,0x000E0000,0x00000E00,0x0E00000E,0x000E0000,
0x00000E00,0x0F00FF0F,0x000E00FF,0x00000E00,0x0E00000E,0x000E0000,0x00000E00,0x0E00000E,
0x000E0000,0xC0FF0F00,0x00C0FF0F,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF070000,0xC0FF07C0,0x07000007,0x00070000,0x00000700,0x07000007,0x00070000,
0x00FF0700,0x0700FF07,0x000700FF,0x00000700,0x07000007,0x00070000,0x00000700,0x07000007,
0x00070000,0x00000700,0x00000007,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x7F000004,0xC0FF0080,0x03E0E001,0x80037080,0x00000720,0x06000007,0x00060000,
0x00000600,0x0E00000E,0x030E0000,0xF0030EF0,0x06300006,0x00073000,0x30000730,0x03308003,
0xE00130C0,0xE0FF00F0,0x00803F00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x000E0000,0xE0000EE0,0x0EE0000E,0x000EE000,0xE0000EE0,0x0EE0000E,0x000EE000,
0xE0000EE0,0x0FE0FF0F,0x000EE0FF,0xE0000EE0,0x0EE0000E,0x000EE000,0xE0000EE0,0x0EE0000E,
0x000EE000,0xE0000EE0,0x00E0000E,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF070000,0x80FF0780,0x00003000,0x30000030,0x00300000,0x00003000,0x30000030,
0x00300000,0x00003000,0x30000030,0x00300000,0x00003000,0x30000030,0x00300000,0x00003000,
0x30000030,0x80FF0700,0x0080FF07,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF000000,0xE0FF00E0,0x00000700,0x07000007,0x00070000,0x00000700,0x07000007,
0x00070000,0x00000700,0x07000007,0x00070000,0x00000700,0x06000007,0x00060000,0x04000E00,
0x1C0F000E,0x00F80700,0x0000F803,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x02000000,0x010CA000,0x80030CC0,0x0C80070C,0x0E0C0007,0x001C0C00,0x0C00380C,0xE00C0070,
0x00C00D00,0x0F00E00F,0x700E00E0,0x00380C00,0x0C003C0C,0x0E0C001C,0x000F0C00,0x0C00070C,
0x010C8003,0xE0010CC0,0x00F0000C,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00070000,0x00000700,0x07000007,0x00070000,0x00000700,0x07000007,0x00070000,
0x00000700,0x07000007,0x00070000,0x00000700,0x07000007,0x00070000,0x00000700,0x07000007,
0x00070000,0xE0FF0700,0x00E0FF07,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x000C0000,0xE0000E60,0x0FE0000E,0x010FE001,0xE0830FE0,0x0D60830F,0xC60C60C7,
0x60EE0C60,0x0C606C0C,0x380C6078,0x60300C60,0x0C60100C,0x000C6000,0x60000C60,0x0C60000C,
0x000C6000,0x60000C60,0x0060000C,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x000E0000,0xE0000EE0,0x0FE0000F,0x800FE080,0xE0C00DE0,0x0CE0C00D,0x600CE0E0,
0xE0700CE0,0x0CE0380C,0x1C0CE038,0xE01C0CE0,0x0CE00E0C,0x070CE00E,0xE0030CE0,0x0CE0030C,
0x010CE001,0xE0000CE0,0x00E0000C,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFE000000,0x80FF0100,0x07808303,0x000EC001,0xE0000EC0,0x1CE0000C,0x001C6000,
0x70001C60,0x1C70001C,0x001C7000,0x70001C70,0x0C60001C,0x000E6000,0xE0000EE0,0x07C00107,
0xC703C081,0x00FF0180,0x0000FE00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF0F0000,0x80FF0F00,0x0EC0030E,0x000EC001,0xE0000EE0,0x0EE0000E,0x000EE000,
0xC0010EE0,0x0F80FF0F,0xFC0F00FF,0x00000E00,0x0E00000E,0x000E0000,0x00000E00,0x0E00000E,
0x000E0000,0x00000E00,0x0000000E,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x7F000008,0xC0FF0000,0x03C0C101,0x0007E080,0x70000760,0x0E700006,0x000E3000,
0x38000E30,0x0E38000E,0x000E3800,0x38000E38,0x0630000E,0x00073000,0x70000730,0x03600003,
0xE301E080,0x80FF00C0,0x00007E00,0x0C00001C,0x000E0000,0x00F00F00,0x0000F007,0x00000000,
0x00000000,0xFF0F0000,0x80FF0F00,0x0EC0030E,0x000EC001,0xE0000EE0,0x0EE0000E,0x010EE000,
0xC0030EC0,0x0F80FF0F,0xFC0F00FF,0x000C0E00,0x0E000E0E,0x070E0007,0x80030E00,0x0E80030E,
0x010EC001,0xE0000EC0,0x00E0000E,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x7F000000,0xC0FF0080,0x03E0C001,0x80036080,0x00800340,0x03008003,0xE0010080,
0x00F80000,0x00007E00,0x0700801F,0xE00100C0,0x00F00000,0x00007000,0x70000070,0x07700002,
0xC107E000,0xC0FF01E0,0x0000FF00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF0F0000,0xF0FF0FF0,0x00001800,0x18000018,0x00180000,0x00001800,0x18000018,
0x00180000,0x00001800,0x18000018,0x00180000,0x00001800,0x18000018,0x00180000,0x00001800,
0x18000018,0x00180000,0x00001800,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x000E0000,0x60000C60,0x0C60000C,0x000C6000,0x60000C60,0x0C60000C,0x000C6000,
0x60000C60,0x0C60000C,0x000C6000,0x60000C60,0x0C60000C,0x000E6000,0xE0000EE0,0x07E0000E,
0x8307C001,0x80FF03C0,0x0000FE00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x001C0000,0x60000C70,0x0EE0000E,0x0006E000,0xC00107C0,0x03C00107,0x81038001,
0x80830380,0x01008301,0xC70100C3,0x00C60000,0x0000E600,0x6C0000EE,0x007C0000,0x00007C00,
0x38000038,0x00380000,0x00001000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00180000,0x30101830,0x1C30101C,0x181C3018,0x60380C70,0x0C603C0C,0x6C0C603C,
0x606C0E60,0x06606E0E,0xC606C066,0xC0C606C0,0x07C0C706,0x8307C083,0x808307C0,0x03808303,
0x01038001,0x80010380,0x00800103,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x000E2000,0xC00107C0,0x03800107,0x83038083,0x00C70100,0x0000CE01,0x7C0000EE,
0x007C0000,0x00003800,0x7C000038,0x007C0000,0x0000EE00,0xC70100CE,0x80830300,0x07808303,
0x0107C001,0xE0000EC0,0x00F0000E,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x000F0800,0x70000730,0x03608003,0xC001E080,0xC0C101C0,0x00C0E100,0x730080E3,
0x00770080,0x00003F00,0x1E00003E,0x001C0000,0x00001C00,0x1C00001C,0x001C0000,0x00001C00,
0x1C00001C,0x001C0000,0x00001C00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xFF0F0000,0xE0FF0FE0,0x00C00100,0x0300C001,0x00030080,0x00000700,0x0E00000E,
0x001C0000,0x00003800,0x70000038,0x00700000,0x0100E000,0xC00100C0,0x00800300,0x07008003,
0x000E0000,0xE0FF0F10,0x00E0FF0F,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x03000000,0xFF0380FF,0x00000380,0x03000003,0x00030000,0x00000300,0x03000003,0x00030000,
0x00000300,0x03000003,0x00030000,0x00000300,0x03000003,0x00030000,0x00000300,0x03000003,
0x00030000,0x00000300,0x03000003,0x00030000,0x80FF0300,0x0080FF03,0x00000000,0x00000000,
0x00000000,0x80030080,0x00C00100,0x0000C001,0xE00000E0,0x00700000,0x00007000,0x38000038,
0x00180000,0x00001C00,0x0E00000C,0x00060000,0x00000700,0x03000007,0x80030080,0x00C00100,
0x0000C001,0xE00000E0,0x00600000,0x00007000,0x20000030,0x00000000,0x00000000,0x00000000,
0x01000000,0xFF01C0FF,0xC00100C0,0x00C00100,0x0100C001,0xC00100C0,0x00C00100,0x0100C001,
0xC00100C0,0x00C00100,0x0100C001,0xC00100C0,0x00C00100,0x0100C001,0xC00100C0,0x00C00100,
0x0100C001,0xC00100C0,0x00C00100,0x0100C001,0xC0FF01C0,0x00C0FF01,0x00000000,0x00000000,
0x00000000,0x08000000,0x001C0000,0x00001E00,0x7700003E,0x00630000,0x0080E300,0x810180C1,
0x808003C0,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x0F000000,0xFF0FF0FF,0x000000F0,0x00000000,0x00000000,0x00000000,
0x00000000,0x3C000000,0x00FE0000,0x0100C701,0x83010083,0x00830100,0x01008301,0xFE0000C7,
0x007C0000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00080000,0x03007F00,0x8101C0FF,
0xE00001E0,0x00600000,0x00006000,0xE03F0060,0x03E0FF01,0x000760C0,0x60000760,0x07E00007,
0x8307E001,0x60FF03E0,0x0060FC01,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00070000,0x00000700,0x07000007,0x00070000,0x00040700,0x07003F07,0xC107C07F,
0xE08007C0,0x07F00007,0x00077000,0x70000770,0x07700007,0x00077000,0x70000770,0x07E08007,
0xC307E080,0x807F07C0,0x00003F06,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x0300FF00,0x830780FF,
0x800007C0,0x0C80000E,0x001C0000,0x00001C00,0x1C00001C,0x001C0000,0x00000E00,0x0700000E,
0xC3078001,0x80FF03C0,0x0000FE00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0xC00000C0,0x00C00000,0x0000C000,0xC02000C0,0x03C0FC01,0x8307C0FE,
0xC00107C0,0x0EC0010E,0x000EC001,0xC0000CC0,0x0EC0000C,0x010EC000,0xC0010EC0,0x07C0010E,
0x8707C003,0xC0FE03C0,0x00E0FC00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00100000,0x0100FE00,0x830300FF,
0xC0010780,0x0EC00006,0x000EC000,0xE0FF0FE0,0x0EE0FF0F,0x000E0000,0x00000E00,0x07000006,
0xC1038000,0x80FF01C0,0x0000FF00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x0F000000,0xE03F00C0,0x00707800,0xE0002070,0x00E00020,0x0000E000,0xE00000E0,
0x00FF0F00,0x0000FF0F,0xE00000E0,0x00E00000,0x0000E000,0xE00000E0,0x00E00000,0x0000E000,
0xE00000E0,0x00E00000,0x0000E000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x20300000,0x03F0FC01,0x0707F0DF,
0x00030600,0x0E80030E,0x03068003,0x00070700,0x03008F07,0xF80300FE,0x00000700,0x07000006,
0xFF070000,0xC0FF0300,0x0CE00106,0x000CE000,0xE0001C60,0x0FC0010E,0xFF0380FF,0x00000000,
0x00000000,0x00070000,0x00000600,0x06000006,0x00060000,0x00000600,0x06000006,0x3F060004,
0x807F0600,0x07C0C306,0x0107C081,0xC00007C0,0x06C00006,0x0006C000,0xC00006C0,0x06C00006,
0x0006C000,0xC00006C0,0x00C00006,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x38000010,0x00380000,0x00003800,0x00000000,0x00000000,0x03000000,0xF80300F8,
0x00380000,0x00003800,0x38000038,0x00380000,0x00003800,0x38000038,0x00380000,0x00003800,
0x38000038,0x80FF0300,0x0080FF03,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x01008000,0xC00100C0,0x00C00100,0x00000000,0x00000000,0x00C07F00,0x0100C07F,
0xC00100C0,0x00C00100,0x0100C001,0xC00100C0,0x00C00100,0x0100C001,0xC00100C0,0x00C00100,
0x0100C001,0xC00100C0,0x00C00100,0x0301C001,0x80870380,0x0000FF03,0x100000FE,0x00000000,
0x00000000,0x000F0000,0x00000E00,0x0E00000E,0x000E0000,0x00000E00,0x0E00000E,0x030EE001,
0x00070E80,0x0E000E0E,0x380E001C,0x00700E00,0x0F00F00F,0x3C0F00B8,0x001E0E00,0x0E000E0E,
0x030E0007,0xC0030E80,0x00E0010E,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0xF8070000,0x00F80700,0x00003800,0x38000038,0x00380000,0x00003800,0x38000038,
0x00380000,0x00003800,0x38000038,0x00380000,0x00003800,0x38000038,0x00380000,0x00003800,
0x38000038,0xC0FF0F00,0x00C0FF0F,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x40200000,0x0FF0F90E,0x1E0F70FB,
0x381C0E30,0x0E381C0E,0x1C0E381C,0x381C0E38,0x0E381C0E,0x1C0E381C,0x381C0E38,0x0E381C0E,
0x1C0E381C,0x381C0E38,0x00381C0E,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00040000,0x03801F03,0x6103C03F,
0xE0C003E0,0x03E08003,0x0003E080,0x60000360,0x03600003,0x00036000,0x60000360,0x03600003,
0x00036000,0x60000360,0x00600003,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00100000,0x0100FE00,0x830300FF,
0xC0010780,0x0EE0010E,0x000EE000,0xE0000CE0,0x0E60000C,0x000EE000,0xE0000EE0,0x07E0000F,
0x8303C001,0x00FF0180,0x0000FE00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00080000,0x0E007F0E,0x830F80FF,
0xC0010FC0,0x0EE0000E,0x000EE000,0xE0000EE0,0x0E60000E,0x000EE000,0xE0000EE0,0x0FE0000E,
0x830FC001,0x80FF0E80,0x0E007E0E,0x000E0000,0x00000E00,0x0E00000E,0x000E0000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00080000,0x01707E00,0xC10370FF,
0xF08003F0,0x07F00007,0x00077000,0x70000670,0x07700006,0x00077000,0xF0000770,0x03F00007,
0xC303F081,0x70FF01F0,0x00707E00,0x00007000,0x70000070,0x00700000,0x00007000,0x00000070,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00040000,0x06803F07,0xE006C07F,
0x80C007C0,0x07008007,0x00070000,0x00000700,0x06000006,0x00060000,0x00000600,0x06000006,
0x00060000,0x00000600,0x00000006,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00100000,0x0100FF00,0x810380FF,
0x800007C0,0x03800007,0xE0030080,0x00FC0100,0x00007F00,0x0300C00F,0xC00100C0,0x06C00004,
0x830FC001,0x80FF03C0,0x0000FE01,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00700000,0x00007000,0x60000070,0x00600000,0x0780FF07,0x600080FF,
0x00600000,0x00006000,0xE00000E0,0x00E00000,0x0000E000,0xE00000E0,0x00E00000,0x0000E000,
0x78004070,0xE07F00C0,0x00803F00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x0EC0000E,0x000EC000,
0xC0000EC0,0x0EC0000E,0x000EC000,0xC0000EC0,0x0EC0000E,0x000EC000,0xC0010EC0,0x07C00107,
0x8707C003,0xC0FC03C0,0x00E0F801,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x07700007,0x00037000,
0x60800360,0x01E08003,0xC001C0C0,0xC0C101C0,0x0080E100,0x630080E3,0x00770000,0x00007600,
0x3E00003E,0x001C0000,0x00003C00,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x18300018,0x38183010,
0x60381C70,0x0C60380C,0x6C0C603C,0x606C0C60,0x06606C0E,0xC6064066,0xC0C606C0,0x07C0C707,
0x8303C083,0x808303C0,0x00808103,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x03E00007,0xC101C081,
0x80C301C0,0x0000E700,0x3E000077,0x003C0000,0x00001C00,0x7E00003E,0x00770000,0x0180E300,
0x8101C0C1,0xE08003C0,0x00700007,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xE0000E00,0x07E0000E,0x0007C000,
0xC00103C0,0x03808103,0xC3018081,0x00C30180,0x0000C700,0xE60000E7,0x007E0000,0x00007C00,
0x3C00003C,0x00380000,0x00003800,0x70000030,0x00600800,0x0F00E01F,0x000200C0,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x07C0FF07,0x0300C0FF,
0x80070080,0x00000700,0x1C00000E,0x00380000,0x00007800,0xE0000070,0x00C00100,0x07008003,
0x000F0080,0xE0FF0F20,0x00E0FF0F,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x1F00C007,0x003C00C0,0x00003000,0x70000070,0x00700000,0x00007000,0x70000070,
0x00700000,0x00006000,0xC00700E0,0x00800700,0x0000C003,0x600000E0,0x00700000,0x00007000,
0x70000070,0x00700000,0x00007000,0x70000070,0x00780000,0x00003C00,0x0700C01F,0x000000C0,
0x00000000,0x1C00001C,0x001C0000,0x00001C00,0x1C00001C,0x001C0000,0x00001C00,0x1C00001C,
0x001C0000,0x00001C00,0x1C00001C,0x001C0000,0x00001C00,0x1C00001C,0x001C0000,0x00001C00,
0x1C00001C,0x001C0000,0x00001C00,0x1C00001C,0x001C0000,0x00001C00,0x1C00001C,0x00000000,
0x01000000,0xFE0100F8,0x000F0000,0x00000700,0x03000003,0x80030080,0x00800300,0x03008003,
0x80030080,0x00800300,0x0000C001,0x780000F8,0x00E00000,0x03008001,0x80030080,0x00800300,
0x03008003,0x80030080,0x00800300,0x03008003,0x00070080,0x01000F00,0xF80100FE,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
0x00000000,0x00000000,0xE0030000,0x70F80720,0x0CE03F0E,0x0700C00F,0x00000000,0x00000000,
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
};
/* @endcond */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
MATHS.h
<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.
************************************************************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
extern void Q_Mult(MMFLOAT *q1, MMFLOAT *q2, MMFLOAT *n);
extern void Q_Invert(MMFLOAT *q, MMFLOAT *n);
extern void cmd_SensorFusion(char *passcmdline);
#ifdef rp2350
extern int parsenumberarray(unsigned char *tp, MMFLOAT **a1float, int64_t **a1int, int argno, int dimensions, int *dims, bool ConstantNotAllowed);
extern int parsefloatrarray(unsigned char *tp, MMFLOAT **a1float, int argno, int dimensions, int *dims, bool ConstantNotAllowed);
extern int parseintegerarray(unsigned char *tp, int64_t **a1int, int argno, int dimensions, int *dims, bool ConstantNotAllowed);
extern int parsestringarray(unsigned char *tp, unsigned char **a1str, int argno, int dimensions, int *dims, bool ConstantNotAllowed, unsigned char *length);
#else
extern int parsenumberarray(unsigned char *tp, MMFLOAT **a1float, int64_t **a1int, int argno, short dimensions, short *dims, bool ConstantNotAllowed);
extern int parsefloatrarray(unsigned char *tp, MMFLOAT **a1float, int argno, int dimensions, short *dims, bool ConstantNotAllowed);
extern int parseintegerarray(unsigned char *tp, int64_t **a1int, int argno, int dimensions, short *dims, bool ConstantNotAllowed);
extern int parsestringarray(unsigned char *tp, unsigned char **a1str, int argno, int dimensions, short *dims, bool ConstantNotAllowed, unsigned char *length);
#endif
extern int parseany(unsigned char *tp, MMFLOAT **a1float, int64_t **a1int, unsigned char ** a1str, int *length, bool stringarray);
void MahonyQuaternionUpdate(MMFLOAT ax, MMFLOAT ay, MMFLOAT az, MMFLOAT gx, MMFLOAT gy, MMFLOAT gz, MMFLOAT mx, MMFLOAT my, MMFLOAT mz, MMFLOAT Ki, MMFLOAT Kp, MMFLOAT deltat, MMFLOAT *yaw, MMFLOAT *pitch, MMFLOAT *roll);
void MadgwickQuaternionUpdate(MMFLOAT ax, MMFLOAT ay, MMFLOAT az, MMFLOAT gx, MMFLOAT gy, MMFLOAT gz, MMFLOAT mx, MMFLOAT my, MMFLOAT mz, MMFLOAT beta, MMFLOAT deltat, MMFLOAT *pitch, MMFLOAT *yaw, MMFLOAT *roll);
extern volatile unsigned int AHRSTimer;
#define CRC4_DEFAULT_POLYNOME 0x03
#define CRC4_ITU 0x03
// CRC 8
#define CRC8_DEFAULT_POLYNOME 0x07
#define CRC8_DVB_S2 0xD5
#define CRC8_AUTOSAR 0x2F
#define CRC8_BLUETOOTH 0xA7
#define CRC8_CCITT 0x07
#define CRC8_DALLAS_MAXIM 0x31 // oneWire
#define CRC8_DARC 0x39
#define CRC8_GSM_B 0x49
#define CRC8_SAEJ1850 0x1D
#define CRC8_WCDMA 0x9B
// CRC 12
#define CRC12_DEFAULT_POLYNOME 0x080D
#define CRC12_CCITT 0x080F
#define CRC12_CDMA2000 0x0F13
#define CRC12_GSM 0x0D31
// CRC 16
#define CRC16_DEFAULT_POLYNOME 0x1021
#define CRC16_CHAKRAVARTY 0x2F15
#define CRC16_ARINC 0xA02B
#define CRC16_CCITT 0x1021
#define CRC16_CDMA2000 0xC867
#define CRC16_DECT 0x0589
#define CRC16_T10_DIF 0x8BB7
#define CRC16_DNP 0x3D65
#define CRC16_IBM 0x8005
#define CRC16_OPENSAFETY_A 0x5935
#define CRC16_OPENSAFETY_B 0x755B
#define CRC16_PROFIBUS 0x1DCF
// CRC 32
#define CRC32_DEFAULT_POLYNOME 0x04C11DB7
#define CRC32_ISO3309 0x04C11DB7
#define CRC32_CASTAGNOLI 0x1EDC6F41
#define CRC32_KOOPMAN 0x741B8CD7
#define CRC32_KOOPMAN_2 0x32583499
#define CRC32_Q 0x814141AB
// CRC 64
#define CRC64_DEFAULT_POLYNOME 0x42F0E1EBA9EA3693
#define CRC64_ECMA64 0x42F0E1EBA9EA3693
#define CRC64_ISO64 0x000000000000001B
typedef struct {
/* Controller gains */
MMFLOAT Kp;
MMFLOAT Ki;
MMFLOAT Kd;
/* Derivative low-pass filter time constant */
MMFLOAT tau;
/* Output limits */
MMFLOAT limMin;
MMFLOAT limMax;
/* Integrator limits */
MMFLOAT limMinInt;
MMFLOAT limMaxInt;
/* Sample time (in seconds) */
MMFLOAT T;
/* Controller "memory" */
MMFLOAT integrator;
MMFLOAT prevError; /* Required for integrator */
MMFLOAT differentiator;
MMFLOAT prevMeasurement; /* Required for differentiator */
/* Controller output */
MMFLOAT out;
} PIDController;
typedef struct PIDchan {
unsigned char *interrupt;
int process;
PIDController *PIDparams;
uint64_t timenext;
bool active;
}s_PIDchan;
extern s_PIDchan PIDchannels[MAXPID+1];
MMFLOAT PIDController_Update(PIDController *pid, MMFLOAT setpoint, MMFLOAT measurement);
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,339 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
MMBasic.h
<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.
************************************************************************************************************************/
#ifndef __MMBASIC_H
#define __MMBASIC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#if defined(MAXIMITE) || defined(UBW32) || defined(DUINOMITE) || defined(COLOUR)
#define MMFAMILY
#endif
#include "configuration.h" // memory configuration defines for the particular hardware this is running on
// Types used to define an item of data. Often they are ORed together.
// Used in tokens, variables and arguments to functions
#define T_NOTYPE 0 // type not set or discovered
#define T_NBR 0x01 // number (or float) type
#define T_STR 0x02 // string type
#define T_INT 0x04 // 64 bit integer type
#define T_PTR 0x08 // the variable points to another variable's data
#define T_IMPLIED 0x10 // the variables type does not have to be specified with a suffix
#define T_CONST 0x20 // the contents of this variable cannot be changed
#define T_BLOCKED 0x40 // Hash table entry blocked after ERASE
#define T_EXPLICIT 0x80 // Was the variable specified with a type suffix
#define TypeMask(a) ((a) & (T_NBR | T_INT | T_STR)) // macro to isolate the variable type bits
// types of tokens. These are or'ed with the data types above to fully define a token
#define T_INV 0 // an invalid token
#define T_NA 0 // an invalid token
#define T_CMD 0x10 // a command
#define T_OPER 0x20 // an operator
#define T_FUN 0x40 // a function (also used for a function that can operate as a command)
#define T_FNA 0x80 // a function that has no arguments
#define C_BASETOKEN 0x80 // the base of the token numbers
// flags used in the program lines
#define T_CMDEND 0 // end of a command
#define T_NEWLINE 1 // Single byte indicating the start of a new line
#define T_LINENBR 2 // three bytes for a line number
#define T_LABEL 3 // variable length indicating a label
#define E_END 255 // dummy last operator in an expression
// these constants are used in the second argument of the findvar() function, they should be or'd together
#define V_FIND 0x0000 // a straight forward find, if the variable is not found it is created and set to zero
#define V_NOFIND_ERR 0x0200 // throw an error if not found
#define V_NOFIND_NULL 0x0400 // return a null pointer if not found
#define V_DIM_VAR 0x0800 // dimension an array
#define V_LOCAL 0x1000 // create a local variable
#define V_EMPTY_OK 0x2000 // allow an empty array variable. ie, var()
#define V_FUNCT 0x4000 // we are defining the name of a function
// these flags are used in the last argument in expression()
#define E_NOERROR true
#define E_ERROR 0
#define E_DONE_GETVAL 0b10
extern struct s_vartbl s_vartbl_val;
struct s_funtbl {
char name[MAXVARLEN]; // variable's name
uint32_t index;
};
extern struct s_funtbl funtbl[MAXSUBFUN];
typedef struct s_vartbl { // structure of the variable table
unsigned char name[MAXVARLEN]; // variable's name
unsigned char type; // its type (T_NUM, T_INT or T_STR)
unsigned char level; // its subroutine or function level (used to track local variables)
unsigned char size; // the number of chars to allocate for each element in a string array
unsigned char namelen;
#ifdef rp2350
int __attribute__ ((aligned (4))) dims[MAXDIM]; // the dimensions. it is an array if the first dimension is NOT zero
#else
short __attribute__ ((aligned (4))) dims[MAXDIM]; // the dimensions. it is an array if the first dimension is NOT zero
#endif
union u_val{
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
} val;
} vartbl_val;
typedef struct s_hash {
short hash;
short level;
} hash_val;
extern struct s_vartbl g_vartbl[];
extern int g_varcnt; // number of variables defined (eg, largest index into the variable table)
//extern int g_Localvarcnt; // number of LOCAL variables defined (eg, largest index into the variable table)
extern int g_Globalvarcnt; // number of GLOBAL variables defined (eg, largest index into the variable table)
extern int g_Localvarcnt; // number of GLOBAL variables defined (eg, largest index into the variable table)
extern int g_VarIndex; // index of the current variable. set after the findvar() function has found/created a variable
extern int g_LocalIndex; // used to track the level of local variables
extern int g_OptionBase; // value of OPTION BASE
extern unsigned char OptionExplicit, OptionEscape, OptionConsole; // true if OPTION EXPLICIT has been used
extern bool OptionNoCheck;
extern unsigned char DefaultType; // the default type if a variable is not specifically typed
#if !defined(BOOL_ALREADY_DEFINED)
#define BOOL_ALREADY_DEFINED
typedef enum _BOOL { FALSE = 0, TRUE } BOOL; // Undefined size
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define MAXLINENBR 65001 // maximim acceptable line number
#define NOLINENBR MAXLINENBR+1
// skip whitespace
// finishes with x pointing to the next non space char
#define skipspace(x) while(*x == ' ') x++
// skip to the next element
// finishes pointing to the zero unsigned char that preceeds an element
#define skipelement(x) while(*x) x++
// skip to the next line
// skips text and and element separators until it is pointing to the zero char marking the start of a new line.
// the next byte will be either the newline token or zero char if end of program
#define skipline(x) while(!(x[-1] == 0 && (x[0] == T_NEWLINE || x[0] == 0)))x++
// find a token
// finishes pointing to the token or zero unsigned char if not found in the line
#define findtoken(x) while(*x != (tkn) && *x)x++
#define IsDigitinline(a) ( a >= '0' && a <= '9' )
//extern const char namestart[256];
//extern const char namein[256];
//extern const char nameend[256];
//extern const char upper[256];
//#define mytoupper(a) upper[(unsigned int)a]
#define mytoupper(a) toupper(a)
//#define isnamestart(c) (namestart[(uint8_t)c]) // true if valid start of a variable name
//#define isnamechar(c) (namein[(uint8_t)c]) // true if valid part of a variable name
//#define isnameend(c) (nameend[(uint8_t)c]) // true if valid at the end of a variable name
#define isnamestart(c) (isalpha((unsigned char)c) || c == '_') // true if valid start of a variable name
#define isnamechar(c) (isalnum((unsigned char)c) || c == '_' || c == '.') // true if valid part of a variable name
#define isnameend(c) (isalnum((unsigned char)c) || c == '_' || c == '.' || c == '$' || c == '!' || c == '%') // true if valid at the end of a variable name
#define tokentype(i) ((i >= C_BASETOKEN && i < TokenTableSize - 1 + C_BASETOKEN) ? (tokentbl[i - C_BASETOKEN].type) : 0) // get the type of a token
#define tokenfunction(i)((i >= C_BASETOKEN && i < TokenTableSize - 1 + C_BASETOKEN) ? (tokentbl[i - C_BASETOKEN].fptr) : (tokentbl[0].fptr)) // get the function pointer of a token
#define tokenname(i) ((i >= C_BASETOKEN && i < TokenTableSize - 1 + C_BASETOKEN) ? (tokentbl[i - C_BASETOKEN].name) : (unsigned char *)"") // get the name of a token
#define commandfunction(i)((i < CommandTableSize - 1) ? (commandtbl[i].fptr) : (commandtbl[0].fptr)) // get the function pointer of a token
#define commandname(i) ((i < CommandTableSize - 1 ) ? (commandtbl[i].name) : (unsigned char *)"") // get the name of a command
// this macro will allocate temporary memory space and build an argument table in it
// x = pointer to the basic text to be split up (unsigned char *)
// y = maximum number of args (will throw an error if exceeded) (int)
// s = a string of characters to be used in detecting where to split the text (unsigned char *)
#define getargs(x, y, s) unsigned char argbuf[STRINGSIZE + STRINGSIZE/2]; unsigned char *argv[y]; int argc; makeargs(x, y, argbuf, argv, &argc, s)
extern int CommandTableSize, TokenTableSize;
extern volatile int MMAbort;
extern jmp_buf mark; // longjump to recover from an error
extern unsigned char BreakKey; // console break key (defaults to CTRL-C)
extern jmp_buf jmprun;
extern int ProgMemSize;
extern int NextData; // used to track the next item to read in DATA & READ stmts
extern unsigned char *NextDataLine; // used to track the next line to read in DATA & READ stmts
extern unsigned char *CurrentLinePtr,*SaveCurrentLinePtr; // pointer to the current line being executed
extern unsigned char *ContinuePoint; // Where to continue from if using the continue statement
extern int ProgramChanged; // true if the program in memory has been changed and not saved
extern unsigned char inpbuf[]; // used to store user keystrokes until we have a line
extern unsigned char tknbuf[]; // used to store the tokenised representation of the users input line
extern unsigned char lastcmd[]; // used to store the command history in case the user uses the up arrow at the command prompt
extern MMFLOAT farg1, farg2, fret; // Global floating point variables used by operators
extern long long int iarg1, iarg2, iret; // Global integer variables used by operators
extern unsigned char *sarg1, *sarg2, *sret; // Global string pointers used by operators
extern int targ; // Global type of argument (string or float) returned by an operator
extern int cmdtoken; // Token number of the command
extern unsigned char *cmdline; // Command line terminated with a zero unsigned char and trimmed of spaces
extern unsigned char *nextstmt; // Pointer to the next statement to be executed.
extern unsigned char *ep; // Pointer to the argument to a function
extern int OptionErrorSkip; // value of OPTION ERROR
extern int MMerrno;
extern char MMErrMsg[MAXERRMSG]; // array holding the error msg
extern unsigned char *subfun[]; // Table of subroutines and functions built when the program starts running
extern char CurrentSubFunName[MAXVARLEN + 1]; // the name of the current sub or fun
extern char CurrentInterruptName[MAXVARLEN + 1];// the name of the current interrupt function
struct s_tokentbl { // structure of the token table
unsigned char *name; // the string (eg, PRINT, FOR, ASC(, etc)
unsigned char type; // the type returned (T_NBR, T_STR, T_INT)
unsigned char precedence; // precedence used by operators only. operators with equal precedence are processed left to right.
void (*fptr)(void); // pointer to the function that will interpret that token
};
extern const struct s_tokentbl tokentbl[];
extern const struct s_tokentbl commandtbl[];
extern unsigned char tokenTHEN, tokenELSE, tokenGOTO, tokenEQUAL, tokenTO, tokenSTEP, tokenWHILE, tokenUNTIL, tokenGOSUB, tokenAS, tokenFOR;
extern unsigned short cmdIF, cmdENDIF, cmdEND_IF, cmdELSEIF, cmdELSE_IF, cmdELSE, cmdSELECT_CASE, cmdFOR, cmdNEXT, cmdWHILE, cmdENDSUB, cmdENDFUNCTION, cmdLOCAL, cmdSTATIC, cmdCASE, cmdDO, cmdLOOP, cmdCASE_ELSE, cmdEND_SELECT;
extern unsigned short cmdSUB, cmdFUN, cmdCSUB, cmdIRET, cmdComment, cmdEndComment;
extern unsigned char *GetIntAddress(unsigned char *p);
extern void MMPrintString(char *s);
// void error(unsigned char *msg) ;
void error(char *msg, ...);
void InitBasic(void);
int FloatToInt32(MMFLOAT);
long long int FloatToInt64(MMFLOAT x);
void makeargs(unsigned char **tp, int maxargs, unsigned char *argbuf, unsigned char *argv[], int *argc, unsigned char *delim);
void *findvar(unsigned char *, int);
void erasearray(unsigned char *n);
void ClearVars(int level, bool all);
void ClearStack(void);
void ClearRuntime(bool all);
void ClearProgram(bool psram);
void *DoExpression(unsigned char *p, int *t);
unsigned char *GetNextCommand(unsigned char *p, unsigned char **CLine, unsigned char *EOFMsg) ;
int CheckEmpty(char *p);
unsigned char *evaluate(unsigned char *p, MMFLOAT *fa, long long int *ia, unsigned char **sa, int *ta, int noerror);
unsigned char *doexpr(unsigned char *p, MMFLOAT *fa, long long int *ia, unsigned char **sa, int *oo, int *t);
void DefinedSubFun(int iscmd, unsigned char *cmd, int index, MMFLOAT *fa, long long int *i64, unsigned char **sa, int *t);
MMFLOAT getnumber(unsigned char *p);
long long int getinteger(unsigned char *p);
long long int getint(unsigned char *p, long long int min, long long int max);
unsigned char *getstring(unsigned char *p);
void tokenise(int console);
void ExecuteProgram(unsigned char *);
void AddProgramLine(int append);
unsigned char *findline(int, int);
unsigned char *findlabel(unsigned char *labelptr);
unsigned char *skipvar(unsigned char *p, int noerror);
unsigned char *skipexpression(unsigned char *p);
int FunctionType(unsigned char *p);
unsigned char *getclosebracket(unsigned char *p);
void makeupper(unsigned char *p);
void checkend(unsigned char *p);
char *fstrstr (const char *s1, const char *s2);
int GetCommandValue(unsigned char *n);
int GetTokenValue(unsigned char *n);
unsigned char *checkstring(unsigned char *p, unsigned char *tkn);
int GetLineLength(unsigned char *p);
unsigned char *MtoC(unsigned char *p);
unsigned char *CtoM(unsigned char *p);
void Mstrcpy(unsigned char *dest, unsigned char *src);
void Mstrcat(unsigned char *dest, unsigned char *src);
int Mstrcmp(unsigned char *s1, unsigned char *s2);
unsigned char *getCstring(unsigned char *p);
unsigned char *getFstring(unsigned char *p);
int IsValidLine(int line);
void InsertLastcmd(unsigned char *s);
int CountLines(unsigned char *target);
extern jmp_buf ErrNext;
int FindSubFun(unsigned char *p, int type);
void PrepareProgram(int ErrAbort);
void MMfputs(unsigned char *p, int filenbr);
extern int TempStringClearStart; // used to prevent clearing of space in an expression that called a FUNCTION
extern unsigned char *LibMemory; // library memory
extern unsigned char *ProgMemory; // program memory
extern int PSize; // size of the program in program memory
extern unsigned char *cmdline; // Command line terminated with a zero unsigned char and trimmed of spaces
extern unsigned char *nextstmt; // Pointer to the next statement to be executed.
extern unsigned char PromptString[MAXPROMPTLEN]; // the prompt for input, an empty string means use the default
extern int multi;
extern void str_replace(char *target, const char *needle, const char *replacement, uint8_t ignore);
extern void MIPS16 STR_REPLACE(char *target, const char *needle, const char *replacement, uint8_t ignore);
#if defined(MMFAMILY)
extern unsigned char FunKey[NBRPROGKEYS][MAXKEYLEN + 1]; // used by the programmable function keys
#endif
#if defined(MMFAMILY) || defined(DOS)
extern unsigned char *ModuleTable[MAXMODULES]; // list of pointers to library modules loaded in memory;
extern int NbrModules; // the number of library modules currently loaded
#endif
#if defined(__PIC32MX__)
inline int str_equal(const unsigned char *s1, const unsigned char *s2);
#else
void IntToStrPad(char *p, long long int nbr, signed char padch, int maxch, int radix);
void IntToStr(char *strr, long long int nbr, unsigned int base);
void FloatToStr(char *p, MMFLOAT f, int m, int n, unsigned char ch);
int str_equal(const unsigned char *s1, const unsigned char *s2);
#endif
int mystrncasecmp (const unsigned char *s1, const unsigned char *s2, size_t n);
int mem_equal(unsigned char *s1, unsigned char *s2, int i);
extern int emptyarray;
typedef uint16_t CommandToken;
#ifdef __cplusplus
}
#endif
#endif /* __MMBASIC_H */
/* @endcond */

View File

@ -0,0 +1,38 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
MMBasic_Includes.h
<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 <stdint.h>
#include "Version.h"
#include "MMBasic.h"
#include "AllCommands.h"
#include "Commands.h"
#include "Custom.h"
#include "Functions.h"
#include "Operators.h"
/* @endcond */

View File

@ -0,0 +1,269 @@
/***********************************************************************************************************************
PicoMite MMBasic
custom.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 "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#if LWIP_TCP
/** Define this to a compile-time IP address initialization
* to connect anything else than IPv4 loopback
*/
#ifndef LWIP_MQTT_EXAMPLE_IPADDR_INIT
#if LWIP_IPV4
#define LWIP_MQTT_EXAMPLE_IPADDR_INIT = IPADDR4_INIT(PP_HTONL(0x144F466D))
#else
#define LWIP_MQTT_EXAMPLE_IPADDR_INIT
#endif
#endif
#undef LWIP_PLATFORM_DIAG
#define LWIP_PLATFORM_DIAG
enum {
TCP_DISCONNECTED,
TCP_CONNECTING,
MQTT_CONNECTING,
MQTT_CONNECTED
};
//static ip_addr_t mqtt_ip LWIP_MQTT_EXAMPLE_IPADDR_INIT;
static mqtt_client_t* mqtt_client=NULL;
unsigned char topicbuff[STRINGSIZE]={0};
unsigned char messagebuff[STRINGSIZE]={0};
unsigned char addressbuff[20]={0};
typedef struct mqtt_dns_t_ {
ip_addr_t remote;
int complete;
} mqtt_dns_t;
mqtt_dns_t mqtt_dns = {
{0},
0
};
typedef struct mqtt_subs_t_ {
char topic[STRINGSIZE];
int complete;
} mqtt_subs_t;
mqtt_subs_t mqtt_subs={
"",
0
};
static void mqtt_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) {
mqtt_dns_t *dns=(mqtt_dns_t *)arg;
if (ipaddr) {
dns->remote = *ipaddr;
dns->complete=1;
char buff[STRINGSIZE]={0};
sprintf(buff,"tcp address %s\r\n", ip4addr_ntoa(ipaddr));
if(!optionsuppressstatus)MMPrintString(buff);
}
}
struct mqtt_connect_client_info_t mqtt_client_info =
{
NULL,
NULL, /* user */
NULL, /* pass */
100, /* keep alive */
NULL, /* will_topic */
NULL, /* will_msg */
1, /* will_qos */
1 /* will_retain */
#if LWIP_ALTCP && LWIP_ALTCP_TLS
, NULL
#endif
};
static void
mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
int mylen=len;
if(mylen>255)mylen=255;
memset(messagebuff,0,sizeof(messagebuff));
memcpy(&messagebuff[1],data,mylen);
messagebuff[0]=mylen;
MQTTComplete=1;
}
static void
mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
int mylen=strlen(topic);
if(mylen>255)mylen=255;
memset(topicbuff,0,sizeof(topicbuff));
memcpy(&topicbuff[1],topic,mylen);
topicbuff[0]=mylen;
}
static void
mqtt_submessage_cb(void *arg, err_t err)
{
mqtt_subs_t *state=(mqtt_subs_t *)arg;
state->complete=1;
}
static void
mqtt_unsubmessage_cb(void *arg, err_t err)
{
mqtt_subs_t *state=(mqtt_subs_t *)arg;
state->complete=1;
}
static void
mqtt_request_cb(void *arg, err_t err)
{
// const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
// LWIP_PLATFORM_DIAG(("MQTT client \"%s\" request cb: err %d\n", client_info->client_id, (int)err));
}
static void
mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
// const struct mqtt_connect_client_info_t* client_info = (const struct mqtt_connect_client_info_t*)arg;
// LWIP_UNUSED_ARG(client);
// LWIP_PLATFORM_DIAG(("MQTT client \"%s\" mqtt connection cb: status %d\n", client_info->client_id, (int)status));
}
#endif /* LWIP_TCP */
void
mqtt_example_init(ip_addr_t *mqtt_ip, int port)
{
#if LWIP_TCP
//mqtt_connection_status_t status;
mqtt_client = mqtt_client_new();
mqtt_client->keep_alive=100;
if(!optionsuppressstatus)printf("Connecting to %s port %u\r\n", ip4addr_ntoa(mqtt_ip), port);
mqtt_client_connect(mqtt_client,
mqtt_ip, port,
mqtt_connection_cb, &mqtt_client_info,
&mqtt_client_info);
Timer4=5000;
while(Timer4 && mqtt_client->conn_state != MQTT_CONNECTED)if(startupcomplete)cyw43_arch_poll();
if(Timer4==0)error("Failed to connect");
mqtt_set_inpub_callback(mqtt_client,
mqtt_incoming_publish_cb,
mqtt_incoming_data_cb,
&mqtt_client_info);
#endif /* LWIP_TCP */
}
void closeMQTT(void){
if(mqtt_client){
mqtt_disconnect(mqtt_client);
mqtt_client_free(mqtt_client);
mqtt_client=NULL;
}
}
//static struct altcp_tls_config *tls_config = NULL;
int cmd_mqtt(void){
unsigned char *tp=checkstring(cmdline,(unsigned char *)"MQTT CONNECT");
if(tp){
getargs(&tp,9,(unsigned char *)",");
char *IP=GetTempMemory(STRINGSIZE);
char *ID=GetTempMemory(STRINGSIZE);
if(mqtt_client)error("Already connected");
int timeout=5000;
if(!(argc==7 || argc==9))error("Syntax");
IP=(char *)getCstring(argv[0]);
int port=getint(argv[2],1,65535);
ip4_addr_t remote_addr;
// if(port==8883){
// tls_config = altcp_tls_create_config_client(NULL, 0);
// mqtt_client_info.tls_config=tls_config;
// }
mqtt_client_info.client_user=(char *)getCstring(argv[4]);
mqtt_client_info.client_pass=(char *)getCstring(argv[6]);
if(argc==9){
MQTTInterrupt=(char *)GetIntAddress(argv[8]);
InterruptUsed=true;
}
else MQTTInterrupt=NULL;
MQTTComplete=0;
strcpy(ID,"WebMite");
strcat(ID,id_out);
IntToStr(&ID[strlen(ID)],time_us_64(),16);
mqtt_client_info.client_id=ID;
if(!isalpha((uint8_t)*IP) && strchr(IP,'.') && strchr(IP,'.')<IP+4){
if(!ip4addr_aton(IP, &remote_addr))error("Invalid address format");
mqtt_dns.remote=remote_addr;
} else {
int err = dns_gethostbyname(IP, &remote_addr, mqtt_dns_found, &mqtt_dns);
Timer4=timeout;
while(!mqtt_dns.complete && Timer4 && !(err==ERR_OK))if(startupcomplete)cyw43_arch_poll();
if(!Timer4)error("Failed to convert web address");
mqtt_dns.complete=0;
}
mqtt_example_init(&mqtt_dns.remote,port);
return 1;
}
tp=checkstring(cmdline,(unsigned char *)"MQTT PUBLISH");
if(tp){
getargs(&tp,7,(unsigned char *)",");
int qos=1;
int retain=1;
if(argc<3)error("Syntax");
char *topic=(char *)getCstring(argv[0]);
char *msg=(char *)getCstring(argv[2]);
if(argc>=5 && *argv[4])qos=getint(argv[4],0,2);
if(argc==7)retain=getint(argv[6],0,1);
mqtt_publish(mqtt_client, topic, msg, strlen(msg), qos, retain, mqtt_request_cb , (void *)&mqtt_client_info);
return 1;
}
tp=checkstring(cmdline,(unsigned char *)"MQTT SUBSCRIBE");
if(tp){
getargs(&tp,3,(unsigned char *)",");
if(!(argc>=1))error("Syntax");
strcpy(mqtt_subs.topic,(char *)getCstring(argv[0]));
int qos=0;
if(argc==3)qos=getint(argv[2],0,2);
mqtt_subs.complete=0;
Timer4=4000;
mqtt_sub_unsub(mqtt_client, mqtt_subs.topic, qos, mqtt_submessage_cb, &mqtt_subs, 1);
while(Timer4 && !mqtt_subs.complete)if(startupcomplete)cyw43_arch_poll();
if(Timer4==0)error("Failed to subscribe to $",mqtt_subs.topic);
return 1;
}
tp=checkstring(cmdline,(unsigned char *)"MQTT UNSUBSCRIBE");
if(tp){
strcpy(mqtt_subs.topic,(char *)getCstring(tp));
mqtt_subs.complete=0;
Timer4=4000;
mqtt_sub_unsub(mqtt_client, mqtt_subs.topic, 0, mqtt_unsubmessage_cb, &mqtt_subs, 0);
while(Timer4 && !mqtt_subs.complete)if(startupcomplete)cyw43_arch_poll();
if(Timer4==0)error("Failed to unsubscribe to $",mqtt_subs.topic);
return 1;
}
tp=checkstring(cmdline,(unsigned char *)"MQTT CLOSE");
if(tp){
if(!mqtt_client)return 1;
closeMQTT();
return 1;
}
return 0;
}

View File

@ -0,0 +1,325 @@
/***********************************************************************************************************************
PicoMite MMBasic
custom.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 "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#define DEBUG_printf
TCP_CLIENT_T *TCP_CLIENT=NULL;
int streampointer=0;
// Perform initialisation
TCP_CLIENT_T* tcp_client_init(void) {
TCP_CLIENT_T *state = calloc(1, sizeof(TCP_CLIENT_T));
if (!state) {
// DEBUG_printf("failed to allocate state\n");
return NULL;
}
// ip4addr_aton(TEST_TCP_SERVER_IP, &state->remote_addr);
return state;
}
// Call back with a DNS result
void tcp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) {
TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
if (ipaddr) {
state->remote_addr = *ipaddr;
char buff[STRINGSIZE]={0};
sprintf(buff,"tcp address %s\r\n", ip4addr_ntoa(ipaddr));
if(!optionsuppressstatus)MMPrintString(buff);
state->complete=1;
// ntp_request(state);
} else {
free(state);
error("tcp dns request failed");
}
}
static err_t tcp_client_close(void *arg) {
TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
err_t err = ERR_OK;
if (state->tcp_pcb != NULL) {
tcp_arg((struct tcp_pcb *)state->tcp_pcb, NULL);
tcp_poll((struct tcp_pcb *)state->tcp_pcb, NULL, 0);
tcp_sent((struct tcp_pcb *)state->tcp_pcb, NULL);
tcp_recv((struct tcp_pcb *)state->tcp_pcb, NULL);
tcp_err((struct tcp_pcb *)state->tcp_pcb, NULL);
err = tcp_close((struct tcp_pcb *)state->tcp_pcb);
if (err != ERR_OK) {
// DEBUG_printf("close failed %d, calling abort\n", err);
tcp_abort((struct tcp_pcb *)state->tcp_pcb);
err = ERR_ABRT;
}
state->tcp_pcb = NULL;
}
return err;
}
static err_t tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) {
// TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
// DEBUG_printf("tcp_client_sent %u\r\n", len);
return ERR_OK;
}
static void tcp_client_err(void *arg, err_t err) {
if (err != ERR_ABRT) {
error("TCP client");
}
}
err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
if (!p) {
return ERR_OK;
}
// this method is callback from lwIP, so cyw43_arch_lwip_begin is not required, however you
// can use this method to cause an assertion in debug mode, if this method is called when
// cyw43_arch_lwip_begin IS needed
// cyw43_arch_lwip_check();
if (p->tot_len > 0) {
routinechecks(); //don't know why I'm doing this but it solves a race condition for the RP2350
// Receive the buffer
const uint16_t buffer_left = state->BUF_SIZE - state->buffer_len;
state->buffer_len += pbuf_copy_partial(p, (void *)state->buffer + state->buffer_len,
p->tot_len > buffer_left ? buffer_left : p->tot_len, 0);
tcp_recved(tpcb, p->tot_len);
cyw43_arch_lwip_begin();
uint64_t *x=(uint64_t *)state->buffer;
x--;
*x=state->buffer_len;
cyw43_arch_lwip_end();
}
pbuf_free(p);
return ERR_OK;
}
err_t tcp_client_recv_stream(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
if (!p) {
return ERR_OK;
}
// this method is callback from lwIP, so cyw43_arch_lwip_begin is not required, however you
// can use this method to cause an assertion in debug mode, if this method is called when
// cyw43_arch_lwip_begin IS needed
// cyw43_arch_lwip_check();
if (p->tot_len > 0) {
for(int j=0;j<p->tot_len;j++){
state->buffer[*state->buffer_write]= ((char *)p->payload)[j];
*state->buffer_write = (*state->buffer_write + 1) % state->BUF_SIZE; // advance the head of the queue
if(*state->buffer_write == *state->buffer_read) { // if the buffer has overflowed
*state->buffer_read = (*state->buffer_read + 1) % state->BUF_SIZE; // throw away the oldest char
}
}
// cyw43_arch_lwip_end();
tcp_recved(tpcb, p->tot_len);
}
pbuf_free(p);
return ERR_OK;
}
static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
if (err != ERR_OK) {
error("connect failed %", err);
}
if(!optionsuppressstatus)MMPrintString("Connected\r\n");
state->connected = true;
return ERR_OK;
}
static bool tcp_client_open(void *arg) {
TCP_CLIENT_T *state = (TCP_CLIENT_T*)arg;
char buff[STRINGSIZE]={0};
sprintf("Connecting to %s port %u\r\n", ip4addr_ntoa(&state->remote_addr), state->TCP_PORT);
if(!optionsuppressstatus)MMPrintString(buff);
state->tcp_pcb = tcp_new_ip_type(IP_GET_TYPE(&state->remote_addr));
if (!state->tcp_pcb) {
error("failed to create pcb");
return false;
}
tcp_arg((struct tcp_pcb *)state->tcp_pcb, state);
// tcp_poll(state->tcp_pcb, tcp_client_poll, POLL_TIME_S * 2);
tcp_sent((struct tcp_pcb *)state->tcp_pcb, tcp_client_sent);
if(state->buffer_write==NULL)tcp_recv((struct tcp_pcb *)state->tcp_pcb, tcp_client_recv);
else tcp_recv((struct tcp_pcb *)state->tcp_pcb, tcp_client_recv_stream);
tcp_err((struct tcp_pcb *)state->tcp_pcb, tcp_client_err);
state->buffer_len = 0;
// cyw43_arch_lwip_begin/end should be used around calls into lwIP to ensure correct locking.
// You can omit them if you are in a callback from lwIP. Note that when using pico_cyw_arch_poll
// these calls are a no-op and can be omitted, but it is a good practice to use them in
// case you switch the cyw43_arch type later.
// cyw43_arch_lwip_begin();
err_t err = tcp_connect((struct tcp_pcb *)state->tcp_pcb, &state->remote_addr, state->TCP_PORT, tcp_client_connected);
// cyw43_arch_lwip_end();
return err == ERR_OK;
}
void close_tcpclient(void){
TCP_CLIENT_T *state = TCP_CLIENT;
if(!state)return;
tcp_client_close(state) ;
free(state);
TCP_CLIENT=NULL;
}
int cmd_tcpclient(void){
unsigned char *tp;
tp=checkstring(cmdline, (unsigned char *)"OPEN TCP CLIENT");
if(tp){
int timeout=5000;
getargs(&tp,5,(unsigned char *)",");
if(argc<3)error("Syntax");
ip4_addr_t remote_addr;
char *IP=GetTempMemory(STRINGSIZE);
TCP_CLIENT_T *state = tcp_client_init();
IP=(char *)getCstring(argv[0]);
int port=getint(argv[2],1,65535);
if(argc==5)timeout=getint(argv[4],1,100000);
TCP_CLIENT=state;
state->TCP_PORT=port;
state->buffer_write=NULL;
if(!isalpha((uint8_t)*IP) && strchr(IP,'.') && strchr(IP,'.')<IP+4){
if(!ip4addr_aton(IP, &remote_addr))error("Invalid address format");
state->remote_addr=remote_addr;
} else {
int err = dns_gethostbyname(IP, &remote_addr, tcp_dns_found, state);
if(err==ERR_OK)state->remote_addr=remote_addr;
else if(err==ERR_INPROGRESS){
Timer4=timeout;
while(!state->complete && Timer4 && !(err==ERR_OK))if(startupcomplete)cyw43_arch_poll();
if(!Timer4)error("Failed to convert web address");
state->complete=0;
} else error("Failed to find TCP address");
}
if (!tcp_client_open(state)) {
error("Failed to open client");
}
Timer4=timeout;
while(!state->connected && Timer4)if(startupcomplete)cyw43_arch_poll();
if(!Timer4)error("No response from client");
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"OPEN TCP STREAM");
if(tp){
int timeout=5000;
getargs(&tp,5,(unsigned char *)",");
if(argc<3)error("Syntax");
ip4_addr_t remote_addr;
char *IP=GetTempMemory(STRINGSIZE);
TCP_CLIENT_T *state = tcp_client_init();
IP=(char *)getCstring(argv[0]);
int port=getint(argv[2],1,65535);
if(argc==5)timeout=getint(argv[4],1,100000);
TCP_CLIENT=state;
state->TCP_PORT=port;
state->buffer_write=&streampointer;
if(!isalpha((uint8_t)*IP) && strchr(IP,'.') && strchr(IP,'.')<IP+4){
if(!ip4addr_aton(IP, &remote_addr))error("Invalid address format");
state->remote_addr=remote_addr;
} else {
int err = dns_gethostbyname(IP, &remote_addr, tcp_dns_found, state);
if(err==ERR_OK)state->remote_addr=remote_addr;
else if(err==ERR_INPROGRESS){
Timer4=timeout;
while(!state->complete && Timer4 && !(err==ERR_OK))ProcessWeb(0);
if(!Timer4)error("Failed to convert web address");
state->complete=0;
} else error("Failed to find TCP address");
}
if (!tcp_client_open(state)) {
error("Failed to open client");
}
Timer4=timeout;
while(!state->connected && Timer4){{if(startupcomplete)ProcessWeb(0);}}
if(!Timer4)error("No response from client");
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"TCP CLIENT REQUEST");
if(tp){
int64_t *dest=NULL;
uint8_t *q=NULL;
int size=0, timeout=5000;
TCP_CLIENT_T *state = TCP_CLIENT;
getargs(&tp,5,(unsigned char *)",");
if(!state)error("No connection");
if(!state->connected)error("No connection");
if(argc<3)error("Syntax");
char *request=(char *)getstring(argv[0]);
size=parseintegerarray(argv[2],&dest,2,1,NULL,true)*8;
dest[0]=0;
q=(uint8_t *)&dest[1];
if(argc==5)timeout=getint(argv[4],1,100000);
state->BUF_SIZE=size;
state->buffer=q;
state->buffer_len=0;
err_t err = tcp_write((struct tcp_pcb *)state->tcp_pcb, &request[1], (uint32_t)request[0], 0);
if(err)error("write failed %",err);
Timer4=timeout;
while(!state->buffer_len && Timer4)ProcessWeb(0);
if(!Timer4)error("No response from server");
else Timer4=200;
while(Timer4)ProcessWeb(0);
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"TCP CLIENT STREAM");
if(tp){
void *ptr1 = NULL;
int64_t *dest=NULL;
uint8_t *q=NULL;
int size=0;
TCP_CLIENT_T *state = TCP_CLIENT;
getargs(&tp,7,(unsigned char *)",");
if(!state)error("No connection");
if(!state->connected)error("No connection");
if(argc!=7)error("Syntax");
char *request=(char *)getstring(argv[0]);
size=parseintegerarray(argv[2],&dest,2,1,NULL,true)*8;
dest[0]=0;
q=(uint8_t *)&dest[1];
ptr1 = findvar(argv[4], V_FIND | V_NOFIND_ERR);
if(g_vartbl[g_VarIndex].type & T_INT) {
if(g_vartbl[g_VarIndex].dims[0] != 0) error("Argument 3 must be an integer");
state->buffer_read = (int *)ptr1;
} else error("Argument 3 must be an integer");
ptr1 = findvar(argv[6], V_FIND | V_NOFIND_ERR);
if(g_vartbl[g_VarIndex].type & T_INT) {
if(g_vartbl[g_VarIndex].dims[0] != 0) error("Argument 4 must be an integer");
state->buffer_write = (int *)ptr1;
} else error("Argument 4 must be an integer");
state->BUF_SIZE=size;
state->buffer=q;
state->buffer_len=0;
err_t err = tcp_write((struct tcp_pcb *)state->tcp_pcb, &request[1], (uint32_t)request[0], 0);
if(err)error("write failed %",err);
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"CLOSE TCP CLIENT");
if(tp){
TCP_CLIENT_T *state = TCP_CLIENT;
if(!state)error("No connection");
close_tcpclient();
return 1;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
MM_Misc.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
#ifndef MISC_HEADER
#define MISC_HEADER
extern void OtherOptions(void);
extern int InterruptUsed;
extern int OptionErrorCheck;
extern unsigned char *InterruptReturn;
extern int check_interrupt(void);
extern unsigned char *GetIntAddress(unsigned char *p);
extern void CrunchData(unsigned char **p, int c);
extern uint32_t getFreeHeap(void);
// struct for the interrupt configuration
#define T_LOHI 1
#define T_HILO 2
#define T_BOTH 3
struct s_inttbl {
int pin; // the pin on which the interrupt is set
int last; // the last value of the pin (ie, hi or low)
char *intp; // pointer to the interrupt routine
int lohi; // trigger condition (T_LOHI, T_HILO, etc).
};
#define NBRINTERRUPTS 10 // number of interrupts that can be set
extern struct s_inttbl inttbl[NBRINTERRUPTS];
extern int TickPeriod[NBRSETTICKS];
extern volatile int TickTimer[NBRSETTICKS];
extern unsigned char *TickInt[NBRSETTICKS];
extern volatile unsigned char TickActive[NBRSETTICKS];
extern unsigned int CurrentCpuSpeed;
extern unsigned int PeripheralBusSpeed;
extern unsigned char *OnKeyGOSUB;
extern unsigned char *OnPS2GOSUB;
extern unsigned char EchoOption;
extern unsigned int GetPeekAddr(unsigned char *p);
extern unsigned int GetPokeAddr(unsigned char *p);
extern void disable_sd(void);
extern void disable_systemspi(void);
extern void disable_systemi2c(void);
extern void disable_audio(void);
extern char *MQTTInterrupt;
extern volatile bool MQTTComplete;
extern char *CSubInterrupt;
extern volatile bool CSubComplete;
extern uint32_t __get_MSP(void);
extern int ExistsFile(char *p);
extern int ExistsDir(char *p, char *q, int *filesystem);
extern MMFLOAT optionangle;
extern bool useoptionangle;
extern bool optionfastaudio;
extern bool optionlogging;
extern bool optionsuppressstatus;
extern bool optionfulltime;
extern int64_t TimeOffsetToUptime;
extern time_t get_epoch(int year, int month,int day, int hour,int minute, int second);
extern uint_fast64_t gettimefromepoch(int *year, int *month, int *day, int *hour, int *minute, int *second);
extern uint64_t __uninitialized_ram(_persistent);
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,184 @@
/***********************************************************************************************************************
PicoMite MMBasic
custom.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 "MMBasic_Includes.h"
#include "Hardware_Includes.h"
NTP_T *NTPstate=NULL;
#define NTP_SERVER "pool.ntp.org"
#define NTP_MSG_LEN 48
#define NTP_PORT 123
#define NTP_DELTA 2208988800 // seconds between 1 Jan 1900 and 1 Jan 1970
#define NTP_TEST_TIME (30 * 1000)
#define NTP_RESEND_TIME (10 * 1000)
volatile time_t timeadjust=0;
volatile uint8_t seconds_buf[4] = {0};
// Called with results of operation
static void ntp_result(NTP_T* state, int status, time_t *result) {
if (status == 0 && result) {
int year, month, day, hour, minute, second;
*result=*result+timeadjust;
struct tm *utc = gmtime(result);
char buff[STRINGSIZE]={0};
sprintf(buff,"got ntp response: %02d/%02d/%04d %02d:%02d:%02d\r\n", utc->tm_mday, utc->tm_mon + 1, utc->tm_year + 1900,
utc->tm_hour, utc->tm_min, utc->tm_sec);
if(!optionsuppressstatus)MMPrintString(buff);
// mT4IntEnable(0);
hour = utc->tm_hour;
minute = utc->tm_min;
second = utc->tm_sec;
day_of_week=utc->tm_wday;
if(day_of_week==0)day_of_week=7;
year = utc->tm_year + 1900;
month = utc->tm_mon + 1;
day = utc->tm_mday;
// mT4IntEnable(1);
TimeOffsetToUptime=get_epoch(year, month, day, hour, minute, second)-time_us_64()/1000000;
}
}
//static int64_t ntp_failed_handler(alarm_id_t id, void *user_data);
// Make an NTP request
static void ntp_request(NTP_T *state) {
// cyw43_arch_lwip_begin/end should be used around calls into lwIP to ensure correct locking.
// You can omit them if you are in a callback from lwIP. Note that when using pico_cyw_arch_poll
// these calls are a no-op and can be omitted, but it is a good practice to use them in
// case you switch the cyw43_arch type later.
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, NTP_MSG_LEN, PBUF_RAM);
uint8_t *req = (uint8_t *) p->payload;
memset(req, 0, NTP_MSG_LEN);
req[0] = 0x1b;
udp_sendto(state->ntp_pcb, p, &state->ntp_server_address, NTP_PORT);
pbuf_free(p);
}
/*static int64_t ntp_failed_handler(alarm_id_t id, void *user_data)
{
NTP_T* state = (NTP_T*)user_data;
free(state);
error("ntp request failed");
return 0;
}*/
// Call back with a DNS result
static void ntp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) {
NTP_T *state = (NTP_T*)arg;
if (ipaddr) {
state->ntp_server_address = *ipaddr;
state->complete=1;
} else {
free(state);
error("ntp dns request failed");
}
}
// NTP data received
static void ntp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
NTP_T *state = (NTP_T*)arg;
uint8_t mode = pbuf_get_at(p, 0) & 0x7;
uint8_t stratum = pbuf_get_at(p, 1);
// Check the result
if (ip_addr_cmp(addr, &state->ntp_server_address) && port == NTP_PORT && p->tot_len == NTP_MSG_LEN &&
mode == 0x4 && stratum != 0) {
pbuf_copy_partial(p, (void *)seconds_buf, sizeof(seconds_buf), 40);
// uSec(200);
state->complete=1;
} else {
pbuf_free(p);
free(state);
error("invalid ntp response");
}
pbuf_free(p);
}
// Perform initialisation
static NTP_T* ntp_init(void) {
NTPstate = (NTP_T *)calloc(1,sizeof(NTP_T));
NTP_T *state=NTPstate;
if (!state) {
error("failed to allocate state\n");
return NULL;
}
return state;
}
void cmd_ntp(unsigned char *tp){
getargs(&tp,5,(unsigned char *)",");
NTP_T *state = ntp_init();
int timeout=5000;
if (!state) error("Can't create NTP structure");
ip4_addr_t remote_addr;
char *IP=GetTempMemory(STRINGSIZE);
if (argc >=1){
MMFLOAT adjust = getnumber(argv[0]);
if (adjust < -12.0 || adjust > 14.0) error("Invalid Time Offset");
timeadjust=(time_t)(adjust*3600.0);
} else timeadjust=0;
if(argc>=3 && *argv[2])strcpy(IP,(char *)getCstring(argv[2]));
else strcpy(IP,NTP_SERVER);
if(argc==5)timeout=getint(argv[4],0,100000);
if(!isalpha((uint8_t)*IP) && strchr(IP,'.') && strchr(IP,'.')<IP+4){
if(!ip4addr_aton(IP, &remote_addr))error("Invalid address format");
state->ntp_server_address=remote_addr;
} else {
int err = dns_gethostbyname(IP, &remote_addr, ntp_dns_found, state);
if(err==ERR_OK)state->ntp_server_address=remote_addr;
else if(err==ERR_INPROGRESS){
Timer4=timeout;
while(!state->complete && Timer4 && !(err==ERR_OK))if(startupcomplete)cyw43_arch_poll();
if(!Timer4)error("Failed to convert web address");
state->complete=0;
} else error("Failed to find NTP address");
}
char buff[STRINGSIZE]={0};
sprintf(buff,"ntp address %s\r\n", ip4addr_ntoa(&state->ntp_server_address));
if(!optionsuppressstatus)MMPrintString(buff);
memset((void *)seconds_buf, 0, sizeof(seconds_buf));
state->ntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
if (!state->ntp_pcb) {
free((void *)state);
error("failed to create pcb\n");
} else udp_recv(state->ntp_pcb, ntp_recv, state);
ntp_request(state);
Timer4=timeout;
while(!state->complete){
if(startupcomplete)cyw43_arch_poll();
if(!Timer4){
udp_remove(NTPstate->ntp_pcb);
// memset(NTPstate,0,sizeof(NTPstate));
free(NTPstate);
error("NTP timeout");
}
}
uint32_t seconds_since_1900 = seconds_buf[0] << 24 | seconds_buf[1] << 16 | seconds_buf[2] << 8 | seconds_buf[3];
if(seconds_since_1900){
uint32_t seconds_since_1970 = seconds_since_1900 - NTP_DELTA;
time_t epoch = seconds_since_1970;
ntp_result(state, 0, &epoch);
}
udp_remove(NTPstate->ntp_pcb);
// memset(NTPstate,0,sizeof(NTPstate));
free(NTPstate);
}

View File

@ -0,0 +1,735 @@
/***********************************************************************************************************************
PicoMite MMBasic
custom.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 "MMBasic_Includes.h"
#include "Hardware_Includes.h"
bool optionsuppressstatus=0;
int TCP_PORT ;
//#define //DEBUG_printf printf
#define DEBUG_printf
const char httpheadersfail[]="HTTP/1.0 404\r\n\r\n";
TCP_SERVER_T *TCPstate=NULL;
jmp_buf recover;
static TCP_SERVER_T* tcp_server_init(void) {
if(!TCPstate) {
TCPstate = (TCP_SERVER_T*)calloc(1,sizeof(TCP_SERVER_T));
memset(TCPstate,0,sizeof(TCP_SERVER_T));
}
if (!TCPstate) {
//DEBUG_printf("failed to allocate state\r\n");
return NULL;
}
for(int i=0;i<MaxPcb;i++){
TCPstate->client_pcb[i]=NULL;
}
TCPstate->telnet_pcb_no=99;
return TCPstate;
}
err_t tcp_server_close(void *arg, int pcb) {
if(pcb==99)return ERR_OK;
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
err_t err = ERR_OK;
if (state->client_pcb[pcb] != 0) {
tcp_arg(state->client_pcb[pcb], NULL);
tcp_sent(state->client_pcb[pcb], NULL);
tcp_recv(state->client_pcb[pcb], NULL);
tcp_err(state->client_pcb[pcb], NULL);
tcp_poll(state->client_pcb[pcb], NULL,0);
err = tcp_close(state->client_pcb[pcb]);
if (err != ERR_OK) {
tcp_abort(state->client_pcb[pcb]);
error("close failed %, calling abort", err);
err = ERR_ABRT;
}
//DEBUG_printf("Close success %x on pcb %x\r\n",state->client_pcb[pcb],pcb);
state->recv_len[pcb]=0;
state->client_pcb[pcb]=NULL;
FreeMemorySafe((void **)&state->buffer_recv[pcb]);
}
return err;
}
static err_t tcp_server_result(void *arg, int status) {
return ERR_OK;
}
static err_t tcp_server_sent(void *arg, struct tcp_pcb *tpcb, u16_t len, int pcb) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
////DEBUG_printf("tcp_server_sent %u\r\n", len);
state->pcbopentime[pcb]=time_us_64();
state->sent_len[pcb] += len;
return ERR_OK;
}
static err_t tcp_server_sent0(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 0);
}
static err_t tcp_server_sent1(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 1);
}
static err_t tcp_server_sent2(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 2);
}
static err_t tcp_server_sent3(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 3);
}
static err_t tcp_server_sent4(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 4);
}
static err_t tcp_server_sent5(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 5);
}
static err_t tcp_server_sent6(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 6);
}
static err_t tcp_server_sent7(void *arg, struct tcp_pcb *tpcb, u16_t len) {
return tcp_server_sent(arg, tpcb, len, 7);
}
err_t tcp_server_send_data(void *arg, struct tcp_pcb *tpcb, int pcb)
{
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
// state->sent_len[pcb] = 0;
// if(pcb!=state->telnet_pcb_no)//DEBUG_printf("Writing %d bytes to client %x\r\n",state->to_send[pcb], (uint32_t)tpcb);
// this method is callback from lwIP, so cyw43_arch_lwip_begin is not required, however you
// can use this method to cause an assertion in debug mode, if this method is called when
// cyw43_arch_lwip_begin IS needed
int t;
err_t err;
uint64_t timestart=time_us_64()+5000000;
while((t=tcp_sndqueuelen(tpcb))>6 && time_us_64()<timestart){
//DEBUG_printf("Send queue %u\r\n", t);
if(startupcomplete)cyw43_arch_poll();
}
state->pcbopentime[pcb]=time_us_64();
if(time_us_64()<timestart){
err = tcp_write(tpcb, state->buffer_sent[pcb], state->to_send[pcb], 0);
} else err=1;
if (err != ERR_OK) {
tcp_server_close(state,pcb);
}
return ERR_OK;
}
err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err, int pcb) {
// static int count=0;
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
if (!p) {
return ERR_OK;
}
// this method is callback from lwIP, so cyw43_arch_lwip_begin is not required, however you
// can use this method to cause an assertion in debug mode, if this method is called when
// cyw43_arch_lwip_begin IS needed
// cyw43_arch_lwip_check();
if (p->tot_len > 0) {
TCPreceived=1;
if(!CurrentLinePtr){ // deal with requests when we don't want them
tcp_recved(tpcb, p->tot_len);
//DEBUG_printf("Sending 404 on pcb %d, rbuff address is %x ",pcb, (uint32_t)state->buffer_recv[pcb]);
state->sent_len[pcb]=0;
state->to_send[pcb]= state->total_sent[pcb] = strlen(httpheadersfail);
state->buffer_sent[pcb]=(unsigned char *)httpheadersfail;
if(state->client_pcb[pcb]){
tcp_server_send_data(state, state->client_pcb[pcb],pcb);
checksent(state,0, pcb);
tcp_server_close(state, pcb) ;
}
} else {
OptionErrorSkip = 1;
if(state->buffer_recv[pcb]!=NULL){
FreeMemorySafe((void **)&state->buffer_recv[pcb]);
// MMPrintString("Internal error in tcp_server_recv - Attempting recovery");
}
state->buffer_recv[pcb]=GetMemory(p->tot_len);
state->inttrig[pcb]=1;
//DEBUG_printf("Tcp_HTTP_recv on pcb %d / %d\r\n",pcb, p->tot_len);
state->recv_len[pcb] = pbuf_copy_partial(p, state->buffer_recv[pcb] , p->tot_len, 0);
if(state->recv_len[pcb]!=p->tot_len) MMPrintString("Warning: WebMite Internal error");
for(int i=0;i<p->tot_len;i++)if(state->buffer_recv[pcb][i]==0)state->buffer_recv[pcb][i]=32;
tcp_recved(tpcb, p->tot_len);
state->pcbopentime[pcb]=time_us_64();
}
}
//DEBUG_printf("Stack pointer is %x free space on heap %u\r\n",((uint32_t)__get_MSP()),getFreeHeap());
pbuf_free(p);
return ERR_OK;
}
err_t tcp_server_recv0(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,0);
}
err_t tcp_server_recv1(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,1);
}
err_t tcp_server_recv2(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,2);
}
err_t tcp_server_recv3(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,3);
}
err_t tcp_server_recv4(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,4);
}
err_t tcp_server_recv5(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,5);
}
err_t tcp_server_recv6(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,6);
}
err_t tcp_server_recv7(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
return tcp_server_recv(arg, tpcb, p, err,7);
}
static void tcp_server_err(void *arg, err_t err, int pcb) {
if (err != ERR_ABRT) {
//DEBUG_printf("tcp_client_err_fn %d\r\n", err);
tcp_server_close(arg, pcb);
}
}
static void tcp_server_err0(void *arg, err_t err) {
tcp_server_err(arg, err, 0);
}
static void tcp_server_err1(void *arg, err_t err) {
tcp_server_err(arg, err, 1);
}
static void tcp_server_err2(void *arg, err_t err) {
tcp_server_err(arg, err, 2);
}
static void tcp_server_err3(void *arg, err_t err) {
tcp_server_err(arg, err, 3);
}
static void tcp_server_err4(void *arg, err_t err) {
tcp_server_err(arg, err, 4);
}
static void tcp_server_err5(void *arg, err_t err) {
tcp_server_err(arg, err, 5);
}
static void tcp_server_err6(void *arg, err_t err) {
tcp_server_err(arg, err, 6);
}
static void tcp_server_err7(void *arg, err_t err) {
tcp_server_err(arg, err, 7);
}
static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
int pcb=0;
if (err != ERR_OK || client_pcb == NULL) {
//DEBUG_printf("Failure in accept\r\n");
tcp_server_result(arg, err);
return ERR_VAL;
}
for(pcb=0;pcb<=MaxPcb;pcb++){
if(pcb==MaxPcb)MMPrintString("Warning: No free connections\r\n");
// if(pcb==MaxPcb)error("No free connections");
if(state->client_pcb[pcb]==NULL){
state->client_pcb[pcb] = client_pcb;
break;
}
}
if(client_pcb->local_port==23 && Option.Telnet){
starttelnet(client_pcb, pcb, arg) ;
return ERR_OK;
} else if(client_pcb->local_port==TCP_PORT && TCP_PORT){
//DEBUG_printf("HTTP Client connected %x on pcb %d\r\n",(uint32_t)client_pcb,pcb);
tcp_arg(client_pcb, state);
state->keepalive[pcb]=0;
tcp_arg(client_pcb, state);
switch(pcb){
case 0:
tcp_sent(client_pcb, tcp_server_sent0);
tcp_recv(client_pcb, tcp_server_recv0);
tcp_err(client_pcb, tcp_server_err0);
break;
case 1:
tcp_sent(client_pcb, tcp_server_sent1);
tcp_recv(client_pcb, tcp_server_recv1);
tcp_err(client_pcb, tcp_server_err1);
break;
case 2:
tcp_sent(client_pcb, tcp_server_sent2);
tcp_recv(client_pcb, tcp_server_recv2);
tcp_err(client_pcb, tcp_server_err2);
break;
case 3:
tcp_sent(client_pcb, tcp_server_sent3);
tcp_recv(client_pcb, tcp_server_recv3);
tcp_err(client_pcb, tcp_server_err3);
break;
case 4:
tcp_sent(client_pcb, tcp_server_sent4);
tcp_recv(client_pcb, tcp_server_recv4);
tcp_err(client_pcb, tcp_server_err4);
break;
case 5:
tcp_sent(client_pcb, tcp_server_sent5);
tcp_recv(client_pcb, tcp_server_recv5);
tcp_err(client_pcb, tcp_server_err5);
break;
case 6:
tcp_sent(client_pcb, tcp_server_sent6);
tcp_recv(client_pcb, tcp_server_recv6);
tcp_err(client_pcb, tcp_server_err6);
break;
case 7:
tcp_sent(client_pcb, tcp_server_sent7);
tcp_recv(client_pcb, tcp_server_recv7);
tcp_err(client_pcb, tcp_server_err7);
break;
}
state->pcbopentime[pcb]=time_us_64();
} //else DEBUG_printf("Attempted connection on port %d\r\n",client_pcb->local_port);
int t=0;
for(int i=0;i<MaxPcb;i++){
if(state->client_pcb[i]==NULL){
t++;
}
}
//DEBUG_printf("Connection still free %u\r\n", t);
return ERR_OK;
}
static bool tcp_server_open(void *arg) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
if(TCP_PORT && WIFIconnected){
MMPrintString("Starting TCP server at ");
MMPrintString(ip4addr_ntoa(netif_ip4_addr(netif_list)));
MMPrintString(" on port ");
PInt(TCP_PORT);PRet();
}
struct tcp_pcb *httppcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
struct tcp_pcb *telnet_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (!httppcb || !telnet_pcb) {
//DEBUG_printf("failed to create pcbs\r\n");
return false;
}
err_t err;
if(TCP_PORT){
err = tcp_bind(httppcb, NULL, TCP_PORT);
if (err) {
char buff[STRINGSIZE]={0};
sprintf(buff,"failed to bind to port %d\n",TCP_PORT);
if(!optionsuppressstatus)MMPrintString(buff);
return false;
}
state->server_pcb = tcp_listen_with_backlog(httppcb, MaxPcb);
if (!state->server_pcb) {
//DEBUG_printf("failed to listen\r\n");
if (httppcb) {
tcp_close(httppcb);
}
return false;
}
tcp_arg(state->server_pcb, state);
tcp_accept(state->server_pcb, tcp_server_accept);
}
if(Option.Telnet){
err = tcp_bind(telnet_pcb, NULL, 23);
if (err) {
char buff[STRINGSIZE]={0};
sprintf(buff,"failed to bind to port %d\n",23);
if(!optionsuppressstatus)MMPrintString(buff);
return false;
}
state->telnet_pcb = tcp_listen_with_backlog(telnet_pcb, MaxPcb);
if (!state->telnet_pcb) {
//DEBUG_printf("failed to listen\r\n");
if (telnet_pcb) {
tcp_close(telnet_pcb);
}
return false;
}
tcp_arg(state->telnet_pcb, state);
tcp_accept(state->telnet_pcb, tcp_server_accept);
}
return true;
}
void checksent(void *arg, int fn, int pcb){
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
int loopcount=1000000;
while(state->sent_len[pcb]!=state->total_sent[pcb] && loopcount ){
loopcount--;
CheckAbort();
}
if(loopcount==0){
if(fn)ForceFileClose(fn);
tcp_server_close(state, pcb) ;
MMPrintString("Warning: LWIP send data timeout\r\n");
}
}
const char httpheaders[]="HTTP/1.1 200 OK\r\nServer:CPi\r\nConnection:close\r\nContent-type:";
const char httptail[]="\r\nContent-Length:";
const char httpend[]="\r\n\r\n";
const char httphtml[]="text/html\r\nContent-Length:";
void cleanserver(void){
if(!TCPstate)return;
TCP_SERVER_T *state = (TCP_SERVER_T*)TCPstate;
for(int i=0 ; i<MaxPcb ; i++){
if(state->client_pcb[i] && i!=state->telnet_pcb_no)tcp_server_close(state,i);
}
}
void cmd_transmit(unsigned char *cmd){
unsigned char *tp;
int tlen;
tp=checkstring(cmd, (unsigned char *)"CODE");
if(tp){
getargs(&tp, 3, (unsigned char *)",");
if(argc != 3)error("Argument count");
TCP_SERVER_T *state = (TCP_SERVER_T*)TCPstate;
char httpheaders[]="HTTP/1.0 404\r\n\r\n";
int pcb = getint(argv[0],1,MaxPcb)-1;
tlen=getint(argv[2],100,999);
IntToStr(&httpheaders[9],tlen,10);
httpheaders[12]='\r';
state->to_send[pcb]=strlen(httpheaders);
state->sent_len[pcb]=0;
state->buffer_sent[pcb]=(unsigned char *)httpheaders;
state->total_sent[pcb]=strlen(httpheaders);
if(setjmp(recover) != 0)error("Transmit failed");
if(state->client_pcb[pcb]){
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
checksent(state,0,pcb);
tcp_server_close(state,pcb);
}
// {if(startupcomplete)ProcessWeb(0);}
return;
}
if((tp=checkstring(cmd, (unsigned char *)"FILE"))){
int32_t fn;
char *fname;
char *ctype;
char *outstr=GetTempMemory(STRINGSIZE);
char p[10]={0};
int FileSize;
UINT n_read;
getargs(&tp, 5, (unsigned char *)",");
if(argc != 5)error("Argument count");
TCP_SERVER_T *state = (TCP_SERVER_T*)TCPstate;
int pcb = getint(argv[0],1,MaxPcb)-1;
fname=(char *)getCstring(argv[2]);
ctype=(char *)getCstring(argv[4]);
strcpy(outstr,httpheaders);
strcat(outstr,ctype);
strcat(outstr,httptail);
if(*fname == 0) error("Cannot find file");
if (ExistsFile(fname)) {
fn = FindFreeFileNbr();
if (!BasicFileOpen(fname, fn, FA_READ))
return;
if(FatFSFileSystem) FileSize = f_size(FileTable[fn].fptr);
else FileSize = lfs_file_size(&lfs,FileTable[fn].lfsptr);
IntToStr(p,FileSize,10);
strcat(outstr,p);
strcat(outstr,httpend);
// int i=0;
state->sent_len[pcb]=0;
state->to_send[pcb]= state->total_sent[pcb] = strlen(outstr);
state->buffer_sent[pcb]=(unsigned char *)outstr;
if(setjmp(recover) != 0)error("Transmit failed");
//DEBUG_printf("sending file header to pcb %d\r\n",pcb);
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
if(FileSize<TCP_MSS*4 && FileSize<FreeSpaceOnHeap()/4){
char *pBuf=GetTempMemory(FileSize);
if(filesource[fn]!=FLASHFILE) f_read(FileTable[fn].fptr, pBuf, FileSize, &n_read);
else n_read=lfs_file_read(&lfs, FileTable[fn].lfsptr, pBuf, FileSize);
state->buffer_sent[pcb]=(unsigned char *)pBuf;
while(n_read>TCP_MSS){
state->to_send[pcb]=TCP_MSS;
state->total_sent[pcb]+=TCP_MSS;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page to pcb %d\r\n",pcb);
n_read-=TCP_MSS;
state->buffer_sent[pcb]+=TCP_MSS;
}
state->to_send[pcb]=n_read;
state->total_sent[pcb]+=n_read;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page end to pcb %d\r\n",pcb);
checksent(state,0, pcb);
} else {
char *pBuf=GetTempMemory(TCP_MSS);
while(1) {
if(
((filesource[fn]==FLASHFILE) && (lfs_file_tell(&lfs,FileTable[fn].lfsptr)==lfs_file_size(&lfs,FileTable[fn].lfsptr)))
|| ((filesource[fn]!=FLASHFILE) && f_eof(FileTable[fn].fptr))
) break;
if(filesource[fn]!=FLASHFILE) f_read(FileTable[fn].fptr, pBuf, TCP_MSS, &n_read);
else n_read=lfs_file_read(&lfs, FileTable[fn].lfsptr, pBuf, TCP_MSS);
state->to_send[pcb]=n_read;
state->buffer_sent[pcb]=(unsigned char *)pBuf;
state->total_sent[pcb]+=n_read;
//DEBUG_printf("sending file content to pcb %d\r\n",pcb);
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
checksent(state,fn, pcb);
state->total_sent[pcb]=0;
state->sent_len[pcb]=0;
}
}
tcp_server_close(state,pcb);
// {if(startupcomplete)ProcessWeb(0);}
FileClose(fn);
} else {
state->to_send[pcb]= state->total_sent[pcb] = strlen(httpheadersfail);
state->buffer_sent[pcb]=(unsigned char *)httpheadersfail;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
checksent(state,0, pcb);
}
tcp_server_close(state,pcb);
// {if(startupcomplete)ProcessWeb(0);}
return;
}
if((tp=checkstring(cmd, (unsigned char *)"PAGE"))){
MMFLOAT f;
int32_t fn;
int64_t i64;
int i;
int t;
char *fname;
char c;
char vartest[MAXVARLEN];
int vartestp;
int FileSize;
int buffersize=4096;
char p[10]={0};
getargs(&tp, 5, (unsigned char *)",");
if(argc<3)error("Argument count");
char *outstr=GetTempMemory(STRINGSIZE);
char *valbuf=GetTempMemory(STRINGSIZE);
strcat(outstr,httpheaders);
strcat(outstr,httphtml);
TCP_SERVER_T *state = (TCP_SERVER_T*)TCPstate;
int pcb = getint(argv[0],1,MaxPcb)-1;
fname=(char *)getCstring(argv[2]);
if(*fname == 0) error("Cannot find file");
if(argc==5)buffersize=getint(argv[4],0,heap_memory_size);
if (ExistsFile(fname)) {
fn = FindFreeFileNbr();
if (!BasicFileOpen(fname, fn, FA_READ)) return;
if(filesource[fn]!=FLASHFILE) FileSize = f_size(FileTable[fn].fptr);
else FileSize = lfs_file_size(&lfs,FileTable[fn].lfsptr);
char *SocketOut=GetMemory(FileSize+buffersize);
int SocketOutPointer=0;
while(1) {
if(FileEOF(fn)) break;
c=FileGetChar(fn);
if(c==26)continue; //deal with xmodem padding
if(SocketOutPointer>FileSize+256)break;
if(c=='{'){ //start of variable definition
vartestp=0;
while(c!='}'){
c=FileGetChar(fn);
if(vartestp==0 && c=='{') break;
if(c!='}')vartest[vartestp++]=c;
}
if(c=='{')SocketOut[SocketOutPointer++]=c;
else {
vartest[vartestp]=0;
unsigned char *s, *st, *temp_tknbuf;
temp_tknbuf = GetMemory(STRINGSIZE);
strcpy((char *)temp_tknbuf, (char *)tknbuf); // first save the current token buffer in case we are in immediate mode
// we have to fool the tokeniser into thinking that it is processing a program line entered at the console
st = GetMemory(STRINGSIZE);
inpbuf[0] = 'r'; inpbuf[1] = '='; // place a dummy assignment in the input buffer to keep the tokeniser happy
strcpy((char *)inpbuf + 2, (char *)vartest);
tokenise(true); // and tokenise it (the result is in tknbuf)
strcpy((char *)st, (char *)(tknbuf + 2 + sizeof(CommandToken)));
t = T_NOTYPE;
int os=OptionExplicit;
OptionExplicit = false;
evaluate(st, &f, &i64, &s, &t, false);
OptionExplicit = os;
if(t & T_NBR) {
FloatToStr(valbuf, f, 0, STR_AUTO_PRECISION, ' '); // set the string value to be saved
for(i=0;i<strlen(valbuf);i++)SocketOut[SocketOutPointer++]=valbuf[i];
} else if(t & T_INT) {
IntToStr(valbuf, i64, 10); // if positive output a space instead of the sign
for(i=0;i<strlen(valbuf);i++)SocketOut[SocketOutPointer++]=valbuf[i];
} else if(t & T_STR) {
for(i=1;i<=s[0];i++)SocketOut[SocketOutPointer++]=s[i];
}
strcpy((char *)tknbuf, (char *)temp_tknbuf);// restore the saved token buffer
FreeMemory(temp_tknbuf) ;
FreeMemory(st);
}
} else
SocketOut[SocketOutPointer++]=c;
}
FileClose(fn);
SocketOut[SocketOutPointer++]=10;
SocketOut[SocketOutPointer++]=13;
SocketOut[SocketOutPointer++]=10;
SocketOut[SocketOutPointer++]=13;
SocketOut[SocketOutPointer]=0;
IntToStr(p,strlen(SocketOut),10);
strcat(outstr,p);
strcat(outstr,httpend);
//
if(setjmp(recover) != 0)error("Transmit failed");
state->to_send[pcb] = state->total_sent[pcb] = strlen(outstr);
state->sent_len[pcb]=0;
state->buffer_sent[pcb]=(unsigned char *)outstr;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page header to pcb %d\r\n",pcb);
//
// state->to_send[pcb]=strlen(SocketOut);
state->buffer_sent[pcb]=(unsigned char *)SocketOut;
int bufflen=strlen(SocketOut);
while(bufflen>TCP_MSS){
state->to_send[pcb]=TCP_MSS;
state->total_sent[pcb]+=TCP_MSS;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page to pcb %d\r\n",pcb);
bufflen-=TCP_MSS;
state->buffer_sent[pcb]+=TCP_MSS;
}
state->to_send[pcb]=bufflen;
state->total_sent[pcb]+=bufflen;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page end to pcb %d\r\n",pcb);
checksent(state,0, pcb);
//
FreeMemory((void *)SocketOut);
} else {
state->to_send[pcb] = state->total_sent[pcb] = strlen(httpheadersfail);
state->sent_len[pcb]=0;
state->buffer_sent[pcb]=(unsigned char *)httpheadersfail;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
checksent(state,0,pcb);
}
tcp_server_close(state,pcb);
// ProcessWeb(0);
return;
}
error("Invalid option");
}
void open_tcp_server(void){
tcp_server_init();
TCP_PORT=Option.TCP_PORT;
if (!TCPstate) {
MMPrintString("Failed to create TCP server\r\n");
}
if (!tcp_server_open(TCPstate)) {
MMPrintString("Failed to create TCP server\r\n");
}
return;
}
int cmd_tcpserver(void){
unsigned char *tp;
tp=checkstring(cmdline, (unsigned char *)"TCP INTERRUPT");
if(tp){
getargs(&tp, 1, (unsigned char *)",");
if(argc!=1)error("Syntax");
TCPreceiveInterrupt= (char *)GetIntAddress(argv[0]);
InterruptUsed=true;
TCPreceived=0;
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"TCP CLOSE");
if(tp){
TCP_SERVER_T *state = TCPstate;
getargs(&tp, 1, (unsigned char *)",");
if(argc!=1)error("Syntax");
int pcb = getint(argv[0],1,MaxPcb)-1;
tcp_server_close(state, pcb) ;
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"TRANSMIT");
if(tp){
cmd_transmit(tp);
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"TCP READ");
if(tp){
void *ptr1 = NULL;
int64_t *dest=NULL;
uint8_t *q=NULL;
int size=0;
TCP_SERVER_T *state = TCPstate;
getargs(&tp, 3, (unsigned char *)",");
if(argc!=3)error("Syntax");
int pcb=getint(argv[0],1,MaxPcb)-1;
ptr1 = findvar(argv[2], V_FIND | V_EMPTY_OK | V_NOFIND_ERR);
if(g_vartbl[g_VarIndex].type & T_INT) {
if(g_vartbl[g_VarIndex].dims[1] != 0) error("Invalid variable");
if(g_vartbl[g_VarIndex].dims[0] <= 0) { // Not an array
error("Argument 2 must be integer array");
}
size=(g_vartbl[g_VarIndex].dims[0] - g_OptionBase +1)*8;
dest = (long long int *)ptr1;
dest[0]=0;
q=(uint8_t *)&dest[1];
} else error("Argument 2 must be integer array");
if(!state->inttrig[pcb]){
memset(ptr1,0,size);
return 1;
}
if(size-8<state->recv_len[pcb])error("array too small");
memcpy(q,state->buffer_recv[pcb],state->recv_len[pcb]);
dest[0]= state->recv_len[pcb];
state->inttrig[pcb]=0;
return 1;
}
tp=checkstring(cmdline, (unsigned char *)"TCP SEND");
if(tp){
TCP_SERVER_T *state = (TCP_SERVER_T*)TCPstate;
int64_t *dest=NULL;
uint8_t *q=NULL;
getargs(&tp, 3, (unsigned char *)",");
if(!TCPstate)error("Server not open");
if(argc != 3)error("Argument count");
int pcb = getint(argv[0],1,MaxPcb)-1;
parseintegerarray(argv[2],&dest,2,1,NULL,false);
q=(uint8_t *)&dest[1];
// int j=(g_vartbl[g_VarIndex].dims[0] - g_OptionBase);
state->buffer_sent[pcb]=q;
int bufflen=dest[0];
state->to_send[pcb] = state->total_sent[pcb] = state->sent_len[pcb]=0;
while(bufflen>TCP_MSS){
state->to_send[pcb]=TCP_MSS;
state->total_sent[pcb]+=TCP_MSS;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page to pcb %d\r\n",pcb);
bufflen-=TCP_MSS;
state->buffer_sent[pcb]+=TCP_MSS;
}
state->to_send[pcb]=bufflen;
state->total_sent[pcb]+=bufflen;
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
//DEBUG_printf("sending page end to pcb %d\r\n",pcb);
checksent(state,0, pcb);
// tcp_server_close(state,pcb);
// ProcessWeb(0);
return 1;
}
return 0;
}

View File

@ -0,0 +1,165 @@
/***********************************************************************************************************************
PicoMite MMBasic
custom.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 "MMBasic_Includes.h"
#include "Hardware_Includes.h"
//#define DEBUG_printf printf
#define DEBUG_printf
static char Telnetbuff[256]={0};
static int Telnetpos=0;
static const uint8_t telnet_init_options[] =
{
// TELNET_CHAR_IAC, TELNET_CHAR_WILL, TELNET_OPT_SUPPRESS_GO_AHEAD,
255,251,3,
// TELNET_CHAR_IAC, TELNET_CHAR_DO, TELNET_OPT_SUPPRESS_GO_AHEAD,
255,253,3,
// TELNET_CHAR_IAC, TELNET_CHAR_WILL, TELNET_OPT_ECHO,
255,251,1,
//
255,253,34,
255,254,34,
0
};
static err_t tcp_telnet_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
// DEBUG_printf("telnet_server_sent %u\n", len);
state->sent_len[state->telnet_pcb_no] = len;
return ERR_OK;
}
void TelnetPutCommand(int command, int option){
Telnetbuff[Telnetpos]=255;
Telnetpos++;
Telnetbuff[Telnetpos]=command;
Telnetpos++;
if(option){
Telnetbuff[Telnetpos]=255;
Telnetpos++;
}
}
void __not_in_flash_func(TelnetPutC)(int c,int flush){
TCP_SERVER_T *state = (TCP_SERVER_T*)TCPstate;
if(state->telnet_pcb_no==99 || !WIFIconnected )return;
if(!(flush==-1)){
Telnetbuff[Telnetpos]=c;
Telnetpos++;
if(c==255){
Telnetbuff[Telnetpos]=c;
Telnetpos++;
}
if(c==13){
Telnetbuff[Telnetpos]=0;
Telnetpos++;
}
}
if(Telnetpos>=sizeof(Telnetbuff-4) || (flush==-1 && Telnetpos)){
int pcb=state->telnet_pcb_no;
state->to_send[pcb]=Telnetpos;
state->buffer_sent[state->telnet_pcb_no]=(uint8_t *)Telnetbuff;
if(state->client_pcb[pcb]){
// cyw43_arch_lwip_check();
tcp_server_send_data(state, state->client_pcb[pcb], pcb);
}
Telnetpos=0;
}
}
err_t tcp_telnet_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
static int lastchar=-1;
// TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
// int pcb=state->telnet_pcb_no;
if (!p) {
return ERR_OK;
}
// cyw43_arch_lwip_check();
if (p->tot_len > 0) {
tcp_recved(tpcb, p->tot_len);
if(((char *)p->payload)[0]==255){
// for(int i=0;i<p->tot_len;i++)DEBUG_printf("%d,",((char *)p->payload)[i]);
// DEBUG_printf("\r\n");
} else {
for(int j=0;j<p->tot_len;j++){
ConsoleRxBuf[ConsoleRxBufHead] = ((char *)p->payload)[j];
if((lastchar==13 && ConsoleRxBuf[ConsoleRxBufHead]==0) ||
(lastchar==255 && ConsoleRxBuf[ConsoleRxBufHead]==255)){
lastchar=-1;
continue;
}
if(BreakKey && ConsoleRxBuf[ConsoleRxBufHead] == BreakKey) {// if the user wants to stop the progran
MMAbort = true; // set the flag for the interpreter to see
ConsoleRxBufHead = ConsoleRxBufTail; // empty the buffer
} else if(ConsoleRxBuf[ConsoleRxBufHead] ==keyselect && KeyInterrupt!=NULL){
Keycomplete=1;
} else {
lastchar=ConsoleRxBuf[ConsoleRxBufHead];
ConsoleRxBufHead = (ConsoleRxBufHead + 1) % CONSOLE_RX_BUF_SIZE; // advance the head of the queue
if(ConsoleRxBufHead == ConsoleRxBufTail) { // if the buffer has overflowed
ConsoleRxBufTail = (ConsoleRxBufTail + 1) % CONSOLE_RX_BUF_SIZE; // throw away the oldest char
}
}
}
}
}
pbuf_free(p);
return ERR_OK;
}
void tcp_telnet_err(void *arg, err_t err) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
// if (err != ERR_ABRT) {
// char buff[STRINGSIZE]={0};
// DEBUG_printf("Telnet disconnected %d\r\n", err);
tcp_server_close(arg,state->telnet_pcb_no);
state->telnet_pcb_no=99;
// if(!CurrentLinePtr) longjmp(mark, 1);
// else longjmp(ErrNext,1) ;
// }
}
/*static err_t tcp_telnet_poll(void *arg, struct tcp_pcb *tpcb) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
// cyw43_arch_lwip_check();
int i=0;
while(state->client_pcb[i]!=tpcb && i<=MaxPcb)i++;
if(i==MaxPcb)error("Internal TCP receive error");
state->write_pcb=i;
DEBUG_printf("tcp_server_poll_fn\r\n");
return tcp_server_close(argstate->telnet_pcb_no); // no activity so close the connection
}*/
void starttelnet(struct tcp_pcb *client_pcb, int pcb, void *arg){
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
// DEBUG_printf("Telnet Client connected %x on pcb %d\r\n",(uint32_t)client_pcb,pcb);
tcp_arg(client_pcb, state);
tcp_sent(client_pcb, tcp_telnet_sent);
tcp_recv(client_pcb, tcp_telnet_recv);
tcp_err(client_pcb, tcp_telnet_err);
state->telnet_pcb_no=pcb;
state->keepalive[pcb]=1;
err_t err = tcp_write(client_pcb, telnet_init_options, sizeof(telnet_init_options), 0);
if (err != ERR_OK) {
tcp_server_close(state,pcb);
}
}

View File

@ -0,0 +1,66 @@
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include "lwip/apps/tftp_common.h"
#include "lwip/apps/tftp_server.h"
struct tftp_context ctx;
int tftp_fnbr;
void* tftp_open(const char* fname, const char* fmode, u8_t write){
if (!InitSDCard()) return NULL;
BYTE mode = 0;
tftp_fnbr=FindFreeFileNbr();
if (write){
mode = FA_WRITE | FA_CREATE_ALWAYS;
if(!optionsuppressstatus)MMPrintString("TFTP request to create ");
}
else {
mode = FA_READ;
if(!optionsuppressstatus)MMPrintString("TFTP request to read ");
}
if(!optionsuppressstatus)MMPrintString(strcmp(fmode,"octet")==0? "binary file : " : "ascii file : ");
if(!optionsuppressstatus)MMPrintString((char *)fname);
if(!optionsuppressstatus)PRet();
if (!BasicFileOpen((char *)fname, tftp_fnbr, mode))
return NULL;
return &tftp_fnbr;
}
void tftp_close(void* handle){
// int nbr;
int fnbr=*(int *)handle;
FileClose(fnbr);
if(!optionsuppressstatus)MMPrintString("TFTP transfer complete\r\n");
}
int tftp_read(void* handle, void* buf, int bytes){
int n_read;
int fnbr=*(int *)handle;
if(filesource[fnbr]==FATFSFILE) f_read(FileTable[fnbr].fptr, buf, bytes, (UINT *)&n_read);
else n_read=lfs_file_read(&lfs, FileTable[fnbr].lfsptr, buf, bytes);
return n_read;
}
int tftp_write(void* handle, struct pbuf* p){
int nbr;
int fnbr=*(int *)handle;
if(filesource[fnbr]==FATFSFILE) f_write(FileTable[fnbr].fptr, p->payload, p->tot_len, (UINT *)&nbr);
else {
nbr=FSerror=lfs_file_write(&lfs, FileTable[fnbr].lfsptr, p->payload, p->tot_len);
}
if(FSerror>0)FSerror=0;
ErrorCheck(tftp_fnbr);
return nbr;
}
void tftp_error(void* handle, int err, const char* msg, int size){
int fnbr=*(int *)handle;
ForceFileClose(fnbr);
MMPrintString("TFTP Error: ");
MMPrintString((char *)msg);
PRet();
}
int cmd_tftp_server_init(void){
ctx.open=tftp_open;
ctx.close=tftp_close;
ctx.error=tftp_error;
ctx.write=tftp_write;
ctx.read=tftp_read;
tftp_init_server(&ctx);
return 1;
}

View File

@ -0,0 +1,120 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include "lwip/udp.h"
#include "lwip/timeouts.h"
#include "lwip/debug.h"
struct udp_pcb *udppcb = NULL, *sendudppcb=NULL;
typedef struct UDP_T_ {
ip_addr_t udp_server_address;
struct udp_pcb *ntp_pcb;
volatile bool complete;
} UDP_T;
UDP_T UDPstate;
static void
udp_recv_func(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
LWIP_UNUSED_ARG(arg);
if(p == NULL) return;
int len = p->len;
if(len>=sizeof(messagebuff))len=sizeof(messagebuff)-1;
memset(messagebuff,0,sizeof(messagebuff));
memcpy(&messagebuff[1],p->payload,len);
messagebuff[0]=len;
memset(addressbuff,0,sizeof(addressbuff));
sprintf((char *)&addressbuff[1],"%d.%d.%d.%d",(int)addr->addr&0xff,(int)(addr->addr>>8)&0xff,(int)(addr->addr>>16)&0xff,(int)(addr->addr>>24)&0xff);
addressbuff[0]=strlen((char *)&addressbuff[1]);
// udp_sendto(upcb, p, addr, port);
pbuf_free(p);
UDPreceive=1;
}
void udp_server_init(void){
udppcb=udp_new();
ip_set_option(udppcb, SOF_BROADCAST);
// err_t ret;
if(Option.UDP_PORT && WIFIconnected && !optionsuppressstatus){
MMPrintString("Starting UDP server at ");
MMPrintString(ip4addr_ntoa(netif_ip4_addr(netif_list)));
MMPrintString(" on port ");
PInt(Option.UDP_PORT);PRet();
}
udp_bind(udppcb, IP_ADDR_ANY, Option.UDP_PORT);
udp_recv(udppcb, udp_recv_func, udppcb);
}
void open_udp_server(void){
udp_server_init();
return;
}
static void udp_dns_found(const char *hostname, const ip_addr_t *ipaddr, void *arg) {
UDP_T *state = (UDP_T*)arg;
if (ipaddr) {
state->udp_server_address = *ipaddr;
state->complete=1;
} else {
free(state);
error("udp dns request failed");
}
}
void cmd_udp(unsigned char *p){
unsigned char *tp;
tp=checkstring(p, (unsigned char *)"INTERRUPT");
if(tp){
getargs(&tp, 1, (unsigned char *)",");
if(argc!=1)error("Syntax");
UDPinterrupt=(char *)GetIntAddress(argv[0]);
InterruptUsed=true;
UDPreceive=0;
return;
}
tp=checkstring(p, (unsigned char *)"SEND");
if(tp){
getargs(&tp, 5, (unsigned char *)",");
if(argc!=5)error("Syntax");
UDP_T *state = &UDPstate;
state->complete=0;
ip4_addr_t remote_addr;
int timeout=5000;
char *IP=GetTempMemory(STRINGSIZE);
strcpy(IP,(char *)getCstring(argv[0]));
if(!isalpha((uint8_t)*IP) && strchr(IP,'.') && strchr(IP,'.')<IP+4){
if(!ip4addr_aton(IP, &remote_addr))error("Invalid address format");
state->udp_server_address=remote_addr;
} else {
int err = dns_gethostbyname(IP, &remote_addr, udp_dns_found, state);
if(err==ERR_OK)state->udp_server_address=remote_addr;
else if(err==ERR_INPROGRESS){
Timer4=timeout;
while(!state->complete && Timer4 && !(err==ERR_OK))if(startupcomplete)cyw43_arch_poll();
if(!Timer4)error("Failed to convert web address");
} else error("Failed to find UDP address");
}
unsigned char *data=getstring(argv[4]);
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, (uint16_t)data[0], PBUF_RAM);
char *req = (char *)p->payload;
memset(req, 0, data[0]);
int port=getint(argv[2],1,65535);
memcpy(req,&data[1],data[0]);
sendudppcb=udp_new();
ip_set_option(sendudppcb, SOF_BROADCAST);
err_t er = udp_sendto(sendudppcb, p, &state->udp_server_address, port);
pbuf_free(p);
if (er != ERR_OK) {
printf("Failed to send UDP packet! error=%d", er);
}
// ProcessWeb(0);
udp_remove(sendudppcb);
sendudppcb=NULL;
return;
}
}
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,123 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Memory.h
<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 <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "configuration.h"
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
// the format is:
// TEXT TYPE P FUNCTION TO CALL
// where type is T_NA, T_FUN, T_FNA or T_OPER argumented by the types T_STR and/or T_NBR
// and P is the precedence (which is only used for operators)
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
#ifndef MEMORY_HEADER
#define MEMORY_HEADER
extern unsigned char *strtmp[]; // used to track temporary string space on the heap
extern int TempMemoryTop; // this is the last index used for allocating temp memory
extern bool g_TempMemoryIsChanged; // used to prevent unnecessary scanning of strtmp[]
typedef enum _M_Req {M_PROG, M_VAR, M_LIMITED} M_Req;
extern void m_alloc(int type);
extern void *GetMemory(int msize);
extern void *GetSystemMemory(int msize);
extern void *GetTempMemory(int NbrBytes);
extern void *GetTempStrMemory(void);
extern void ClearTempMemory(void);
extern void ClearSpecificTempMemory(void *addr);
extern void TestStackOverflow(void);
extern void FreeMemory(unsigned char *addr);
extern void InitHeap(bool all);
extern unsigned char *HeapBottom(void);
extern int FreeSpaceOnHeap(void);
extern int LargestContiguousHeap(void);
extern unsigned char *DOS_ProgMemory;
extern void *ReAllocMemory(void *addr, size_t msize);
extern void FreeMemorySafe(void **addr);
extern void *GetAlignedMemory(int size);
extern void FreeMemorySafe(void **addr);
extern int MemSize(void *addr);
extern unsigned char *MMHeap;
#ifdef PICOMITEVGA
extern unsigned char *WriteBuf;
extern unsigned char *FrameBuf;
extern unsigned char *SecondFrame;
extern unsigned char *DisplayBuf;
extern unsigned char *LayerBuf;
extern unsigned char *SecondLayer;
#else
extern unsigned char *WriteBuf;
extern unsigned char *FrameBuf;
extern unsigned char *LayerBuf;
#endif
extern uint32_t heap_memory_size;
extern unsigned char *FRAMEBUFFER;
extern uint32_t framebuffersize;
extern unsigned char __attribute__ ((aligned (256))) AllMemory[];
struct s_ctrl {
short int x1, y1, x2, y2; // the coordinates of the touch sensitive area
int fc, bc; // foreground and background colours
int fcc; // foreground colour for the caption (default colour when the control was created)
float value;
float min, max, inc; // the spinbox minimum/maximum and the increment value. NOTE: Radio buttons, gauge and LEDs also store data in these variables
unsigned char *s; // the caption
unsigned char *fmt; // pointer to the format string for FORMATBOX
unsigned char page; // the display page
unsigned char ref, type, state; // reference nbr, type (button, etc) and the state (disabled, etc)
unsigned char font; // the font in use when the control was created (used when redrawing)
unsigned char dummy[3];
};
extern struct s_ctrl *Ctrl; // list of the controls
#define PAGESIZE 256 // the allocation granuality
#define PAGEBITS 2 // nbr of status bits per page of allocated memory, must be a power of 2
#define PUSED 1 // flag that indicates that the page is in use
#define PLAST 2 // flag to show that this is the last page in a single allocation
#define PAGESPERWORD ((sizeof(unsigned int) * 8)/PAGEBITS)
#define MRoundUp(a) (((a) + (PAGESIZE - 1)) & (~(PAGESIZE - 1)))// round up to the nearest page size [position 131:9]
#define MRoundUpK2(a) (((a) + (PAGESIZE*8 - 1)) & (~(PAGESIZE*8 - 1)))// round up to the nearest page size [position 131:9]
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,111 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// Misc_12x20_LE.c
// Font type : Full (95 characters)
// Font size : 12x20 pixels
// Memory usage : 2854 bytes
#ifndef Misc_12x20_LE_h
#define Misc_12x20_LE_h
const unsigned char Misc_12x20_LE[2854] = {
0x0C,0x14,0x20,0x5F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x60,0x06,0x00,0x60,0x06,0x00,0x60,0x02,0x00,0x20,0x00,0x00,0x00,0x06,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, // !
0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0xC0,0xCC,0x0C,0xC0,0x44,0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
0x00,0x00,0x00,0x00,0x00,0x48,0x04,0x80,0x48,0x04,0x80,0x48,0x1F,0xC0,0x90,0x09,0x00,0x90,0x3F,0x80,0x90,0x09,0x00,0x90,0x09,0x00,0x90,0x00,0x00,0x00, // #
0x00,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0xE8,0x11,0x81,0x08,0x10,0x00,0xC0,0x03,0x00,0x08,0x10,0x81,0x88,0x17,0x00,0x20,0x02,0x00,0x20,0x00,0x00,0x00, // $
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x01,0x10,0x11,0x01,0x10,0x0E,0x60,0x38,0x0C,0x03,0x38,0x04,0x40,0x44,0x04,0x40,0x38,0x00,0x00,0x00,0x00,0x00,0x00, // %
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x80,0x08,0x00,0x80,0x04,0x00,0xE8,0x11,0x01,0x10,0x13,0x00,0xCC,0x00,0x00,0x00,0x00,0x00,0x00, // &
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x30,0x06,0x00,0x40,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x10,0x01,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x10,0x01,0x00,0x08,0x00,0x00,0x00, // (
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x40,0x04,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x40,0x04,0x00,0x80,0x00,0x00,0x00, // )
0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x02,0x01,0xFC,0x02,0x00,0x50,0x08,0x80,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // *
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x02,0x00,0x20,0x3F,0xE0,0x20,0x02,0x00,0x20,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // +
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x30,0x06,0x00,0x40,0x08,0x00,0x00, // ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, // .
0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x40,0x08,0x00,0x80,0x10,0x01,0x00,0x20,0x02,0x00,0x40,0x04,0x00,0x80,0x08,0x01,0x00,0x10,0x02,0x00,0x20,0x00,0x00, //
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x88,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x08,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00, // 0
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x01,0xA0,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // 1
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x88,0x10,0x41,0x04,0x00,0x40,0x08,0x01,0x00,0x20,0x04,0x00,0x84,0x10,0x43,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // 2
0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x01,0x08,0x00,0x40,0x04,0x00,0x80,0x70,0x00,0x80,0x04,0x00,0x40,0x04,0x10,0x80,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // 3
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x28,0x02,0x80,0x48,0x04,0x80,0x88,0x08,0x81,0x08,0x1F,0xC0,0x08,0x00,0x80,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, // 4
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x81,0x00,0x10,0x01,0x00,0x17,0x01,0x88,0x00,0x40,0x04,0x00,0x40,0x04,0x30,0x80,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // 5
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0xC0,0x08,0x01,0x00,0x10,0x01,0x70,0x18,0x81,0x04,0x10,0x41,0x04,0x08,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00, // 6
0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC1,0x04,0x00,0x40,0x04,0x00,0x80,0x08,0x00,0x80,0x08,0x01,0x00,0x10,0x01,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00, // 7
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x88,0x10,0x41,0x04,0x08,0x80,0x70,0x08,0x81,0x04,0x10,0x41,0x04,0x08,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00, // 8
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x88,0x10,0x41,0x04,0x10,0x40,0x8C,0x07,0x40,0x04,0x00,0x40,0x08,0x01,0x80,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, // 9
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00, // :
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x60,0x0C,0x00,0x80,0x10,0x00,0x00, // ;
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x18,0x06,0x01,0x80,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFE,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // =
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x18,0x06,0x01,0x80,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // >
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x10,0x41,0x04,0x00,0x40,0x04,0x03,0x80,0x20,0x02,0x00,0x00,0x03,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00, // ?
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x88,0x10,0x41,0x04,0x11,0xC1,0x24,0x12,0x41,0x24,0x11,0xE1,0x00,0x10,0x00,0x86,0x07,0x80,0x00,0x00,0x00,0x00, // @
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE0,0x02,0x00,0x50,0x05,0x00,0x88,0x08,0x81,0x04,0x1F,0xC2,0x02,0x20,0x27,0x8F,0x00,0x00,0x00,0x00,0x00,0x00, // A
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x10,0x81,0x04,0x10,0x41,0x08,0x1F,0x81,0x04,0x10,0x21,0x02,0x10,0x43,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // B
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7A,0x18,0x61,0x02,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x01,0x02,0x18,0x40,0x78,0x00,0x00,0x00,0x00,0x00,0x00, // C
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF0,0x10,0xC1,0x04,0x10,0x21,0x02,0x10,0x21,0x02,0x10,0x21,0x04,0x10,0xC3,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // D
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFC,0x10,0x41,0x04,0x10,0x41,0x20,0x1E,0x01,0x20,0x10,0x41,0x04,0x10,0x43,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // E
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFC,0x10,0x41,0x04,0x10,0x41,0x20,0x1E,0x01,0x20,0x10,0x01,0x00,0x10,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // F
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7A,0x18,0x61,0x02,0x20,0x02,0x00,0x20,0x02,0x0F,0x20,0x21,0x02,0x18,0x40,0x78,0x00,0x00,0x00,0x00,0x00,0x00, // G
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x8E,0x10,0x41,0x04,0x10,0x41,0x04,0x1F,0xC1,0x04,0x10,0x41,0x04,0x10,0x43,0x8E,0x00,0x00,0x00,0x00,0x00,0x00, // H
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFC,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // I
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x82,0x08,0x20,0x82,0x08,0x11,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, // J
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xCF,0x10,0x41,0x08,0x11,0x01,0x20,0x16,0x01,0x90,0x10,0x81,0x08,0x10,0x43,0xC7,0x00,0x00,0x00,0x00,0x00,0x00, // K
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x20,0x82,0x08,0x23,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, // L
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x30,0x62,0x8A,0x28,0xA2,0x52,0x25,0x22,0x22,0x22,0x22,0x02,0x20,0x27,0x8F,0x00,0x00,0x00,0x00,0x00,0x00, // M
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x9E,0x18,0x41,0x44,0x14,0x41,0x24,0x12,0x41,0x14,0x11,0x41,0x0C,0x10,0xC3,0xC4,0x00,0x00,0x00,0x00,0x00,0x00, // N
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x18,0xC1,0x04,0x20,0x22,0x02,0x20,0x22,0x02,0x20,0x21,0x04,0x18,0xC0,0x70,0x00,0x00,0x00,0x00,0x00,0x00, // O
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF8,0x10,0x41,0x02,0x10,0x21,0x04,0x1F,0x81,0x00,0x10,0x01,0x00,0x10,0x03,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, // P
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x18,0xC1,0x04,0x20,0x22,0x02,0x20,0x22,0x02,0x20,0x21,0x04,0x18,0xC0,0x70,0x0E,0x21,0x1C,0x00,0x00,0x00, // Q
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF8,0x10,0x41,0x02,0x10,0x21,0x04,0x1F,0x81,0x10,0x10,0x81,0x08,0x10,0x43,0xC3,0x00,0x00,0x00,0x00,0x00,0x00, // R
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF4,0x10,0xC2,0x04,0x20,0x01,0x00,0x0F,0x00,0x08,0x00,0x42,0x04,0x30,0x82,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // S
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xFE,0x22,0x22,0x22,0x22,0x20,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // T
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x9E,0x20,0x42,0x04,0x20,0x42,0x04,0x20,0x42,0x04,0x20,0x42,0x04,0x10,0x80,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // U
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x8F,0x20,0x22,0x02,0x10,0x41,0x04,0x08,0x80,0x88,0x05,0x00,0x50,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // V
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x8F,0x20,0x22,0x22,0x22,0x22,0x22,0x15,0x41,0x54,0x15,0x41,0x54,0x08,0x80,0x88,0x00,0x00,0x00,0x00,0x00,0x00, // W
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x8E,0x10,0x40,0x88,0x08,0x80,0x50,0x02,0x00,0x50,0x08,0x80,0x88,0x10,0x43,0x8E,0x00,0x00,0x00,0x00,0x00,0x00, // X
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x8E,0x10,0x40,0x88,0x08,0x80,0x50,0x05,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // Y
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFC,0x10,0x41,0x04,0x00,0x80,0x10,0x02,0x00,0x40,0x08,0x01,0x04,0x10,0x41,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // Z
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x03,0x80,0x00, // [
0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x80,0x08,0x00,0x40,0x04,0x00,0x20,0x02,0x00,0x10,0x01,0x00,0x08,0x00,0x80,0x04,0x00,0x40,0x02,0x00,0x20,0x00, // backslash
0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x0E,0x00,0x00, // ]
0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x50,0x08,0x81,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFF, // _
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x88,0x08,0x80,0x88,0x08,0x80,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // `
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x01,0x08,0x00,0x81,0xF8,0x20,0x82,0x08,0x21,0x81,0xEE,0x00,0x00,0x00,0x00,0x00,0x00, // a
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x01,0x00,0x10,0x01,0x00,0x17,0x81,0x84,0x10,0x21,0x02,0x10,0x21,0x02,0x18,0x43,0x78,0x00,0x00,0x00,0x00,0x00,0x00, // b
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x41,0x0C,0x20,0x42,0x00,0x20,0x02,0x00,0x10,0xC0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // c
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x04,0x00,0x40,0x04,0x0F,0x41,0x0C,0x20,0x42,0x04,0x20,0x42,0x04,0x10,0xC0,0xF6,0x00,0x00,0x00,0x00,0x00,0x00, // d
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x01,0x08,0x20,0x43,0xFC,0x20,0x02,0x00,0x10,0xC0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // e
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xE0,0x20,0x04,0x00,0x40,0x1F,0xC0,0x40,0x04,0x00,0x40,0x04,0x00,0x40,0x04,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // f
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x61,0x0C,0x20,0x42,0x04,0x20,0x42,0x04,0x10,0xC0,0xF4,0x00,0x40,0x04,0x00,0x81,0xF0, // g
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x01,0x00,0x10,0x01,0x00,0x17,0x81,0x84,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x43,0x8E,0x00,0x00,0x00,0x00,0x00,0x00, // h
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x0E,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // i
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x1F,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x01,0x01,0xE0, // j
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x01,0x00,0x10,0x01,0x00,0x13,0xC1,0x10,0x12,0x01,0xC0,0x12,0x01,0x10,0x10,0x83,0x1E,0x00,0x00,0x00,0x00,0x00,0x00, // k
0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x01,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // l
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xC3,0x32,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x27,0x33,0x00,0x00,0x00,0x00,0x00,0x00, // m
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x81,0x84,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0x43,0x8E,0x00,0x00,0x00,0x00,0x00,0x00, // n
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x01,0x08,0x20,0x42,0x04,0x20,0x42,0x04,0x10,0x80,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // o
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x81,0x84,0x10,0x21,0x02,0x10,0x21,0x02,0x18,0x41,0x78,0x10,0x01,0x00,0x10,0x03,0xC0, // p
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x61,0x0C,0x20,0x42,0x04,0x20,0x42,0x04,0x10,0xC0,0xF4,0x00,0x40,0x04,0x00,0x40,0x1E, // q
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x80,0xC4,0x08,0x00,0x80,0x08,0x00,0x80,0x08,0x03,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // r
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x41,0x0C,0x10,0x40,0xE0,0x01,0x81,0x04,0x18,0x41,0x78,0x00,0x00,0x00,0x00,0x00,0x00, // s
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x00,0x40,0x1F,0xC0,0x40,0x04,0x00,0x40,0x04,0x00,0x40,0x04,0x20,0x3C,0x00,0x00,0x00,0x00,0x00,0x00, // t
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0xC1,0x04,0x10,0x41,0x04,0x10,0x41,0x04,0x10,0xC0,0xF6,0x00,0x00,0x00,0x00,0x00,0x00, // u
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0xE1,0x04,0x08,0x80,0x88,0x05,0x00,0x50,0x02,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // v
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0xE1,0x04,0x12,0x41,0x24,0x15,0x41,0x54,0x08,0x80,0x88,0x00,0x00,0x00,0x00,0x00,0x00, // w
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0xC1,0x08,0x09,0x00,0x60,0x06,0x00,0x90,0x10,0x83,0x9C,0x00,0x00,0x00,0x00,0x00,0x00, // x
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0xE1,0x04,0x10,0x40,0x88,0x08,0x80,0x50,0x05,0x00,0x20,0x02,0x00,0x40,0x04,0x03,0xE0, // y
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xC1,0x04,0x10,0x80,0x10,0x02,0x00,0x44,0x08,0x41,0xFC,0x00,0x00,0x00,0x00,0x00,0x00, // z
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0xC0,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x01,0x80,0x00, // {
0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x00, // |
0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x18,0x02,0x00,0x20,0x02,0x00,0x20,0x02,0x00,0x20,0x0C,0x00,0x00, // }
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x26,0x40,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
};
#endif
/* @endcond */

View File

@ -0,0 +1,977 @@
/***********************************************************************************************************************
MMBasic
Onewire.c
Handles all the commands and functions related to One Wire support.
The one wire support is based on code from Dallas Semiconductor Corporation:
Copyright 2012 Gerard Sexton
This file is free software: you can redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
Copyright (C) 1999-2006 Dallas Semiconductor Corporation,
All Rights Reserved.
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
************************************************************************************************************************/
/**
* @file Onewire.c
* @author Geoff Graham, Peter Mather
* @brief Source for GPS MMBasic function
*/
/**
* @cond
* The following section will be excluded from the documentation.
*/
#define _SUPPRESS_PLIB_WARNING // required for XC1.33 Later compiler versions will need PLIB to be installed
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#define FALSE 0
#define TRUE 1
#define PinRead(a) gpio_get(PinDef[a].GPno)
void owReset(unsigned char *p);
void owWrite(unsigned char *p);
void owRead(unsigned char *p);
#ifdef INCLUDE_1WIRE_SEARCH
static int LastDiscrepancy;
static int LastFamilyDiscrepancy;
static int LastDeviceFlag;
static unsigned char SerialNum[8];
#endif
#ifdef INCLUDE_CRC
static unsigned short utilcrc16;
static unsigned char utilcrc8;
static const unsigned char dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
static const unsigned short oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
#endif
int mmOWvalue; // value of MM.OW
void ow_pinChk(int pin);
int ow_reset(int pin);
void ow_writeByte(int pin, int data);
int ow_readByte(int pin);
int ow_verifyByte(int pin, int data);
int ow_touchByte(int pin, int data);
int ow_touchBit(int pin, int );
void ow_writeBit(int pin, int );
int ow_readBit(int pin);
void setcrc16(unsigned short reset);
unsigned short docrc16(unsigned short cdata);
void setcrc8(unsigned char reset);
unsigned char docrc8(unsigned char cdata);
int ow_first(int pin, int do_reset, int alarm_only);
int ow_next(int pin, int do_reset, int alarm_only);
int ow_verify(int pin, int alarm_only);
void ow_serialNum(unsigned char *serialnum_buf, int do_read);
void ow_familySearchSetup(int search_family);
void ow_skipFamily(void);
/* @endcond */
// the main OneWire command
void cmd_onewire(void) {
unsigned char *p;
if((p = checkstring(cmdline, (unsigned char *)"RESET")) != NULL)
owReset(p);
else if((p = checkstring(cmdline, (unsigned char *)"WRITE")) != NULL)
owWrite(p);
else if((p = checkstring(cmdline, (unsigned char *)"READ")) != NULL)
owRead(p);
#ifdef INCLUDE_1WIRE_SEARCH
// else if((p = checkstring(cmdline, "SEARCH")) != NULL)
// owSearch(p);
#endif
else
error("Unknown command");
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
/****************************************************************************************************************************
The DS18B20 command and function
*****************************************************************************************************************************/
// this holds an array of 64-bit ints (one for each pin on the chip)
// each number is zero if not being used for temperature measurement
// or the timeout value if a temperature measurement is underway
long long int *ds18b20Timers;
void Init_ds18b20(int pin, int precision) {
// set up initial pin status (open drain, output, high)
ow_pinChk(pin);
ExtCfg(pin, EXT_NOT_CONFIG, 0); // set pin to unconfigured
gpio_init(PinDef[pin].GPno);
ow_reset(pin);
disable_interrupts_pico();
ow_writeByte(pin, 0xcc); // command skip the ROM
ow_writeByte(pin, 0x4E); // write to the scratchpad
ow_writeByte(pin, 0x00); // dummy data to TH
ow_writeByte(pin, 0x00); // dummy data to TL
ow_writeByte(pin, precision << 5); // select the resolution
ow_reset(pin);
ow_writeByte(pin, 0xcc); // skip the ROM
ow_writeByte(pin, 0x44); // command start the conversion
enable_interrupts_pico();
PinSetBit(pin, LATSET);
gpio_set_dir(PinDef[pin].GPno, GPIO_OUT);
gpio_put(PinDef[pin].GPno,GPIO_PIN_SET);
ExtCfg(pin, EXT_DS18B20_RESERVED, 0);
}
/* @endcond */
void cmd_ds18b20(void) {
int pin, precision;
getargs(&cmdline, 5,(unsigned char *)",");
if(argc < 1) error("Argument count");
char code;
if(!(code=codecheck(argv[0])))argv[0]+=2;
pin = getinteger(argv[0]);
if(!code)pin=codemap(pin);
precision = 1;
if(argc >= 3 && *argv[2]) precision = getint(argv[2], 0, 3);
int timeout=(100 << precision);
if(argc==5)timeout=getint(argv[4],100,2000);
Init_ds18b20(pin, precision);
if(ds18b20Timers == NULL) ds18b20Timers = GetMemory(NBRPINS*sizeof(long long int)); // if this is the first time allocate memory for the timer array
ds18b20Timers[pin] = ds18b20Timer + timeout; // set the timer count to wait for the conversion
}
void fun_ds18b20(void) {
int pin, b1, b2;
getargs(&ep,3,(unsigned char *)",");
if(!(argc==1 || argc==3))error("Syntax");
char code;
int timeout=200000;
if(!(code=codecheck(argv[0])))argv[0]+=2;
pin = getinteger(argv[0]);
if(!code)pin=codemap(pin);
if(argc==3)timeout=getint(argv[2],100,2000)*1000;
if(ds18b20Timers == NULL || ds18b20Timers[pin] == 0) {
// the TIMR command has not used
Init_ds18b20(pin, 1); // the default is 10 bits
uSec(timeout); // and 200mS conversion
} else {
// the TIMR command has been used
while(ds18b20Timer < ds18b20Timers[pin]); // wait for the conversion
ds18b20Timers[pin] = 0;
}
if(!ow_readBit(pin)) {
fret = 1000.0;
} else {
ow_reset(pin);
disable_interrupts_pico();
ow_writeByte(pin, 0xcc); // skip the ROM (again)
ow_writeByte(pin, 0xBE); // command read data
b1 = ow_readByte(pin);
b2 = ow_readByte(pin);
enable_interrupts_pico();
ow_reset(pin);
if(b1 == 255 && b2 == 255){
fret = 1000.0;
} else
fret = (MMFLOAT)((short)(((unsigned short)b2 << 8) | (unsigned short)b1)) / 16.0;
}
ExtCfg(pin, EXT_NOT_CONFIG, 0);
targ = T_NBR;
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
/****************************************************************************************************************************
General functions
*****************************************************************************************************************************/
// send one wire reset and optionally return presence response
void owReset(unsigned char *p) {
int pin;
char code;
if(!(code=codecheck(p)))p+=2;
pin = getinteger(p);
if(!code)pin=codemap( pin);
ow_pinChk(pin);
// set up initial pin status (open drain, output, high)
ExtCfg(pin, EXT_NOT_CONFIG, 0); // set pin to unconfigured
gpio_init(PinDef[pin].GPno);
PinSetBit(pin, LATSET);
PinSetBit(pin, ODCSET);
ow_reset(pin);
ExtCurrentConfig[pin] = EXT_NOT_CONFIG;
}
void owWriteCore(int pin, int * buf, int len, int flag){
disable_interrupts_pico();
for (int i = 0; i < len; i++) {
if (flag & 0x04) {
if (buf[i]) {
// Write '1' bit
PinSetBit(pin, LATCLR); // drive pin low
uSec(6);
PinSetBit(pin, LATSET); // release the bus
uSec(64); // wait 64Sec
} else {
// Write '0' bit
PinSetBit(pin, LATCLR); // drive pin low
uSec(60); // wait 60uSec
PinSetBit(pin, LATSET); // release the bus
uSec(10);
}
} else {
ow_writeByte(pin, buf[i]);
}
}
enable_interrupts_pico();
}
// send one wire data
void owWrite(unsigned char *p) {
int pin, flag, len, i, buf[255];
unsigned char *cp;
getargs(&p, MAX_ARG_COUNT*2,(unsigned char *)",");
if (!(argc & 0x01) || (argc < 7)) error("Argument count");
char code;
if(!(code=codecheck(argv[0])))argv[0]+=2;
pin = getinteger(argv[0]);
if(!code)pin=codemap(pin);
ow_pinChk(pin);
flag = getint(argv[2], 0, 15);
len = getint(argv[4], 1, 255);
// check the first char for a legal variable name
cp = argv[6];
skipspace(cp);
//if (argc > 7 || (len == 1 && type == 0)) { // numeric expressions for data
if (len != ((argc - 5) >> 1)) error("Argument count");
for (i = 0; i < len; i++) {
buf[i] = getinteger(argv[i + i + 6]);
}
// set up initial pin status (open drain, output, high)
ExtCfg(pin, EXT_NOT_CONFIG, 0); // set pin to unconfigured
gpio_init(PinDef[pin].GPno);
PinSetBit(pin, LATSET);
PinSetBit(pin, ODCSET);
PinSetBit(pin, TRISCLR); // this line added by JH
if (flag & 0x01) ow_reset(pin);
owWriteCore(pin, buf, len, flag);
if (flag & 0x02) ow_reset(pin);
if (flag & 0x08) { // strong pullup required?
gpio_set_dir(PinDef[pin].GPno, GPIO_OUT);
gpio_put(PinDef[pin].GPno,GPIO_PIN_SET);
}
ExtCurrentConfig[pin] = EXT_NOT_CONFIG;
return;
}
void owReadCore(int pin, int * buf, int len, int flag){
disable_interrupts_pico();
PinSetBit(pin, TRISCLR); // set as output *** added this line
for (int i = 0; i < len; i++) {
if (flag & 0x04) {
buf[i] = ow_readBit(pin);
} else {
buf[i] = ow_readByte(pin);
}
}
enable_interrupts_pico();
}
// read one wire data
void owRead(unsigned char *p) {
int pin, flag, len, i, buf[255];
void *ptr = NULL;
getargs(&p, MAX_ARG_COUNT*2,(unsigned char *)",");
if (!(argc & 0x01) || (argc < 7)) error("Argument count");
char code;
if(!(code=codecheck(argv[0])))argv[0]+=2;
pin = getinteger(argv[0]);
if(!code)pin=codemap( pin);
ow_pinChk(pin);
flag = getint(argv[2], 0, 15);
len = getint(argv[4], 1, 255);
// check the validity of the argument list
if (len != ((argc - 5) >> 1)) error("Argument count");
for (i = 0; i < len; i++) {
ptr = findvar(argv[i + i + 6], V_FIND);
if(g_vartbl[g_VarIndex].type & T_CONST) error("Cannot change a constant");
if (!(g_vartbl[g_VarIndex].type & (T_NBR | T_INT)) || g_vartbl[g_VarIndex].dims[0] != 0) error("Invalid variable");
}
// set up initial pin status (open drain, output, high)
ExtCfg(pin, EXT_NOT_CONFIG, 0); // set pin to unconfigured
gpio_init(PinDef[pin].GPno);
PinSetBit(pin, LATSET);
PinSetBit(pin, ODCSET);
if (flag & 0x01) ow_reset(pin);
owReadCore(pin, buf, len, flag);
if (flag & 0x02) ow_reset(pin);
if (flag & 0x08) { // strong pullup required?
PinSetBit(pin, LATSET);
PinSetBit(pin, TRISCLR);
}
for (i = 0; i < len; i++) {
ptr = findvar(argv[i + i + 6], V_FIND);
if(g_vartbl[g_VarIndex].type & T_NBR)
*((MMFLOAT *)ptr) = buf[i];
else
*((long long int *)ptr) = buf[i];
}
ExtCurrentConfig[pin] = EXT_NOT_CONFIG;
return;
}
#ifdef INCLUDE_1WIRE_SEARCH
// One wire search
// flag: 1 = reset search
// 2 = alarm set
// 4 = family search
// 8 = skip current family
// 16 = verify
//
/* @endcond */
void fun_owSearch(void) {
int pin, flag, alarm, i;
union map
{
unsigned char serbytes[8];
unsigned long long int ser;
} buf,inp;
unsigned char filter=0;
getargs(&ep, MAX_ARG_COUNT*2,(unsigned char *)",");
if (!(argc & 0x01) || (argc < 3)) error("Argument count");
char code;
if(!(code=codecheck(argv[0])))argv[0]+=2;
pin = getinteger(argv[0]);
if(!code)pin=codemap( pin);
ow_pinChk(pin);
flag = getinteger(argv[2]);
if (flag < 0 || flag > 31) error("Number out of bounds");
if (((flag & 0x01) && flag > 7) || ((flag & 0x04) && flag > 7) || ((flag & 0x08) && flag > 15)) error("Invalid flag combination");
if ((flag & 0x04) || (flag & 0x10)) {
if(argc < 3) error("Argument count");
inp.ser=getinteger(argv[4]);
for (i = 0; i < 8; i++) {
buf.serbytes[7-i] = inp.serbytes[i];
}
filter=buf.serbytes[0];
}
if (flag & 0x02) alarm = 1; else alarm = 0;
// set up initial pin status (open drain, output, high)
ExtCfg(pin, EXT_NOT_CONFIG, 0); // set pin to unconfigured
gpio_init(PinDef[pin].GPno);
PinSetBit(pin, LATSET);
PinSetBit(pin, ODCSET);
if (flag & 0x01) {
mmOWvalue = ow_first(pin, 1, alarm);
} else if (flag & 0x08) {
ow_skipFamily();
mmOWvalue = ow_next(pin, 1, alarm);
} else if (flag & 0x10) {
ow_serialNum(buf.serbytes, 0);
mmOWvalue = ow_verify(pin, alarm);
} else {
mmOWvalue = ow_next(pin, 1, alarm);
}
if(flag & 0x04){
while(SerialNum[0]!=filter && mmOWvalue){
mmOWvalue = ow_next(pin, 1, alarm);
}
}
for (i = 0; i < 8; i++) {
buf.serbytes[7-i] = SerialNum[i];
}
if(!mmOWvalue)buf.ser=0;
iret=buf.ser;
targ = T_INT;
return;
}
#endif
/*
* @cond
* The following section will be excluded from the documentation.
*/
#if defined(INCLUDE_CRC)
void fun_owCRC8(void){
int len, i, x;
unsigned char buf[255], uc = 0;
getargs(&ep, MAX_ARG_COUNT*2,","); // this is a macro and must be the first executable stmt in a block
if (!(argc & 0x01) || (argc < 3)) error("Argument count");
len = getinteger(argv[0]);
if ((len < 1) || (len > 255)) error("Number out of bounds");
if (len != ((argc - 1) >> 1)) error("Argument count");
for (i = 0; i < len; i++) {
x = getinteger(argv[i + i + 6]);
if (x < 0 || x > 255) error("Number out of bounds");
buf[i] = (unsigned char)x;
}
setcrc8(0);
for (i = 0; i < len; i++) {
uc = docrc8(buf[i]);
}
fret = (MMFLOAT)uc;
}
void fun_owCRC16(void){
int len, i, x;
unsigned short buf[255], us = 0;
getargs(&ep, MAX_ARG_COUNT*2,","); // this is a macro and must be the first executable stmt in a block
if (!(argc & 0x01) || (argc < 3)) error("Argument count");
len = getinteger(argv[0]);
if ((len < 1) || (len > 255)) error("Number out of bounds");
if (len != ((argc - 1) >> 1)) error("Argument count");
for (i = 0; i < len; i++) {
x = getinteger(argv[i + i + 6]);
if (x < 0 || x > 65535) error("Number out of bounds");
buf[i] = (unsigned short)x;
}
setcrc16(0);
for (i = 0; i < len; i++) {
us = docrc16(buf[i]);
}
fret = (MMFLOAT)us;
}
#endif
/* @endcond */
void fun_mmOW(void) {
iret = mmOWvalue;
targ = T_INT;
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
void ow_pinChk(int pin) {
// if(ClockSpeed < 10000000) error("CPU speed too low");
CheckPin(pin, CP_CHECKALL);
return;
}
// send one wire reset and detect presence response - returns 1 if found else 0
int ow_reset(int pin) {
PinSetBit(pin, LATSET);
PinSetBit(pin, TRISCLR);
PinSetBit(pin, LATCLR); // drive pin low
uSec(481); // wait 481uSec
PinSetBit(pin, TRISSET); // set as input
PinSetBit(pin, LATSET); // release the bus
uSec(70); // wait 70uSec
mmOWvalue = PinRead(pin) ^ 0x01; // read pin and invert response
PinSetBit(pin, TRISCLR); // set as output
uSec(411); // wait 411uSec
return mmOWvalue;
}
void __not_in_flash_func(ow_writeByte)(int pin, int data) {
int loop;
for (loop = 0; loop < 8; loop++) {
ow_writeBit(pin, data & 0x01);
data >>= 1;
}
return;
}
int __not_in_flash_func(ow_readByte)(int pin) {
int loop, result = 0;
for (loop = 0; loop < 8; loop++) {
result >>= 1;
if (ow_readBit(pin)) result |= 0x80;
}
return result;
}
int ow_touchByte(int pin, int data) {
int loop, result = 0;
for (loop = 0; loop < 8; loop++) {
result >>= 1;
if (data & 0x01) { // if sending a '1' then read a bit else write a '0'
if (ow_readBit(pin)) result |= 0x80;
} else {
ow_writeBit(pin, 0x00);
}
data >>= 1;
}
return result;
}
int ow_touchBit(int pin, int bit) {
int result = 0;
if (bit & 0x01) { // if sending a '1' then read a bit else write a '0'
if (ow_readBit(pin)) result = 1;
} else {
ow_writeBit(pin, 0x00);
}
return result;
}
// note that the uSec() function will not time short delays at low clock speeds
// so we directly use the core timer for short delays
void __not_in_flash_func(ow_writeBit)(int pin, int bit) {
if (bit) {
// Write '1' bit
PinSetBit(pin, LATCLR); // drive pin low
uSec(6);
PinSetBit(pin, LATSET); // release the bus
uSec(64); // wait 64Sec
} else {
// Write '0' bit
PinSetBit(pin, LATCLR); // drive pin low
uSec(60); // wait 60uSec
PinSetBit(pin, LATSET); // release the bus
uSec(10);
}
return;
}
// note that the uSec() function will not time short delays at low clock speeds
// so we directly use the core timer for short delays
int ow_readBit(int pin) {
int result;
PinSetBit(pin, TRISCLR); // set as output *** JH
PinSetBit(pin, LATCLR); // drive pin low
uSec(3);
PinSetBit(pin, TRISSET); // set as input
PinSetBit(pin, LATSET); // release the bus
uSec(10);
result = PinRead(pin); // read pin
// PinSetBit(pin, TRISCLR);
uSec(53); // wait 56uSec
return result;
}
#ifdef INCLUDE_1WIRE_SEARCH
int ow_verifyByte(int pin, int data) {
return (ow_touchByte(pin, data) == data) ? 1 : 0;
}
//--------------------------------------------------------------------------
// The 'ow_first' finds the first device on the 1-Wire Net
//
// When 'alarm_only' is TRUE (1) the find alarm command 0xEC is
// sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// 'pin' - I/O Pin.
// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
// perform reset before search.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
// sent instead of the normal search command 0xF0
//
// Returns: TRUE (1) : when a 1-Wire device was found and it's
// Serial Number placed in the global SerialNum[portnum]
// FALSE (0): There are no devices on the 1-Wire Net.
//
int ow_first(int pin, int do_reset, int alarm_only) {
// reset the search state
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
return ow_next(pin, do_reset, alarm_only);
}
//--------------------------------------------------------------------------
// The 'ow_next' function does a general search. This function
// continues from the previos search state. The search state
// can be reset by using the 'ow_first' function.
//
// When 'alarm_only' is TRUE (1) the find alarm command
// 0xEC is sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// 'pin' - I/O Pin.
// 'do_reset' - TRUE (1) perform reset before search, FALSE (0) do not
// perform reset before search.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
// sent instead of the normal search command 0xF0
//
// Returns: TRUE (1) : when a 1-Wire device was found and it's
// Serial Number placed in the global SerialNum[portnum]
// FALSE (0): when no new device was found. Either the
// last search was the last device or there
// are no devices on the 1-Wire Net.
//
int ow_next(int pin, int do_reset, int alarm_only) {
int bit_test, search_direction, bit_number;
int last_zero, serial_byte_number, next_result;
unsigned char serial_byte_mask, lastcrc8;
// initialize for search
bit_number = 1;
last_zero = 0;
serial_byte_number = 0;
serial_byte_mask = 1;
next_result = 0;
lastcrc8 = 0;
setcrc8(0);
// if the last call was not the last one
if (!LastDeviceFlag) {
// check if reset first is requested
if (do_reset) {
// reset the 1-wire
// if there are no parts on 1-wire, return FALSE
if (!ow_reset(pin)) {
// reset the search
LastDiscrepancy = 0;
LastFamilyDiscrepancy = 0;
return FALSE;
}
}
// If finding alarming devices issue a different command
if (alarm_only) {
ow_writeByte(pin, 0xEC); // issue the alarming search command
} else {
ow_writeByte(pin, 0xF0); // issue the search command
}
// loop to do the search
do {
// read a bit and its compliment
bit_test = ow_touchBit(pin, 1) << 1;
bit_test |= ow_touchBit(pin, 1);
// check for no devices on 1-wire
if (bit_test == 3) break;
else {
// all devices coupled have 0 or 1
if (bit_test > 0) {
search_direction = !(bit_test & 0x01); // bit write value for search
} else {
// if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time
if (bit_number < LastDiscrepancy)
search_direction = ((SerialNum[serial_byte_number] & serial_byte_mask) > 0);
else
// if equal to last pick 1, if not then pick 0
search_direction = (bit_number == LastDiscrepancy);
// if 0 was picked then record its position in LastZero
if (search_direction == 0) {
last_zero = bit_number;
// check for Last discrepancy in family
if (last_zero < 9) LastFamilyDiscrepancy = last_zero;
}
}
// set or clear the bit in the SerialNum byte serial_byte_number
// with mask serial_byte_mask
if (search_direction == 1)
SerialNum [serial_byte_number] |= serial_byte_mask;
else
SerialNum [serial_byte_number] &= ~serial_byte_mask;
// serial number search direction write bit
ow_touchBit(pin, search_direction);
// increment the byte counter bit_number
// and shift the mask serial_byte_mask
bit_number++;
serial_byte_mask <<= 1;
// if the mask is 0 then go to new SerialNum byte serial_byte_number
// and reset mask
if (serial_byte_mask == 0) {
// The below has been added to accomodate the valid CRC with the
// possible changing serial number values of the DS28E04.
if (((SerialNum[0] & 0x7F) == 0x1C) && (serial_byte_number == 1))
lastcrc8 = docrc8(0x7F);
else
lastcrc8 = docrc8(SerialNum[serial_byte_number]); // accumulate the CRC
serial_byte_number++;
serial_byte_mask = 1;
}
}
} while(serial_byte_number < 8); // loop until through all SerialNum[portnum] bytes 0-7
// if the search was successful then
if (!((bit_number < 65) || lastcrc8)) {
// search successful so set LastDiscrepancy, LastDeviceFlag, next_result
LastDiscrepancy = last_zero;
LastDeviceFlag = (LastDiscrepancy == 0);
next_result = TRUE;
}
}
// if no device found then reset counters so next 'next' will be
// like a first
if (!next_result || !SerialNum[0]) {
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
next_result = FALSE;
}
return next_result;
}
//--------------------------------------------------------------------------
// The 'ow_verify' function checks that the device with the serial number
// in the global SerialNum buffer is present.
//
// When 'alarm_only' is TRUE (1) the find alarm command
// 0xEC is sent instead of the normal search command 0xF0.
// Using the find alarm command 0xEC will limit the search to only
// 1-Wire devices that are in an 'alarm' state.
//
// 'pin' - I/O Pin.
// 'alarm_only' - TRUE (1) the find alarm command 0xEC is
// sent instead of the normal search command 0xF0
//
// Returns: TRUE (1) : device verified present.
// FALSE (0): device not present.
//
int ow_verify(int pin, int alarm_only) {
unsigned char serialNum_backup[8];
int i, rslt, ld_backup, ldf_backup, lfd_backup;
// keep a backup copy of the current state
for (i = 0; i < 8; i++) serialNum_backup[i] = SerialNum[i];
ld_backup = LastDiscrepancy;
ldf_backup = LastDeviceFlag;
lfd_backup = LastFamilyDiscrepancy;
// set search to find the same device
LastDiscrepancy = 64;
LastDeviceFlag = FALSE;
if (ow_next(pin, 1, alarm_only)) {
// check if same device found
rslt = TRUE;
for (i = 0; i < 8; i++) {
if (serialNum_backup[i] != SerialNum[i]) {
rslt = FALSE;
break;
}
}
} else {
rslt = FALSE;
}
// restore the search state
for (i = 0; i < 8; i++) SerialNum[i] = serialNum_backup[i];
LastDiscrepancy = ld_backup;
LastDeviceFlag = ldf_backup;
LastFamilyDiscrepancy = lfd_backup;
// return the result of the verify
return rslt;
}
//--------------------------------------------------------------------------
// The 'ow_serialNum' function either reads or sets the SerialNum buffer
// that is used in the search functions 'ow_first' and 'ow_next'.
// This function contains two parameters, 'serialnum_buf' is a pointer
// to a buffer provided by the caller. 'serialnum_buf' should point to
// an array of 8 unsigned chars. The second parameter is a flag called
// 'do_read' that is TRUE (1) if the operation is to read and FALSE
// (0) if the operation is to set the internal SerialNum buffer from
// the data in the provided buffer.
//
// 'serialnum_buf' - buffer to that contains the serial number to set
// when do_read = FALSE (0) and buffer to get the serial
// number when do_read = TRUE (1).
// 'do_read' - flag to indicate reading (1) or setting (0) the current
// serial number.
//
void ow_serialNum(unsigned char *serialnum_buf, int do_read)
{
unsigned char i;
// read the internal buffer and place in 'serialnum_buf'
if (do_read) {
for (i = 0; i < 8; i++) serialnum_buf[i] = SerialNum[i];
} else { // set the internal buffer from the data in 'serialnum_buf'
for (i = 0; i < 8; i++) SerialNum[i] = serialnum_buf[i];
}
}
//--------------------------------------------------------------------------
// Setup the search algorithm to find a certain family of devices
// the next time a search function is called 'owNext'.
//
// 'search_family' - family code type to set the search algorithm to find
// next.
//
void ow_familySearchSetup(int search_family)
{
int i;
// set the search state to find SearchFamily type devices
SerialNum[0] = search_family;
for (i = 1; i < 8; i++) SerialNum[i] = 0;
LastDiscrepancy = 64;
LastDeviceFlag = FALSE;
}
//--------------------------------------------------------------------------
// Set the current search state to skip the current family code.
//
void ow_skipFamily(void)
{
// set the Last discrepancy to last family discrepancy
LastDiscrepancy = LastFamilyDiscrepancy;
LastFamilyDiscrepancy = 0;
// check for end of list
if (LastDiscrepancy == 0) LastDeviceFlag = TRUE;
}
#endif
#if defined(INCLUDE_CRC)
void setcrc16(unsigned short reset) {
utilcrc16 = reset;
return;
}
unsigned short docrc16(unsigned short cdata) {
cdata = (cdata ^ (utilcrc16 & 0xff)) & 0xff;
utilcrc16 >>= 8;
if (oddparity[cdata & 0xf] ^ oddparity[cdata >> 4]) utilcrc16 ^= 0xc001;
cdata <<= 6;
utilcrc16 ^= cdata;
cdata <<= 1;
utilcrc16 ^= cdata;
return utilcrc16;
}
void setcrc8(unsigned char reset) {
utilcrc8 = reset;
return;
}
unsigned char docrc8(unsigned char cdata) {
utilcrc8 = dscrc_table[utilcrc8 ^ cdata];
return utilcrc8;
}
#endif
/* @endcond */

View File

@ -0,0 +1,33 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
MMBasic
Onewire.h
Include file that contains the globals and defines for Onewire.c (One Wire support) in MMBasic.
Copyright 2012 Gerard Sexton
This file is free software: you can redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
************************************************************************************************************************/
// These two together take up about 4K of flash and no one seems to use them !!
//#define INCLUDE_CRC
#define INCLUDE_1WIRE_SEARCH
/* ********************************************************************************
All other required definitions and global variables should be define here
**********************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#ifndef ONEWIRE_HEADER
#define ONEWIRE_HEADER
extern long long int *ds18b20Timers;
extern int mmOWvalue;
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,239 @@
/***********************************************************************************************************************
PicoMite MMBasic
Operators.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.
************************************************************************************************************************/
/**
* @file Operators.c
* @author Geoff Graham, Peter Mather
* @brief Source for standard MMBasic operators
*/
/**
* @cond
* The following section will be excluded from the documentation.
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include <errno.h>
/********************************************************************************************************************************************
basic operators
each function is responsible for decoding a basic operator
all function names are in the form op_xxxx() so, if you want to search for the function responsible for the AND operator look for op_and
There are 5 globals used by these finctions:
farg1, farg2 These are the floating point arguments to the operator. farg1 is the left argument
sarg1, sarg2 These are the string pointers to the arguments for a the string operator. sarg1 is the left argument
fret Is the return value for a basic operator that returns a float value
iret Is the return value for a basic operator that returns an integer
sret Is the return value for a basic operator that returns a string
targ Is the type of the arguments. normally this is set by the caller and is not changed by the function
********************************************************************************************************************************************/
void __not_in_flash_func(op_invalid)(void) {
error("Syntax error");
}
/* @endcond */
void __not_in_flash_func(op_exp)(void) {
long long int i;
if(targ & T_NBR){
fret = (MMFLOAT)pow(farg1, farg2);
if(fret==INFINITY) error("Overflow");
}
else {
if(iarg2 < 0) {
targ = T_NBR;
fret = (MMFLOAT)pow((MMFLOAT)iarg1, (MMFLOAT)iarg2);
} else
for(iret = i = 1; i <= iarg2; i++) iret *= iarg1;
}
}
void __not_in_flash_func(op_mul)(void) {
if(targ & T_NBR){
fret = farg1 * farg2;
if(fret==INFINITY) error("Overflow");
}
else
iret = iarg1 * iarg2;
}
// division will always return a float even if given integer arguments
void __not_in_flash_func(op_div)(void) {
if(farg2 == 0) error("Divide by zero");
fret = farg1 / farg2;
if(fret==INFINITY) error("Overflow");
targ = T_NBR;
}
void __not_in_flash_func(op_divint)(void) {
if(iarg2 == 0) error("Divide by zero");
iret = iarg1 / iarg2;
}
void __not_in_flash_func(op_add)(void) {
if(targ & T_NBR){
fret = farg1 + farg2;
if(fret==INFINITY) error("Overflow");
}
else if(targ & T_INT)
iret = iarg1 + iarg2;
else {
if(*sarg1 + *sarg2 > MAXSTRLEN) error("String too long");
sret = GetTempMemory(STRINGSIZE); // this will last for the life of the command
Mstrcpy(sret, sarg1);
Mstrcat(sret, sarg2);
}
}
void __not_in_flash_func(op_subtract)(void) {
if(targ & T_NBR)
fret = farg1 - farg2;
else
iret = iarg1 - iarg2;
}
void __not_in_flash_func(op_mod)(void) {
if(iarg2 == 0) error("Divide by zero");
iret = iarg1 % iarg2;
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
static inline long long int (compare)(void) {
long long int r;
MMFLOAT f;
if(targ & T_NBR) {
f = farg1 - farg2;
if(f > 0)
r = 1;
else if(f < 0)
r = -1;
else
r = 0;
}
else
if(targ & T_INT)
r = iarg1 - iarg2;
else
r = Mstrcmp(sarg1, sarg2);
targ = T_INT; // always return an float, even if the args are string
return r;
}
/* @endcond */
void __not_in_flash_func(op_ne)(void) {
if(targ & T_INT)
iret = iarg1 != iarg2;
else
iret = (compare() != 0);
}
void __not_in_flash_func(op_gte)(void) {
iret = (compare() >= 0);
}
void __not_in_flash_func(op_lte)(void) {
iret = (compare() <= 0);
}
void __not_in_flash_func(op_lt)(void) {
iret = (compare() < 0);
}
void __not_in_flash_func(op_gt)(void) {
iret = (compare() > 0);
}
void __not_in_flash_func(op_equal)(void) {
if(targ & T_INT)
iret = iarg1 == iarg2;
else
iret = (compare() == 0);
}
void __not_in_flash_func(op_shiftleft)(void) {
iret = (long long int )((unsigned long long int )iarg1 << (long long int )iarg2);
}
void __not_in_flash_func(op_shiftright)(void) {
iret = (long long int )((unsigned long long int )iarg1 >> (long long int )iarg2);
}
void __not_in_flash_func(op_and)(void) {
iret = (long long int )((unsigned long long int )iarg1 & (unsigned long long int )iarg2);
}
void __not_in_flash_func(op_or)(void) {
iret = (long long int )((unsigned long long int )iarg1 | (unsigned long long int )iarg2);
}
void __not_in_flash_func(op_xor)(void) {
iret = (long long int )((unsigned long long int )iarg1 ^ (unsigned long long int )iarg2);
}
void __not_in_flash_func(op_not)(void){
// don't do anything, just a place holder
error("Syntax error");
}
void __not_in_flash_func(op_inv)(void){
// don't do anything, just a place holder
error("Syntax error");
}

View File

@ -0,0 +1,41 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Operators.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
// the format is:
// TEXT TYPE P FUNCTION TO CALL
// where type is T_NA, T_FUN, T_FNA or T_OPER argumented by the types T_STR and/or T_NBR and/or T_INT
// and P is the precedence (which is only used for operators)
#endif
/* @endcond */

View File

@ -0,0 +1,65 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/*
* Keyboard.h
*
* Created on: 20 Apr 2019
* Author: Peter
*/
#ifndef PS2KEYBOARD_H_
#define PS2KEYBOARD_H_
/* *********************************************************************************************************************
MMBasic
Keyboard.h
Include file that contains the globals and defines for Keyboard.c in MMBasic.
Copyright 2011 - 2018 Geoff Graham. All Rights Reserved.
This file and modified versions of this file are supplied to specific individuals or organisations under the following
provisions:
- This file, or any files that comprise the MMBasic source (modified or not), may not be distributed or copied to any other
person or organisation without written permission.
- Object files (.o and .hex files) generated using this file (modified or not) may not be distributed or copied to any other
person or organisation without written permission.
- This file is provided in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
************************************************************************************************************************/
// global keyboard functions
extern void initKeyboard(void);
extern void CNInterrupt(uint64_t dd);
extern void MNInterrupt(uint64_t dd);
extern void CheckKeyboard(void);
extern volatile int PS2code;
extern volatile bool PS2int;
// definition of the keyboard PS/2 state machine
#define PS2START 0
#define PS2BIT 1
#define PS2PARITY 2
#define PS2STOP 3
#define PS2COMMAND 4
#define PS2ERROR 9
// definitions related to setting the keyboard type
#define NO_KEYBOARD 0
#define CONFIG_US 1
#define CONFIG_FR 2
#define CONFIG_GR 3
#define CONFIG_IT 4
#define CONFIG_BE 5
#define CONFIG_UK 6
#define CONFIG_ES 7
#define CONFIG_BR 8
#define CONFIG_I2C 128
#endif /* PS2KEYBOARD_H_ */
/* @endcond */

View File

@ -0,0 +1,483 @@
/*******************************************************************************************
*
* Definitions used when calling MMBasic Interpreter API Functions from CFunctions
* For PicoMite MMBasic V6.00.01
*
* This file is public domain and may be used without license.
*
* Use with AMRCFGENV144.bas
*
* V1.6.2
* NB: Base address has changed from previous versions to match V5.07.05
* V1.6.3 struct option_s updated to match 5.07.05 as defined in fileIO.h
* V1.6.4 Additional links
* v1.6.5 Latest Beta29 and PICOMITEVGA PICOMITEWEB Compiled with GCC 11.2.1
* v1.6.6 Updated to match 5.07.07 and 5.07.08b5 updates for fixed IP address
* v1.6.7 Updated to match 5.07.08 release matches option_s and CSubComplete now char
* v2.0.0 Updated for MMBasic 6.00.00 and also for RP2350 chip.
* BaseAddress is different for PICO and PICO2 Set the correct #define
* Note: Use ? HEX$(MM.INFO(CALLTABLE)) to verify the location of the calltable.
* struct option_s updated to match v6.00.00RC15
* v2.0.1 struct option_s updated to match v6.00.01 Release
*
******************************************************************************************/
/*** Uncomment one of these three ***/
#define PICOMITE
//#define PICOMITEVGA
//#define PICOMITEWEB
/*** Uncomment this define if using PICO2 Chip ***/
#define PICORP2350
/*** Uncomment this define if HDMI pins required ***/
#define GUICONTROLS
/*****************************************************************************************/
#define MAXVARLEN 32 // maximum length of a variable name
#define MAXDIM 5 // maximum nbr of dimensions to an array
#define MMFLOAT double
#define MAXKEYLEN 64
//Addresses in the API Table for the pointers to each function
#ifdef PICORP2350
#define BaseAddress 0x1000023C
#else
#define BaseAddress 0x100002D4
#endif
#define Vector_uSec (*(unsigned int *)(BaseAddress+0x00)) // void uSec(unsigned int us)
#define Vector_putConsole (*(unsigned int *)(BaseAddress+0x04)) // void putConsole(int C))
#define Vector_getConsole (*(unsigned int *)(BaseAddress+0x08)) // int getConsole(void)
#define Vector_ExtCfg (*(unsigned int *)(BaseAddress+0x0C)) // void ExtCfg(int pin, int cfg, int option)
#define Vector_ExtSet (*(unsigned int *)(BaseAddress+0x10)) // void ExtSet(int pin, int val)
#define Vector_ExtInp (*(unsigned int *)(BaseAddress+0x14)) // int ExtInp(int pin)
#define Vector_PinSetBit (*(unsigned int *)(BaseAddress+0x18)) // void PinSetBit(int pin, unsigned int offset)
#define Vector_PinRead (*(unsigned int *)(BaseAddress+0x1C)) // int PinRead(int pin)
#define Vector_MMPrintString (*(unsigned int *)(BaseAddress+0x20)) // void MMPrintString(char* s)
#define Vector_IntToStr (*(unsigned int *)(BaseAddress+0x24)) // void IntToStr(char *strr, long long int nbr, unsigned int base)
#define Vector_CheckAbort (*(unsigned int *)(BaseAddress+0x28)) // void CheckAbort(void)
#define Vector_GetMemory (*(unsigned int *)(BaseAddress+0x2C)) // void *GetMemory(size_t msize);
#define Vector_GetTempMemory (*(unsigned int *)(BaseAddress+0x30)) // void *GetTempMemory(int NbrBytes)
#define Vector_FreeMemory (*(unsigned int *)(BaseAddress+0x34)) // void FreeMemory(void *addr)
#define Vector_DrawRectangle *(unsigned int *)(BaseAddress+0x38 ) // void DrawRectangle(int x1, int y1, int x2, int y2, int C))
#define Vector_DrawBitmap *(unsigned int *)(BaseAddress+0x3c ) // void DrawBitmap(int x1, int y1, int width, int height, int scale, int fg, int bg, unsigned char *bitmap )
#define Vector_DrawLine (*(unsigned int *)(BaseAddress+0x40)) // void DrawLine(int x1, int y1, int x2, int y2, int w, int C))
#define Vector_FontTable (*(unsigned int *)(BaseAddress+0x44)) // const unsigned char *FontTable[FONT_NBR]
#define Vector_ExtCurrentConfig (*(unsigned int *)(BaseAddress+0x48)) // int ExtCurrentConfig[NBRPINS + 1];
#define Vector_HRes (*(unsigned int *)(BaseAddress+0x4C)) // HRes
#define Vector_VRes (*(unsigned int *)(BaseAddress+0x50)) // VRes
#define Vector_SoftReset (*(unsigned int *)(BaseAddress+0x54)) // void SoftReset(void)
#define Vector_error (*(unsigned int *)(BaseAddress+0x58)) // void error(char *msg)
#define Vector_ProgFlash (*(unsigned int *)(BaseAddress+0x5C)) // ProgFlash
#define Vector_vartbl (*(unsigned int *)(BaseAddress+0x60)) // g_vartbl
#define Vector_varcnt (*(unsigned int *)(BaseAddress+0x64)) // g_varcnt
#define Vector_DrawBuffer *(unsigned int *)(BaseAddress+0x68 ) // void DrawRectangle(int x1, int y1, int x2, int y2, int C))
#define Vector_ReadBuffer *(unsigned int *)(BaseAddress+0x6c ) // void DrawRectangle(int x1, int y1, int x2, int y2, int C))
#define Vector_FloatToStr (*(unsigned int *)(BaseAddress+0x70)) // convert a float to a string including scientific notation if necessary
#define Vector_ExecuteProgram (*(unsigned int *)(BaseAddress+0x74)) // void ExecuteProgram(char *fname)
#define Vector_CFuncmSec (*(unsigned int *)(BaseAddress+0x78)) // CFuncmSec
#define Vector_CFuncRam (*(unsigned int *)(BaseAddress+0x7C)) // StartOfCFuncRam
#define Vector_ScrollLCD *(unsigned int *)(BaseAddress+0x80 ) // void scrollLCD(int lines, int blank)
#define Vector_IntToFloat (*(unsigned int *)(BaseAddress+0x84)) // MMFLOAT IntToFloat(long long int a)
#define Vector_FloatToInt (*(unsigned int *)(BaseAddress+0x88)) // long long int FloatToInt64(MMFLOAT x)
#define Vector_Option (*(unsigned int *)(BaseAddress+0x8C)) // Option
#define Vector_Sine (*(unsigned int *)(BaseAddress+0x90)) // MMFLOAT sin(MMFLOAT)
#define Vector_DrawCircle (*(unsigned int *)(BaseAddress+0x94)) // DrawCircle(int x, int y, int radius, int w, int c, int fill, MMFLOAT aspect)
#define Vector_DrawTriangle (*(unsigned int *)(BaseAddress+0x98)) // DrawTriangle(int x0, int y0, int x1, int y1, int x2, int y2, int c, int fill)
#define Vector_Timer (*(unsigned int *)(BaseAddress+0x9C)) // uint64_t timer(void)
#define Vector_FMul (*(unsigned int *)(BaseAddress+0xA0)) // MMFLOAT FMul(MMFLOAT a, MMFLOAT b){ return a * b; }
#define Vector_FAdd (*(unsigned int *)(BaseAddress+0xA4)) // MMFLOAT FAdd(MMFLOAT a, MMFLOAT b){ return a + b; }
#define Vector_FSub (*(unsigned int *)(BaseAddress+0xA8)) // MMFLOAT FSub(MMFLOAT a, MMFLOAT b){ return a - b; }
#define Vector_FDiv (*(unsigned int *)(BaseAddress+0xAC)) // MMFLOAT FDiv(MMFLOAT a, MMFLOAT b){ return a / b; }
#define Vector_FCmp (*(unsigned int *)(BaseAddress+0xB0)) // int FCmp(MMFLOAT a,MMFLOAT b){if(a>b) return 1;else if(a<b)return -1; else return 0;}
#define Vector_LoadFloat (*(unsigned int *)(BaseAddress+0xB4)) /* MMFLOAT LoadFloat(unsigned long long C)){union ftype{ unsigned long long a; MMFLOAT b;}f;f.a=c;return f.b; }*/
#define Vector_CFuncInt1 *(unsigned int *)(BaseAddress+0xB8 ) // CFuncInt1
#define Vector_CFuncInt2 *(unsigned int *)(BaseAddress+0xBC) // CFuncInt2
#define Vector_CSubComplete (*(unsigned int *)(BaseAddress+0xC0)) // CSubComplete
#define Vector_AudioOutput *(unsigned int *)(BaseAddress+0xC4) // AudioOutput(int left, int right)
#define Vector_IDiv (*(unsigned int *)(BaseAddress+0xC8)) // int IDiv(int a, int b){ return a / b; }
#define Vector_AUDIO_WRAP (*(volatile unsigned int *)(BaseAddress+0xCC))// AUDIO_WRAP
#define Vector_CFuncInt3 *(unsigned int *)(BaseAddress+0xD0 ) // CFuncInt3
#define Vector_CFuncInt4 *(unsigned int *)(BaseAddress+0xD4) // CFuncInt4
#define Vector_PIOExecute (*(unsigned int *)(BaseAddress+0xD8)) // void PioExecute(int pio, int sm, uint32_t instruction)
//Macros to call each function.
#define uSec(a) ((void (*)(unsigned long long )) Vector_uSec) (a)
#define putConsole(a,b) ((void(*)(int, int)) Vector_putConsole) (a,b)
#define getConsole() ((int (*)(void)) Vector_getConsole) ()
#define ExtCfg(a,b,c) ((void (*)(int, int, int)) Vector_ExtCfg) (a,b,c)
#define ExtSet(a,b) ((void(*)(int, int)) Vector_ExtSet) (a,b)
#define ExtInp(a) ((int(*)(int)) Vector_ExtInp) (a)
#define PinSetBit(a,b) ((void(*)(int, int)) Vector_PinSetBit) (a,b)
#define PinRead(a) ((int(*)(int)) Vector_PinRead) (a)
#define MMPrintString(a) ((void (*)(char*)) Vector_MMPrintString) (a)
#define IntToStr(a,b,c) ((void (*)(char *, long long int, unsigned int)) Vector_IntToStr) (a,b,c)
#define CheckAbort() ((void (*)(void)) Vector_CheckAbort) ()
#define GetMemory(a) ((void* (*)(int)) Vector_GetMemory) (a)
#define GetTempMemory(a) ((void* (*)(int)) Vector_GetTempMemory) (a)
#define FreeMemory(a) ((void (*)(void *)) Vector_FreeMemory) (a)
#define DrawRectangle(a,b,c,d,e) ((void (*)(int,int,int,int,int)) (*(unsigned int *)Vector_DrawRectangle)) (a,b,c,d,e)
#define DrawRectangleVector (*(unsigned int *)Vector_DrawRectangle)
#define DrawBitmap(a,b,c,d,e,f,g,h) ((void (*)(int,int,int,int,int,int,int, char*)) (*(unsigned int *)Vector_DrawBitmap)) (a,b,c,d,e,f,g,h)
#define DrawBitmapVector (*(unsigned int *)Vector_DrawBitmap)
#define DrawLine(a,b,c,d,e,f) ((void (*)(int,int,int,int,int,int)) Vector_DrawLine) (a,b,c,d,e,f)
#define FontTable (void*)((int*)(Vector_FontTable))
#define ExtCurrentConfig ((int *) Vector_ExtCurrentConfig)
#define HRes (*(unsigned int *) Vector_HRes)
#define VRes (*(unsigned int *) Vector_VRes)
#define SoftReset() ((void (*)(void)) Vector_SoftReset) ()
#define error(a) ((void (*)(char *)) Vector_error) (a)
#define ProgFlash ((int *) Vector_ProgFlash)
#define g_vartbl (*(struct s_vartbl *) Vector_vartbl)
#define g_varcnt (*(unsigned int *) Vector_varcnt)
#define DrawBuffer(a,b,c,d,e) ((void (*)(int,int,int,int,char *)) (*(unsigned int *)Vector_DrawBuffer)) (a,b,c,d,e)
#define DrawBufferVector (*(unsigned int *)Vector_DrawBuffer)
#define ReadBuffer(a,b,c,d,e) ((void (*)(int,int,int,int,char *)) (*(unsigned int *)Vector_ReadBuffer)) (a,b,c,d,e)
#define ReadBufferVector (*(unsigned int *)Vector_ReadBuffer)
#define FloatToStr(a,b,c,d,e) ((void (*)(char *, MMFLOAT, int, int, char)) Vector_FloatToStr) (a,b,c,d,e)
// NOTE: The argument to RunBasicSub is a string specifying the name of the BASIC subroutine to be executed.
// It MUST be terminated with TWO null chars.
#define RunBasicSub(a) ((void (*)(char *)) Vector_ExecuteProgram) (a)
#define CFuncmSec (*(unsigned int *) Vector_CFuncmSec)
#define CFuncRam ((int *) Vector_CFuncRam)
#define ScrollLCD(a,b) ((void (*)(int, int)) (*(unsigned int *)Vector_ScrollLCD)) (a, b)
#define ScrollLCDVector (*(unsigned int *)Vector_ScrollLCD)
#define ScrollBufferV(a,b) ((void (*)(int, int)) (*(unsigned int *)Vector_ScrollBufferV)) (a, b)
#define ScrollBufferVVector (*(unsigned int *)Vector_ScrollBufferV)
#define ScrollBufferH(a) ((void (*)(int)) (*(unsigned int *)Vector_ScrollBufferH)) (a)
#define ScrollBufferHVector (*(unsigned int *)Vector_ScrollBufferH)
#define DrawBufferFast(a,b,c,d,e) ((void (*)(int,int,int,int, char*)) (*(unsigned int *)Vector_DrawBufferFast)) (a,b,c,d,e)
#define DrawBufferFastVector (*(unsigned int *)Vector_DrawBufferFast)
#define ReadBufferFast(a,b,c,d,e) ((void (*)(int,int,int,int, char*)) (*(unsigned int *)Vector_ReadBufferFast)) (a,b,c,d,e)
#define ReadBufferFastVector (*(unsigned int *)Vector_ReadBufferFast)
#define MoveBufferFast(a,b,c,d,e,f,g) ((void (*)(int,int,int,int, int,int,int)) (*(unsigned int *)Vector_MoveBuffer)) (a,b,c,d,e,f,g)
#define MoveBufferFastVector (*(unsigned int *)Vector_MoveBuffer)
#define DrawPixel(a,b,c) ((void(*)(int, int, int)) Vector_DrawPixel) (a,b,c)
#define RoutineChecks() ((void (*)(void)) Vector_RoutineChecks) ()
#define GetPageAddress(a) ((int(*)(int)) Vector_GetPageAddress) (a)
//#define memcpy(a,b,c) ((void (*)(void *, void *, int)) Vector_mycopysafe) (a,b,c)
#define IntToFloat(a) ((MMFLOAT (*)(long long)) Vector_IntToFloat) (a)
#define FloatToInt(a) ((long long (*)(MMFLOAT)) Vector_FloatToInt) (a)
#define Option (*(struct option_s *)(unsigned int)Vector_Option)
#define ReadPageAddress (*(unsigned int *) Vector_ReadPageAddress)
#define WritePageAddress (*(unsigned int *) Vector_WritePageAddress)
#define uSecTimer ((unsigned long long (*)(void)) Vector_Timer)
#define FastTimer ((unsigned long long (*)(void)) Vector_FastTimer)
#define TicksPerUsec (*(unsigned int *) Vector_TicksPerUsec)
#define map(a) ((int(*)(int)) Vector_Map) (a)
#define Sine(a) ((MMFLOAT (*)(MMFLOAT)) Vector_Sine) (a)
#define VideoColour (*(int *) Vector_VideoColour)
#define DrawCircle(a,b,c,d,e,f,g) ((void (*)(int,int,int,int,int,int,MMFLOAT)) Vector_DrawCircle) (a,b,c,d,e,f,g)
#define DrawTriangle(a,b,c,d,e,f,g,h) ((void (*)(int,int,int,int,int,int,int,int)) Vector_DrawTriangle) (a,b,c,d,e,f,g,h)
#define LoadFloat(a) ((MMFLOAT (*)(unsigned int)) Vector_LoadFloat) (a)
#define FMul(a,b) ((MMFLOAT (*)(MMFLOAT, MMFLOAT)) Vector_FMul) (a,b)
#define FAdd(a,b) ((MMFLOAT (*)(MMFLOAT, MMFLOAT)) Vector_FAdd) (a,b)
#define FSub(a,b) ((MMFLOAT (*)(MMFLOAT, MMFLOAT)) Vector_FSub) (a,b)
#define FDiv(a,b) ((MMFLOAT (*)(MMFLOAT, MMFLOAT)) Vector_FDiv) (a,b)
#define FCmp(a,b) ((int (*)(MMFLOAT, MMFLOAT)) Vector_FCmp) (a,b)
#define CFuncInt1 (*(unsigned int *) Vector_CFuncInt1)
#define CFuncInt2 (*(unsigned int *) Vector_CFuncInt2)
//#define Interrupt (*(unsigned int *) Vector_CSubComplete)
#define Interrupt (*(char *) Vector_CSubComplete) //CSubComplete now char in 5.08.00
#define AudioOutputVector (*(unsigned int *) Vector_AudioOutput)
#define AudioOutput(a,b) ((void (*)(uint16_t, uint16_t)) (*(unsigned int *)Vector_AudioOutput)) (a, b)
#define IDiv(a,b) ((int (*)(int, int)) Vector_IDiv) (a,b)
#define AUDIO_WRAP (*(uint16_t *) Vector_AUDIO_WRAP)
#define CFuncInt3 (*(unsigned int *) Vector_CFuncInt3)
#define CFuncInt4 (*(unsigned int *) Vector_CFuncInt4)
#define PIOExecute(a,b,c) ((void (*)(int, int, unsigned int)) Vector_PIOExecute) (a,b,c)
// the structure of the variable table, passed to the CFunction as a pointer Vector_vartbl which is #defined as g_vartbl
struct s_vartbl { // structure of the variable table
char name[MAXVARLEN]; // variable's name
char type; // its type (T_NUM, T_INT or T_STR)
char level; // its subroutine or function level (used to track local variables)
unsigned char size; // the number of chars to allocate for each element in a string array
char dummy;
int __attribute__ ((aligned (4))) dims[MAXDIM]; // the dimensions. it is an array if the first dimension is NOT zero
union u_val{
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
char *s; // pointer to the allocated memory if it is a string
} __attribute__ ((aligned (8))) val;
} __attribute__ ((aligned (8))) val;
// Useful macros
// Types used to define a variable in the variable table (g_vartbl). Often they are ORed together.
// Also used in tokens and arguments to functions
#define T_NOTYPE 0 // type not set or discovered
#define T_NBR 0x01 // number (or float) type
#define T_STR 0x02 // string type
#define T_INT 0x04 // 64 bit integer type
#define T_PTR 0x08 // the variable points to another variable's data
#define T_IMPLIED 0x10 // the variables type does not have to be specified with a suffix
#define T_CONST 0x20 // the contents of this variable cannot be changed
#define T_BLOCKED 0x40 // Hash table entry blocked after ERASE
//***************************************************************************************************
// Constants and definitions copied from the Micromite MkII and Micromite Plus source
//***************************************************************************************************
//The Option structure
struct option_s {
int Magic;
char Autorun;
char Tab;
char Invert;
char Listcase; //8
//
unsigned int PROG_FLASH_SIZE;
unsigned int HEAP_SIZE;
char Height;
char Width;
unsigned char DISPLAY_TYPE;
char DISPLAY_ORIENTATION; //12=20
//
int PIN;
int Baudrate;
char ColourCode;
unsigned char MOUSE_CLOCK;
unsigned char MOUSE_DATA;
char spare;
int CPU_Speed;
unsigned int Telnet; // 40 used to store status on console OFF/ON/BOTH
int DefaultFC, DefaultBC; // 44 the default colours
short DefaultBrightness; // 48 default backlight brightness //40
unsigned char KEYBOARD_CLOCK;
unsigned char KEYBOARD_DATA;
unsigned short VGAFC, VGABC; // the default colours 36=56 //50?
//
// display related
unsigned char DefaultFont;
unsigned char KeyboardConfig;
unsigned char RTC_Clock;
unsigned char RTC_Data; //4=60
//
#ifdef PICOMITE
int dummy; // maximum number of controls allowed //48
#endif
#ifdef PICOMITEWEB
uint16_t TCP_PORT; // maximum number of controls allowed //48
uint16_t ServerResponceTime;
#endif
#ifdef PICOMITEVGA
int16_t X_TILE; // maximum number of controls allowed //48
int16_t Y_TILE; // maximum number of controls allowed //48
#endif
// for the SPI LCDs 4=64
unsigned char LCD_CD;
unsigned char LCD_CS;
unsigned char LCD_Reset;
// touch related
unsigned char TOUCH_CS;
unsigned char TOUCH_IRQ;
char TOUCH_SWAPXY;
unsigned char repeat;
char disabletftp;//56 8=72
int TOUCH_XZERO;
int TOUCH_YZERO;
float TOUCH_XSCALE;
float TOUCH_YSCALE; //72 16=88
#ifdef GUICONTROLS
int MaxCtrls;
#else
uint8_t HDMIclock;
uint8_t HDMId0;
uint8_t HDMId1;
uint8_t HDMId2;
#endif
unsigned int FlashSize; //8=96
unsigned char SD_CS;
unsigned char SYSTEM_MOSI;
unsigned char SYSTEM_MISO;
unsigned char SYSTEM_CLK;
unsigned char DISPLAY_BL;
unsigned char DISPLAY_CONSOLE;
unsigned char TOUCH_Click;
char LCD_RD; // used for the RD pin for SSD1963 //8=104
unsigned char AUDIO_L;
unsigned char AUDIO_R;
unsigned char AUDIO_SLICE;
unsigned char SDspeed;
unsigned char pins[8]; //8=116 // general use storage for CFunctions written by PeterM //86
char LCDVOP;
char I2Coffset;
unsigned char NoHeartbeat;
char Refresh;
unsigned char SYSTEM_I2C_SDA;
unsigned char SYSTEM_I2C_SCL;
unsigned char RTC;
char PWM; //8=124
unsigned char INT1pin;
unsigned char INT2pin;
unsigned char INT3pin;
unsigned char INT4pin;
unsigned char SD_CLK_PIN;
unsigned char SD_MOSI_PIN;
unsigned char SD_MISO_PIN;
unsigned char SerialConsole; //8=132
unsigned char SerialTX;
unsigned char SerialRX;
unsigned char numlock;
unsigned char capslock; //4=136
unsigned int LIBRARY_FLASH_SIZE; // 4=140
unsigned char AUDIO_CLK_PIN;
unsigned char AUDIO_MOSI_PIN;
unsigned char SYSTEM_I2C_SLOW;
unsigned char AUDIO_CS_PIN; //+4=144
#ifdef PICOMITEWEB
uint16_t UDP_PORT;
uint16_t UDPServerResponceTime;
char hostname[32];
char ipaddress[16];
char mask[16];
char gateway[16];
unsigned char x[1]; //112=256
#else
unsigned char x[85]; //112=256
#endif
unsigned char PSRAM_CS_PIN;
unsigned char BGR;
unsigned char NoScroll;
unsigned char CombinedCS;
unsigned char USBKeyboard;
unsigned char VGA_HSYNC;
unsigned char VGA_BLUE;
unsigned char AUDIO_MISO_PIN;
unsigned char AUDIO_DCS_PIN;
unsigned char AUDIO_DREQ_PIN;
unsigned char AUDIO_RESET_PIN;
unsigned char SSD_DC;
unsigned char SSD_WR;
unsigned char SSD_RD;
unsigned char SSD_RESET;
unsigned char BackLightLevel;
unsigned char NoReset;
unsigned char AllPins;
unsigned char modbuff;
short RepeatStart;
short RepeatRate;
int modbuffsize; // +18=
unsigned char F1key[MAXKEYLEN]; //64=320
unsigned char F5key[MAXKEYLEN]; //64=384
unsigned char F6key[MAXKEYLEN]; //64=448
unsigned char F7key[MAXKEYLEN]; //64=512
unsigned char F8key[MAXKEYLEN]; //64=576
unsigned char F9key[MAXKEYLEN]; //64=640
unsigned char SSID[MAXKEYLEN]; //64=704
unsigned char PASSWORD[MAXKEYLEN]; //64=768
unsigned char platform[32];
unsigned char extensions[96]; //128=896 == 7 XMODEM blocks
// To enable older CFunctions to run any new options *MUST* be added at the end of the list
} __attribute__((packed));
// Define the offsets from the PORT address
// these are used by GetPortAddr(a,b)
#define ANSEL -8
#define ANSELCLR -7
#define ANSELSET -6
#define ANSELINV -5
#define TRIS -4
#define TRISCLR -3
#define TRISSET -2
#define TRISINV -1
#define PORT 0
#define PORTCLR 1
#define PORTSET 2
#define PORTINV 3
#define LAT 4
#define LATCLR 5
#define LATSET 6
#define LATINV 7
#define ODC 8
#define ODCCLR 9
#define ODCSET 10
#define ODCINV 11
#define CNPU 12
#define CNPUCLR 13
#define CNPUSET 14
#define CNPUINV 15
#define CNPD 16
#define CNPDCLR 17
#define CNPDSET 18
#define CNPDINV 19
#define CNCON 20
#define CNCONCLR 21
#define CNCONSET 22
#define CNCONINV 23
#define CNEN 24
#define CNENCLR 25
#define CNENSET 26
#define CNENINV 27
#define CNSTAT 28
#define CNSTATCLR 29
#define CNSTATSET 30
#define CNSTATINV 31
// configurations for an I/O pin
// these are used by ExtCfg(a,b,c)
#define EXT_NOT_CONFIG 0
#define EXT_ANA_IN 1
#define EXT_DIG_IN 2
#define EXT_FREQ_IN 3
#define EXT_PER_IN 4
#define EXT_CNT_IN 5
#define EXT_INT_HI 6
#define EXT_INT_LO 7
#define EXT_DIG_OUT 8
#define EXT_HEARTBEAT 9
#define EXT_INT_BOTH 10
#define EXT_UART0TX 11
#define EXT_UART0RX 12
#define EXT_UART1TX 13
#define EXT_UART1RX 14
#define EXT_I2C0SDA 15
#define EXT_I2C0SCL 16
#define EXT_I2C1SDA 17
#define EXT_I2C1SCL 18
#define EXT_SPI0RX 19
#define EXT_SPI0TX 20
#define EXT_SPI0SCK 21
#define EXT_SPI1RX 22
#define EXT_SPI1TX 23
#define EXT_SPI1SCK 24
#define EXT_IR 25
#define EXT_INT1 26
#define EXT_INT2 27
#define EXT_INT3 28
#define EXT_INT4 29
#define EXT_PWM0A 30
#define EXT_PWM0B 31
#define EXT_PWM1A 32
#define EXT_PWM1B 33
#define EXT_PWM2A 34
#define EXT_PWM2B 35
#define EXT_PWM3A 36
#define EXT_PWM3B 37
#define EXT_PWM4A 38
#define EXT_PWM4B 39
#define EXT_PWM5A 40
#define EXT_PWM5B 41
#define EXT_PWM6A 42
#define EXT_PWM6B 43
#define EXT_PWM7A 44
#define EXT_PWM7B 45
#define EXT_PIO0_OUT 46
#define EXT_PIO1_OUT 47
#define EXT_DS18B20_RESERVED 0x100 // this pin is reserved for DS18B20 and cannot be used
#define EXT_COM_RESERVED 0x200 // this pin is reserved and SETPIN and PIN cannot be used
#define EXT_BOOT_RESERVED 0x400 // this pin is reserved at bootup and cannot be used
#define NOP() __asm volatile ("nop")
#define USERLCDPANEL 25

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
; ============================================================================
; QVGA PIO (16 instructions)
; ============================================================================
; Control word (right shifted):
; - bit 0..26 (27 bits) loop counter N
; - bit 27..31 (5 bits) jump address
.program i2s
.side_set 2 ; HSYNC and VSYNC output (2 bits)
.wrap_target
Set x,30 side 0
Pull noblock side 1
loop1:
Out pins,1 side 0
Jmp x--,loop1 side 1
Set x,30 side 2
Pull noblock side 3
loop2:
Out pins,1 side 2
Jmp x--,loop2 side 3
.wrap ; wrap jump to .wrap_target

View File

@ -0,0 +1,62 @@
; ============================================================================
; QVGA PIO (16 instructions)
; ============================================================================
; Control word (right shifted):
; - bit 0..26 (27 bits) loop counter N
; - bit 27..31 (5 bits) jump address
.program qvga
.side_set 2 ; HSYNC and VSYNC output (2 bits)
.define NOSYNC 0 ; no sync, output image or blanking
.define HSYNC 1 ; HSYNC pulse (or CSYNC pulse)
.define VSYNC 2 ; VSYNC pulse
.define VHSYNC 3 ; HSYNC and VSYNC pulse
.define BPP 4 ; number of bits per pixel
; ===== [3 instructions] HSYNC pulse, N=delay in clock cycles - 3
; starts HSYNC at time 0
public hsync:
jmp x--,hsync side HSYNC ; [N+1] loop
public entry: ; program entry point
out x,27 side HSYNC ; [1] get next loop counter N
out pc,5 side HSYNC ; [1] jump to next function
; ===== [3 instructions] VSYNC pulse, N=delay in clock cycles - 3
; starts VSYNC at time 0
public vsync:
jmp x--,vsync side VSYNC ; [N+1] loop
out x,27 side VSYNC ; [1] get next loop counter N
out pc,5 side VSYNC ; [1] jump to next function
; ===== [3 instructions] VSYNC and HSYNC pulse, N=delay in clock cycles - 3
; starts HSYNC and VSYNC at time 0
public vhsync:
jmp x--,vhsync side VHSYNC ; [N+1] loop
out x,27 side VHSYNC ; [1] get next loop counter N
out pc,5 side VHSYNC ; [1] jump to next function
; ===== [4 instructions] DARK pulse, N=delay in clock cycles - 4
; sets blanking at time 0, starts NOSYNC at time 0
public dark:
mov pins,null side NOSYNC ; [1] dark output
dark_loop:
jmp x--,dark_loop side NOSYNC ; [N+1] loop
.wrap_target ; wrap jump target
out x,27 side NOSYNC ; [1] get next loop counter N
out pc,5 side NOSYNC ; [1] jump to next function
; ===== [3 instructions] output pixels at 5 clocks per pixel, N=number of pixels-2
; number of pixels must be multiple of: 1 at BP=32, 2 at BPP=16, 4 at BPP=8, 8 at BPP=4, 16 at BPP=2, 32 at BPP=1
; Output first pixel at time 0
public output:
out pins,BPP side NOSYNC [2] ; [3] output pixel
jmp x--,output side NOSYNC [1] ; [2] loop (N+1 pixels)
out pins,BPP side NOSYNC [2] ; [3] output pixel
.wrap ; wrap jump to .wrap_target

View File

@ -0,0 +1,4 @@
V5.09.00b0
Introduction of USB variants for PicoMite and PicoMiteVGA
Rationalisation of BLIT and SPRITE

View File

@ -0,0 +1,94 @@
# PicoCalc
Information Command | Decription
:--- | :---
MM.INFO(BATTERY) | <ins>PICOCALC ONLY</ins> <br/> Returns the current battery level percentage (0-100).
MM.INFO(CHARGING) | <ins>PICOCALC ONLY</ins> <br/> Returns 1 if battery is charging on external power, 0 if battery is not charging.
Option Command | Decription
:--- | :---
OPTION BACKLIGHT KB brightness | <ins>PICOCALC ONLY</ins> <br/> Sets the brightness of the keyboard backlight. 'brightness' is a value between 0 (backlight off) and 255 (maximum brightness).
INSTALL PICO SDK
----------------
```bash
sudo apt update && sudo apt install -y cmake gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential git
mkdir -p ~/pico && cd ~/pico
git clone https://github.com/raspberrypi/pico-sdk.git
cd pico-sdk
git checkout tags/2.1.1 -b sdk2.1.1
git submodule update --init
echo 'export PICO_SDK_PATH=~/pico/pico-sdk' >> ~/.bashrc
source ~/.bashrc
```
SETUP PICOCALC FIRMWARE
-----------------------
```bash
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
```
EDIT ``~/picocalc/PicoMiteAllVersions/CMakeLists.txt`` TO CHOOSE TARGET
-----------------------------------------------------------------------
```makefile
set(PICOCALC true)
# Compile for PICO 1 Board
#set(COMPILE PICO)
# Compile for PICO 2 Board
#set(COMPILE PICORP2350)
set(COMPILE WEBRP2350)
```
BUILD PICOCALC FIRMWARE
-----------------------
```bash
cd ~/picocalc/PicoMiteAllVersions
mkdir build
cd build
cmake ..
make
```
(_original readme follows..._)
# PicoMiteRP2350
This contains files to build MMbasic V6.00.02RC23 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>
Change CMakeLists.txt line 4 to determine which variant to build<br>
<br>
RP2040<br>
set(COMPILE PICO)<br>
set(COMPILE VGA)<br>
set(COMPILE PICOUSB)<br>
set(COMPILE VGAUSB)<br>
set(COMPILE WEB)<br>
<br>
RP2350<br>
set(COMPILE PICORP2350)<br>
set(COMPILE VGARP2350)<br>
set(COMPILE PICOUSBRP2350)<br>
set(COMPILE VGAUSBRP2350)<br>
set(COMPILE HDMI)<br>
set(COMPILE HDMIUSB)<br>
set(COMPILE WEBRP2350)<br>
<br>
Any of the RP2350 variants or the RP2040 variants can be built by simply changing the set(COMPILE aaaa)<br>
However, to swap between a rp2040 build and a rp2350 build (or visa versa) needs a different build directory.
The process for doing this is as follows:<br>
Close VSCode<br>
Rename the current build directory - e.g. build -> buildrp2040<br>
Rename the inactive build directory - e.g. buildrp2350 -> build<br>
edit CMakeLists.txt to choose a setting for the other chip and save it - e.g. set(COMPILE PICO) -> set(COMPILE PICORP2350)<br>
Restart VSCode<br>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,479 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
SPI-LCD.h.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.
************************************************************************************************************************/
#ifndef SPI_LCD_HEADER
#define SPI_LCD_HEADER
#include "hardware/spi.h"
extern void ConfigDisplaySPI(unsigned char *p);
extern void InitDisplaySPI(int InitOnly);
extern void SetAndReserve(int pin, int inp, int init, int type);
extern void OpenSpiChannel(void);
extern void DisplayNotSet(void);
extern void SPISpeedSet(int speed);
extern void DefineRegionSPI(int xstart, int ystart, int xend, int yend, int rw);
extern void ClearCS(int pin);
extern void ResetController(void);
extern void spi_write_command(unsigned char data);
extern void spi_write_cd(unsigned char command, int data, ...);
extern void spi_write_data(unsigned char data);
extern void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c);
extern void DrawBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p);
extern void DrawBitmapSPI(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap);
extern void ReadBufferSPI(int x1, int y1, int x2, int y2, unsigned char* p) ;
extern void DrawRectangleSPISCR(int x1, int y1, int x2, int y2, int c);
extern void DrawBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p);
extern void DrawBitmapSPISCR(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap);
extern void ReadBufferSPISCR(int x1, int y1, int x2, int y2, unsigned char* p) ;
extern void ScrollLCDSPISCR(int lines);
extern void set_cs(void);
extern void __not_in_flash_func(spi_write_fast)(spi_inst_t *spi, const uint8_t *src, size_t len);
extern void __not_in_flash_func(spi_finish)(spi_inst_t *spi);
#define SSD1331_COLORORDER_RGB
#define SSD1331_CMD_DRAWLINE 0x21
#define SSD1331_CMD_DRAWRECT 0x22
#define SSD1331_CMD_FILL 0x26
#define SSD1331_CMD_SETCOLUMN 0x15
#define SSD1331_CMD_SETROW 0x75
#define SSD1331_CMD_CONTRASTA 0x81
#define SSD1331_CMD_CONTRASTB 0x82
#define SSD1331_CMD_CONTRASTC 0x83
#define SSD1331_CMD_MASTERCURRENT 0x87
#define SSD1331_CMD_SETREMAP 0xA0
#define SSD1331_CMD_STARTLINE 0xA1
#define SSD1331_CMD_DISPLAYOFFSET 0xA2
#define SSD1331_CMD_NORMALDISPLAY 0xA4
#define SSD1331_CMD_DISPLAYALLON 0xA5
#define SSD1331_CMD_DISPLAYALLOFF 0xA6
#define SSD1331_CMD_INVERTDISPLAY 0xA7
#define SSD1331_CMD_SETMULTIPLEX 0xA8
#define SSD1331_CMD_SETMASTER 0xAD
#define SSD1331_CMD_DISPLAYDIM 0xAC
#define SSD1331_CMD_DISPLAYOFF 0xAE
#define SSD1331_CMD_DISPLAYON 0xAF
#define SSD1331_CMD_POWERMODE 0xB0
#define SSD1331_CMD_PRECHARGE 0xB1
#define SSD1331_CMD_CLOCKDIV 0xB3
#define SSD1331_CMD_PRECHARGEA 0x8A
#define SSD1331_CMD_PRECHARGEB 0x8B
#define SSD1331_CMD_PRECHARGEC 0x8C
#define SSD1331_CMD_PRECHARGELEVEL 0xBB
#define SSD1331_CMD_VCOMH 0xBE
#define ST7735_NOP 0x0
#define ST7735_SWRESET 0x01
#define ST7735_RDDID 0x04
#define ST7735_RDDST 0x09
#define ST7735_SLPIN 0x10
#define ST7735_SLPOUT 0x11
#define ST7735_PTLON 0x12
#define ST7735_NORON 0x13
#define ST7735_INVOFF 0x20
#define ST7735_INVON 0x21
#define ST7735_DISPOFF 0x28
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_RAMRD 0x2E
#define ST7735_PTLAR 0x30
#define ST7735_MADCTL 0x36
#define ST7735_COLMOD 0x3A
#define ST7735_FRMCTR1 0xB1
#define ST7735_FRMCTR2 0xB2
#define ST7735_FRMCTR3 0xB3
#define ST7735_INVCTR 0xB4
#define ST7735_DISSET5 0xB6
#define ST7735_PWCTR1 0xC0
#define ST7735_PWCTR2 0xC1
#define ST7735_PWCTR3 0xC2
#define ST7735_PWCTR4 0xC3
#define ST7735_PWCTR5 0xC4
#define ST7735_VMCTR1 0xC5
#define ST7735_RDID1 0xDA
#define ST7735_RDID2 0xDB
#define ST7735_RDID3 0xDC
#define ST7735_RDID4 0xDD
#define ST7735_PWCTR6 0xFC
#define ST7735_GMCTRP1 0xE0
#define ST7735_GMCTRN1 0xE1
#define ST7735_Portrait 0xC0
#define ST7735_Portrait180 0
#define ST7735_Landscape 0xA0
#define ST7735_Landscape180 0x60
#define ILI9341_SOFTRESET 0x01
#define ILI9341_SLEEPIN 0x10
#define ILI9341_SLEEPOUT 0x11
#define ILI9341_NORMALDISP 0x13
#define ILI9341_INVERTOFF 0x20
#define ILI9341_INVERTON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPLAYOFF 0x28
#define ILI9341_DISPLAYON 0x29
#define ILI9341_COLADDRSET 0x2A
#define ILI9341_PAGEADDRSET 0x2B
#define ILI9341_MEMORYWRITE 0x2C
#define ILI9341_RAMRD 0x2E
#define ILI9341_PIXELFORMAT 0x3A
#define ILI9341_FRAMECONTROL 0xB1
#define ILI9341_DISPLAYFUNC 0xB6
#define ILI9341_ENTRYMODE 0xB7
#define ILI9341_POWERCONTROL1 0xC0
#define ILI9341_POWERCONTROL2 0xC1
#define ILI9341_VCOMCONTROL1 0xC5
#define ILI9341_VCOMCONTROL2 0xC7
#define ILI9341_MEMCONTROL 0x36
#define ILI9341_MADCTL_MY 0x80
#define ILI9341_MADCTL_MX 0x40
#define ILI9341_MADCTL_MV 0x20
#define ILI9341_MADCTL_ML 0x10
#define ILI9341_MADCTL_RGB 0x00
#define ILI9341_MADCTL_BGR 0x08
#define ILI9341_MADCTL_MH 0x04
#define ILI9341_Portrait ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR
#define ILI9341_Portrait180 ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR
#define ILI9341_Landscape ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR
#define ILI9341_Landscape180 ILI9341_MADCTL_MY | ILI9341_MADCTL_MX | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR
#define ILI9481_MADCTL_FH 0x02
#define ILI9481_MADCTL_FV 0x01
#define ILI9481_Portrait ILI9481_MADCTL_FH | ILI9341_MADCTL_BGR
#define ILI9481_Portrait180 ILI9481_MADCTL_FV | ILI9341_MADCTL_BGR
#define ILI9481_Landscape ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR
#define ILI9481_Landscape180 ILI9481_MADCTL_FV | ILI9481_MADCTL_FH | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR
//
#define ILI9163_NOP 0x00//Non operation
#define ILI9163_SWRESET 0x01//Soft Reset
#define ILI9163_SLPIN 0x10//Sleep ON
#define ILI9163_SLPOUT 0x11//Sleep OFF
#define ILI9163_PTLON 0x12//Partial Mode ON
#define ILI9163_NORML 0x13//Normal Display ON
#define ILI9163_DINVOF 0x20//Display Inversion OFF
#define ILI9163_DINVON 0x21//Display Inversion ON
#define ILI9163_GAMMASET 0x26//Gamma Set (0x01[1],0x02[2],0x04[3],0x08[4])
#define ILI9163_DISPOFF 0x28//Display OFF
#define ILI9163_DISPON 0x29//Display ON
#define ILI9163_IDLEON 0x39//Idle Mode ON
#define ILI9163_IDLEOF 0x38//Idle Mode OFF
#define ILI9163_CLMADRS 0x2A//Column Address Set
#define ILI9163_PGEADRS 0x2B//Page Address Set
#define ILI9163_RAMWR 0x2C//Memory Write
#define ILI9163_RAMRD 0x2E//Memory Read
#define ILI9163_CLRSPACE 0x2D//Color Space : 4K/65K/262K
#define ILI9163_PARTAREA 0x30//Partial Area
#define ILI9163_VSCLLDEF 0x33//Vertical Scroll Definition
#define ILI9163_TEFXLON 0x35//Tearing Effect Line ON
#define ILI9163_TEFXLOF 0x34//Tearing Effect Line OFF
#define ILI9163_MADCTL 0x36//Memory Access Control
#define ILI9163_VSSTADRS 0x37//Vertical Scrolling Start address
#define ILI9163_PIXFMT 0x3A//Interface Pixel Format
#define ILI9341_GETSCANLINE 0x45//read the current scanline
#define ILI9163_FRMCTR1 0xB1//Frame Rate Control (In normal mode/Full colors)
#define ILI9163_FRMCTR2 0xB2//Frame Rate Control(In Idle mode/8-colors)
#define ILI9163_FRMCTR3 0xB3//Frame Rate Control(In Partial mode/full colors)
#define ILI9163_DINVCTR 0xB4//Display Inversion Control
#define ILI9163_RGBBLK 0xB5//RGB Interface Blanking Porch setting
#define ILI9163_DFUNCTR 0xB6//Display Fuction set 5
#define ILI9163_SDRVDIR 0xB7//Source Driver Direction Control
#define ILI9163_GDRVDIR 0xB8//Gate Driver Direction Control
#define ILI9163_PWCTR1 0xC0//Power_Control1
#define ILI9163_PWCTR2 0xC1//Power_Control2
#define ILI9163_PWCTR3 0xC2//Power_Control3
#define ILI9163_PWCTR4 0xC3//Power_Control4
#define ILI9163_PWCTR5 0xC4//Power_Control5
#define ILI9163_VCOMCTR1 0xC5//VCOM_Control 1
#define ILI9163_VCOMCTR2 0xC6//VCOM_Control 2
#define ILI9163_VCOMOFFS 0xC7//VCOM Offset Control
#define ILI9163_PGAMMAC 0xE0//Positive Gamma Correction Setting
#define ILI9163_NGAMMAC 0xE1//Negative Gamma Correction Setting
#define ILI9163_GAMRSEL 0xF2//GAM_R_SEL
#define ILI9163_Portrait 0b00001000
#define ILI9163_Portrait180 0b11001000
#define ILI9163_Landscape 0b01101000
#define ILI9163_Landscape180 0b10101000
#define ST77XX_SWRESET 0x01
#define ST77XX_DISPON 0x29
#define ST77XX_CASET 0x2A
#define ST77XX_RASET 0x2B
#define ST77XX_INVON 0x21
#define ST77XX_INVOFF 0x20
#define ST77XX_NORON 0x13
#define ST77XX_SLPOUT 0x11
#define ST77XX_COLMOD 0x3A
#define GDEH029A1_PU_DELAY 300
#define GDEH029A1_X_PIXELS 128
#define GDEH029A1_Y_PIXELS 296
#define GDEH029A1_WIDTH GDEH029A1_X_PIXELS
#define GDEH029A1_HEIGHT GDEH029A1_Y_PIXELS
#define DRIVER_OUTPUT_CONTROL 0x01
#define BOOSTER_SOFT_START_CONTROL 0x0C
#define GATE_SCAN_START_POSITION 0x0F
#define DEEP_SLEEP_MODE 0x10
#define DATA_ENTRY_MODE_SETTING 0x11
#define SW_RESET 0x12
#define TEMPERATURE_SENSOR_CONTROL 0x1A
#define MASTER_ACTIVATION 0x20
#define DISPLAY_UPDATE_CONTROL_1 0x21
#define DISPLAY_UPDATE_CONTROL_2 0x22
#define WRITE_RAM 0x24
#define WRITE_VCOM_REGISTER 0x2C
#define WRITE_LUT_REGISTER 0x32
#define SET_DUMMY_LINE_PERIOD 0x3A
#define SET_GATE_TIME 0x3B
#define BORDER_WAVEFORM_CONTROL 0x3C
#define SET_RAM_X_ADD_START_END_POS 0x44
#define SET_RAM_Y_ADD_START_END_POS 0x45
#define SET_RAM_X_ADDRESS_COUNTER 0x4E
#define SET_RAM_Y_ADDRESS_COUNTER 0x4F
#define TERMINATE_FRAME_READ_WRITE 0xFF
#define SPI_POLARITY_LOW false
#define SPI_PHASE_1EDGE false
#define SPI_POLARITY_HIGH true
#define SPI_PHASE_2EDGE true
#define ST7920setcommand 0b11111000
#define ST7920setata 0b11111010
#define SDFAST 0
#define SDSLOW 1
#define SSD1306I2C 2
#define SSD1306I2C32 3
#define I2C_PANEL SSD1306I2C32 // anything less than or equal to I2C_PANEL is handled by the I2C driver
#define ILI9163 4
#define ILI9341 5
#define ST7735 6
#define ST7735S 7
#define SSD1331 8
#define ST7789 9
#define ILI9481 10
#define ILI9488 11
#define ILI9488P 12
#define ST7789A 13
#define ST7789B 14
#define ILI9488W 15
#define ST7796S 16
#define ST7735S_W 17
#define GC9A01 18
#define ILI9481IPS 19
#define N5110 20
#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 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 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 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 VIRTUAL VIRTUAL_C
#define VIRTUAL_M 54
#define VS1053slow 55
#define VS1053fast 56
#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 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 TFT_SLPIN 0x10
#define TFT_SLPOUT 0x11
#define TFT_INVOFF 0x20
#define TFT_INVON 0x21
#define TFT_DISPOFF 0x28
#define TFT_DISPON 0x29
#define TFT_CASET 0x2A
#define TFT_RASET 0x2B
#define TFT_RAMWR 0x2C
#define TFT_RAMRD 0x2E
#define TFT_MADCTL 0x36
#define TFT_MAD_MY 0x80
#define TFT_MAD_MX 0x40
#define TFT_MAD_MV 0x20
#define TFT_MAD_ML 0x10
#define TFT_MAD_RGB 0x00
#define TFT_MAD_BGR 0x08
#define TFT_MAD_MH 0x04
#define TFT_MAD_SS 0x02
#define TFT_MAD_GS 0x01
#define TFT_IDXRD 0x00 // ILI9341 only, indexed control register read
#define GC9A01_TFTWIDTH 240
#define GC9A01_TFTHEIGHT 240
#define GC9A01_RST_DELAY 120 ///< delay ms wait for reset finish
#define GC9A01_SLPIN_DELAY 120 ///< delay ms wait for sleep in finish
#define GC9A01_SLPOUT_DELAY 120 ///< delay ms wait for sleep out finish
#define GC9A01_NOP 0x00
#define GC9A01_SWRESET 0x01
#define GC9A01_RDDID 0x04
#define GC9A01_RDDST 0x09
#define GC9A01_SLPIN 0x10
#define GC9A01_SLPOUT 0x11
#define GC9A01_PTLON 0x12
#define GC9A01_NORON 0x13
#define GC9A01_INVOFF 0x20
#define GC9A01_INVON 0x21
#define GC9A01_DISPOFF 0x28
#define GC9A01_DISPON 0x29
#define GC9A01_CASET 0x2A
#define GC9A01_RASET 0x2B
#define GC9A01_RAMWR 0x2C
#define GC9A01_RAMRD 0x2E
#define GC9A01_PTLAR 0x30
#define GC9A01_COLMOD 0x3A
#define GC9A01_MADCTL 0x36
#define GC9A01_MADCTL_MY 0x80
#define GC9A01_MADCTL_MX 0x40
#define GC9A01_MADCTL_MV 0x20
#define GC9A01_MADCTL_ML 0x10
#define GC9A01_MADCTL_RGB 0x00
#define GC9A01_RDID1 0xDA
#define GC9A01_RDID2 0xDB
#define GC9A01_RDID3 0xDC
#define GC9A01_RDID4 0xDD
#define LANDSCAPE 1
#define PORTRAIT 2
#define RLANDSCAPE 3
#define RPORTRAIT 4
#define DISPLAY_LANDSCAPE (Option.DISPLAY_ORIENTATION & 1)
#define TOUCH_NOT_CALIBRATED -999999
#define RESET_COMMAND 9999 // indicates that the reset was caused by the RESET command
#define WATCHDOG_TIMEOUT 9998 // reset caused by the watchdog timer
#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 SCREWUP_TIMEOUT 9994 // reset caused by the execute timer
#define SOFT_RESET 9993
#define POSSIBLE_WATCHDOG 9992
#define INVALID_CLOCKSPEED 9991
#define RESET_CLOCKSPEED 9990
#define FLASH_SPI_SPEED 20000000
#define LCD_SPI_SPEED 25000000 // the speed of the SPI bus when talking to an SPI LCD display controller
#define TOUCH_SPI_SPEED 300000
#define SLOW_TOUCH_SPEED 120000
#define NOKIA_SPI_SPEED 4000000
#define ST7920_SPI_SPEED 600000
#define SDCARD_SPI_SPEED 12000000
#define NONE_SPI_DEVICE -1
#define P_INPUT 1 // for setting the TRIS on I/O bits
#define P_OUTPUT 0
#define P_ON 1
#define P_OFF 0
#define P_I2C_SCL 0
#define P_I2C_SDA 1
extern void Display_Refresh(void);
extern void waitwhilebusy(void);
struct Displays {
unsigned char ref;
char name [13];
int speed;
int horizontal;
int vertical;
int bits;
unsigned char buffered;
int CPOL;
int CPHASE;
};
extern const struct Displays display_details[];
extern int LCD_CS_PIN;
extern int LCD_CD_PIN;
extern int LCD_Reset_PIN;
extern int LCD_E_INKbusy;
extern void (*xmit_byte_multi)(const BYTE *buff, int cnt);
extern void (*rcvr_byte_multi)(BYTE *buff, int cnt);
extern int (*SET_SPI_CLK)(int speed, int polarity, int edge);
extern void SPISpeedSet(int device);
extern BYTE (*xchg_byte)(BYTE data_out);
extern int SD_SPI_SPEED;
extern int __not_in_flash_func(HW0Clk)(int speed, int polarity, int edge);
extern int __not_in_flash_func(HW1Clk)(int speed, int polarity, int edge);
extern int __not_in_flash_func(BitBangSetClk)(int speed, int polarity, int edge);
extern BYTE __not_in_flash_func(HW0SwapSPI)(BYTE data_out);
extern BYTE __not_in_flash_func(HW1SwapSPI)(BYTE data_out);
extern BYTE BitBangSwapSPI(BYTE data_out);
extern void __not_in_flash_func(HW0SendSPI)(const BYTE *buff, int cnt);
extern void __not_in_flash_func(HW1SendSPI)(const BYTE *buff, int cnt);
extern void BitBangSendSPI(const BYTE *buff, int cnt);
extern void __not_in_flash_func(HW0ReadSPI)(BYTE *buff, int cnt);
extern void __not_in_flash_func(HW1ReadSPI)(BYTE *buff, int cnt);
extern void BitBangReadSPI(BYTE *buff, int cnt);
extern void ScrollLCDSPI(int lines);
extern void SetCS(void);
extern int GetLineILI9341(void);
#endif
/* @endcond */

View File

@ -0,0 +1,342 @@
/***********************************************************************************************************************
PicoMite MMBasic
SPI.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.
************************************************************************************************************************/
/**
* @file SPI.c
* @author Geoff Graham, Peter Mather
* @brief Source for SPI MMBasic commands and functions
*/
/**
* @cond
* The following section will be excluded from the documentation.
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include "hardware/spi.h"
unsigned int *GetSendDataList(unsigned char *p, unsigned int *nbr);
long long int *GetReceiveDataBuffer(unsigned char *p, unsigned int *nbr);
uint8_t spibits=8;
uint8_t spi2bits=8;
/* @endcond */
void cmd_spi(void) {
int speed;
unsigned char *p;
unsigned int nbr, *d;
long long int *dd;
if(SPI0TXpin==99 || SPI0RXpin==99|| SPI0SCKpin==99)error("Not all pins set for SPI");
if(checkstring(cmdline, (unsigned char *)"CLOSE")) {
if(!SPI0locked) SPIClose();
else error("Allocated to System SPI");
return;
}
if((p = checkstring(cmdline, (unsigned char *)"WRITE")) != NULL) {
union car
{
uint32_t aTxBuffer;
uint16_t bTXBuffer[2];
uint8_t cTxBuffer[4];
} mybuff;
if(ExtCurrentConfig[SPI0TXpin] < EXT_COM_RESERVED) error("Not open");
d = GetSendDataList(p, &nbr);
while(nbr--) {
mybuff.aTxBuffer=*d++;
if(spibits>8)spi_write16_blocking(spi0,&mybuff.bTXBuffer[0],1);
else spi_write_blocking(spi0,&mybuff.cTxBuffer[0],1);
}
return;
}
if((p = checkstring(cmdline, (unsigned char *)"READ")) != NULL) {
union car
{
uint32_t aRxBuffer;
uint16_t bRXBuffer[2];
uint8_t cRxBuffer[4];
} mybuff;
if(ExtCurrentConfig[SPI0RXpin] < EXT_COM_RESERVED) error("Not open");
dd = GetReceiveDataBuffer(p, &nbr);
while(nbr--) {
mybuff.aRxBuffer=0;
if(spibits>8)spi_read16_blocking(spi0,0,&mybuff.bRXBuffer[0],1);
else spi_read_blocking(spi0,0,&mybuff.cRxBuffer[0],1);
*dd++ = mybuff.aRxBuffer;
}
return;
}
p = checkstring(cmdline, (unsigned char *)"OPEN");
if(p == NULL) error("Invalid syntax");
if(ExtCurrentConfig[SPI0TXpin] >= EXT_COM_RESERVED) error("Already open");
{ // start a new block for getargs()
int mode;
getargs(&p, 5, (unsigned char *)",");
if(argc < 3) error("Incorrect argument count");
mode=getinteger(argv[2]);
speed = getinteger(argv[0]);
spibits=8;
if(argc==5)spibits=getint(argv[4],4,16);
spi_init(spi0, speed);
spi_set_format(spi0, spibits, (mode & 2 ? true: false),(mode & 1 ? true: false), SPI_MSB_FIRST);
ExtCfg(SPI0TXpin, EXT_COM_RESERVED, 0);
ExtCfg(SPI0RXpin, EXT_COM_RESERVED, 0);
ExtCfg(SPI0SCKpin, EXT_COM_RESERVED, 0);
}
}
// output and get a byte via SPI
void fun_spi(void) {
union car
{
uint64_t aTxBuffer;
uint16_t bTXBuffer[4];
uint8_t cTxBuffer[8];
} inbuff, outbuff;
inbuff.aTxBuffer=0;
outbuff.aTxBuffer=getinteger(ep);
if(ExtCurrentConfig[SPI0TXpin] < EXT_COM_RESERVED) error("Not open");
if(spibits>8)spi_write16_read16_blocking(spi0,&outbuff.bTXBuffer[0],&inbuff.bTXBuffer[0],1);
else spi_write_read_blocking(spi0,&outbuff.cTxBuffer[0],&inbuff.cTxBuffer[0],1);
iret=inbuff.aTxBuffer;
targ = T_INT;
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
void SPIClose(void){
if(SPI0TXpin!=99){
if(ExtCurrentConfig[SPI0TXpin] < EXT_BOOT_RESERVED) {
spi_deinit(spi0);
ExtCfg(SPI0TXpin, EXT_NOT_CONFIG, 0);
ExtCfg(SPI0RXpin, EXT_NOT_CONFIG, 0); // reset to not in use
ExtCfg(SPI0SCKpin, EXT_NOT_CONFIG, 0);
}
}
}
/* @endcond */
void cmd_spi2(void) {
int speed;
unsigned char *p;
unsigned int nbr, *d;
long long int *dd;
if(SPI1TXpin==99 || SPI1RXpin==99 || SPI1SCKpin==99)error("Not all pins set for SPI2");
if(checkstring(cmdline, (unsigned char *)"CLOSE")) {
if(!SPI1locked) SPI2Close();
else error("Allocated to System SPI");
return;
}
if((p = checkstring(cmdline, (unsigned char *)"WRITE")) != NULL) {
union car
{
uint32_t aTxBuffer;
uint16_t bTXBuffer[2];
uint8_t cTxBuffer[4];
} mybuff;
if(ExtCurrentConfig[SPI1TXpin] < EXT_COM_RESERVED) error("Not open");
d = GetSendDataList(p, &nbr);
while(nbr--) {
mybuff.aTxBuffer=*d++;
if(spi2bits>8)spi_write16_blocking(spi1,&mybuff.bTXBuffer[0],1);
else spi_write_blocking(spi1,&mybuff.cTxBuffer[0],1);
// HAL_SPI_Transmit(&hspi2, mybuff.cTxBuffer,1, 5000);
}
return;
}
if((p = checkstring(cmdline, (unsigned char *)"READ")) != NULL) {
union car
{
uint32_t aRxBuffer;
uint16_t bRXBuffer[2];
uint8_t cRxBuffer[4];
} mybuff;
if(ExtCurrentConfig[SPI1TXpin] < EXT_COM_RESERVED) error("Not open");
dd = GetReceiveDataBuffer(p, &nbr);
while(nbr--) {
mybuff.aRxBuffer=0;
if(spi2bits>8)spi_read16_blocking(spi1,0,&mybuff.bRXBuffer[0],1);
else spi_read_blocking(spi1,0,&mybuff.cRxBuffer[0],1);
*dd++ = mybuff.aRxBuffer;
}
return;
}
p = checkstring(cmdline, (unsigned char *)"OPEN");
if(p == NULL) error("Invalid syntax");
if(ExtCurrentConfig[SPI1TXpin] >= EXT_COM_RESERVED) error("Already open");
{ // start a new block for getargs()
int mode;
getargs(&p, 5, (unsigned char *)",");
if(argc < 3) error("Incorrect argument count");
mode=getinteger(argv[2]);
speed = getinteger(argv[0]);
spi2bits=8;
if(argc==5)spi2bits=getint(argv[4],4,16);
spi_init(spi1, speed);
spi_set_format(spi1, spi2bits, (mode & 2 ? true: false),(mode & 1 ? true: false), SPI_MSB_FIRST);
ExtCfg(SPI1TXpin, EXT_COM_RESERVED, 0);
ExtCfg(SPI1RXpin, EXT_COM_RESERVED, 0);
ExtCfg(SPI1SCKpin, EXT_COM_RESERVED, 0);
}
}
// output and get a byte via SPI
void fun_spi2(void) {
union car
{
uint64_t aTxBuffer;
uint16_t bTXBuffer[4];
uint8_t cTxBuffer[8];
} inbuff, outbuff;
inbuff.aTxBuffer=0;
outbuff.aTxBuffer=getinteger(ep);
if(ExtCurrentConfig[SPI1TXpin] < EXT_COM_RESERVED) error("Not open");
if(spi2bits>8)spi_write16_read16_blocking(spi1,&outbuff.bTXBuffer[0],&inbuff.bTXBuffer[0],1);
else spi_write_read_blocking(spi1,&outbuff.cTxBuffer[0],&inbuff.cTxBuffer[0],1);
iret=inbuff.aTxBuffer;
targ = T_INT;
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
void SPI2Close(void){
if(SPI1TXpin!=99){
if(ExtCurrentConfig[SPI1TXpin] < EXT_BOOT_RESERVED) {
spi_deinit(spi1);
ExtCfg(SPI1TXpin, EXT_NOT_CONFIG, 0);
ExtCfg(SPI1RXpin, EXT_NOT_CONFIG, 0); // reset to not in use
ExtCfg(SPI1SCKpin, EXT_NOT_CONFIG, 0);
}
}
}
unsigned int *GetSendDataList(unsigned char *p, unsigned int *nbr) {
unsigned int *buf;
int i;
void *ptr;
getargs(&p, MAX_ARG_COUNT, (unsigned char *)",");
if(!(argc & 1)) error("Invalid syntax");
*nbr = getint(argv[0], 0, 9999999);
if(!*nbr) return NULL;
buf = GetTempMemory(*nbr * sizeof(unsigned int));
// first check if this is the situation with just two arguments where the second argument could be a string or a simple variable or an array
// check the correct arg count AND that the second argument looks like a variable AND it is not a function
if(argc == 3 && isnamestart(*argv[2]) && *skipvar(argv[2], false) == 0 && !(FindSubFun(argv[2], 1) >= 0 && strchr((char *)argv[2], '(') != NULL)) {
ptr = findvar(argv[2], V_NOFIND_NULL | V_EMPTY_OK);
if(ptr == NULL) error("Invalid variable");
// now check if it is a non array string
if(g_vartbl[g_VarIndex].type & T_STR) {
if(g_vartbl[g_VarIndex].dims[0] != 0) error("Invalid variable");
if(*((char *)ptr) < *nbr) error("Insufficient data");
ptr += sizeof(char); // skip the length byte in a MMBasic string
for (i = 0; i < *nbr; i++) {
buf[i] = *(char *)ptr;
ptr += sizeof(char);
}
return buf;
}
// if it is a MMFLOAT or integer do some sanity checks
if(g_vartbl[g_VarIndex].dims[1] != 0) error("Invalid variable");
if(*nbr > 1) {
if(g_vartbl[g_VarIndex].dims[0] == 0) error("Invalid variable");
if(*nbr > (g_vartbl[g_VarIndex].dims[0] + 1 - g_OptionBase)) error("Insufficient data");
}
// now check if it is a MMFLOAT
if(g_vartbl[g_VarIndex].type & T_NBR) {
for (i = 0; i < *nbr; i++) {
buf[i] = FloatToInt32(*(MMFLOAT *)ptr);
ptr += sizeof(MMFLOAT);
}
return buf;
}
// try for an integer
if(g_vartbl[g_VarIndex].type & T_INT) {
for (i = 0; i < *nbr; i++) {
buf[i] = *(unsigned int *)ptr;
ptr += sizeof(long long int);
}
return buf;
}
}
// if we got to here we must have a simple list of expressions to send (phew!)
if(*nbr != ((argc - 1) >> 1)) error("Incorrect argument count");
for (i = 0; i < *nbr; i++) {
buf[i] = getinteger(argv[i + i + 2]);
}
return buf;
}
long long int *GetReceiveDataBuffer(unsigned char *p, unsigned int *nbr) {
void *ptr;
getargs(&p, 3, (unsigned char *)",");
if(argc != 3) error("Invalid syntax");
*nbr = getinteger(argv[0]);
ptr = findvar(argv[2], V_NOFIND_NULL | V_EMPTY_OK);
if(ptr == NULL) error("Invalid variable");
if((g_vartbl[g_VarIndex].type & T_INT) && g_vartbl[g_VarIndex].dims[0] > 0 && g_vartbl[g_VarIndex].dims[1] == 0) { // integer array
if( (((long long int *)ptr - g_vartbl[g_VarIndex].val.ia) + *nbr) > (g_vartbl[g_VarIndex].dims[0] + 1 - g_OptionBase) )
error("Insufficient array size");
}
else error("Invalid variable");
return ptr;
}
/* @endcond */

View File

@ -0,0 +1,29 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
SPI.h
<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.
************************************************************************************************************************/
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,262 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
SSD1963.h
<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.
************************************************************************************************************************/
#ifndef _SSD1963_H
#define _SSD1963_H
// parameters of the display panel (refer to the glass data sheet)
extern int SSD1963HorizPulseWidth, SSD1963HorizBackPorch, SSD1963HorizFrontPorch;
extern int SSD1963VertPulseWidth, SSD1963VertBackPorch, SSD1963VertFrontPorch;
extern int SSD1963PClock1, SSD1963PClock2, SSD1963PClock3;
extern int SSD1963Mode1, SSD1963Mode2;
extern int ScrollStart;
// define global functions
extern void InitSSD1963(void);
extern void InitILI9341(void);
extern void InitILI9341_8(void);
extern void SetBacklightSSD1963(int intensity);
extern void SetTearingCfg(int state, int mode);
extern void DrawBitmapSSD1963(int x1, int y1, int width, int height, int scale, int fg, int bg, unsigned char *bitmap);
extern void DrawBitmap320(int x1, int y1, int width, int height, int scale, int fg, int bg, unsigned char *bitmap);
extern void DisplayPutC(char c);
extern void DisplayPutS(char *);
extern void DrawBufferSSD1963(int x1, int y1, int x2, int y2, unsigned char* p);
extern void DrawBLITBufferSSD1963(int x1, int y1, int x2, int y2, unsigned char* p);
extern void DrawBuffer320(int x1, int y1, int x2, int y2, unsigned char* p);
extern void DrawBLITBuffer320(int x1, int y1, int x2, int y2, unsigned char* p);
extern void ReadBufferSSD1963(int x1, int y1, int x2, int y2, unsigned char* p);
extern void ReadBLITBufferSSD1963(int x1, int y1, int x2, int y2, unsigned char* p);
extern void ReadBuffer320(int x1, int y1, int x2, int y2, unsigned char* p);
extern void ReadBLITBuffer320(int x1, int y1, int x2, int y2, unsigned char* p);
extern void DrawRectangleSSD1963(int x1, int y1, int x2, int y2, int c);
extern void DrawRectangle320(int x1, int y1, int x2, int y2, int c);
extern void InitDisplaySSD(void) ;
extern void ConfigDisplaySSD(unsigned char *p);
extern void SetAreaSSD1963(int x1, int y1, int x2, int y2);
extern void SetAreaILI9341(int xstart, int ystart, int xend, int yend, int rw);
extern void WriteColor(unsigned int c);
extern void WriteComand(int cmd);
extern void WriteData(int data);
extern int display_backlight;
// cursor definition
extern void ShowCursor(int show);
extern volatile int CursorTimer; // used to time the flashing cursor
extern volatile int ClickTimer; // used to time the click when touch occurs
extern volatile int TouchTimer; // used to time the response to touch
extern void ScrollSSD1963(int lines);
#ifdef rp2350
extern const uint8_t PINMAP[48];
#else
extern const uint8_t PINMAP[30];
#endif
void WriteData16bit(int data);
void Write16bitCommand(int cmd) ;
void SetAreaIPS_4_16(int xstart, int ystart, int xend, int yend, int rw);
void WriteCmdDataIPS_4_16(int cmd,int n,int data);
#define GPIO3 3
#define GPIO2 2
#define GPIO1 1
#define GPIO0 0
#define LCD_RESET (1<<GPIO0) // LCD Reset signal (Reset for display panel, NOT ssd1963)
#define LCD_SPENA 0
#define LCD_SPCLK 0
#define LCD_SPDAT 0
#define SSD1963_LANDSCAPE 0b00
#define SSD1963_PORTRAIT ((1 << 7) | (1 << 5))
#define SSD1963_RLANDSCAPE (SSD1963_LANDSCAPE | 0b11)
#define SSD1963_RPORTRAIT (SSD1963_PORTRAIT | 0b11)
// SSD1963 command table
#define CMD_NOP 0x00 //No operation
#define CMD_SOFT_RESET 0x01 //Software reset
#define CMD_GET_PWR_MODE 0x0A //Get the current power mode
#define CMD_GET_ADDR_MODE 0x0B //Get the frame memory to the display panel read order
#define CMD_GET_PIXEL_FORMAT 0x0C //Get the current pixel format
#define CMD_GET_DISPLAY_MODE 0x0D //Returns the display mode
#define CMD_GET_SIGNAL_MODE 0x0E //
#define CMD_GET_DIAGNOSTIC 0x0F
#define CMD_ENT_SLEEP 0x10
#define CMD_EXIT_SLEEP 0x11
#define CMD_ENT_PARTIAL_MODE 0x12
#define CMD_ENT_NORMAL_MODE 0x13
#define CMD_EXIT_INVERT_MODE 0x20
#define CMD_ENT_INVERT_MODE 0x21
#define CMD_SET_GAMMA 0x26
#define CMD_BLANK_DISPLAY 0x28
#define CMD_ON_DISPLAY 0x29
#define CMD_SET_COLUMN 0x2A
#define CMD_SET_PAGE 0x2B
#define CMD_WR_MEMSTART 0x2C
#define CMD_RD_MEMSTART 0x2E
#define CMD_SET_PARTIAL_AREA 0x30
#define CMD_SET_SCROLL_AREA 0x33
#define CMD_SET_TEAR_OFF 0x34 //synchronization information is not sent from the display
#define CMD_SET_TEAR_ON 0x35 //sync. information is sent from the display
#define CMD_SET_ADDR_MODE 0x36 //set fram buffer read order to the display panel
#define CMD_SET_SCROLL_START 0x37
#define CMD_EXIT_IDLE_MODE 0x38
#define CMD_ENT_IDLE_MODE 0x39
#define CMD_SET_PIXEL_FORMAT 0x3A //defines how many bits per pixel is used
#define CMD_WR_MEM_AUTO 0x3C
#define CMD_RD_MEM_AUTO 0x3E
#define CMD_SET_TEAR_SCANLINE 0x44
#define CMD_GET_SCANLINE 0x45
#define CMD_RD_DDB_START 0xA1
#define CMD_RD_DDB_AUTO 0xA8
#define CMD_SET_PANEL_MODE 0xB0
#define CMD_GET_PANEL_MODE 0xB1
#define CMD_SET_HOR_PERIOD 0xB4
#define CMD_GET_HOR_PERIOD 0xB5
#define CMD_SET_VER_PERIOD 0xB6
#define CMD_GET_VER_PERIOD 0xB7
#define CMD_SET_GPIO_CONF 0xB8
#define CMD_GET_GPIO_CONF 0xB9
#define CMD_SET_GPIO_VAL 0xBA
#define CMD_GET_GPIO_STATUS 0xBB
#define CMD_SET_POST_PROC 0xBC
#define CMD_GET_POST_PROC 0xBD
#define CMD_SET_PWM_CONF 0xBE
#define CMD_GET_PWM_CONF 0xBF
#define CMD_SET_LCD_GEN0 0xC0
#define CMD_GET_LCD_GEN0 0xC1
#define CMD_SET_LCD_GEN1 0xC2
#define CMD_GET_LCD_GEN1 0xC3
#define CMD_SET_LCD_GEN2 0xC4
#define CMD_GET_LCD_GEN2 0xC5
#define CMD_SET_LCD_GEN3 0xC6
#define CMD_GET_LCD_GEN3 0xC7
#define CMD_SET_GPIO0_ROP 0xC8
#define CMD_GET_GPIO0_ROP 0xC9
#define CMD_SET_GPIO1_ROP 0xCA
#define CMD_GET_GPIO1_ROP 0xCB
#define CMD_SET_GPIO2_ROP 0xCC
#define CMD_GET_GPIO2_ROP 0xCD
#define CMD_SET_GPIO3_ROP 0xCE
#define CMD_GET_GPIO3_ROP 0xCF
#define CMD_SET_ABC_DBC_CONF 0xD0
#define CMD_GET_ABC_DBC_CONF 0xD1
#define CMD_SET_DBC_HISTO_PTR 0xD2
#define CMD_GET_DBC_HISTO_PTR 0xD3
#define CMD_SET_DBC_THRES 0xD4
#define CMD_GET_DBC_THRES 0xD5
#define CMD_SET_ABM_TMR 0xD6
#define CMD_GET_ABM_TMR 0xD7
#define CMD_SET_AMB_LVL0 0xD8
#define CMD_GET_AMB_LVL0 0xD9
#define CMD_SET_AMB_LVL1 0xDA
#define CMD_GET_AMB_LVL1 0xDB
#define CMD_SET_AMB_LVL2 0xDC
#define CMD_GET_AMB_LVL2 0xDD
#define CMD_SET_AMB_LVL3 0xDE
#define CMD_GET_AMB_LVL3 0xDF
#define CMD_PLL_START 0xE0 //start the PLL
#define CMD_PLL_STOP 0xE1 //disable the PLL
#define CMD_SET_PLL_MN 0xE2
#define CMD_GET_PLL_MN 0xE3
#define CMD_GET_PLL_STATUS 0xE4 //get the current PLL status
#define CMD_ENT_DEEP_SLEEP 0xE5
#define CMD_SET_PCLK 0xE6 //set pixel clock (LSHIFT signal) frequency
#define CMD_GET_PCLK 0xE7 //get pixel clock (LSHIFT signal) freq. settings
#define CMD_SET_DATA_INTERFACE 0xF0
#define CMD_GET_DATA_INTERFACE 0xF1
#define SSD1963_DC_PIN PINMAP[Option.SSD_DC]
#define SSD1963_WR_PIN PINMAP[Option.SSD_WR]
#define SSD1963_RD_PIN PINMAP[Option.SSD_RD]
#define SSD1963_RESET_PIN PINMAP[Option.SSD_RESET]
#define SSD1963_DAT1 Option.SSD_DATA
#define SSD1963_DAT2 PINMAP[PinDef[Option.SSD_DATA].GPno+1]
#define SSD1963_DAT3 PINMAP[PinDef[Option.SSD_DATA].GPno+2]
#define SSD1963_DAT4 PINMAP[PinDef[Option.SSD_DATA].GPno+3]
#define SSD1963_DAT5 PINMAP[PinDef[Option.SSD_DATA].GPno+4]
#define SSD1963_DAT6 PINMAP[PinDef[Option.SSD_DATA].GPno+5]
#define SSD1963_DAT7 PINMAP[PinDef[Option.SSD_DATA].GPno+6]
#define SSD1963_DAT8 PINMAP[PinDef[Option.SSD_DATA].GPno+7]
#define SSD1963_DAT9 PINMAP[PinDef[Option.SSD_DATA].GPno+8]
#define SSD1963_DAT10 PINMAP[PinDef[Option.SSD_DATA].GPno+9]
#define SSD1963_DAT11 PINMAP[PinDef[Option.SSD_DATA].GPno+10]
#define SSD1963_DAT12 PINMAP[PinDef[Option.SSD_DATA].GPno+11]
#define SSD1963_DAT13 PINMAP[PinDef[Option.SSD_DATA].GPno+12]
#define SSD1963_DAT14 PINMAP[PinDef[Option.SSD_DATA].GPno+13]
#define SSD1963_DAT15 PINMAP[PinDef[Option.SSD_DATA].GPno+14]
#define SSD1963_DAT16 PINMAP[PinDef[Option.SSD_DATA].GPno+15]
#define SSD1963_DC_GPPIN Option.SSD_DC
#define SSD1963_WR_GPPIN Option.SSD_WR
#define SSD1963_RD_GPPIN Option.SSD_RD
#define SSD1963_RESET_GPPIN Option.SSD_RESET
#define SSD1963_GPDAT1 PinDef[Option.SSD_DATA].GPno
#define SSD1963_GPDAT2 SSD1963_GPDAT1+1
#define SSD1963_GPDAT3 SSD1963_GPDAT1+2
#define SSD1963_GPDAT4 SSD1963_GPDAT1+3
#define SSD1963_GPDAT5 SSD1963_GPDAT1+4
#define SSD1963_GPDAT6 SSD1963_GPDAT1+5
#define SSD1963_GPDAT7 SSD1963_GPDAT1+6
#define SSD1963_GPDAT8 SSD1963_GPDAT1+7
#define SSD1963_GPDAT9 SSD1963_GPDAT1+8
#define SSD1963_GPDAT10 SSD1963_GPDAT1+9
#define SSD1963_GPDAT11 SSD1963_GPDAT1+10
#define SSD1963_GPDAT12 SSD1963_GPDAT1+11
#define SSD1963_GPDAT13 SSD1963_GPDAT1+12
#define SSD1963_GPDAT14 SSD1963_GPDAT1+13
#define SSD1963_GPDAT15 SSD1963_GPDAT1+14
#define SSD1963_GPDAT16 SSD1963_GPDAT1+15
#define nop asm("NOP")
#define ILI9341_PWCTR1 0xC0
#define ILI9341_PWCTR2 0xC1
#define ILI9341_PWCTR3 0xC2
#define ILI9341_PWCTR4 0xC3
#define ILI9341_PWCTR5 0xC4
#define ILI9341_VMCTR1 0xC5
#define ILI9341_VMCTR2 0xC7
#define ILI9341_PTLAR 0x30
#define ILI9341_VSCRDEF 0x33
#define ILI9341_MADCTL 0x36
#define ILI9341_VSCRSADD 0x37
#define ILI9341_PIXFMT 0x3A
#define ILI9341_FRMCTR1 0xB1
#define ILI9341_FRMCTR2 0xB2
#define ILI9341_FRMCTR3 0xB3
#define ILI9341_INVCTR 0xB4
#define ILI9341_DFUNCTR 0xB6
#define ILI9341_GMCTRP1 0xE0
#define ILI9341_GMCTRN1 0xE1
#define ILI9341_SLPIN 0x10
#define ILI9341_SLPOUT 0x11
#define ILI9341_PTLON 0x12
#define ILI9341_NORON 0x13
#define ILI9341_INVOFF 0x20
#define ILI9341_INVON 0x21
#define ILI9341_GAMMASET 0x26
#define ILI9341_DISPOFF 0x28
#define ILI9341_DISPON 0x29
#endif
/* @endcond */

View File

@ -0,0 +1,475 @@
/***********************************************************************************************************************
PicoMite MMBasic
Serial.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 "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include "hardware/uart.h"
#include "hardware/irq.h"
// variables for com1
int com1 = 0; // true if COM1 is enabled
int com1_buf_size; // size of the buffer used to receive chars
int com1_baud = 0; // determines the baud rate
char *com1_interrupt; // pointer to the interrupt routine
int com1_ilevel; // number nbr of chars in the buffer for an interrupt
int com1_TX_complete = false;
unsigned char *com1Rx_buf; // pointer to the buffer for received characters
volatile int com1Rx_head, com1Rx_tail; // head and tail of the ring buffer for com1
unsigned char *com1Tx_buf; // pointer to the buffer for transmitted characters
volatile int com1Tx_head, com1Tx_tail; // head and tail of the ring buffer for com1
volatile int com1complete=1;
uint16_t Rx1Buffer;
char com1_mode; // keeps track of the settings for com4
unsigned char com1_bit9 = 0; // used to track the 9th bit
extern uint32_t ticks_per_microsecond;
// variables for com2
int com2 = 0; // true if COM2 is enabled
int com2_buf_size; // size of the buffer used to receive chars
int com2_baud = 0; // determines the baud rate
char *com2_interrupt; // pointer to the interrupt routine
int com2_ilevel; // number nbr of chars in the buffer for an interrupt
int com2_TX_complete = false;
unsigned char *com2Rx_buf; // pointer to the buffer for received characters
volatile int com2Rx_head, com2Rx_tail; // head and tail of the ring buffer for com2 Rx
unsigned char *com2Tx_buf; // pointer to the buffer for transmitted characters
volatile int com2Tx_head, com2Tx_tail; // head and tail of the ring buffer for com2 Tx
volatile int com2complete=1;
char com2_mode; // keeps track of the settings for com4
unsigned char com2_bit9 = 0; // used to track the 9th bit
// uart interrupt handler
void on_uart_irq0() {
if(uart_is_readable(uart0)) {
char cc = uart_getc(uart0);
if(!(Option.SerialConsole & 1)){
if(GPSchannel==1){
*gpsbuf=cc;
gpsbuf++;
gpscount++;
if((char)cc==10 || gpscount==128){
if(gpscurrent){
*gpsbuf=0;
gpscurrent=0;
gpscount=0;
gpsbuf=gpsbuf1;
gpsready=gpsbuf2;
} else {
*gpsbuf=0;
gpscurrent=1;
gpscount=0;
gpsbuf=gpsbuf2;
gpsready=gpsbuf1;
}
}
} else {
com1Rx_buf[com1Rx_head] =cc; // store the byte in the ring buffer
com1Rx_head = (com1Rx_head + 1) % com1_buf_size; // advance the head of the queue
if(com1Rx_head == com1Rx_tail) { // if the buffer has overflowed
com1Rx_tail = (com1Rx_tail + 1) % com1_buf_size; // throw away the oldest char
}
}
} else {
ConsoleRxBuf[ConsoleRxBufHead] = cc; // store the byte in the ring buffer
if(BreakKey && ConsoleRxBuf[ConsoleRxBufHead] == BreakKey) {// if the user wants to stop the progran
MMAbort = true; // set the flag for the interpreter to see
ConsoleRxBufHead = ConsoleRxBufTail; // empty the buffer
} else {
ConsoleRxBufHead = (ConsoleRxBufHead + 1) % CONSOLE_RX_BUF_SIZE; // advance the head of the queue
if(ConsoleRxBufHead == ConsoleRxBufTail) { // if the buffer has overflowed
ConsoleRxBufTail = (ConsoleRxBufTail + 1) % CONSOLE_RX_BUF_SIZE; // throw away the oldest char
}
}
}
}
if(uart_is_writable(uart0)){
if(!(Option.SerialConsole & 1)){
if(com1Tx_head != com1Tx_tail) {
uart_putc_raw(uart0,com1Tx_buf[com1Tx_tail]);
com1Tx_tail = (com1Tx_tail + 1) % TX_BUFFER_SIZE; // advance the tail of the queue
} else {
uart_set_irq_enables(uart0, true, false);
com1_TX_complete=true;
}
} else {
if(ConsoleTxBufTail != ConsoleTxBufHead) {
uart_putc_raw(uart0,ConsoleTxBuf[ConsoleTxBufTail]);
ConsoleTxBufTail = (ConsoleTxBufTail + 1) % CONSOLE_TX_BUF_SIZE; // advance the tail of the queue
} else {
uart_set_irq_enables(uart0, true, false);
}
}
}
}
void on_uart_irq1() {
if (uart_is_readable(uart1)) {
char cc = uart_getc(uart1);
if(!(Option.SerialConsole & 2)){
if(GPSchannel==2){
*gpsbuf=cc;
gpsbuf++;
gpscount++;
if((char)cc==10 || gpscount==128){
if(gpscurrent){
*gpsbuf=0;
gpscurrent=0;
gpscount=0;
gpsbuf=gpsbuf1;
gpsready=gpsbuf2;
} else {
*gpsbuf=0;
gpscurrent=1;
gpscount=0;
gpsbuf=gpsbuf2;
gpsready=gpsbuf1;
}
}
} else {
com2Rx_buf[com2Rx_head] = cc; // store the byte in the ring buffer
com2Rx_head = (com2Rx_head + 1) % com2_buf_size; // advance the head of the queue
if(com2Rx_head == com2Rx_tail) { // if the buffer has overflowed
com2Rx_tail = (com2Rx_tail + 1) % com2_buf_size; // throw away the oldest char
}
}
} else {
ConsoleRxBuf[ConsoleRxBufHead] = cc; // store the byte in the ring buffer
if(BreakKey && ConsoleRxBuf[ConsoleRxBufHead] == BreakKey) {// if the user wants to stop the progran
MMAbort = true; // set the flag for the interpreter to see
ConsoleRxBufHead = ConsoleRxBufTail; // empty the buffer
} else {
ConsoleRxBufHead = (ConsoleRxBufHead + 1) % CONSOLE_RX_BUF_SIZE; // advance the head of the queue
if(ConsoleRxBufHead == ConsoleRxBufTail) { // if the buffer has overflowed
ConsoleRxBufTail = (ConsoleRxBufTail + 1) % CONSOLE_RX_BUF_SIZE; // throw away the oldest char
}
}
}
}
if(uart_is_writable(uart1)){
if(!(Option.SerialConsole & 2)){
if(com2Tx_head != com2Tx_tail) {
uart_putc_raw(uart1,com2Tx_buf[com2Tx_tail]);
com2Tx_tail = (com2Tx_tail + 1) % TX_BUFFER_SIZE; // advance the tail of the queue
} else {
uart_set_irq_enables(uart1, true, false);
com2_TX_complete=true;
}
} else {
if(ConsoleTxBufTail != ConsoleTxBufHead) {
uart_putc_raw(uart1,ConsoleTxBuf[ConsoleTxBufTail]);
ConsoleTxBufTail = (ConsoleTxBufTail + 1) % CONSOLE_TX_BUF_SIZE; // advance the tail of the queue
} else {
uart_set_irq_enables(uart1, true, false);
}
}
}
}
/***************************************************************************************************
Initialise the serial function including the timer and interrupts.
****************************************************************************************************/
#define UART_ID (uart ? uart1: uart0)
void invert_serial(int uart){
int txpin, rxpin;
if(uart==0){
txpin=PinDef[UART0TXpin].GPno;
rxpin=PinDef[UART0RXpin].GPno;
} else {
txpin=PinDef[UART1TXpin].GPno;
rxpin=PinDef[UART1RXpin].GPno;
}
gpio_set_outover(txpin, GPIO_OVERRIDE_INVERT);
gpio_set_inover(rxpin, GPIO_OVERRIDE_INVERT);
}
void MIPS16 setupuart(int uart, int s2,int parity, int b7, int baud, int inv){
uart_init(UART_ID,baud);
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, b7, s2, parity);
uart_set_fifo_enabled(UART_ID, false);
if(inv)invert_serial(uart);
int UART_IRQ = (UART_ID == uart0 ? UART0_IRQ : UART1_IRQ);
if(uart){
irq_set_exclusive_handler(UART_IRQ, on_uart_irq1);
irq_set_enabled(UART_IRQ, true);
} else {
irq_set_exclusive_handler(UART_IRQ, on_uart_irq0);
irq_set_enabled(UART_IRQ, true);
}
uart_set_irq_enables(UART_ID, true, false);
uart_set_irq_enables(UART_ID, true, false);
}
/***************************************************************************************************
Initialise the serial function including the timer and interrupts.
****************************************************************************************************/
void MIPS16 SerialOpen(unsigned char *spec) {
int baud, i, s2, parity, b7, bufsize, inv=0, ilevel=1;
char *interrupt;
getargs(&spec, 21, (unsigned char *)":,"); // this is a macro and must be the first executable stmt
if(argc != 2 && (argc & 0x01) == 0) error("COM specification");
b7 = 8;
parity = UART_PARITY_NONE;
s2 = 1;
for(i = 0; i < 5; i++) {
if(str_equal(argv[argc - 1], (unsigned char *)"EVEN")) {
if(parity)error("Syntax");
else {parity = UART_PARITY_EVEN; argc -= 2; } // set even parity
}
if(str_equal(argv[argc - 1], (unsigned char *)"ODD")) {
if(parity)error("Syntax");
else {parity = UART_PARITY_ODD; argc -= 2; } // set even parity
}
if(str_equal(argv[argc - 1], (unsigned char *)"INV")) { inv = 1; argc -= 2; }; // invert the serial port
if(str_equal(argv[argc - 1], (unsigned char *)"DE")) error("DE not Supported"); // get the two stop bit option
if(str_equal(argv[argc - 1], (unsigned char *)"OC")) error("OC not Supported"); // get the two stop bit option
if(str_equal(argv[argc - 1], (unsigned char *)"9BIT")) error("9BIT not Supported"); // get the two stop bit option
if(str_equal(argv[argc - 1], (unsigned char *)"S2")) { s2 = 2; argc -= 2; } // get the two stop bit option
if(str_equal(argv[argc - 1], (unsigned char *)"7BIT")) { b7 = 7; argc -= 2; } // set the 7 bit byte option
}
if(argc < 1 || argc > 9) error("COM specification");
if(argc >= 3 && *argv[2]) {
baud = getint(argv[2],Option.CPU_Speed*1000/16/65535,921600); // get the baud rate as a number
} else
baud = COM_DEFAULT_BAUD_RATE;
if(argc >= 5 && *argv[4])
bufsize = getinteger(argv[4]); // get the buffer size as a number
else
bufsize = COM_DEFAULT_BUF_SIZE;
if(argc >= 7) {
InterruptUsed = true;
argv[6]=(unsigned char *)strupr((char *)argv[6]);
interrupt = (char *)GetIntAddress(argv[6]); // get the interrupt location
} else
interrupt = NULL;
if(argc == 9) {
ilevel = getinteger(argv[8]); // get the buffer level for interrupt as a number
if(ilevel < 1 || ilevel > bufsize) error("COM specification");
} else
ilevel = 1;
/* if(argc >= 11) {
InterruptUsed = true;
argv[6]=strupr(argv[10]);
TXinterrupt = GetIntAddress(argv[10]); // get the interrupt location
} else
TXinterrupt = NULL;
*/
if(spec[3] == '1') {
///////////////////////////////// this is COM1 ////////////////////////////////////
if(com1) error("Already open");
if(UART0TXpin==99 || UART0RXpin==99)error("Pins not set for COM1");
com1_buf_size = bufsize; // extracted from the comspec above
com1_interrupt = interrupt;
com1_ilevel = ilevel;
// setup for receive
com1Rx_buf = GetMemory(com1_buf_size); // setup the buffer
com1Rx_head = com1Rx_tail = 0;
ExtCfg(UART0RXpin, EXT_COM_RESERVED, 0); // reserve the pin for com use
// setup for transmit
com1Tx_buf = GetMemory(TX_BUFFER_SIZE); // setup the buffer
com1Tx_head = com1Tx_tail = 0;
ExtCfg(UART0TXpin, EXT_COM_RESERVED, 0);
setupuart(0, s2, parity, b7, baud, inv);
com1 = true;
uSec(1000);
com1Rx_head = com1Rx_tail = 0;
com1Tx_head = com1Tx_tail = 0;
}
else if (spec[3] == '2') {
///////////////////////////////// this is COM2 ////////////////////////////////////
if(com2) error("Already open");
if(UART1TXpin==99 || UART1RXpin==99)error("Pins not set for COM2");
com2_buf_size = bufsize; // extracted from the comspec above
com2_interrupt = interrupt;
com2_ilevel = ilevel;
// com2_TX_interrupt = TXinterrupt;
// com2_TX_complete = false;
// setup for receive
com2Rx_buf = GetMemory(com2_buf_size); // setup the buffer
com2Rx_head = com2Rx_tail = 0;
ExtCfg(UART1RXpin, EXT_COM_RESERVED, 0); // reserve the pin for com use
// setup for transmit
com2Tx_buf = GetMemory(TX_BUFFER_SIZE); // setup the buffer
com2Tx_head = com2Tx_tail = 0;
ExtCfg(UART1TXpin, EXT_COM_RESERVED, 0); // reserve the pin for com use
setupuart(1, s2, parity, b7, baud, inv);
com2 = true;
uSec(1000);
com2Rx_head = com2Rx_tail = 0;
com2Tx_head = com2Tx_tail = 0;
}
}
/***************************************************************************************************
Close a serial port.
****************************************************************************************************/
void MIPS16 SerialClose(int comnbr) {
if(comnbr == 1 && com1) {
uart_deinit(uart0);
com1 = false;
com1_interrupt = NULL;
if(UART0RXpin!=99)ExtCfg(UART0RXpin, EXT_NOT_CONFIG, 0);
if(UART0TXpin!=99)ExtCfg(UART0TXpin, EXT_NOT_CONFIG, 0);
if(com1Rx_buf!=NULL){FreeMemory(com1Rx_buf); com1Rx_buf=NULL;}
if(com1Tx_buf!=NULL){FreeMemory(com1Tx_buf); com1Tx_buf=NULL;}
}
else if(comnbr == 2 && com2) {
uart_deinit(uart1);
com2 = false;
com2_interrupt = NULL;
if(UART1RXpin!=99)ExtCfg(UART1RXpin, EXT_NOT_CONFIG, 0);
if(UART1TXpin!=99)ExtCfg(UART1TXpin, EXT_NOT_CONFIG, 0);
if(com2Rx_buf!=NULL){FreeMemory(com2Rx_buf); com2Rx_buf=NULL;}
if(com2Tx_buf!=NULL){FreeMemory(com2Tx_buf); com2Tx_buf=NULL;}
}
}
/***************************************************************************************************
Add a character to the serial output buffer.
****************************************************************************************************/
unsigned char SerialPutchar(int comnbr, unsigned char c) {
if(comnbr == 1) {
while(com1Tx_tail == ((com1Tx_head + 1) % TX_BUFFER_SIZE)) // wait if the buffer is full
if(MMAbort) { // allow the user to abort a hung serial port
com1Tx_tail = com1Tx_head = 0; // clear the buffer
longjmp(mark, 1); // and abort
}
int empty=uart_is_writable(uart0);
com1Tx_buf[com1Tx_head] = c; // add the char
com1Tx_head = (com1Tx_head + 1) % TX_BUFFER_SIZE; // advance the head of the queue
if(empty){
uart_set_irq_enables(uart0, true, true);
irq_set_pending(UART0_IRQ);
}
}
else if(comnbr == 2) {
while(com2Tx_tail == ((com2Tx_head + 1) % TX_BUFFER_SIZE)) // wait if the buffer is full
if(MMAbort) { // allow the user to abort a hung serial port
com2Tx_tail = com2Tx_head = 0; // clear the buffer
longjmp(mark, 1); // and abort
}
int empty=uart_is_writable(uart1);
com2Tx_buf[com2Tx_head] = c; // add the char
com2Tx_head = (com2Tx_head + 1) % TX_BUFFER_SIZE; // advance the head of the queue
if(empty){
uart_set_irq_enables(uart1, true, true);
irq_set_pending(UART1_IRQ);
}
}
return c;
}
/***************************************************************************************************
Get the status the serial receive buffer.
Returns the number of characters waiting in the buffer
****************************************************************************************************/
int SerialRxStatus(int comnbr) {
int i = 0;
if(comnbr == 1) {
uart_set_irq_enables(uart0, false, true);
i = com1Rx_head - com1Rx_tail;
uart_set_irq_enables(uart0, true, true);
if(i < 0) i += com1_buf_size;
}
else if(comnbr == 2) {
uart_set_irq_enables(uart1, false, true);
i = com2Rx_head - com2Rx_tail;
uart_set_irq_enables(uart1, true, true);
if(i < 0) i += com2_buf_size;
}
return i;
}
/***************************************************************************************************
Get the status the serial transmit buffer.
Returns the number of characters waiting in the buffer
****************************************************************************************************/
int SerialTxStatus(int comnbr) {
int i = 0;
if(comnbr == 1) {
i = com1Tx_head - com1Tx_tail;
if(i < 0) i += TX_BUFFER_SIZE;
}
else if(comnbr == 2) {
i = com2Tx_head - com2Tx_tail;
if(i < 0) i += TX_BUFFER_SIZE;
}
return i;
}
/***************************************************************************************************
Get a character from the serial receive buffer.
Note that this is returned as an integer and -1 means that there are no characters available
****************************************************************************************************/
int SerialGetchar(int comnbr) {
int c;
c = -1; // -1 is no data
if(comnbr == 1) {
uart_set_irq_enables(uart0, false, true);
if(com1Rx_head != com1Rx_tail) { // if the queue has something in it
c = com1Rx_buf[com1Rx_tail]; // get the char
com1Rx_tail = (com1Rx_tail + 1) % com1_buf_size; // and remove from the buffer
}
uart_set_irq_enables(uart0, true, true);
}
else if(comnbr == 2) {
uart_set_irq_enables(uart1, false, true);
if(com2Rx_head != com2Rx_tail) { // if the queue has something in it
c = com2Rx_buf[com2Rx_tail]; // get the char
com2Rx_tail = (com2Rx_tail + 1) % com2_buf_size; // and remove from the buffer
}
uart_set_irq_enables(uart1, true, true);
}
return c;
}

View File

@ -0,0 +1,98 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Serial.h
<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.
************************************************************************************************************************/
/* ********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
// General definitions used by other modules
#ifndef SERIAL_HEADER
#define SERIAL_HEADER
#define COM_DEFAULT_BAUD_RATE 9600
#define COM_DEFAULT_BUF_SIZE 1024
#define TX_BUFFER_SIZE 256
// global variables
extern int com1; // true if COM1 is enabled
extern int com1_buf_size; // size of the buffer used to receive chars
extern int com1_baud; // determines the baud rate
extern char *com1_interrupt; // pointer to the interrupt routine
extern int com1_TX_complete;
extern int com1_ilevel; // number nbr of chars in the buffer for an interrupt
extern unsigned char *com1Rx_buf; // pointer to the buffer for received characters
// extern volatile int com1Rx_head, com1Rx_tail; // head and tail of the ring buffer for com1
extern unsigned char *com1Tx_buf; // pointer to the buffer for transmitted characters
// extern volatile int com1Tx_head, com1Tx_tail; // head and tail of the ring buffer for com1
extern volatile int com1complete;
extern uint16_t Rx1Buffer;
#define COM1_9B 0b001 // 9 bit data enabled
#define COM1_DE 0b010 // RS485 enable flag in use
// char com2_mode; // keeps track of the settings for com1
extern unsigned char com1_bit9; // used to track the 9th bit
// variables for com2
extern int com2; // true if COM2 is enabled
extern int com2_buf_size; // size of the buffer used to receive chars
extern int com2_baud; // determines the baud rate
extern char *com2_interrupt, *com2_TX_interrupt; // pointer to the interrupt routine
extern int com2_TX_complete;
extern int com2_ilevel; // number nbr of chars in the buffer for an interrupt
extern unsigned char *com2Rx_buf; // pointer to the buffer for received characters
extern volatile int com2Rx_head, com2Rx_tail; // head and tail of the ring buffer for com2 Rx
extern unsigned char *com2Tx_buf; // pointer to the buffer for transmitted characters
extern volatile int com2Tx_head, com2Tx_tail; // head and tail of the ring buffer for com2 Tx
extern volatile int com2complete;
extern void on_uart_irq0();
extern void on_uart_irq1();
// global functions
void SerialOpen(unsigned char *spec);
void SerialClose(int comnbr);
unsigned char SerialPutchar(int comnbr, unsigned char c);
int SerialRxStatus(int comnbr);
int SerialTxStatus(int comnbr);
int SerialGetchar(int comnbr);
void setupuart(int uart, int s2,int b9,int b7, int baud, int inv);
extern void start_console(void);
extern void stop_console(void);
extern void start_com1(void);
extern void stop_com1e(void);
extern void start_com2(void);
extern void stop_com2(void);
extern void MX_USART1_UART_Init1(void);
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,464 @@
/***********************************************************************************************************************
PicoMite MMBasic
Touch.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.
************************************************************************************************************************/
/** @file Touch.c
* @author Geoff Graham, Peter Mather
* @brief Source for the MMBasic Touch function
*/
/*
* @cond
* The following section will be excluded from the documentation.
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include "hardware/structs/systick.h"
#ifdef PICOMITEWEB
#include "pico/cyw43_arch.h"
#endif
#ifndef PICOMITEWEB
#include "pico/multicore.h"
extern mutex_t frameBufferMutex;
#endif
#include "hardware/i2c.h"
int GetTouchValue(int cmd);
void TDelay(void);
// these are defined so that the state of the touch PEN IRQ can be determined with the minimum of CPU cycles
int TouchIrqPortBit;
int TOUCH_IRQ_PIN;
int TOUCH_CS_PIN;
int TOUCH_Click_PIN;
int TOUCH_GETIRQTRIS=0;
static int gt911_addr=GT911_ADDR;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// configure the touch parameters (chip select pin and the IRQ pin)
// this is called by the OPTION TOUCH command
void MIPS16 ConfigTouch(unsigned char *p) {
int pin1, pin2=0, pin3=0;
uint8_t TOUCH_CAP=0;
int threshold=50;
unsigned char *tp=NULL;
tp = checkstring(p, (unsigned char *)"FT6336");
if(tp)TOUCH_CAP=1;
if(tp){
p=tp;
if(!Option.SYSTEM_I2C_SDA)error("System I2C not set");
if(!TOUCH_CAP)TOUCH_CAP=2;
}
getargs(&p, 7, (unsigned char *)",");
if(!(Option.SYSTEM_CLK || TOUCH_CAP))error("System SPI not configured");
if(!TOUCH_CAP){
if(!(argc == 3 || argc == 5)) error("Argument count");
} else if(argc<3)error("Argument count");
unsigned char code;
if(!(code=codecheck(argv[0])))argv[0]+=2;
pin1 = getinteger(argv[0]);
if(!code)pin1=codemap(pin1);
if(IsInvalidPin(pin1)) error("Invalid pin");
if(!(code=codecheck(argv[2])))argv[2]+=2;
pin2 = getinteger(argv[2]);
if(!code)pin2=codemap(pin2);
if(IsInvalidPin(pin2)) error("Invalid pin");
if(argc >= 5 && *argv[4]) {
if(!(code=codecheck(argv[4])))argv[4]+=2;
pin3 = getinteger(argv[4]);
if(!code)pin3=codemap(pin3);
if(IsInvalidPin(pin3)) error("Invalid pin");
}
if(TOUCH_CAP){
if(argc==7) threshold=getint(argv[6],0,255);
}
if(ExtCurrentConfig[pin1] != EXT_NOT_CONFIG) error("Pin %/| is in use",pin1,pin1);
if(pin2)
if(ExtCurrentConfig[pin2] != EXT_NOT_CONFIG) error("Pin %/| is in use",pin2,pin2);
if(pin3)
if(ExtCurrentConfig[pin3] != EXT_NOT_CONFIG) error("Pin %/| is in use",pin3,pin3);
Option.TOUCH_CS = (TOUCH_CAP ? pin2 :pin1);
Option.TOUCH_IRQ = (TOUCH_CAP ? pin1 :pin2);
Option.TOUCH_Click = pin3;
Option.TOUCH_XZERO = Option.TOUCH_YZERO = 0; // record the touch feature as not calibrated
Option.TOUCH_CAP=TOUCH_CAP;
Option.THRESHOLD_CAP=threshold;
}
int gt911_dev_mode_w(uint8_t value)
{
uint8_t tmp;
tmp = read8Register16(gt911_addr,GT911_DEV_MODE_REG);
if (mmI2Cvalue == 0L)
{
tmp &= ~GT911_DEV_MODE_BIT_MASK;
tmp |= value << GT911_DEV_MODE_BIT_POSITION;
Write8Register16(gt911_addr,GT911_DEV_MODE_REG, tmp);
}
return mmI2Cvalue;
}
int32_t gt911_dev_mode_r(uint8_t *pValue)
{
*pValue=read8Register16(gt911_addr,GT911_DEV_MODE_REG);
if (mmI2Cvalue == 0L)
{
*pValue &= GT911_DEV_MODE_BIT_MASK;
*pValue = *pValue >> GT911_DEV_MODE_BIT_POSITION;
}
return mmI2Cvalue;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// setup touch based on the settings saved in flash
void MIPS16 InitTouch(void) {
if(Option.TOUCH_CAP==1){
if(!Option.TOUCH_IRQ || !Option.SYSTEM_I2C_SCL) return; //shouldn't be needed
PinSetBit(CAP_RESET, LATCLR);
uSec(1000);
PinSetBit(CAP_RESET, LATSET);
uSec(500000);
if(readRegister8(FT6X36_ADDR, FT6X36_REG_PANEL_ID) != FT6X36_VENDID)MMPrintString("Touch panel ID not found\r\n");
uint8_t id = readRegister8(FT6X36_ADDR, FT6X36_REG_CHIPID);
if (!(id == FT6206_CHIPID || id == FT6236_CHIPID || id == FT6336_CHIPID)){PIntH(id);MMPrintString(" Touch panel not found\r\n");}
WriteRegister8(FT6X36_ADDR, FT6X36_REG_DEVICE_MODE, 0x00);
WriteRegister8(FT6X36_ADDR, FT6X36_REG_INTERRUPT_MODE, 0x00);
WriteRegister8(FT6X36_ADDR, FT6X36_REG_CTRL, 0x00);
WriteRegister8(FT6X36_ADDR, FT6X36_REG_THRESHHOLD, Option.THRESHOLD_CAP);
WriteRegister8(FT6X36_ADDR, FT6X36_REG_TOUCHRATE_ACTIVE, 0x01);
TOUCH_GETIRQTRIS = 1;
/* } else if(Option.TOUCH_CAP==2){
if(!Option.TOUCH_IRQ || !Option.SYSTEM_I2C_SCL) return; //shouldn't be needed
MMPrintString("Initialising GT911\r\n");
uint8_t read_data;
PinSetBit(CAP_RESET, LATCLR);
uSec(1000);
PinSetBit(CAP_RESET, LATSET);
uSec(500000);
gt911_addr=GT911_ADDR;
int ret=i2c_read_blocking(I2C0locked? i2c0 : i2c1, gt911_addr, &read_data, 1, false);
if(ret<0){
gt911_addr=GT911_ADDR2;
ret=i2c_read_blocking(I2C0locked? i2c0 : i2c1, gt911_addr, &read_data, 1, false);
}
if(ret<0){
MMPrintString("GT911 controller not found\r\n");
return;
}
if(gt911_dev_mode_w(GT911_DEV_MODE_FACTORY) != GT911_OK){
MMPrintString("e0\r\n");
}
else if (gt911_dev_mode_r(&read_data) != GT911_OK){
MMPrintString("e1\r\n");
} else {
PInt(read_data);PRet();
uSec(300000);
if (read_data != GT911_DEV_MODE_FACTORY)
{
// Return error to caller
MMPrintString("e3\r\n");
}
else {
read_data = 0x04U;
Write8Register16(gt911_addr, GT911_TD_STAT_REG, read_data);
if(mmI2Cvalue!=GT911_OK){
MMPrintString("e4\r\n");
}
else {
uint8_t end_calibration = 0U;
uSec(300000);
for (int nbr_attempt = 0; ((nbr_attempt < 100U) && (end_calibration == 0U)) ; nbr_attempt++)
{
if (gt911_dev_mode_r(&read_data) != GT911_OK)
{
MMPrintString("e5\r\n");
break;
}
if (read_data == GT911_DEV_MODE_WORKING)
{
// Auto Switch to GT911_DEV_MODE_WORKING : means calibration have ended
end_calibration = 1U; // exit for loop
}
uSec(300000);
}
}
}
}*/
} else {
if(!Option.TOUCH_CS) return;
GetTouchValue(CMD_PENIRQ_ON); // send the controller the command to turn on PenIRQ
TOUCH_GETIRQTRIS = 1;
GetTouchAxis(CMD_MEASURE_X);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// this function is only used in calibration
// it draws the target, waits for the touch to stabilise and returns the x and y in raw touch controller numbers (ie, not scaled)
void MIPS16 GetCalibration(int x, int y, int *xval, int *yval) {
int i, j;
#define TCAL_FONT 0x02
ClearScreen(BLACK);
GUIPrintString(HRes/2, VRes/2 - GetFontHeight(TCAL_FONT)/2, TCAL_FONT, JUSTIFY_CENTER, JUSTIFY_MIDDLE, 0, WHITE, BLACK, "Touch Target");
GUIPrintString(HRes/2, VRes/2 + GetFontHeight(TCAL_FONT)/2, TCAL_FONT, JUSTIFY_CENTER, JUSTIFY_MIDDLE, 0, WHITE, BLACK, "and Hold");
DrawLine(x - (TARGET_OFFSET * 3)/4, y, x + (TARGET_OFFSET * 3)/4, y, 1, WHITE);
DrawLine(x, y - (TARGET_OFFSET * 3)/4, x, y + (TARGET_OFFSET * 3)/4, 1, WHITE);
DrawCircle(x, y, TARGET_OFFSET/2, 1, WHITE, -1, 1);
if(!Option.TOUCH_CAP){
while(!TOUCH_DOWN) CheckAbort(); // wait for the touch
for(i = j = 0; i < 50; i++) { // throw away the first 50 reads as rubbish
GetTouchAxis(CMD_MEASURE_X); GetTouchAxis(CMD_MEASURE_Y);
}
// make a lot of readings and average them
for(i = j = 0; i < 50; i++) j += GetTouchAxis(CMD_MEASURE_X);
*xval = j/50;
for(i = j = 0; i < 50; i++) j += GetTouchAxis(CMD_MEASURE_Y);
*yval = j/50;
ClearScreen(BLACK);
while(TOUCH_DOWN) CheckAbort(); // wait for the touch to be lifted
uSec(25000);
} else {
while(!TOUCH_DOWN) CheckAbort(); // wait for the touch
uSec(100000);
// for(i = j = 0; i < 10; i++) { // throw away the first 50 reads as rubbish
// GetTouch(GET_X_AXIS); GetTouch(GET_Y_AXIS);
// }
// make a lot of readings and average them
for(i = j = 0; i < 5; i++) j += GetTouchAxisCap(GET_X_AXIS);
*xval = j/5;
for(i = j = 0; i < 5; i++) j += GetTouchAxisCap(GET_Y_AXIS);
*yval = j/5;
ClearScreen(BLACK);
while(TOUCH_DOWN) CheckAbort(); // wait for the touch to be lifted
// while(readRegister8(FT6X36_ADDR, FT6X36_REG_NUM_TOUCHES)) CheckAbort(); // wait for the touch to be lifted
uSec(25000);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// this is the main function to call to get a touch reading
// if y is true the y reading will be returned, otherwise the x reading
// this function does noise reduction and scales the reading to pixels
// a return of TOUCH_ERROR means that the pen is not down
int __not_in_flash_func(GetTouch)(int y) {
int i=TOUCH_ERROR;
// static int lastx, lasty;
TOUCH_GETIRQTRIS=0;
if(Option.TOUCH_CS == 0 && Option.TOUCH_IRQ ==0) error("Touch option not set");
if(!Option.TOUCH_XZERO && !Option.TOUCH_YZERO) error("Touch not calibrated");
if(PinRead(Option.TOUCH_IRQ)){ TOUCH_GETIRQTRIS=1 ; return TOUCH_ERROR;}
if(Option.TOUCH_CAP==1){
uint32_t in;
if(y>=10){
if(readRegister8(FT6X36_ADDR, FT6X36_REG_NUM_TOUCHES)!=2){ TOUCH_GETIRQTRIS=1 ; return TOUCH_ERROR;}
in=readRegister32(FT6X36_ADDR, FT6X36_REG_P2_XH);
y-=10;
} else in=readRegister32(FT6X36_ADDR, FT6X36_REG_P1_XH);
if(Option.TOUCH_SWAPXY)y=!y;
if(y){
i=(in & 0xF0000)>>8;
i |= (in>>24);
} else {
i=(in & 0xF)<<8;
i |= ((in>>8) & 0xFF);
}
if(Option.TOUCH_SWAPXY)y=!y;
if(y){
i=(MMFLOAT)(i-Option.TOUCH_YZERO) * Option.TOUCH_YSCALE;
} else {
i=(MMFLOAT)(i-Option.TOUCH_XZERO) * Option.TOUCH_XSCALE;
}
if(i < 0 || i >= (y ? VRes : HRes))i=TOUCH_ERROR;
} else {
if(y) {
i = ((MMFLOAT)(GetTouchAxis(Option.TOUCH_SWAPXY? CMD_MEASURE_X:CMD_MEASURE_Y) - Option.TOUCH_YZERO) * Option.TOUCH_YSCALE);
// if(i < lasty - CAL_ERROR_MARGIN || i > lasty + CAL_ERROR_MARGIN) { lasty = i; i = TOUCH_ERROR; }
} else {
i = ((MMFLOAT)(GetTouchAxis(Option.TOUCH_SWAPXY? CMD_MEASURE_Y:CMD_MEASURE_X) - Option.TOUCH_XZERO) * Option.TOUCH_XSCALE);
// if(i < lastx - CAL_ERROR_MARGIN || i > lastx + CAL_ERROR_MARGIN) { lastx = i; i = TOUCH_ERROR; }
}
if(i < 0 || i >= (y ? VRes : HRes))i=TOUCH_ERROR;
}
TOUCH_GETIRQTRIS=1;
return i;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// this will get a reading from a single axis
// the returned value is not scaled, it is the raw number produced by the touch controller
// it takes multiple readings, discards the outliers and returns the average of the medium values
int __not_in_flash_func(GetTouchAxis)(int cmd) {
int i, j, t, b[TOUCH_SAMPLES];
TOUCH_GETIRQTRIS=0;
PinSetBit(Option.TOUCH_IRQ, CNPDSET); // Set the PenIRQ to an output
#ifdef PICOMITE
if(SPIatRisk)mutex_enter_blocking(&frameBufferMutex); // lock the frame buffer
#endif
GetTouchValue(cmd);
// we take TOUCH_SAMPLES readings and sort them into descending order in buffer b[].
for(i = 0; i < TOUCH_SAMPLES; i++) {
b[i] = GetTouchValue(cmd); // get the value
if (CurrentlyPlaying == P_WAV || CurrentlyPlaying == P_FLAC || CurrentlyPlaying == P_MIDI || CurrentlyPlaying == P_MP3){
#ifdef PICOMITE
if(SPIatRisk)mutex_enter_blocking(&frameBufferMutex); // lock the frame buffer
#endif
checkWAVinput();
#ifdef PICOMITE
if(SPIatRisk)mutex_exit(&frameBufferMutex);
#endif
}
if(CurrentlyPlaying == P_MOD || CurrentlyPlaying == P_STREAM ) checkWAVinput();
for(j = i; j > 0; j--) { // and sort into position
if(b[j - 1] < b[j]) {
t = b[j - 1];
b[j - 1] = b[j];
b[j] = t;
}
else
break;
}
}
// we then discard the top TOUCH_DISCARD samples and the bottom TOUCH_DISCARD samples and add up the remainder
for(j = 0, i = TOUCH_DISCARD; i < TOUCH_SAMPLES - TOUCH_DISCARD; i++) j += b[i];
// and return the average
i = j / (TOUCH_SAMPLES - (TOUCH_DISCARD * 2));
GetTouchValue(CMD_PENIRQ_ON); // send the command to turn PenIRQ on
PinSetBit(Option.TOUCH_IRQ, CNPUSET); // Set the PenIRQ to an input
TOUCH_GETIRQTRIS=1;
#ifdef PICOMITE
if(SPIatRisk)mutex_exit(&frameBufferMutex);
#endif
return i;
}
int __not_in_flash_func(GetTouchAxisCap)(int y) {
uint32_t i,in;
TOUCH_GETIRQTRIS=0;
in=readRegister32(FT6X36_ADDR, FT6X36_REG_P1_XH);
if(y){
i=(in & 0xF0000)>>8;
i |= (in>>24);
} else {
i=(in & 0xF)<<8;
i |= ((in>>8) & 0xFF);
}
TOUCH_GETIRQTRIS=1;
return i;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// this will get a single reading from the touch controller
//
// it assumes that PenIRQ line has been pulled low and that the SPI baudrate is correct
// this takes 260uS at 120MHz
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int __not_in_flash_func(GetTouchValue)(int cmd) {
int val;
unsigned int lb, hb;
if(!SSDTYPE)SPISpeedSet(TOUCH);
else SPISpeedSet(SLOWTOUCH);
if(Option.CombinedCS){
gpio_put(TOUCH_CS_PIN,GPIO_PIN_SET);
gpio_set_dir(TOUCH_CS_PIN, GPIO_OUT);
} else gpio_put(TOUCH_CS_PIN,GPIO_PIN_RESET); // set CS low
TDelay();
val=xchg_byte(cmd); // SpiChnPutC(TOUCH_SPI_CHANNEL, cmd);
hb=xchg_byte(0); // send the read command (also selects the axis)
val = (hb & 0b1111111) << 5; // the top 7 bits
lb=xchg_byte(0); // send the read command (also selects the axis)
val |= (lb >> 3) & 0b11111; // the bottom 5 bits
if(Option.CombinedCS)gpio_set_dir(TOUCH_CS_PIN, GPIO_IN);
else ClearCS(Option.TOUCH_CS);
#ifdef PICOMITEWEB
ProcessWeb(1);
#endif
return val;
}
void __not_in_flash_func(TDelay)(void) // provides a small (~200ns) delay for the touch screen controller.
{
int ticks_per_millisecond=ticks_per_second/1000;
int T=16777215 + setuptime-((4*ticks_per_millisecond)/20000) ;
shortpause(T);
}
/* @endcond */
// the MMBasic TOUCH() function
void fun_touch(void) {
if(checkstring(ep, (unsigned char *)"X"))
iret = GetTouch(GET_X_AXIS);
else if(checkstring(ep, (unsigned char *)"Y"))
iret = GetTouch(GET_Y_AXIS);
else if(checkstring(ep, (unsigned char *)"DOWN"))
iret = TOUCH_DOWN;
else if(checkstring(ep, (unsigned char *)"UP"))
iret = !TOUCH_DOWN;
#ifdef GUICONTROLS
else if(checkstring(ep, (unsigned char *)"REF"))
iret = CurrentRef;
else if(checkstring(ep, (unsigned char *)"LASTREF"))
iret = LastRef;
else if(checkstring(ep, (unsigned char *)"LASTX"))
iret = LastX;
else if(checkstring(ep, (unsigned char *)"LASTY"))
iret = LastY;
#endif
else {
if(Option.TOUCH_CAP){
if(checkstring(ep, (unsigned char *)"X2"))
iret = GetTouch(GET_X_AXIS2);
else if(checkstring(ep, (unsigned char *)"Y2"))
iret = GetTouch(GET_Y_AXIS2);
// else if(checkstring(ep, (unsigned char *)"GESTURE"))
// iret = readRegister8(FT6X36_ADDR, FT6X36_REG_GESTURE_ID);
else error("Invalid argument");
} else error("Invalid argument");
}
targ = T_INT;
}

View File

@ -0,0 +1,533 @@
/**
* @cond
* The following section will be excluded from the documentation.
*/
/***********************************************************************************************************************
PicoMite MMBasic
Touch.h
<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.
************************************************************************************************************************/
/**********************************************************************************
the C language function associated with commands, functions or operators should be
declared here
**********************************************************************************/
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
void fun_touch(void);
#endif
/**********************************************************************************
All command tokens tokens (eg, PRINT, FOR, etc) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_COMMAND_TABLE
#endif
/**********************************************************************************
All other tokens (keywords, functions, operators) should be inserted in this table
**********************************************************************************/
#ifdef INCLUDE_TOKEN_TABLE
#endif
#if !defined(INCLUDE_COMMAND_TABLE) && !defined(INCLUDE_TOKEN_TABLE)
#define CAL_ERROR_MARGIN 16
#define TARGET_OFFSET 30
#define TOUCH_SAMPLES 8
#define TOUCH_DISCARD 2
#define GET_X_AXIS 0
#define GET_Y_AXIS 1
#define GET_X_AXIS2 0x10
#define GET_Y_AXIS2 0x11
#define PENIRQ_ON 3
#define TOUCH_NOT_CALIBRATED -999999
#define TOUCH_ERROR -1
#define CMD_MEASURE_X 0b10010000
#define CMD_MEASURE_Y 0b11010000
#define CMD_PENIRQ_ON 0b10010000
extern void ConfigTouch(unsigned char *p);
extern void InitTouch(void);
extern void GetCalibration(int x, int y, int *xval, int *yval);
// extern volatile int TouchX, TouchY;
extern volatile bool TouchState, TouchDown, TouchUp;
extern int TOUCH_GETIRQTRIS;
#define TOUCH_ERROR -1
// these are defined so that the state of the touch PEN IRQ can be determined with the minimum of CPU cycles
extern volatile unsigned int TouchIrqPortAddr;
extern int TouchIrqPortBit;
#define TOUCH_DOWN (!(PinRead(Option.TOUCH_IRQ)))
extern int GetTouchValue(int cmd);
extern int TOUCH_IRQ_PIN;
extern int TOUCH_CS_PIN;
extern int TOUCH_Click_PIN;
extern int GetTouch(int x);
extern int GetTouchAxis(int);
extern int GetTouchAxisCap(int);
#define FT6X36_ADDR 0x38
#define FT6X36_REG_DEVICE_MODE 0x00
#define FT6X36_REG_GESTURE_ID 0x01
#define FT6X36_REG_NUM_TOUCHES 0x02
#define FT6X36_REG_P1_XH 0x03
#define FT6X36_REG_P1_XL 0x04
#define FT6X36_REG_P1_YH 0x05
#define FT6X36_REG_P1_YL 0x06
#define FT6X36_REG_P1_WEIGHT 0x07
#define FT6X36_REG_P1_MISC 0x08
#define FT6X36_REG_P2_XH 0x09
#define FT6X36_REG_P2_XL 0x0A
#define FT6X36_REG_P2_YH 0x0B
#define FT6X36_REG_P2_YL 0x0C
#define FT6X36_REG_P2_WEIGHT 0x0D
#define FT6X36_REG_P2_MISC 0x0E
#define FT6X36_REG_THRESHHOLD 0x80
#define FT6X36_REG_FILTER_COEF 0x85
#define FT6X36_REG_CTRL 0x86
#define FT6X36_REG_TIME_ENTER_MONITOR 0x87
#define FT6X36_REG_TOUCHRATE_ACTIVE 0x88
#define FT6X36_REG_TOUCHRATE_MONITOR 0x89 // value in ms
#define FT6X36_REG_RADIAN_VALUE 0x91
#define FT6X36_REG_OFFSET_LEFT_RIGHT 0x92
#define FT6X36_REG_OFFSET_UP_DOWN 0x93
#define FT6X36_REG_DISTANCE_LEFT_RIGHT 0x94
#define FT6X36_REG_DISTANCE_UP_DOWN 0x95
#define FT6X36_REG_DISTANCE_ZOOM 0x96
#define FT6X36_REG_LIB_VERSION_H 0xA1
#define FT6X36_REG_LIB_VERSION_L 0xA2
#define FT6X36_REG_CHIPID 0xA3
#define FT6X36_REG_INTERRUPT_MODE 0xA4
#define FT6X36_REG_POWER_MODE 0xA5
#define FT6X36_REG_FIRMWARE_VERSION 0xA6
#define FT6X36_REG_PANEL_ID 0xA8
#define FT6X36_REG_STATE 0xBC
#define FT6X36_PMODE_ACTIVE 0x00
#define FT6X36_PMODE_MONITOR 0x01
#define FT6X36_PMODE_STANDBY 0x02
#define FT6X36_PMODE_HIBERNATE 0x03
#define FT6X36_VENDID 0x11
#define FT6206_CHIPID 0x06
#define FT6236_CHIPID 0x36
#define FT6336_CHIPID 0x64
#define FT6X36_DEFAULT_THRESHOLD 22
#define CAP_RESET Option.TOUCH_CS
#define GT911_ADDR 0x14
#define GT911_ADDR2 0x5D
#define GT911_DEV_MODE_BIT_MASK 0x70U
#define GT911_DEV_MODE_BIT_POSITION 4U
#define GT911_GEST_ID_BIT_MASK 0xFFU
#define GT911_GEST_ID_BIT_POSITION 0U
#define GT911_TD_STATUS_BIT_BUFFER_STAT 0x80U
#define GT911_TD_STATUS_BIT_HAVEKEY 0x10U
#define GT911_TD_STATUS_BITS_NBTOUCHPTS 0x0FU
//JCC adding END
#define GT911_TD_STATUS_BIT_MASK 0x07U
#define GT911_TD_STATUS_BIT_POSITION 0U
#define GT911_MAX_X_LENGTH HRes
#define GT911_MAX_Y_LENGTH VRes
#define GT911_P1_XH_EF_BIT_MASK 0xC0U
#define GT911_P1_XH_EF_BIT_POSITION 6U
#define GT911_P1_XL_TP_BIT_MASK 0xFFU
#define GT911_P1_XL_TP_BIT_POSITION 0U
#define GT911_P1_TID_BIT_MASK 0xFFU
#define GT911_P1_TID_BIT_POSITION 7U
/* Current mode register of the GT911 (R/W) */
/* Gesture ID register */
#define GT911_GEST_ID_REG 0x814BU
/* Gesture mode enabled */
#define GT911_GESTURE_EN 0x8U
/* Gesture Coordinates registers */
#define GT911_START_X_L 0x814DU
#define GT911_START_X_H 0x814EU
#define GT911_START_Y_L 0x814FU
#define GT911_START_Y_H 0x8150U
#define GT911_END_X_L 0x8151U
#define GT911_END_X_H 0x8152U
#define GT911_END_Y_L 0x8153U
#define GT911_END_Y_H 0x8154U
#define GT911_WEIGHT_L 0x8155U
#define GT911_WEIGHT_H 0x8156U
#define GT911_HEIGHT_L 0x8157U
#define GT911_HEIGHT_H 0x8158U
/* Touch Data Status register : gives number of active touch points (0..5) */
#define GT911_TD_STAT_REG 0x814EU
/* P1 X, Y coordinates, weight(Point size) and track-id registers */
#define GT911_P1_XL_REG 0x8150U
#define GT911_P1_XH_REG 0x8151U
#define GT911_P1_YL_REG 0x8152U
#define GT911_P1_YH_REG 0x8153U
#define GT911_P1_WEIGHTL_REG 0x8154U
#define GT911_P1_WEIGHTH_REG 0x8155U
#define GT911_P1_TID_REG 0x8157U
/* P2 X, Y coordinates, weight and tid registers */
#define GT911_P2_XL_REG 0x8158U
#define GT911_P2_XH_REG 0x8159U
#define GT911_P2_YL_REG 0x815AU
#define GT911_P2_YH_REG 0x815BU
#define GT911_P2_WEIGHTL_REG 0x815CU
#define GT911_P2_WEIGHTH_REG 0x815DU
#define GT911_P2_TID_REG 0x815FU
/* P3 X, Y coordinates, weight and tid registers */
#define GT911_P3_XL_REG 0x8160U
#define GT911_P3_XH_REG 0x8161U
#define GT911_P3_YL_REG 0x8162U
#define GT911_P3_YH_REG 0x8163U
#define GT911_P3_WEIGHTL_REG 0x8164U
#define GT911_P3_WEIGHTH_REG 0x8165U
#define GT911_P3_TID_REG 0x8167U
/* P4 X, Y coordinates, weight and tid registers */
#define GT911_P4_XL_REG 0x8168U
#define GT911_P4_XH_REG 0x8169U
#define GT911_P4_YL_REG 0x816AU
#define GT911_P4_YH_REG 0x816BU
#define GT911_P4_WEIGHTL_REG 0x816CU
#define GT911_P4_WEIGHTH_REG 0x816DU
#define GT911_P4_TID_REG 0x816FU
/* P5 X, Y coordinates, weight and tid registers */
#define GT911_P5_XL_REG 0x8170U
#define GT911_P5_XH_REG 0x8171U
#define GT911_P5_YL_REG 0x8172U
#define GT911_P5_YH_REG 0x8173U
#define GT911_P5_WEIGHTL_REG 0x8174U
#define GT911_P5_WEIGHTH_REG 0x8175U
#define GT911_P5_TID_REG 0x8177U
/* Threshold for touch detection */
#define GT911_TH_GROUP_REG 0x80U
/* Filter function coefficients */
#define GT911_TH_DIFF_REG 0x85U
/* Control register */
#define GT911_CTRL_REG 0x86U
/* The time period of switching from Active mode to Monitor mode when there is no touching */
#define GT911_TIMEENTERMONITOR_REG 0x87U
/* Report rate in Active mode */
#define GT911_PERIODACTIVE_REG 0x88U
/* Report rate in Monitor mode */
#define GT911_PERIODMONITOR_REG 0x89U
/* Maximum offset while Moving Left and Moving Right gesture */
#define GT911_OFFSET_LR_REG 0x92U
/* Maximum offset while Moving Up and Moving Down gesture */
#define GT911_OFFSET_UD_REG 0x93U
/* Minimum distance while moving gesture */
#define GT911_DIS_GESTURE_REG 0x8071U
/* High 8-bit of LIB Version info */
#define GT911_LIB_VER_H_REG 0xA1U
/* Low 8-bit of LIB Version info */
#define GT911_LIB_VER_L_REG 0xA2U
/* Chip Selecting */
#define GT911_CIPHER_REG 0xA3U
/* Module_Switch1 register for Interrupt */
#define GT911_MSW1_REG 0x804DU
/* Current power mode the GT911 system is in (R) */
#define GT911_PWR_MODE_REG 0xA5U
/* GT911 firmware version */
#define GT911_FIRMID_REG 0x8144U
/* GT911 Chip identification register */
#define GT911_CHIP_ID_REG 0x8140U
/* Release code version */
#define GT911_RELEASE_CODE_ID_REG 0xAFU
/* Current operating mode the GT911 system is in (R) */
#define GT911_COMMAND_REG 0x8040U
/* Coordinates report rate (= 5+N ms) */
#define GT911_REFRESH_RATE_REG 0x8056U
#define GT911_REFRESH_RATE_MSK 0x0FU
/* Version number configuration */
#define GT911_CONFIG_VERS_REG 0x8047U
/* Checksum configuration register */
#define GT911_CONFIG_CHKSUM_REG 0x80FFU
/* Configuration update flag register */
#define GT911_CONFIG_FRESH_REG 0x8100U
/* Command check register */
#define GT911_COMMAND_CHK_REG 0x8046U
/* Gesture configuration registers */
#define GT911_GESTURE_PRESS_TIME 0x8072U
#define GT911_GESTURE_TIME_ABORT 0x00U
#define GT911_GESTURE_SLOPE_ADJUST 0x8073U
#define GT911_GESTURE_ADJUST_VAL 0x00U
#define GT911_GESTURE_CTRL_REG 0x8074U
#define GT911_GESTURE_INVALID_TIM 0x0FU
#define GT911_GESTURE_SWITCH1_REG 0x8075U
#define GT911_GESTURE_SWITCH2_REG 0x8076U
#define GT911_GESTURE_SWITCH1_VAL 0x00U
#define GT911_GESTURE_SWITCH2_VAL 0x00U
#define GT911_GESTURE_REFRESH_REG 0x8077U
#define GT911_GESTURE_TH_REG 0x8078U
#define GT911_OK (0)
#define GT911_ERROR (-1)
/* Max detectable simultaneous touches */
#define GT911_MAX_NB_TOUCH 5U
/* Touch GT911 IDs: "911" */
#define GT911_ID 0x00313139U
#define GT911_ID1 0x39U
#define GT911_ID2 0x31U
#define GT911_ID3 0x31U
/* Possible values of GT911_DEV_MODE_REG */
#define GT911_DEV_MODE_WORKING 0x00U
#define GT911_DEV_MODE_FACTORY 0x04U
/* Possible values of GT911_GEST_ID_REG */
#define GT911_GEST_ID_NO_GESTURE 0x00U
#define GT911_GEST_ID_SWIPE_RIGHT 0xAAU
#define GT911_GEST_ID_SWIPE_LEFT 0xBBU
#define GT911_GEST_ID_SWIPE_DOWN 0xABU
#define GT911_GEST_ID_SWIPE_UP 0xBAU
#define GT911_GEST_ID_DOUBLE_TAP 0xCCU
/* Values Pn_XH and Pn_YH related */
#define GT911_TOUCH_EVT_FLAG_PRESS_DOWN 0x00U
#define GT911_TOUCH_EVT_FLAG_LIFT_UP 0x01U
#define GT911_TOUCH_EVT_FLAG_CONTACT 0x02U
#define GT911_TOUCH_EVT_FLAG_NO_EVENT 0x03U
/* Possible values of GT911_MSW1_REG(Module_Switch1) */
#define GT911_M_SW1_INTERRUPT_RISING 0x00U
#define GT911_M_SW1_INTERRUPT_FALLING 0x01U
#define GT911_M_SW1_INTERRUPT_LOW 0x02U
#define GT911_M_SW1_INTERRUPT_HIGH 0x03U
/* Mask for reading the MSW1 register without INT trigger */
#define GT911_M_SW1_DATA_MASK 0xFCU
/* Current mode register of the GT911 (R/W) */
#define GT911_DEV_MODE_REG 0x8040U
/* Gesture ID register */
#define GT911_GEST_ID_REG 0x814BU
/* Gesture mode enabled */
#define GT911_GESTURE_EN 0x8U
/* Gesture Coordinates registers */
#define GT911_START_X_L 0x814DU
#define GT911_START_X_H 0x814EU
#define GT911_START_Y_L 0x814FU
#define GT911_START_Y_H 0x8150U
#define GT911_END_X_L 0x8151U
#define GT911_END_X_H 0x8152U
#define GT911_END_Y_L 0x8153U
#define GT911_END_Y_H 0x8154U
#define GT911_WEIGHT_L 0x8155U
#define GT911_WEIGHT_H 0x8156U
#define GT911_HEIGHT_L 0x8157U
#define GT911_HEIGHT_H 0x8158U
/* Touch Data Status register : gives number of active touch points (0..5) */
#define GT911_TD_STAT_REG 0x814EU
/* P1 X, Y coordinates, weight(Point size) and track-id registers */
#define GT911_P1_XL_REG 0x8150U
#define GT911_P1_XH_REG 0x8151U
#define GT911_P1_YL_REG 0x8152U
#define GT911_P1_YH_REG 0x8153U
#define GT911_P1_WEIGHTL_REG 0x8154U
#define GT911_P1_WEIGHTH_REG 0x8155U
#define GT911_P1_TID_REG 0x8157U
/* P2 X, Y coordinates, weight and tid registers */
#define GT911_P2_XL_REG 0x8158U
#define GT911_P2_XH_REG 0x8159U
#define GT911_P2_YL_REG 0x815AU
#define GT911_P2_YH_REG 0x815BU
#define GT911_P2_WEIGHTL_REG 0x815CU
#define GT911_P2_WEIGHTH_REG 0x815DU
#define GT911_P2_TID_REG 0x815FU
/* P3 X, Y coordinates, weight and tid registers */
#define GT911_P3_XL_REG 0x8160U
#define GT911_P3_XH_REG 0x8161U
#define GT911_P3_YL_REG 0x8162U
#define GT911_P3_YH_REG 0x8163U
#define GT911_P3_WEIGHTL_REG 0x8164U
#define GT911_P3_WEIGHTH_REG 0x8165U
#define GT911_P3_TID_REG 0x8167U
/* P4 X, Y coordinates, weight and tid registers */
#define GT911_P4_XL_REG 0x8168U
#define GT911_P4_XH_REG 0x8169U
#define GT911_P4_YL_REG 0x816AU
#define GT911_P4_YH_REG 0x816BU
#define GT911_P4_WEIGHTL_REG 0x816CU
#define GT911_P4_WEIGHTH_REG 0x816DU
#define GT911_P4_TID_REG 0x816FU
/* P5 X, Y coordinates, weight and tid registers */
#define GT911_P5_XL_REG 0x8170U
#define GT911_P5_XH_REG 0x8171U
#define GT911_P5_YL_REG 0x8172U
#define GT911_P5_YH_REG 0x8173U
#define GT911_P5_WEIGHTL_REG 0x8174U
#define GT911_P5_WEIGHTH_REG 0x8175U
#define GT911_P5_TID_REG 0x8177U
/* Threshold for touch detection */
#define GT911_TH_GROUP_REG 0x80U
/* Filter function coefficients */
#define GT911_TH_DIFF_REG 0x85U
/* Control register */
#define GT911_CTRL_REG 0x86U
/* The time period of switching from Active mode to Monitor mode when there is no touching */
#define GT911_TIMEENTERMONITOR_REG 0x87U
/* Report rate in Active mode */
#define GT911_PERIODACTIVE_REG 0x88U
/* Report rate in Monitor mode */
#define GT911_PERIODMONITOR_REG 0x89U
/* Maximum offset while Moving Left and Moving Right gesture */
#define GT911_OFFSET_LR_REG 0x92U
/* Maximum offset while Moving Up and Moving Down gesture */
#define GT911_OFFSET_UD_REG 0x93U
/* Minimum distance while moving gesture */
#define GT911_DIS_GESTURE_REG 0x8071U
/* High 8-bit of LIB Version info */
#define GT911_LIB_VER_H_REG 0xA1U
/* Low 8-bit of LIB Version info */
#define GT911_LIB_VER_L_REG 0xA2U
/* Chip Selecting */
#define GT911_CIPHER_REG 0xA3U
/* Module_Switch1 register for Interrupt */
#define GT911_MSW1_REG 0x804DU
/* Current power mode the GT911 system is in (R) */
#define GT911_PWR_MODE_REG 0xA5U
/* GT911 firmware version */
#define GT911_FIRMID_REG 0x8144U
/* GT911 Chip identification register */
#define GT911_CHIP_ID_REG 0x8140U
/* Release code version */
#define GT911_RELEASE_CODE_ID_REG 0xAFU
/* Current operating mode the GT911 system is in (R) */
#define GT911_COMMAND_REG 0x8040U
/* Coordinates report rate (= 5+N ms) */
#define GT911_REFRESH_RATE_REG 0x8056U
#define GT911_REFRESH_RATE_MSK 0x0FU
/* Version number configuration */
#define GT911_CONFIG_VERS_REG 0x8047U
/* Checksum configuration register */
#define GT911_CONFIG_CHKSUM_REG 0x80FFU
/* Configuration update flag register */
#define GT911_CONFIG_FRESH_REG 0x8100U
/* Command check register */
#define GT911_COMMAND_CHK_REG 0x8046U
/* Gesture configuration registers */
#define GT911_GESTURE_PRESS_TIME 0x8072U
#define GT911_GESTURE_TIME_ABORT 0x00U
#define GT911_GESTURE_SLOPE_ADJUST 0x8073U
#define GT911_GESTURE_ADJUST_VAL 0x00U
#define GT911_GESTURE_CTRL_REG 0x8074U
#define GT911_GESTURE_INVALID_TIM 0x0FU
#define GT911_GESTURE_SWITCH1_REG 0x8075U
#define GT911_GESTURE_SWITCH2_REG 0x8076U
#define GT911_GESTURE_SWITCH1_VAL 0x00U
#define GT911_GESTURE_SWITCH2_VAL 0x00U
#define GT911_GESTURE_REFRESH_REG 0x8077U
#define GT911_GESTURE_TH_REG 0x8078U
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,700 @@
/**
* This is a driver library for VS1053 MP3 Codec Breakout
* (Ogg Vorbis / MP3 / AAC / WMA / FLAC / MIDI Audio Codec Chip).
* Adapted for Espressif ESP8266 and ESP32 boards.
*
* version 1.0.1
*
* Licensed under GNU GPLv3 <http://gplv3.fsf.org/>
* Copyright © 2018
*
* @authors baldram, edzelf, MagicCube, maniacbug
*
* Development log:
* - 2011: initial VS1053 Arduino library
* originally written by J. Coliz (github: @maniacbug),
* - 2016: refactored and integrated into Esp-radio sketch
* by Ed Smallenburg (github: @edzelf)
* - 2017: refactored to use as PlatformIO library
* by Marcin Szalomski (github: @baldram | twitter: @baldram)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License or later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
#include "VS1053.h"
#include "vs1053b-patches.h"
#define LOG(...)
extern void __not_in_flash_func(spi_write_fast)(spi_inst_t *spi, const uint8_t *src, size_t len);
extern void __not_in_flash_func(spi_finish)(spi_inst_t *spi);
//#define LOG printf
#define _BV( bit ) ( 1<<(bit) )
uint8_t cs_pin; // Pin where CS line is connected
uint8_t dcs_pin; // Pin where DCS line is connected
uint8_t dreq_pin; // Pin where DREQ line is connected
uint8_t reset_pin; // Pin where DREQ line is connected
uint8_t curvol; // Current volume setting 0..100%
int8_t curbalance = 0; // Current balance setting -100..100
uint8_t endFillByte; // Byte to send when stopping song
const uint8_t vs1053_chunk_size = 32;
// SCI Register
const uint8_t SCI_MODE = 0x0;
const uint8_t SCI_STATUS = 0x1;
const uint8_t SCI_BASS = 0x2;
const uint8_t SCI_CLOCKF = 0x3;
const uint8_t SCI_DECODE_TIME = 0x4; // current decoded time in full seconds
const uint8_t SCI_AUDATA = 0x5;
const uint8_t SCI_WRAM = 0x6;
const uint8_t SCI_WRAMADDR = 0x7;
const uint8_t SCI_AIADDR = 0xA;
const uint8_t SCI_VOL = 0xB;
const uint8_t SCI_AICTRL0 = 0xC;
const uint8_t SCI_AICTRL1 = 0xD;
const uint8_t SCI_num_registers = 0xF;
// SCI_MODE bits
const uint8_t SM_SDINEW = 11; // Bitnumber in SCI_MODE always on
const uint8_t SM_RESET = 2; // Bitnumber in SCI_MODE soft reset
const uint8_t SM_CANCEL = 3; // Bitnumber in SCI_MODE cancel song
const uint8_t SM_TESTS = 5; // Bitnumber in SCI_MODE for tests
const uint8_t SM_LINE1 = 14; // Bitnumber in SCI_MODE for Line input
const uint8_t SM_STREAM = 6; // Bitnumber in SCI_MODE for Streaming Mode
const uint8_t SM_LAYER12 = 1;
const uint16_t ADDR_REG_GPIO_DDR_RW = 0xc017;
const uint16_t ADDR_REG_GPIO_VAL_R = 0xc018;
const uint16_t ADDR_REG_GPIO_ODATA_RW = 0xc019;
const uint16_t ADDR_REG_I2S_CONFIG_RW = 0xc040;
#define xmit_multi(a,b) spi_write_blocking((AUDIO_SPI==1 ? spi0 : spi1),a,b);
static BYTE __not_in_flash_func(xchg)(BYTE data_out){
BYTE data_in=0;
spi_write_read_blocking((AUDIO_SPI==1 ? spi0 : spi1),&data_out,&data_in,1);
return data_in;
}
uint8_t stdmax(int a, int b){
if(a>b)return a;
return b;
}
int stdmap(int v){
v=(v*80)/100;
if(v==0)return 0xFE;
else return 100-v;
}
void await_data_request() {
while (!(gpio_get(dreq_pin))) {
}
}
void control_mode_on() {
gpio_put(dcs_pin,GPIO_PIN_SET);
gpio_put(cs_pin,GPIO_PIN_RESET);
}
void control_mode_off() {
gpio_put(cs_pin,GPIO_PIN_SET);
}
void __not_in_flash_func(data_mode_on()) {
gpio_put(cs_pin,GPIO_PIN_SET);
gpio_put(dcs_pin,GPIO_PIN_RESET);
}
void __not_in_flash_func(data_mode_off()) {
gpio_put(dcs_pin,GPIO_PIN_SET);
}
bool data_request() {
return (gpio_get(dreq_pin) == 1);
}
uint16_t read_register(uint8_t _reg){
uint16_t result;
control_mode_on();
xchg(3);
xchg(_reg);
// Note: transfer16 does not seem to work
result = (xchg(0xFF) << 8) | // Read 16 bits data
(xchg(0xFF));
await_data_request(); // Wait for DREQ to be HIGH again
control_mode_off();
return result;
}
void writeRegister(uint8_t _reg, uint16_t _value){
control_mode_on();
xchg(2); // Write operation
xchg(_reg); // Register to write (0..0xF)
xchg(_value>>8);
xchg(_value & 0xFF);
// SPI.write16(_value); // Send 16 bits data
await_data_request();
control_mode_off();
}
void __not_in_flash_func(sdi_send_buffer)(uint8_t *data, size_t len) {
size_t chunk_length; // Length of chunk 32 byte or shorter
gpio_put(cs_pin,GPIO_PIN_SET);
gpio_put(dcs_pin,GPIO_PIN_RESET);
while (len) // More to do?
{
while (!(gpio_get(dreq_pin))) {
}
chunk_length = len;
if (len > vs1053_chunk_size) {
chunk_length = vs1053_chunk_size;
}
len -= chunk_length;
if(PinDef[Option.AUDIO_CLK_PIN].mode & SPI0SCK)spi_write_fast(spi0, data, chunk_length);
else spi_write_fast(spi1, data, chunk_length);
// xmit_multi(data, chunk_length);
data += chunk_length;
}
if(PinDef[Option.AUDIO_CLK_PIN].mode & SPI0SCK)spi_finish(spi0);
else spi_finish(spi1);
gpio_put(dcs_pin,GPIO_PIN_SET);
}
void sdi_send_fillers(size_t len) {
size_t chunk_length; // Length of chunk 32 byte or shorter
data_mode_on();
while (len) // More to do?
{
await_data_request(); // Wait for space available
chunk_length = len;
if (len > vs1053_chunk_size) {
chunk_length = vs1053_chunk_size;
}
len -= chunk_length;
while (chunk_length--) {
xchg(endFillByte);
}
}
data_mode_off();
}
void wram_write(uint16_t address, uint16_t data) {
writeRegister(SCI_WRAMADDR, address);
writeRegister(SCI_WRAM, data);
}
uint16_t wram_read(uint16_t address) {
writeRegister(SCI_WRAMADDR, address); // Start reading from WRAM
return read_register(SCI_WRAM); // Read back result
}
uint16_t VS1053free(void){
uint16_t wrp, rdp; // VS1053b read and write pointers
writeRegister(SCI_WRAMADDR, 0x5A7D); // Start reading from WRAM
wrp = read_register(SCI_WRAM);
rdp = read_register(SCI_WRAM);
return (wrp-rdp) & 1023;
}
bool testComm(const char *header) {
// Test the communication with the VS1053 module. The result wille be returned.
// If DREQ is low, there is problably no VS1053 connected. Pull the line HIGH
// in order to prevent an endless loop waiting for this signal. The rest of the
// software will still work, but readbacks from VS1053 will fail.
int i; // Loop control
uint16_t r1, r2, cnt = 0;
uint16_t delta = 300; // 3 for fast SPI
uSec(20000);
if (!gpio_get(dreq_pin)) {
error("VS1053 not properly installed!");
// Allow testing without the VS1053 module
// pinMode(dreq_pin, INPUT_PULLUP); // DREQ is now input with pull-up
return false; // Return bad result
}
// Further TESTING. Check if SCI bus can write and read without errors.
// We will use the volume setting for this.
// Will give warnings on serial output if DEBUG is active.
// A maximum of 20 errors will be reported.
if (strstr(header, "Fast")) {
delta = 30; // Fast SPI, more loops
}
LOG("%s", header); // Show a header
for (i = 0; (i < 0xFFFF) && (cnt < 20); i += delta) {
writeRegister(SCI_VOL, i); // Write data to SCI_VOL
r1 = read_register(SCI_VOL); // Read back for the first time
r2 = read_register(SCI_VOL); // Read back a second time
if (r1 != r2 || i != r1 || i != r2) // Check for 2 equal reads
{
error("VS1053 read failure");
cnt++;
uSec(10000);
}
}
return (cnt == 0); // Return the result
}
void VS1053reset(uint8_t _reset_pin){
reset_pin=_reset_pin;
PinSetBit(PINMAP[reset_pin],LATCLR);
uSec(20000);
PinSetBit(PINMAP[reset_pin],LATSET);
PinSetBit(PINMAP[dreq_pin],CNPUSET);
uSec(100000);
}
void VS1053(uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t _reset_pin){
dreq_pin=_dreq_pin;
cs_pin=_cs_pin;
dcs_pin=_dcs_pin;
reset_pin=_reset_pin;
PinSetBit(PINMAP[reset_pin],LATCLR);
uSec(20000);
PinSetBit(PINMAP[reset_pin],LATSET);
PinSetBit(PINMAP[dreq_pin],CNPUSET);
uSec(100000);
LOG("\r\n");
LOG("Reset VS1053...\r\n");
LOG("End reset VS1053...\r\n");
// gpio_put(cs_pin,GPIO_PIN_SET); // Back to normal again
// gpio_put(dcs_pin,GPIO_PIN_SET);
// uSec(500000);
// Init SPI in slow mode ( 0.2 MHz )
// SET_SPI_CLK(display_details[device].speed, display_details[device].CPOL, display_details[device].CPHASE);
spi_init((AUDIO_SPI==1 ? spi0 : spi1), 8000);
spi_set_format((AUDIO_SPI==1 ? spi0 : spi1), 8, 0,0, SPI_MSB_FIRST);
// printDetails("Right after reset/startup");
uSec(20000);
// printDetails("20 msec after reset");
if (testComm("Slow SPI,Testing VS1053 read/write registers...\r\n")) {
//softReset();
// Switch on the analog parts
writeRegister(SCI_AUDATA, 44101); // 44.1kHz stereo
// The next clocksetting allows SPI clocking at 5 MHz, 4 MHz is safe then.
writeRegister(SCI_CLOCKF, 0xE000); // Normal clock settings multiplyer 3.0 = 12.2 MHz
// SPI Clock to 4 MHz. Now you can set high speed SPI clock.
spi_init((AUDIO_SPI==1 ? spi0 : spi1), 5400000);
// PInt(spi_get_baudrate(AUDIO_SPI==1 ? spi0 : spi1));PRet();
spi_set_format((AUDIO_SPI==1 ? spi0 : spi1), 8, 0,0, SPI_MSB_FIRST);
uSec(5000);
writeRegister(SCI_MODE, _BV(SM_SDINEW) | _BV(SM_LINE1) | _BV(SM_LAYER12));
testComm("Fast SPI, Testing VS1053 read/write registers again...\r\n");
uSec(5000);
await_data_request();
endFillByte = wram_read(0x1E06) & 0xFF;
LOG("endFillByte is %X\r\n", endFillByte);
//printDetails("After last clocksetting") ;
uSec(5000);
}
}
void setVolume(uint8_t vol) {
// Set volume. Both left and right.
// Input value is 0..100. 100 is the loudest.
uint8_t valueL, valueR; // Values to send to SCI_VOL
curvol = vol; // Save for later use
valueL = vol;
valueR = vol;
if (curbalance < 0) {
valueR = stdmax(0, vol + curbalance);
} else if (curbalance > 0) {
valueL = stdmax(0, vol - curbalance);
}
valueL = stdmap(valueL); // 0..100% to left channel
valueR = stdmap(valueR); // 0..100% to right channel
writeRegister(SCI_VOL, (valueL << 8) | valueR); // Volume left and right
}
void setVolumes(int valueL, int valueR) {
valueL = stdmap(valueL); // 0..100% to left channel
valueR = stdmap(valueR); // 0..100% to right channel
int value=((valueL << 8) | valueR);
writeRegister(SCI_VOL, value); // Volume left and right
}
void setBalance(int8_t balance) {
if (balance > 100) {
curbalance = 100;
} else if (balance < -100) {
curbalance = -100;
} else {
curbalance = balance;
}
}
void setTone(uint8_t *rtone) { // Set bass/treble (4 nibbles)
// Set tone characteristics. See documentation for the 4 nibbles.
uint16_t value = 0; // Value to send to SCI_BASS
int i; // Loop control
for (i = 0; i < 4; i++) {
value = (value << 4) | rtone[i]; // Shift next nibble in
}
writeRegister(SCI_BASS, value); // Volume left and right
}
uint8_t getVolume() { // Get the currenet volume setting.
return curvol;
}
int8_t getBalance() { // Get the currenet balance setting.
return curbalance;
}
void startSong() {
sdi_send_fillers(10);
}
void __not_in_flash_func(playChunk)(uint8_t *data, size_t len) {
sdi_send_buffer(data, len);
}
void stopSong() {
uint16_t modereg; // Read from mode register
int i; // Loop control
sdi_send_fillers(2052);
uSec(10000);
writeRegister(SCI_MODE, _BV(SM_SDINEW) | _BV(SM_CANCEL));
for (i = 0; i < 200; i++) {
sdi_send_fillers(32);
modereg = read_register(SCI_MODE); // Read status
if ((modereg & _BV(SM_CANCEL)) == 0) {
sdi_send_fillers(2052);
LOG("Song stopped correctly after %d msec\r\n", i * 10);
return;
}
uSec(10000);
}
printDetails("Song stopped incorrectly!");
}
void LoadUserCode(void) {
int i;
for (i=0;i<CODE_SIZE;i++) {
writeRegister(atab[i], dtab[i]);
}
}
void softReset() {
LOG("Performing soft-reset\r\n");
writeRegister(SCI_MODE, _BV(SM_SDINEW) | _BV(SM_RESET | _BV(SM_LAYER12)));
uSec(10000);
await_data_request();
}
/**
* VLSI datasheet: "SM_STREAM activates VS1053bs stream mode. In this mode, data should be sent with as
* even intervals as possible and preferable in blocks of less than 512 bytes, and VS1053b makes
* every attempt to keep its input buffer half full by changing its playback speed up to 5%. For best
* quality sound, the average speed error should be within 0.5%, the bitrate should not exceed
* 160 kbit/s and VBR should not be used. For details, see Application Notes for VS10XX. This
* mode only works with MP3 and WAV files."
*/
void streamModeOn() {
LOG("Performing streamModeOn\r\n");
writeRegister(SCI_MODE, _BV(SM_SDINEW) | _BV(SM_STREAM));
uSec(10000);
await_data_request();
}
void streamModeOff() {
LOG("Performing streamModeOff\r\n");
writeRegister(SCI_MODE, _BV(SM_SDINEW));
uSec(10000);
await_data_request();
}
void printDetails(const char *header) {
uint16_t regbuf[16];
uint8_t i;
(void)regbuf;
LOG("%s", header);
LOG("REG Contents\r\n");
LOG("--- -----\r\n");
for (i = 0; i <= SCI_num_registers; i++) {
regbuf[i] = read_register(i);
}
for (i = 0; i <= SCI_num_registers; i++) {
uSec(5000);
LOG("%3X - %5X\r\n", i, regbuf[i]);
}
}
/**
* An optional switch.
* Most VS1053 modules will start up in MIDI mode. The result is that there is no audio when playing MP3.
* You can modify the board, but there is a more elegant way without soldering.
* No side effects for boards which do not need this switch. It means you can call it just in case.
*
* Read more here: http://www.bajdi.com/lcsoft-vs1053-mp3-module/#comment-33773
*/
void switchToMp3Mode() {
wram_write(ADDR_REG_GPIO_DDR_RW, 3); // GPIO DDR = 3
wram_write(ADDR_REG_GPIO_ODATA_RW, 0); // GPIO ODATA = 0
uSec(10000);
LOG("Switched to mp3 mode\r\n");
softReset();
}
/**
* A lightweight method to check if VS1053 is correctly wired up (power supply and connection to SPI interface).
*
* @return true if the chip is wired up correctly
*/
bool isChipConnected() {
uint16_t status = read_register(SCI_STATUS);
return !(status == 0 || status == 0xFFFF);
}
/**
* get the Version Number for the VLSI chip
* VLSI datasheet: 0 for VS1001, 1 for VS1011, 2 for VS1002, 3 for VS1003, 4 for VS1053 and VS8053,
* 5 for VS1033, 7 for VS1103, and 6 for VS1063.
*/
uint16_t getChipVersion() {
uint16_t status = read_register(SCI_STATUS);
return ( (status & 0x00F0) >> 4);
}
/**
* Provides current decoded time in full seconds (from SCI_DECODE_TIME register value)
*
* When decoding correct data, current decoded time is shown in SCI_DECODE_TIME
* register in full seconds. The user may change the value of this register.
* In that case the new value should be written twice to make absolutely certain
* that the change is not overwritten by the firmware. A write to SCI_DECODE_TIME
* also resets the byteRate calculation.
*
* SCI_DECODE_TIME is reset at every hardware and software reset. It is no longer
* cleared when decoding of a file ends to allow the decode time to proceed
* automatically with looped files and with seamless playback of multiple files.
* With fast playback (see the playSpeed extra parameter) the decode time also
* counts faster. Some codecs (WMA and Ogg Vorbis) can also indicate the absolute
* play position, see the positionMsec extra parameter in section 10.11.
*
* @see VS1053b Datasheet (1.31) / 9.6.5 SCI_DECODE_TIME (RW)
*
* @return current decoded time in full seconds
*/
uint16_t getDecodedTime() {
return read_register(SCI_DECODE_TIME);
}
/**
* Clears decoded time (sets SCI_DECODE_TIME register to 0x00)
*
* The user may change the value of this register. In that case the new value
* should be written twice to make absolutely certain that the change is not
* overwritten by the firmware. A write to SCI_DECODE_TIME also resets the
* byteRate calculation.
*/
void clearDecodedTime() {
writeRegister(SCI_DECODE_TIME, 0x00);
writeRegister(SCI_DECODE_TIME, 0x00);
}
/**
* Fine tune the data rate
*/
void adjustRate(long ppm2) {
writeRegister(SCI_WRAMADDR, 0x1e07);
writeRegister(SCI_WRAM, ppm2);
writeRegister(SCI_WRAM, ppm2 >> 16);
// oldClock4KHz = 0 forces adjustment calculation when rate checked.
writeRegister(SCI_WRAMADDR, 0x5b1c);
writeRegister(SCI_WRAM, 0);
// Write to AUDATA or CLOCKF checks rate and recalculates adjustment.
writeRegister(SCI_AUDATA, read_register(SCI_AUDATA));
}
/**
* Load the latest generic firmware patch
*/
void loadDefaultVs1053Patches() {
LoadUserCode();
LOG("Loaded latest patch\r\n");
};
#define PLUGIN_SIZE 28
const unsigned short plugin[28] = { /* Compressed plugin */
0x0007, 0x0001, 0x8050, 0x0006, 0x0014, 0x0030, 0x0715, 0xb080, /* 0 */
0x3400, 0x0007, 0x9255, 0x3d00, 0x0024, 0x0030, 0x0295, 0x6890, /* 8 */
0x3400, 0x0030, 0x0495, 0x3d00, 0x0024, 0x2908, 0x4d40, 0x0030, /* 10 */
0x0200, 0x000a, 0x0001, 0x0050,
};
void RTLoadUserCode(void) {
int i = 0;
while (i<sizeof(plugin)/sizeof(plugin[0])) {
unsigned short addr, n, val;
addr = plugin[i++];
n = plugin[i++];
if (n & 0x8000U) { /* RLE run, replicate n samples */
n &= 0x7FFF;
val = plugin[i++];
while (n--) {
writeRegister(addr, val);
}
} else { /* Copy run, copy n samples */
while (n--) {
val = plugin[i++];
writeRegister(addr, val);
}
}
}
}
void sendMIDI(uint8_t data)
{
xchg(0);
xchg(data);
}
//Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(uint8_t cmd, uint8_t data1, uint8_t data2) {
//
// Wait for chip to be ready (Unlikely to be an issue with real time MIDI)
//
await_data_request();
data_mode_on();
sendMIDI(cmd);
//Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes
//(sort of: http://253.ccarh.org/handout/midiprotocol/)
if( (cmd & 0xF0) <= 0xB0 || (cmd & 0xF0) >= 0xE0) {
sendMIDI(data1);
sendMIDI(data2);
} else {
sendMIDI(data1);
}
data_mode_off() ;
}
//Send a MIDI note-on message. Like pressing a piano key
//channel ranges from 0-15
void noteOn(uint8_t channel, uint8_t note, uint8_t attack_velocity) {
talkMIDI( (0x90 | channel), note, attack_velocity);
}
//Send a MIDI note-off message. Like releasing a piano key
void noteOff(uint8_t channel, uint8_t note, uint8_t release_velocity) {
talkMIDI( (0x80 | channel), note, release_velocity);
}
void miditest(int test) {
RTLoadUserCode();
uSec(100000);
if(test==0)return;
talkMIDI(0xB0, 0x07, 120); //0xB0 is channel message, set channel volume to near max (127)
if(test==1){
//Demo Basic MIDI instruments, GM1
//=================================================================
MMPrintString("Basic Instruments\r\n");
talkMIDI(0xB0, 0, 0x00); //Default bank GM1
//Change to different instrument
for(int instrument = 0 ; instrument < 127 ; instrument++) {
CheckAbort();
MMPrintString(" Instrument: ");
PInt(instrument);PRet();
talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command
//Play notes from F#-0 (30) to F#-5 (90):
for (int note = 30 ; note < 40 ; note++) {
MMPrintString("N:");
PInt(note);PRet();
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, note, 127);
uSec(200000);
//Turn off the note with a given off/release velocity
noteOff(0, note, 127);
uSec(50000);
}
uSec(100000); //uSec between instruments
}
} else if(test==2){
//Demo GM2 / Fancy sounds
//=================================================================
MMPrintString("Demo Fancy Sounds\r\n");
talkMIDI(0xB0, 0, 0x78); //Bank select drums
//For this bank 0x78, the instrument does not matter, only the note
for(int instrument = 30 ; instrument < 31 ; instrument++) {
CheckAbort();
MMPrintString(" Instrument: ");
PInt(instrument);PRet();
talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command
//Play fancy sounds from 'High Q' to 'Open Surdo [EXC 6]'
for (int note = 27 ; note < 87 ; note++) {
MMPrintString("N:");
PInt(note);PRet();
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, note, 127);
uSec(50000);
//Turn off the note with a given off/release velocity
noteOff(0, note, 127);
uSec(50000);
}
uSec(100000); //uSec between instruments
}
} else if(test==3){
//Demo Melodic
//=================================================================
MMPrintString("Demo Melodic? Sounds\r\n");
talkMIDI(0xB0, 0, 0x79); //Bank select Melodic
//These don't sound different from the main bank to me
//Change to different instrument
for(int instrument = 27 ; instrument < 87 ; instrument++) {
CheckAbort();
MMPrintString(" Instrument: ");
PInt(instrument);PRet();
talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte command
//Play notes from F#-0 (30) to F#-5 (90):
for (int note = 30 ; note < 40 ; note++) {
MMPrintString("N:");PRet();
PInt(note);
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, note, 127);
uSec(500000);
//Turn off the note with a given off/release velocity
noteOff(0, note, 127);
uSec(50000);
}
uSec(100000); //uSec between instruments
}
}
}
//=================================================================

View File

@ -0,0 +1,152 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/*
* This is a driver library for VS1053 MP3 Codec Breakout
* (Ogg Vorbis / MP3 / AAC / WMA / FLAC / MIDI Audio Codec Chip).
* Adapted for Espressif ESP8266 and ESP32 boards.
*
* version 1.0.1
*
* Licensed under GNU GPLv3 <http://gplv3.fsf.org/>
* Copyright © 2017
*
* @authors baldram, edzelf, MagicCube, maniacbug
*
* Development log:
* - 2011: initial VS1053 Arduino library
* originally written by J. Coliz (github: @maniacbug),
* - 2016: refactored and integrated into Esp-radio sketch
* by Ed Smallenburg (github: @edzelf)
* - 2017: refactored to use as PlatformIO library
* by Marcin Szalomski (github: @baldram | twitter: @baldram)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License or later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VS1053_H
#define VS1053_H
#include "stdint.h"
enum VS1053_I2S_RATE {
VS1053_I2S_RATE_192_KHZ,
VS1053_I2S_RATE_96_KHZ,
VS1053_I2S_RATE_48_KHZ
};
// (-100 = right channel silent, 100 = left channel silent)
uint16_t read_register(uint8_t _reg) ;
void sdi_send_buffer(uint8_t *data, size_t len);
void sdi_send_fillers(size_t length);
void wram_write(uint16_t address, uint16_t data);
uint16_t wram_read(uint16_t address);
// Constructor. Only sets pin values. Doesn't touch the chip. Be sure to call begin()!
void VS1053(uint8_t _cs_pin, uint8_t _dcs_pin, uint8_t _dreq_pin, uint8_t _reset_pin);
// Begin operation. Sets pins correctly, and prepares SPI bus.
void begin();
// Prepare to start playing. Call this each time a new song starts
void startSong();
// Play a chunk of data. Copies the data to the chip. Blocks until complete
void playChunk(uint8_t *data, size_t len);
// Finish playing a song. Call this after the last playChunk call
void stopSong();
// Set the player volume.Level from 0-100, higher is louder
void setVolume(uint8_t vol);
// Adjusting the left and right volume balance, higher to enhance the right side, lower to enhance the left side.
void setBalance(int8_t balance);
// Set the player baas/treble, 4 nibbles for treble gain/freq and bass gain/freq
void setTone(uint8_t *rtone);
// Get the currenet volume setting, higher is louder
uint8_t getVolume();
// Get the currenet balance setting (-100..100)
int8_t getBalance();
// Print configuration details to serial output.
void printDetails(const char *header);
// Do a soft reset
void softReset();
// Test communication with module
bool testComm(const char *header);
// Fine tune the data rate
void adjustRate(long ppm2);
// Streaming Mode On
void streamModeOn();
// Default: Streaming Mode Off
void streamModeOff();
// An optional switch preventing the module starting up in MIDI mode
void switchToMp3Mode();
// disable I2S output; this is the default state
void disableI2sOut();
// // enable I2S output (GPIO4=LRCLK/WSEL; GPIO5=MCLK; GPIO6=SCLK/BCLK; GPIO7=SDATA/DOUT)
// void enableI2sOut(VS1053_I2S_RATE i2sRate = VS1053_I2S_RATE_48_KHZ);
// Checks whether the VS1053 chip is connected and is able to exchange data to the ESP
bool isChipConnected();
// gets Version of the VLSI chip being used
uint16_t getChipVersion();
// Provides SCI_DECODE_TIME register value
uint16_t getDecodedTime();
// Clears SCI_DECODE_TIME register (sets 0x00)
void clearDecodedTime();
// Writes to VS10xx's SCI (serial command interface) SPI bus.
// A low level method which lets users access the internals of the VS1053.
void writeRegister(uint8_t _reg, uint16_t _value);
// Load a patch or plugin to fix bugs and/or extend functionality.
// For more info about patches see http://www.vlsi.fi/en/support/software/vs10xxpatches.html
void loadUserCode(void);
// Loads the latest generic firmware patch.
void loadDefaultVs1053Patches();
void noteOn(uint8_t channel, uint8_t note, uint8_t attack_velocity);
void noteOff(uint8_t channel, uint8_t note, uint8_t release_velocity);
void miditest(int test);
void talkMIDI(uint8_t cmd, uint8_t data1, uint8_t data2);
uint16_t VS1053free(void);
extern volatile uint16_t VSbuffer;
void setVolumes(int valueL, int valueR);
void VS1053reset(uint8_t _reset_pin);
#endif
/* @endcond */

View File

@ -0,0 +1,40 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
Version.h
<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.
list all
************************************************************************************************************************/
#define VERSION "6.00.02RC23" // define the version number
#define YEAR "2011-2025" // and the year
#define YEAR2 "2016-2025"
#ifdef rp2350
#define CHIP "RP2350 "
#else
#define CHIP "RP2040"
#endif
/* @endcond */

View File

@ -0,0 +1,411 @@
/***********************************************************************************************************************
PicoMite MMBasic
XModem.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.
************************************************************************************************************************/
/**
* @file XModem.c
* @author Geoff Graham, Peter Mather
* @brief Source for the MMBasic XMODEM command
*/
/**
* @cond
* The following section will be excluded from the documentation.
*/
#include "MMBasic_Includes.h"
#include "Hardware_Includes.h"
void xmodemTransmit(char *p, int fnbr);
void xmodemReceive(char *sp, int maxbytes, int fnbr, int crunch);
int FindFreeFileNbr(void);
bool rcvnoint;
/* @endcond */
void MIPS16 cmd_xmodem(void) {
char *buf, BreakKeySave, *p, *fromp;
int rcv = 0, fnbr, crunch = false;
char *fname;
ClearExternalIO();
if(toupper(*cmdline) == 'R')
rcv = true;
else if(toupper(*cmdline) == 'S')
rcv = false;
else if(toupper(*cmdline) == 'C')
crunch = rcv = true;
else
error("Syntax");
while(isalpha(*cmdline)) cmdline++ ; // find the filename (if it is there)
skipspace(cmdline);
BreakKeySave = BreakKey;
BreakKey = 0;
if(*cmdline == 0 || *cmdline == '\'') {
// no file name, so this is a transfer to/from program memory
if(CurrentLinePtr) error("Invalid in a program");
if(Option.DISPLAY_TYPE>=VIRTUAL && WriteBuf)FreeMemorySafe((void **)&WriteBuf);
if(rcv)ClearProgram(true); // we need all the RAM
else {
closeframebuffer('A');
CloseAudio(1);
ClearVars(0,true);
}
buf = GetTempMemory(EDIT_BUFFER_SIZE);
if(rcv) {
xmodemReceive(buf, EDIT_BUFFER_SIZE, 0, crunch);
ClearSavedVars(); // clear any saved variables
SaveProgramToFlash((unsigned char *)buf, true);
} else {
int nbrlines = 0;
// we must copy program memory into RAM expanding tokens as we go
fromp = (char *)ProgMemory;
p = buf; // the RAM buffer
while(1) {
if(*fromp == T_NEWLINE) {
fromp = (char *)llist((unsigned char *)p, (unsigned char *)fromp); // expand the line into the buffer
nbrlines++;
if(!(nbrlines==1 && p[0]=='\'' && p[1]=='#')){
p += strlen(p);
if((p - buf) > (EDIT_BUFFER_SIZE - STRINGSIZE)) error("Not enough memory");
*p++ = '\n'; *p = 0; // terminate that line
}
}
if(fromp[0] == 0 || fromp[0] == 0xff) break; // finally, is it the end of the program?
}
--p; *p = 0; // erase the last line terminator
xmodemTransmit(buf, 0); // send it off
}
} else {
// this is a transfer to/from the SD card
if(crunch) error("Invalid command");
if(!InitSDCard()) return;
fnbr = FindFreeFileNbr();
fname = (char *)getFstring(cmdline); // get the file name
if(Option.SerialConsole){
rcvnoint=true;
uart_set_irq_enables((Option.SerialConsole & 3)==1 ? uart0 : uart1, false, false);
} else rcvnoint=false;
if(rcv) {
if(!BasicFileOpen(fname, fnbr, FA_WRITE | FA_CREATE_ALWAYS)) return;
xmodemReceive(NULL, 0, fnbr, false);
if(rcvnoint)uart_set_irq_enables((Option.SerialConsole & 3)==1 ? uart0 : uart1, true, false);
} else {
if(!BasicFileOpen(fname, fnbr, FA_READ)) return;
xmodemTransmit(NULL, fnbr);
if(rcvnoint)uart_set_irq_enables((Option.SerialConsole & 3)==1 ? uart0 : uart1, true, false);
}
FileClose(fnbr);
}
BreakKey = BreakKeySave;
cmdline=NULL;
do_end(false);
longjmp(mark, 1); // jump back to the input prompt
}
/*
* @cond
* The following section will be excluded from the documentation.
*/
int _inbyte(int timeout) {
int c;
uint64_t timer=time_us_64()+timeout*1000;
if(!rcvnoint){
while(time_us_64() < timer) {
c = getConsole();
if(c != -1) {
return c;
}
}
} else {
while(time_us_64() < timer && !uart_is_readable((Option.SerialConsole & 3)==1 ? uart0 : uart1)) {}
if(time_us_64() < timer) return uart_getc((Option.SerialConsole & 3)==1 ? uart0 : uart1);
}
return -1;
}
char _outbyte(char c, int f){
if(!rcvnoint)SerialConsolePutC(c,f);
else uart_putc_raw((Option.SerialConsole & 3)==1 ? uart0 : uart1, c);
return c;
}
// for the MX470 we don't want any XModem data echoed to the LCD panel
//#define _outbyte(c,d) SerialConsolePutC(c,d)
/***********************************************************************************************
the xmodem protocol
************************************************************************************************/
/* derived from the work of Georges Menie (www.menie.org) Copyright 2001-2010 Georges Menie
* very much debugged and changed
*
* this is just the basic XModem protocol (no 1K blocks, crc, etc). It has been tested on
* Terra Term and is intended for use with that software.
*/
#define SOH 0x01
#define STX 0x02
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define PAD 0x1a
#define DLY_1S 1000
#define MAXRETRANS 25
#define X_BLOCK_SIZE 128
#define X_BUF_SIZE X_BLOCK_SIZE + 6 // 128 for XModem + 3 head chars + 2 crc + nul
static int check(const unsigned char *buf, int sz)
{
int i;
unsigned char cks = 0;
for (i = 0; i < sz; ++i) {
cks += buf[i];
}
if (cks == buf[sz])
return 1;
return 0;
}
static void flushinput(void)
{
while (_inbyte(((DLY_1S)*3)>>1) >= 0)
#ifdef PICOMITEWEB
ProcessWeb(1)
#endif
;
}
// receive data
// if sp == NULL we are saving to a file on the SD card (fnbr is the file number)
// otherwise we are saving to RAM which will later be written to program memory
void xmodemReceive(char *sp, int maxbytes, int fnbr, int crunch) {
unsigned char xbuff[X_BUF_SIZE];
unsigned char *p;
unsigned char trychar = NAK; //'C';
unsigned char packetno = 1;
int i, c;
int retry, retrans = MAXRETRANS;
CrunchData((unsigned char **)&sp, 0); // initialise the crunch subroutine
// first establish communication with the remote
while(1) {
for( retry = 0; retry < 32; ++retry) {
if(trychar) _outbyte(trychar,1);
if ((c = _inbyte((DLY_1S)<<1)) >= 0) {
switch (c) {
case SOH:
goto start_recv;
case EOT:
flushinput();
_outbyte(ACK,1);;
if(sp != NULL) {
if(maxbytes <= 0) error("Not enough memory");
*sp++ = 0; // terminate the data
}
return; // no more data
case CAN:
flushinput();
_outbyte(ACK,1);
error("Cancelled by remote");
break;
default:
break;
}
}
}
flushinput();
_outbyte(CAN,1);
_outbyte(CAN,1);
_outbyte(CAN,1);
error("Remote did not respond"); // no sync
start_recv:
trychar = 0;
p = xbuff;
*p++ = SOH;
for (i = 0; i < (X_BLOCK_SIZE+3); ++i) {
if ((c = _inbyte(DLY_1S)) < 0) goto reject;
*p++ = c;
}
if (xbuff[1] == (unsigned char)(~xbuff[2]) && (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) && check(&xbuff[3], X_BLOCK_SIZE)) {
if (xbuff[1] == packetno) {
for(i = 0 ; i < X_BLOCK_SIZE ; i++) {
if(sp != NULL) {
// save the data to the RAM buffer
if(--maxbytes > 0) {
if(xbuff[i + 3] == PAD) continue;
// if(xbuff[i + 3] == PAD)
// *sp++ = 0; // replace any EOF's (used to pad out a block) with NUL
// else
if(xbuff[i + 3] == 0) continue;
if(crunch)
CrunchData((unsigned char **)&sp, xbuff[i + 3]);
else
*sp++ = xbuff[i + 3]; // saving to a memory buffer
}
} else {
// we are saving to a file
FilePutChar(xbuff[i + 3], fnbr);
}
}
++packetno;
retrans = MAXRETRANS+1;
}
if (--retrans <= 0) {
flushinput();
_outbyte(CAN,1);
_outbyte(CAN,1);
_outbyte(CAN,1);
error("Too many errors");
}
_outbyte(ACK,1);
continue;
}
reject:
flushinput();
_outbyte(NAK,1);
}
}
// transmit data
// if p == NULL we are reading the data to be sent from a file on the SD card (fnbr is the file number)
// otherwise we are reading from RAM and p points to the start of the data (which is terminated by a zero char)
void xmodemTransmit(char *p, int fnbr) {
unsigned char xbuff[X_BUF_SIZE];
unsigned char packetno = 1;
char prevchar = 0;
int i, c, len;
int retry;
// first establish communication with the remote
while(1) {
for( retry = 0; retry < 32; ++retry) {
if ((c = _inbyte((DLY_1S)<<1)) >= 0) {
switch (c) {
case NAK: // start sending
goto start_trans;
case CAN:
if ((c = _inbyte(DLY_1S)) == CAN) {
_outbyte(ACK,1);;
flushinput();
error("Cancelled by remote");
}
break;
default:
break;
}
}
}
_outbyte(CAN,1);;
_outbyte(CAN,1);;
_outbyte(CAN,1);;
flushinput();
error("Remote did not respond"); // no sync
// send a packet
while(1) {
start_trans:
memset (xbuff, 0, X_BUF_SIZE); // start with an empty buffer
xbuff[0] = SOH; // copy the header
xbuff[1] = packetno;
xbuff[2] = ~packetno;
if(p != NULL) {
// our data is in RAM
for(len = 0; len < 128 && *p; len++) {
if(*p == '\n' && prevchar != '\r')
prevchar = xbuff[len + 3] = '\r';
else
prevchar = xbuff[len + 3] = *p++; // copy the data from memory into the packet
}
} else {
// we get the data from a file
for(len = 0; len < 128 && !FileEOF(fnbr); len++) {
xbuff[len + 3] = FileGetChar(fnbr); // copy the data from the file into the packet
}
}
if (len > 0) {
unsigned char ccks = 0;
for (i = 3; i < X_BLOCK_SIZE+3; ++i) {
ccks += xbuff[i];
}
xbuff[X_BLOCK_SIZE+3] = ccks;
// now send the block
for (retry = 0; retry < MAXRETRANS && !MMAbort; ++retry) {
// send the block
for (i = 0; i < X_BLOCK_SIZE+4 && !MMAbort; ++i) {
_outbyte(xbuff[i],1);
}
// check the response
if ((c = _inbyte(DLY_1S)) >= 0 ) {
switch (c) {
case ACK:
++packetno;
goto start_trans;
case CAN: // cancelled by remote
_outbyte(ACK,1);;
flushinput();
error("Cancelled by remote");
break;
case NAK: // receiver got a corrupt block
default:
break;
}
}
}
// too many retrys... give up
_outbyte(CAN,1);
_outbyte(CAN,1);
_outbyte(CAN,1);
flushinput();
error("Too many errors");
}
// finished sending - send end of text
else {
for (retry = 0; retry < 10; ++retry) {
_outbyte(EOT,1);
if ((c = _inbyte((DLY_1S)<<1)) == ACK) break;
}
flushinput();
if(c == ACK) return;
error("Error closing");
}
}
}
}
/* @endcond */

View File

@ -0,0 +1,30 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
xmodem.h
<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.
************************************************************************************************************************/
/* @endcond */

View File

@ -0,0 +1,108 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// X_8x13_LE.c
// Font type : Full (95 characters)
// Font size : 8x13 pixels
// Memory usage : 1239 bytes
const unsigned char X_8x13_LE[1239] = {
0x08,0x0D,0x20,0x5F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space
0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, // !
0x00,0x00,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
0x00,0x00,0x00,0x24,0x24,0x7E,0x24,0x7E,0x24,0x24,0x00,0x00,0x00, // #
0x00,0x00,0x00,0x10,0x3C,0x50,0x38,0x14,0x78,0x10,0x00,0x00,0x00, // $
0x00,0x00,0x22,0x52,0x24,0x08,0x08,0x10,0x24,0x2A,0x44,0x00,0x00, // %
0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x4A,0x44,0x3A,0x00,0x00, // &
0x00,0x00,0x38,0x30,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
0x00,0x00,0x04,0x08,0x08,0x10,0x10,0x10,0x08,0x08,0x04,0x00,0x00, // (
0x00,0x00,0x20,0x10,0x10,0x08,0x08,0x08,0x10,0x10,0x20,0x00,0x00, // )
0x00,0x00,0x00,0x00,0x24,0x18,0x7E,0x18,0x24,0x00,0x00,0x00,0x00, // *
0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, // +
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x30,0x40,0x00, // ,
0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00, // -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x10,0x00, // .
0x00,0x00,0x02,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x00,0x00, //
0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00, // 0
0x00,0x00,0x10,0x30,0x50,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, // 1
0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00, // 2
0x00,0x00,0x7E,0x02,0x04,0x08,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00, // 3
0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x44,0x7E,0x04,0x04,0x00,0x00, // 4
0x00,0x00,0x7E,0x40,0x40,0x5C,0x62,0x02,0x02,0x42,0x3C,0x00,0x00, // 5
0x00,0x00,0x1C,0x20,0x40,0x40,0x5C,0x62,0x42,0x42,0x3C,0x00,0x00, // 6
0x00,0x00,0x7E,0x02,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, // 7
0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00, // 8
0x00,0x00,0x3C,0x42,0x42,0x46,0x3A,0x02,0x02,0x04,0x38,0x00,0x00, // 9
0x00,0x00,0x00,0x00,0x10,0x38,0x10,0x00,0x00,0x10,0x38,0x10,0x00, // :
0x00,0x00,0x00,0x00,0x10,0x38,0x10,0x00,0x00,0x38,0x30,0x40,0x00, // ;
0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x02,0x00,0x00, // <
0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // =
0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, // >
0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x08,0x08,0x00,0x08,0x00,0x00, // ?
0x00,0x00,0x3C,0x42,0x42,0x4E,0x52,0x56,0x4A,0x40,0x3C,0x00,0x00, // @
0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x00,0x00, // A
0x00,0x00,0xFC,0x42,0x42,0x42,0x7C,0x42,0x42,0x42,0xFC,0x00,0x00, // B
0x00,0x00,0x3C,0x42,0x40,0x40,0x40,0x40,0x40,0x42,0x3C,0x00,0x00, // C
0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0xFC,0x00,0x00, // D
0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7E,0x00,0x00, // E
0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, // F
0x00,0x00,0x3C,0x42,0x40,0x40,0x40,0x4E,0x42,0x46,0x3A,0x00,0x00, // G
0x00,0x00,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x00,0x00, // H
0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, // I
0x00,0x00,0x1E,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x38,0x00,0x00, // J
0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00, // K
0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00, // L
0x00,0x00,0x82,0x82,0xC6,0xAA,0x92,0x92,0x82,0x82,0x82,0x00,0x00, // M
0x00,0x00,0x42,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x42,0x00,0x00, // N
0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // O
0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0x00,0x00, // P
0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x52,0x4A,0x3C,0x02,0x00, // Q
0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x50,0x48,0x44,0x42,0x00,0x00, // R
0x00,0x00,0x3C,0x42,0x40,0x40,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00, // S
0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // T
0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // U
0x00,0x00,0x82,0x82,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x00,0x00, // V
0x00,0x00,0x82,0x82,0x82,0x82,0x92,0x92,0x92,0xAA,0x44,0x00,0x00, // W
0x00,0x00,0x82,0x82,0x44,0x28,0x10,0x28,0x44,0x82,0x82,0x00,0x00, // X
0x00,0x00,0x82,0x82,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // Y
0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x40,0x7E,0x00,0x00, // Z
0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C,0x00,0x00, // [
0x00,0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x02,0x00,0x00, // backslash
0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00,0x00, // ]
0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00, // _
0x00,0x00,0x18,0x24,0x24,0x24,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // `
0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x3E,0x42,0x46,0x3A,0x00,0x00, // a
0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x62,0x5C,0x00,0x00, // b
0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x42,0x3C,0x00,0x00, // c
0x00,0x00,0x02,0x02,0x02,0x3A,0x46,0x42,0x42,0x46,0x3A,0x00,0x00, // d
0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00, // e
0x00,0x00,0x1C,0x22,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x00,0x00, // f
0x00,0x00,0x00,0x00,0x00,0x3A,0x44,0x44,0x38,0x40,0x3C,0x42,0x3C, // g
0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x00,0x00, // h
0x00,0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, // i
0x00,0x00,0x00,0x04,0x00,0x0C,0x04,0x04,0x04,0x04,0x44,0x44,0x38, // j
0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x70,0x48,0x44,0x42,0x00,0x00, // k
0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, // l
0x00,0x00,0x00,0x00,0x00,0xEC,0x92,0x92,0x92,0x92,0x82,0x00,0x00, // m
0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x00,0x00, // n
0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, // o
0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x62,0x5C,0x40,0x40,0x40, // p
0x00,0x00,0x00,0x00,0x00,0x3A,0x46,0x42,0x46,0x3A,0x02,0x02,0x02, // q
0x00,0x00,0x00,0x00,0x00,0x5C,0x22,0x20,0x20,0x20,0x20,0x00,0x00, // r
0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x30,0x0C,0x42,0x3C,0x00,0x00, // s
0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x22,0x1C,0x00,0x00, // t
0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3A,0x00,0x00, // u
0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x00,0x00, // v
0x00,0x00,0x00,0x00,0x00,0x82,0x82,0x92,0x92,0xAA,0x44,0x00,0x00, // w
0x00,0x00,0x00,0x00,0x00,0x42,0x24,0x18,0x18,0x24,0x42,0x00,0x00, // x
0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x46,0x3A,0x02,0x42,0x3C, // y
0x00,0x00,0x00,0x00,0x00,0x7E,0x04,0x08,0x10,0x20,0x7E,0x00,0x00, // z
0x00,0x00,0x0E,0x10,0x10,0x08,0x30,0x08,0x10,0x10,0x0E,0x00,0x00, // {
0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, // |
0x00,0x00,0x70,0x08,0x08,0x10,0x0C,0x10,0x08,0x08,0x70,0x00,0x00, // }
0x00,0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
};
/* @endcond */

View File

@ -0,0 +1,572 @@
/*
This is an implementation of the AES algorithm, specifically ECB, CTR and CBC mode.
Block size can be chosen in aes.h - available choices are AES128, AES192, AES256.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
ECB-AES128
----------
plain-text:
6bc1bee22e409f96e93d7e117393172a
ae2d8a571e03ac9c9eb76fac45af8e51
30c81c46a35ce411e5fbc1191a0a52ef
f69f2445df4f9b17ad2b417be66c3710
key:
2b7e151628aed2a6abf7158809cf4f3c
resulting cipher
3ad77bb40d7a3660a89ecaf32466ef97
f5d3d58503b9699de785895a96fdbaaf
43b1cd7f598ece23881b00e3ed030688
7b0c785e27e8ad3f8223207104725dd4
NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
You should pad the end of the string with zeros if this is not the case.
For AES192/256 the key size is proportionally larger.
*/
/*****************************************************************************/
/* Includes: */
/*****************************************************************************/
#include <string.h> // CBC mode, for memset
#include "aes.h"
/*****************************************************************************/
/* Defines: */
/*****************************************************************************/
// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4
#if defined(AES256) && (AES256 == 1)
#define Nk 8
#define Nr 14
#elif defined(AES192) && (AES192 == 1)
#define Nk 6
#define Nr 12
#else
#define Nk 4 // The number of 32 bit words in a key.
#define Nr 10 // The number of rounds in AES Cipher.
#endif
// jcallan@github points out that declaring Multiply as a function
// reduces code size considerably with the Keil ARM compiler.
// See this link for more information: https://github.com/kokke/tiny-AES-C/pull/3
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
/*****************************************************************************/
/* Private variables: */
/*****************************************************************************/
// state - array holding the intermediate results during decryption.
typedef uint8_t state_t[4][4];
// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM
// The numbers below can be computed dynamically trading ROM for RAM -
// This can be useful in (embedded) bootloader applications, where ROM is often limited.
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static const uint8_t rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
#endif
// The round constant word array, Rcon[i], contains the values given by
// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
static const uint8_t Rcon[11] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
/*
* Jordan Goulder points out in PR #12 (https://github.com/kokke/tiny-AES-C/pull/12),
* that you can remove most of the elements in the Rcon array, because they are unused.
*
* From Wikipedia's article on the Rijndael key schedule @ https://en.wikipedia.org/wiki/Rijndael_key_schedule#Rcon
*
* "Only the first some of these constants are actually used up to rcon[10] for AES-128 (as 11 round keys are needed),
* up to rcon[8] for AES-192, up to rcon[7] for AES-256. rcon[0] is not used in AES algorithm."
*/
/*****************************************************************************/
/* Private functions: */
/*****************************************************************************/
/*
static uint8_t getSBoxValue(uint8_t num)
{
return sbox[num];
}
*/
#define getSBoxValue(num) (sbox[(num)])
// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.
static void KeyExpansion(uint8_t* RoundKey, const uint8_t* Key)
{
unsigned i, j, k;
uint8_t tempa[4]; // Used for the column/row operations
// The first round key is the key itself.
for (i = 0; i < Nk; ++i)
{
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
// All other round keys are found from the previous round keys.
for (i = Nk; i < Nb * (Nr + 1); ++i)
{
{
k = (i - 1) * 4;
tempa[0]=RoundKey[k + 0];
tempa[1]=RoundKey[k + 1];
tempa[2]=RoundKey[k + 2];
tempa[3]=RoundKey[k + 3];
}
if (i % Nk == 0)
{
// This function shifts the 4 bytes in a word to the left once.
// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
// Function RotWord()
{
const uint8_t u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}
// SubWord() is a function that takes a four-byte input word and
// applies the S-box to each of the four bytes to produce an output word.
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i/Nk];
}
#if defined(AES256) && (AES256 == 1)
if (i % Nk == 4)
{
// Function Subword()
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
}
#endif
j = i * 4; k=(i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key)
{
KeyExpansion(ctx->RoundKey, key);
}
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv)
{
KeyExpansion(ctx->RoundKey, key);
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv)
{
memcpy (ctx->Iv, iv, AES_BLOCKLEN);
}
#endif
// This function adds the round key to state.
// The round key is added to the state by an XOR function.
static void AddRoundKey(uint8_t round, state_t* state, const uint8_t* RoundKey)
{
uint8_t i,j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];
}
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void SubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxValue((*state)[j][i]);
}
}
}
// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
static void ShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to left
temp = (*state)[0][1];
(*state)[0][1] = (*state)[1][1];
(*state)[1][1] = (*state)[2][1];
(*state)[2][1] = (*state)[3][1];
(*state)[3][1] = temp;
// Rotate second row 2 columns to left
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to left
temp = (*state)[0][3];
(*state)[0][3] = (*state)[3][3];
(*state)[3][3] = (*state)[2][3];
(*state)[2][3] = (*state)[1][3];
(*state)[1][3] = temp;
}
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
static void MixColumns(state_t* state)
{
uint8_t i;
uint8_t Tmp, Tm, t;
for (i = 0; i < 4; ++i)
{
t = (*state)[i][0];
Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3] ;
Tm = (*state)[i][0] ^ (*state)[i][1] ; Tm = xtime(Tm); (*state)[i][0] ^= Tm ^ Tmp ;
Tm = (*state)[i][1] ^ (*state)[i][2] ; Tm = xtime(Tm); (*state)[i][1] ^= Tm ^ Tmp ;
Tm = (*state)[i][2] ^ (*state)[i][3] ; Tm = xtime(Tm); (*state)[i][2] ^= Tm ^ Tmp ;
Tm = (*state)[i][3] ^ t ; Tm = xtime(Tm); (*state)[i][3] ^= Tm ^ Tmp ;
}
}
// Multiply is used to multiply numbers in the field GF(2^8)
// Note: The last call to xtime() is unneeded, but often ends up generating a smaller binary
// The compiler seems to be able to vectorize the operation better this way.
// See https://github.com/kokke/tiny-AES-c/pull/34
#if MULTIPLY_AS_A_FUNCTION
static uint8_t Multiply(uint8_t x, uint8_t y)
{
return (((y & 1) * x) ^
((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime(xtime(x))) ^
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))); /* this last call to xtime() can be omitted */
}
#else
#define Multiply(x, y) \
( ((y & 1) * x) ^ \
((y>>1 & 1) * xtime(x)) ^ \
((y>>2 & 1) * xtime(xtime(x))) ^ \
((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ \
((y>>4 & 1) * xtime(xtime(xtime(xtime(x)))))) \
#endif
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*
static uint8_t getSBoxInvert(uint8_t num)
{
return rsbox[num];
}
*/
#define getSBoxInvert(num) (rsbox[(num)])
// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
static void InvMixColumns(state_t* state)
{
int i;
uint8_t a, b, c, d;
for (i = 0; i < 4; ++i)
{
a = (*state)[i][0];
b = (*state)[i][1];
c = (*state)[i][2];
d = (*state)[i][3];
(*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
(*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
(*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
(*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
}
}
// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
static void InvSubBytes(state_t* state)
{
uint8_t i, j;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < 4; ++j)
{
(*state)[j][i] = getSBoxInvert((*state)[j][i]);
}
}
}
static void InvShiftRows(state_t* state)
{
uint8_t temp;
// Rotate first row 1 columns to right
temp = (*state)[3][1];
(*state)[3][1] = (*state)[2][1];
(*state)[2][1] = (*state)[1][1];
(*state)[1][1] = (*state)[0][1];
(*state)[0][1] = temp;
// Rotate second row 2 columns to right
temp = (*state)[0][2];
(*state)[0][2] = (*state)[2][2];
(*state)[2][2] = temp;
temp = (*state)[1][2];
(*state)[1][2] = (*state)[3][2];
(*state)[3][2] = temp;
// Rotate third row 3 columns to right
temp = (*state)[0][3];
(*state)[0][3] = (*state)[1][3];
(*state)[1][3] = (*state)[2][3];
(*state)[2][3] = (*state)[3][3];
(*state)[3][3] = temp;
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
// Cipher is the main function that encrypts the PlainText.
static void Cipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(0, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without MixColumns()
for (round = 1; ; ++round)
{
SubBytes(state);
ShiftRows(state);
if (round == Nr) {
break;
}
MixColumns(state);
AddRoundKey(round, state, RoundKey);
}
// Add round key to last round
AddRoundKey(Nr, state, RoundKey);
}
#if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
static void InvCipher(state_t* state, const uint8_t* RoundKey)
{
uint8_t round = 0;
// Add the First round key to the state before starting the rounds.
AddRoundKey(Nr, state, RoundKey);
// There will be Nr rounds.
// The first Nr-1 rounds are identical.
// These Nr rounds are executed in the loop below.
// Last one without InvMixColumn()
for (round = (Nr - 1); ; --round)
{
InvShiftRows(state);
InvSubBytes(state);
AddRoundKey(round, state, RoundKey);
if (round == 0) {
break;
}
InvMixColumns(state);
}
}
#endif // #if (defined(CBC) && CBC == 1) || (defined(ECB) && ECB == 1)
/*****************************************************************************/
/* Public functions: */
/*****************************************************************************/
#if defined(ECB) && (ECB == 1)
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call encrypts the PlainText with the Key using AES algorithm.
Cipher((state_t*)buf, ctx->RoundKey);
}
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf)
{
// The next function call decrypts the PlainText with the Key using AES algorithm.
InvCipher((state_t*)buf, ctx->RoundKey);
}
#endif // #if defined(ECB) && (ECB == 1)
#if defined(CBC) && (CBC == 1)
static void XorWithIv(uint8_t* buf, const uint8_t* Iv)
{
uint8_t i;
for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size
{
buf[i] ^= Iv[i];
}
}
void AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t* buf, size_t length)
{
size_t i;
uint8_t *Iv = ctx->Iv;
for (i = 0; i < length; i += AES_BLOCKLEN)
{
XorWithIv(buf, Iv);
Cipher((state_t*)buf, ctx->RoundKey);
Iv = buf;
buf += AES_BLOCKLEN;
}
/* store Iv in ctx for next call */
memcpy(ctx->Iv, Iv, AES_BLOCKLEN);
}
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
{
size_t i;
uint8_t storeNextIv[AES_BLOCKLEN];
for (i = 0; i < length; i += AES_BLOCKLEN)
{
memcpy(storeNextIv, buf, AES_BLOCKLEN);
InvCipher((state_t*)buf, ctx->RoundKey);
XorWithIv(buf, ctx->Iv);
memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);
buf += AES_BLOCKLEN;
}
}
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
/* Symmetrical operation: same function for encrypting as for decrypting. Note any IV/nonce should never be reused with the same key */
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length)
{
uint8_t buffer[AES_BLOCKLEN];
size_t i;
int bi;
for (i = 0, bi = AES_BLOCKLEN; i < length; ++i, ++bi)
{
if (bi == AES_BLOCKLEN) /* we need to regen xor compliment in buffer */
{
memcpy(buffer, ctx->Iv, AES_BLOCKLEN);
Cipher((state_t*)buffer,ctx->RoundKey);
/* Increment Iv and handle overflow */
for (bi = (AES_BLOCKLEN - 1); bi >= 0; --bi)
{
/* inc will overflow */
if (ctx->Iv[bi] == 255)
{
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += 1;
break;
}
bi = 0;
}
buf[i] = (buf[i] ^ buffer[bi]);
}
}
#endif // #if defined(CTR) && (CTR == 1)

View File

@ -0,0 +1,91 @@
#ifndef _AES_H_
#define _AES_H_
#include <stdint.h>
#include <stddef.h>
// #define the macros below to 1/0 to enable/disable the mode of operation.
//
// CBC enables AES encryption in CBC-mode of operation.
// CTR enables encryption in counter-mode.
// ECB enables the basic ECB 16-byte block algorithm. All can be enabled simultaneously.
// The #ifndef-guard allows it to be configured before #include'ing or at compile time.
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 1
#endif
#ifndef CTR
#define CTR 1
#endif
#define AES128 1
//#define AES192 1
//#define AES256 1
#define AES_BLOCKLEN 16 // Block length in bytes - AES is 128b block only
#if defined(AES256) && (AES256 == 1)
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#elif defined(AES192) && (AES192 == 1)
#define AES_KEYLEN 24
#define AES_keyExpSize 208
#else
#define AES_KEYLEN 16 // Key length in bytes
#define AES_keyExpSize 176
#endif
struct AES_ctx
{
uint8_t RoundKey[AES_keyExpSize];
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
uint8_t Iv[AES_BLOCKLEN];
#endif
};
void AES_init_ctx(struct AES_ctx* ctx, const uint8_t* key);
#if (defined(CBC) && (CBC == 1)) || (defined(CTR) && (CTR == 1))
void AES_init_ctx_iv(struct AES_ctx* ctx, const uint8_t* key, const uint8_t* iv);
void AES_ctx_set_iv(struct AES_ctx* ctx, const uint8_t* iv);
#endif
#if defined(ECB) && (ECB == 1)
// buffer size is exactly AES_BLOCKLEN bytes;
// you need only AES_init_ctx as IV is not used in ECB
// NB: ECB is considered insecure for most uses
void AES_ECB_encrypt(const struct AES_ctx* ctx, uint8_t* buf);
void AES_ECB_decrypt(const struct AES_ctx* ctx, uint8_t* buf);
#endif // #if defined(ECB) && (ECB == !)
#if defined(CBC) && (CBC == 1)
// buffer size MUST be mutile of AES_BLOCKLEN;
// Suggest https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx via AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CBC_encrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
void AES_CBC_decrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
#endif // #if defined(CBC) && (CBC == 1)
#if defined(CTR) && (CTR == 1)
// Same function for encrypting as for decrypting.
// IV is incremented for every block, and used after encryption as XOR-compliment for output
// Suggesting https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7 for padding scheme
// NOTES: you need to set IV in ctx with AES_init_ctx_iv() or AES_ctx_set_iv()
// no IV should ever be reused with the same key
void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, size_t length);
#endif // #if defined(CTR) && (CTR == 1)
#endif // _AES_H_

View File

@ -0,0 +1,117 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
// arial_bold.c
// Font type : Full (95 characters)
// Font size : 16x16 pixels
// Memory usage : 3044 bytes
// Submitted by : MBWK
const unsigned char arial_bold[3044] ={
0x10,0x10,0x20,0x5F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <space>
0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, // !
0x00,0x00,0x00,0x00,0x06,0x60,0x06,0x60,0x06,0x60,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // "
0x00,0x00,0x00,0x00,0x03,0x60,0x03,0x60,0x06,0xC0,0x3F,0xF0,0x3F,0xF0,0x06,0xC0,0x0D,0x80,0x3F,0xF0,0x3F,0xF0,0x0D,0x80,0x1B,0x00,0x1B,0x00,0x00,0x00,0x00,0x00, // #
0x00,0x00,0x01,0x00,0x03,0x80,0x07,0xC0,0x0D,0x60,0x0D,0x00,0x0F,0x00,0x07,0x80,0x03,0xC0,0x01,0xE0,0x0D,0x60,0x0D,0x60,0x07,0xC0,0x03,0x80,0x01,0x00,0x00,0x00, // $
0x00,0x00,0x00,0x00,0x3C,0x18,0x66,0x30,0x66,0x30,0x66,0x60,0x66,0xC0,0x3C,0xC0,0x01,0x9E,0x01,0xB3,0x03,0x33,0x03,0x33,0x06,0x33,0x0C,0x1E,0x00,0x00,0x00,0x00, // %
0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0xE0,0x0C,0x60,0x0C,0x60,0x07,0xC0,0x07,0x80,0x0D,0x90,0x19,0xD8,0x18,0xF0,0x18,0x78,0x0F,0xFC,0x07,0x88,0x00,0x00,0x00,0x00, // &
0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '
0x00,0x00,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x00,0x00,0x00,0x00, // (
0x00,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x00,0x00,0x00,0x00, // )
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x33,0x98,0x3F,0xF8,0x07,0xC0,0x07,0xC0,0x0E,0xE0,0x1C,0x70,0x04,0x40,0x00,0x00,0x00,0x00,0x00,0x00, // *
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x07,0xF8,0x07,0xF8,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // +
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x00,0x00, // ,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x03,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // -
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .
0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, // /
0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00, // 0
0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x80,0x07,0x80,0x0D,0x80,0x09,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00, // 1
0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x30,0x0C,0x30,0x00,0x30,0x00,0x60,0x00,0xE0,0x01,0xC0,0x03,0x80,0x06,0x00,0x0F,0xF0,0x0F,0xF0,0x00,0x00,0x00,0x00, // 2
0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0xF0,0x0E,0x30,0x00,0x30,0x01,0xE0,0x01,0xE0,0x00,0x70,0x00,0x30,0x0C,0x30,0x0E,0x70,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00, // 3
0x00,0x00,0x00,0x00,0x00,0x60,0x00,0xE0,0x00,0xE0,0x01,0xE0,0x03,0x60,0x03,0x60,0x06,0x60,0x0C,0x60,0x0F,0xF0,0x0F,0xF0,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00, // 4
0x00,0x00,0x00,0x00,0x07,0xE0,0x07,0xE0,0x06,0x00,0x0C,0x00,0x0F,0xC0,0x0F,0xE0,0x0C,0x70,0x00,0x30,0x0C,0x30,0x0E,0x70,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00, // 5
0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0xF0,0x06,0x30,0x0C,0x00,0x0D,0xC0,0x0F,0xE0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x06,0x30,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00, // 6
0x00,0x00,0x00,0x00,0x0F,0xF0,0x0F,0xF0,0x00,0x60,0x00,0xC0,0x00,0xC0,0x01,0x80,0x01,0x80,0x01,0x80,0x03,0x80,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00, // 7
0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x07,0xE0,0x07,0xE0,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00, // 8
0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0C,0x60,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x07,0xF0,0x03,0xB0,0x00,0x30,0x0C,0x60,0x0F,0xE0,0x07,0xC0,0x00,0x00,0x00,0x00, // 9
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // :
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x80,0x00,0x80,0x01,0x00,0x00,0x00, // ;
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xE0,0x03,0xC0,0x0F,0x00,0x1C,0x00,0x0F,0x00,0x03,0xC0,0x00,0xE0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // <
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xF0,0x1F,0xF0,0x00,0x00,0x00,0x00,0x1F,0xF0,0x1F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // =
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0E,0x00,0x07,0x80,0x01,0xE0,0x00,0x70,0x01,0xE0,0x07,0x80,0x0E,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // >
0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x30,0x0C,0x30,0x00,0x70,0x00,0xE0,0x01,0xC0,0x01,0x80,0x01,0x80,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00, // ?
0x00,0x00,0x07,0xC0,0x0C,0x30,0x13,0x78,0x17,0xE8,0x2C,0xC8,0x2C,0xC8,0x2C,0xC8,0x2F,0xD0,0x26,0xE0,0x10,0x08,0x08,0x10,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, // @
0x00,0x00,0x00,0x00,0x03,0x80,0x03,0x80,0x06,0xC0,0x06,0xC0,0x06,0xC0,0x0C,0x60,0x0C,0x60,0x0F,0xE0,0x1F,0xF0,0x18,0x30,0x18,0x30,0x30,0x18,0x00,0x00,0x00,0x00, // A
0x00,0x00,0x00,0x00,0x1F,0xE0,0x1F,0xF0,0x18,0x30,0x18,0x30,0x18,0x30,0x1F,0xE0,0x1F,0xF0,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0xF0,0x1F,0xE0,0x00,0x00,0x00,0x00, // B
0x00,0x00,0x00,0x00,0x03,0xE0,0x0F,0xF0,0x0C,0x38,0x1C,0x10,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x1C,0x10,0x0C,0x38,0x0F,0xF0,0x03,0xE0,0x00,0x00,0x00,0x00, // C
0x00,0x00,0x00,0x00,0x1F,0xC0,0x1F,0xF0,0x18,0x30,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x30,0x1F,0xF0,0x1F,0xC0,0x00,0x00,0x00,0x00, // D
0x00,0x00,0x00,0x00,0x0F,0xF8,0x0F,0xF8,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0F,0xF8,0x0F,0xF8,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0F,0xF8,0x0F,0xF8,0x00,0x00,0x00,0x00, // E
0x00,0x00,0x00,0x00,0x0F,0xF0,0x0F,0xF0,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0F,0xE0,0x0F,0xE0,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, // F
0x00,0x00,0x00,0x00,0x07,0xE0,0x1F,0xF0,0x18,0x38,0x38,0x10,0x30,0x00,0x30,0x00,0x30,0xF8,0x30,0xF8,0x38,0x18,0x18,0x38,0x1F,0xF8,0x07,0xE0,0x00,0x00,0x00,0x00, // G
0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0xF8,0x1F,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, // H
0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00, // I
0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x0C,0x30,0x0E,0x70,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00, // J
0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x18,0x60,0x18,0xC0,0x19,0x80,0x1B,0xC0,0x1E,0xC0,0x1C,0x60,0x18,0x70,0x18,0x30,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, // K
0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0F,0xF0,0x0F,0xF0,0x00,0x00,0x00,0x00, // L
0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x38,0x3C,0x78,0x3C,0x78,0x34,0x58,0x36,0xD8,0x36,0xD8,0x36,0xD8,0x33,0x98,0x33,0x98,0x33,0x98,0x31,0x18,0x00,0x00,0x00,0x00, // M
0x00,0x00,0x00,0x00,0x18,0x18,0x1C,0x18,0x1E,0x18,0x1E,0x18,0x1B,0x18,0x19,0x98,0x19,0x98,0x18,0xD8,0x18,0x78,0x18,0x78,0x18,0x38,0x18,0x18,0x00,0x00,0x00,0x00, // N
0x00,0x00,0x00,0x00,0x07,0xC0,0x1F,0xF0,0x18,0x30,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x18,0x30,0x1F,0xF0,0x07,0xC0,0x00,0x00,0x00,0x00, // O
0x00,0x00,0x00,0x00,0x0F,0xE0,0x0F,0xF0,0x0C,0x38,0x0C,0x18,0x0C,0x38,0x0F,0xF0,0x0F,0xE0,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, // P
0x00,0x00,0x00,0x00,0x07,0xC0,0x1F,0xF0,0x18,0x30,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x31,0xB8,0x18,0xF0,0x1F,0xF0,0x07,0xB0,0x00,0x18,0x00,0x00, // Q
0x00,0x00,0x00,0x00,0x1F,0xE0,0x1F,0xF0,0x18,0x38,0x18,0x18,0x18,0x38,0x1F,0xF0,0x1F,0xC0,0x18,0xE0,0x18,0x70,0x18,0x30,0x18,0x38,0x18,0x1C,0x00,0x00,0x00,0x00, // R
0x00,0x00,0x00,0x00,0x03,0xE0,0x07,0xF0,0x0E,0x38,0x0C,0x18,0x0F,0x00,0x07,0xE0,0x01,0xF0,0x00,0x38,0x0C,0x18,0x0E,0x38,0x07,0xF0,0x03,0xE0,0x00,0x00,0x00,0x00, // S
0x00,0x00,0x00,0x00,0x1F,0xF8,0x1F,0xF8,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00, // T
0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1C,0x38,0x0F,0xF0,0x07,0xE0,0x00,0x00,0x00,0x00, // U
0x00,0x00,0x00,0x00,0x30,0x18,0x18,0x30,0x18,0x30,0x18,0x30,0x0C,0x60,0x0C,0x60,0x0E,0xE0,0x06,0xC0,0x06,0xC0,0x03,0x80,0x03,0x80,0x03,0x80,0x00,0x00,0x00,0x00, // V
0x00,0x00,0x00,0x00,0x31,0xC6,0x31,0xC6,0x31,0xC6,0x1B,0x6C,0x1B,0x6C,0x1B,0x6C,0x1B,0x6C,0x1B,0x6C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x00,0x00,0x00,0x00, // W
0x00,0x00,0x00,0x00,0x18,0x30,0x1C,0x70,0x0C,0x60,0x06,0xC0,0x07,0xC0,0x03,0x80,0x03,0x80,0x07,0xC0,0x06,0xC0,0x0C,0x60,0x1C,0x70,0x18,0x30,0x00,0x00,0x00,0x00, // X
0x00,0x00,0x00,0x00,0x18,0x18,0x1C,0x38,0x0C,0x30,0x06,0x60,0x06,0x60,0x03,0xC0,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00, // Y
0x00,0x00,0x00,0x00,0x07,0xF8,0x07,0xF8,0x00,0x30,0x00,0x60,0x00,0xE0,0x00,0xC0,0x01,0x80,0x03,0x80,0x03,0x00,0x06,0x00,0x0F,0xF8,0x0F,0xF8,0x00,0x00,0x00,0x00, // Z
0x00,0x00,0x03,0xC0,0x03,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0xC0,0x03,0xC0,0x00,0x00, // [
0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00, // <backslash>
0x00,0x00,0x03,0xC0,0x03,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x03,0xC0,0x03,0xC0,0x00,0x00, // ]
0x00,0x00,0x01,0x80,0x03,0xC0,0x03,0xC0,0x06,0x60,0x06,0x60,0x06,0x60,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00, // _
0x00,0x00,0x00,0x00,0x01,0x80,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // `
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0xE0,0x0C,0x60,0x01,0xE0,0x07,0xE0,0x0E,0x60,0x0C,0x60,0x0F,0xE0,0x07,0xB0,0x00,0x00,0x00,0x00,0x00,0x00, // a
0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0D,0xC0,0x0F,0xE0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x0F,0xE0,0x0D,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // b
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x60,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0E,0x60,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // c
0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x30,0x03,0xB0,0x07,0xF0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x07,0xF0,0x03,0xB0,0x00,0x00,0x00,0x00,0x00,0x00, // d
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x07,0xC0,0x0C,0x60,0x0F,0xE0,0x0F,0xE0,0x0C,0x00,0x0E,0x60,0x07,0xC0,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // e
0x00,0x00,0x03,0xC0,0x07,0xC0,0x06,0x00,0x0F,0x80,0x0F,0x80,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // f
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x60,0x0F,0xE0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x18,0x60,0x1C,0xE0,0x0F,0xE0,0x07,0x60,0x18,0x60,0x1F,0xE0,0x0F,0xC0,0x00,0x00, // g
0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0D,0xE0,0x0F,0xF0,0x0E,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00, // h
0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // i
0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x07,0x80,0x07,0x00, // j
0x00,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x60,0x0C,0xC0,0x0D,0x80,0x0F,0x80,0x0F,0xC0,0x0E,0xC0,0x0C,0xC0,0x0C,0x60,0x0C,0x60,0x00,0x00,0x00,0x00,0x00,0x00, // k
0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // l
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x38,0x3F,0xFC,0x39,0xCC,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x31,0x8C,0x00,0x00,0x00,0x00,0x00,0x00, // m
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0xE0,0x0F,0xF0,0x0E,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00, // n
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x07,0xE0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x07,0xE0,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // o
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0xC0,0x0F,0xE0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x0F,0xE0,0x0D,0xC0,0x0C,0x00,0x0C,0x00,0x0C,0x00, // p
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xB0,0x07,0xF0,0x0E,0x70,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0E,0x70,0x07,0xF0,0x03,0xB0,0x00,0x30,0x00,0x30,0x00,0x30, // q
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x70,0x03,0xF0,0x03,0x80,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // r
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x0F,0xE0,0x0C,0x60,0x0F,0x00,0x07,0xC0,0x00,0xE0,0x0C,0x60,0x0F,0xE0,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // s
0x00,0x00,0x01,0x00,0x03,0x00,0x03,0x00,0x07,0xC0,0x07,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0xC0,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // t
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x70,0x0F,0xF0,0x07,0xB0,0x00,0x00,0x00,0x00,0x00,0x00, // u
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x30,0x06,0x30,0x06,0x30,0x03,0x60,0x03,0x60,0x03,0x60,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // v
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0xC6,0x31,0xC6,0x19,0xCC,0x1B,0x6C,0x1B,0x6C,0x1B,0x6C,0x0E,0x38,0x0E,0x38,0x0E,0x38,0x00,0x00,0x00,0x00,0x00,0x00, // w
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x30,0x07,0x70,0x03,0x60,0x01,0xC0,0x01,0xC0,0x01,0xC0,0x03,0x60,0x07,0x70,0x06,0x30,0x00,0x00,0x00,0x00,0x00,0x00, // x
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x18,0x0C,0x18,0x06,0x30,0x06,0x30,0x03,0x60,0x03,0x60,0x03,0xE0,0x01,0xC0,0x01,0xC0,0x01,0x80,0x07,0x80,0x07,0x00, // y
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xF8,0x03,0xF8,0x00,0x30,0x00,0x70,0x00,0xE0,0x01,0xC0,0x01,0x80,0x03,0xF8,0x03,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // z
0x01,0xC0,0x03,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x0E,0x00,0x0E,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0xC0,0x01,0xC0,0x00,0x00, // {
0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80, // |
0x03,0x80,0x03,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0x70,0x00,0x70,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x00,0xC0,0x03,0xC0,0x03,0x80,0x00,0x00, // }
0x00,0x00,0x00,0x00,0x07,0x88,0x0F,0xF8,0x08,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~
};
/* @endcond */

View File

@ -0,0 +1,62 @@
.syntax unified
@ High-throughput block transfer using the FPU register set as a 128-byte
@ buffer.
@
@ This implementation exploits the IT Folding feature of the Cortex-M4.
@ An IT instruction following a 16-bit Thumb instruction, when both are
@ aligned into a 32-bit memory word, takes no additional cycles to issue.
@
@ Arguments:
@ r0 source address
@ r1 destination address
@ r2 number of words to transfer.
.section .time_critical,"ax",%progbits
.balign 4
.global _Z10copy_wordsPKmPmm
.thumb_func
_Z10copy_wordsPKmPmm:
@ Name our registers.
src .req r0
dst .req r1
count .req r2
@ The caller may have been using floating point.
@ Save the callee-save portion of the register file.
vpush {s16 - s31} @ 17
@ 'Warm up' the transfer engine, which wants to operate in units of
@ 128 bytes, by making smaller transfers until count a multiple of
@ Special-case the single word transfer; the macro below won't work.
lsrs.n count, #1 @ 1
itt cs @ 0 (aligned)
vldmcs.32 src!, {s0} @ 2
vstmcs.32 dst!, {s0} @ 2
@ Transfer n+1 words.
.macro XFER n @ 5 + 2*n
lsrs.n count, #1 @ 1
itt cs @ 0 (aligned)
vldmcs.32 src!, {s0 - s\n} @ 1+1+n
vstmcs.32 dst!, {s0 - s\n} @ 1+1+n
.endm
XFER 1 @ 7
XFER 3 @ 11
XFER 7 @ 19
XFER 15 @ 35
@ Handle the case where we've been asked to transfer <32 words.
@ In such a case, count will now be zero, and the Z flag will still
@ be set from the last XFER.
@
@ Force the branch to use a 32-bit instruction to preserve alignment
@ of the loop branch below; this saves a cycle per time that branch
@ is taken.
@
@ Note that the target of this branch (at 1 below) is also aligned,
@ saving a cycle on the rare escape path.
beq.w 1f @ 1 (n.t.)
@ All warmed up, transfer in units of 128 bytes.
0: vldm.32 src!, {s0 - s31} @ 33
vstm.32 dst!, {s0 - s31} @ 33
subs.n count, #1 @ 1
bne.n 0b @ ~3 (taken)
@ Restore FPU state.
1: vpop {s16 - s31} @ 17
bx lr @ 1-3??

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,305 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/*
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef cJSON__h
#define cJSON__h
#ifdef __cplusplus
extern "C"
{
#endif
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifdef __WINDOWS__
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
For *nix builds that support visibility attribute, you can define similar behavior by
setting default visibility to hidden by adding
-fvisibility=hidden (for gcc)
or
-xldscope=hidden (for sun cc)
to CFLAGS
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
*/
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
/* export symbols by default, this is necessary for copy pasting the C and header file */
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_EXPORT_SYMBOLS
#endif
#if defined(CJSON_HIDE_SYMBOLS)
#define CJSON_PUBLIC(type) type CJSON_STDCALL
#elif defined(CJSON_EXPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
#elif defined(CJSON_IMPORT_SYMBOLS)
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
#endif
#else /* !__WINDOWS__ */
#define CJSON_CDECL
#define CJSON_STDCALL
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
#else
#define CJSON_PUBLIC(type) type
#endif
#endif
/* project version */
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 15
#include <stddef.h>
/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw (1 << 7) /* raw json */
#define cJSON_IsReference 256
#define cJSON_StringIsConst 512
/* The cJSON structure: */
typedef struct cJSON
{
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON *prev;
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;
/* The type of the item, as above. */
int type;
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;
} cJSON;
typedef struct cJSON_Hooks
{
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
typedef int cJSON_bool;
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
* This is to prevent stack overflows. */
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void);
/* Supply malloc, realloc and free functions to cJSON */
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
/* Render a cJSON entity to text for transfer/storage. */
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. */
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
/* Check item type and return its value */
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
/* Create a string where valuestring references a string so
* it will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
/* Create an object/array that only references it's elements so
* they will not be freed by cJSON_Delete */
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
/* These utilities create an Array of count items.
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
/* Append item to the specified array/object. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
* writing to `item->string` */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detach items from Arrays/Objects. */
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
/* Update array items. */
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
* The item->next and ->prev pointers are always zero on return from Duplicate. */
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
* The input pointer json cannot point to a read-only address area, such as a string constant,
* but should point to a readable and writable address area. */
CJSON_PUBLIC(void) cJSON_Minify(char *json);
/* Helper functions for creating and adding items to an object at the same time.
* They return the added item or NULL on failure. */
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
#define cJSON_SetBoolValue(object, boolValue) ( \
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
cJSON_Invalid\
)
/* Macro for iterating over an array or object */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
CJSON_PUBLIC(void) cJSON_free(void *object);
#ifdef __cplusplus
}
#endif
#endif
/* @endcond */

View File

@ -0,0 +1,401 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/* *********************************************************************************************************************
PicoMite MMBasic
configuration.h
<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.
************************************************************************************************************************/
#ifndef __CONFIGURATION_H
#define __CONFIGURATION_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef PICOMITEVGA
#ifdef rp2350
#define MAXSUBFUN 512 // each entry takes up 4 bytes
#define MAXVARS 768 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#ifdef USBKEYBOARD
#define HEAP_MEMORY_SIZE (184*1024)
#else
#define HEAP_MEMORY_SIZE (184*1024)
#endif
#define FLASH_TARGET_OFFSET (864 * 1024)
#ifdef HDMI
#define MAXMODES 5
#ifdef USBKEYBOARD
#define MagicKey 0x81613124
#define HEAPTOP 0x2007D000
#else
#define MagicKey 0x976EB2A0
#define HEAPTOP 0x2007D000
#endif
#define MAX_CPU Freq378P
#define MIN_CPU Freq252P
#else
#define MAXMODES 3
#ifdef USBKEYBOARD
#define MagicKey 0x8E605904
#define HEAPTOP 0x2007C000
#else
#define MagicKey 0x600EAFAF
#define HEAPTOP 0x2007C000
#endif
#ifdef rp2350
#define MAX_CPU 378000
#else
#define MAX_CPU 378000
#endif
#define MIN_CPU 252000
#endif
#else
#ifdef USBKEYBOARD
#define FLASH_TARGET_OFFSET (848* 1024)
#define MagicKey 0x41FBA715
#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 HEAPTOP 0x2003f000
#define MAXVARS 480 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#endif
#define MAXMODES 2
#define HEAP_MEMORY_SIZE (100*1024)
#define MAX_CPU 378000
#define MIN_CPU 252000
#define MAXSUBFUN 256 // each entry takes up 4 bytes
#endif
#define MODE_H_S_ACTIVE_PIXELS 640
#define MODE_V_S_ACTIVE_LINES 480
#define MODE1SIZE_S MODE_H_S_ACTIVE_PIXELS * MODE_V_S_ACTIVE_LINES /8
#define MODE2SIZE_S (MODE_H_S_ACTIVE_PIXELS/2) * (MODE_V_S_ACTIVE_LINES/2)/2
#define MODE3SIZE_S (MODE_H_S_ACTIVE_PIXELS) * (MODE_V_S_ACTIVE_LINES)/2
#define MODE4SIZE_S (MODE_H_S_ACTIVE_PIXELS/2) * (MODE_V_S_ACTIVE_LINES/2)*2
#define MODE5SIZE_S (MODE_H_S_ACTIVE_PIXELS/2) * (MODE_V_S_ACTIVE_LINES/2)
#define MODE_H_4_ACTIVE_PIXELS 720
#define MODE_V_4_ACTIVE_LINES 400
#define MODE1SIZE_4 MODE_H_4_ACTIVE_PIXELS * MODE_V_4_ACTIVE_LINES /8
#define MODE2SIZE_4 (MODE_H_4_ACTIVE_PIXELS/2) * (MODE_V_4_ACTIVE_LINES/2)/2
#define MODE3SIZE_4 (MODE_H_4_ACTIVE_PIXELS) * (MODE_V_4_ACTIVE_LINES)/2
#define MODE4SIZE_4 (MODE_H_4_ACTIVE_PIXELS/2) * (MODE_V_4_ACTIVE_LINES/2)*2
#define MODE5SIZE_4 (MODE_H_4_ACTIVE_PIXELS/2) * (MODE_V_4_ACTIVE_LINES/2)
#define MODE_H_W_ACTIVE_PIXELS 1280
#define MODE_V_W_ACTIVE_LINES 720
#define MODE1SIZE_W MODE_H_W_ACTIVE_PIXELS * MODE_V_W_ACTIVE_LINES /8
#define MODE2SIZE_W (MODE_H_W_ACTIVE_PIXELS/4) * (MODE_V_W_ACTIVE_LINES/4)/2
#define MODE3SIZE_W (MODE_H_W_ACTIVE_PIXELS/2) * (MODE_V_W_ACTIVE_LINES/2)/2
#define MODE5SIZE_W (MODE_H_W_ACTIVE_PIXELS/4) * (MODE_V_W_ACTIVE_LINES/4)
#define MODE_H_8_ACTIVE_PIXELS 848
#define MODE_V_8_ACTIVE_LINES 480
#define MODE1SIZE_8 MODE_H_8_ACTIVE_PIXELS * MODE_V_8_ACTIVE_LINES /8
#define MODE2SIZE_8 (MODE_H_8_ACTIVE_PIXELS/2) * (MODE_V_8_ACTIVE_LINES/2)/2
#define MODE3SIZE_8 (MODE_H_8_ACTIVE_PIXELS) * (MODE_V_8_ACTIVE_LINES)/2
#define MODE5SIZE_8 (MODE_H_8_ACTIVE_PIXELS/2) * (MODE_V_8_ACTIVE_LINES/2)
#define MODE_H_L_ACTIVE_PIXELS 1024
#define MODE_V_L_ACTIVE_LINES 768
#define MODE1SIZE_L MODE_H_L_ACTIVE_PIXELS * MODE_V_L_ACTIVE_LINES /8
#define MODE2SIZE_L (MODE_H_L_ACTIVE_PIXELS/4) * (MODE_V_L_ACTIVE_LINES/4)/2
#define MODE3SIZE_L (MODE_H_L_ACTIVE_PIXELS/2) * (MODE_V_L_ACTIVE_LINES/2)/2
#define MODE5SIZE_L (MODE_H_L_ACTIVE_PIXELS/4) * (MODE_V_L_ACTIVE_LINES/4)
#define MODE_H_V_ACTIVE_PIXELS 800
#define MODE_V_V_ACTIVE_LINES 600
#define MODE1SIZE_V MODE_H_V_ACTIVE_PIXELS * MODE_V_V_ACTIVE_LINES /8
#define MODE2SIZE_V (MODE_H_V_ACTIVE_PIXELS/2) * (MODE_V_V_ACTIVE_LINES/2)/2
#define MODE3SIZE_V (MODE_H_V_ACTIVE_PIXELS) * (MODE_V_V_ACTIVE_LINES)/2
#define MODE5SIZE_V (MODE_H_V_ACTIVE_PIXELS/2) * (MODE_V_V_ACTIVE_LINES/2)
#define Freq720P 372000
#define Freq480P 315000
#define Freq252P 252000
#define Freq378P 378000
#define FreqXGA 375000
#define FreqSVGA 360000
#define Freq848 336000
#define Freq400 283200
#define FullColour (Option.CPU_Speed ==Freq252P || Option.CPU_Speed==Freq378P || Option.CPU_Speed ==Freq480P || Option.CPU_Speed ==Freq400)
#define MediumRes (Option.CPU_Speed==FreqSVGA || Option.CPU_Speed==Freq848)
#endif
#ifdef PICOMITEWEB
#ifdef rp2350
#define MAXSUBFUN 512 // each entry takes up 4 bytes
#define MAXVARS 768 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#define HEAP_MEMORY_SIZE (208*1024)
#define HEAPTOP 0x2006E000
#else
#define MAXSUBFUN 256 // each entry takes up 4 bytes
#define MAXVARS 480 // 8 + MAXVARLEN + MAXDIM * 2 (ie, 56 bytes) - these do not incl array members
#define HEAP_MEMORY_SIZE (88*1024)
#define HEAPTOP 0x2003D000
#endif
#include "lwipopts_examples_common.h"
#define FLASH_TARGET_OFFSET (1080 * 1024)
#define MagicKey 0x57128B1C
#define MaxPcb 8
#define MAX_CPU 252000
#define MIN_CPU 126000
#endif
#ifdef PICOMITE
#define MIN_CPU 48000
#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 MAX_CPU (rp2350a ? 396000 : 378000)
#define MAXSUBFUN 512 // each entry takes up 4 bytes
#ifdef USBKEYBOARD
#define MagicKey 0xD8069F27
#define HEAPTOP 0x20078000
#else
#define MagicKey 0x119B6ED7
#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 MAX_CPU 420000
#define MAXSUBFUN 256 // each entry takes up 4 bytes
#ifdef USBKEYBOARD
#define MagicKey 0x68EFA19E
#define HEAPTOP 0x2003F000
#else
#define MagicKey 0xE1473B93
#define HEAPTOP 0x2003EC00
#endif
#endif
#endif
#define MMFLOAT double
#define FLOAT3D float
#define sqrt3d sqrtf
#define round3d roundf
#define fabs3d fabsf
#define MAX_PROG_SIZE HEAP_MEMORY_SIZE
#define SAVEDVARS_FLASH_SIZE 16384
#define FLASH_ERASE_SIZE 4096
#define MAXFLASHSLOTS 3
#define MAXRAMSLOTS 5
#define MAXVARHASH MAXVARS/2
// more static memory allocations (less important)
#define MAXFORLOOPS 20 // each entry uses 17 bytes
#define MAXDOLOOPS 20 // each entry uses 12 bytes
#define MAXGOSUB 50 // each entry uses 4 bytes
#define MAX_MULTILINE_IF 20 // each entry uses 8 bytes
#define MAXTEMPSTRINGS 64 // each entry takes up 4 bytes
#define MAXSUBHASH MAXSUBFUN
// operating characteristics
#define MAXVARLEN 32 // maximum length of a variable name
#define MAXSTRLEN 255 // maximum length of a string
#define STRINGSIZE 256 // must be 1 more than MAXSTRLEN. 2 of these buffers are staticaly created
#define MAXOPENFILES 10 // maximum number of open files
#ifdef rp2350
#define MAXDIM 5 // maximum nbr of dimensions to an array
#else
#define MAXDIM 6 // maximum nbr of dimensions to an array
#endif
#ifdef PICOMITEWEB
#define CONSOLE_RX_BUF_SIZE TCP_MSS
#else
#define CONSOLE_RX_BUF_SIZE 256
#endif
#define CONSOLE_TX_BUF_SIZE 256
#define MAXOPENFILES 10
#define MAXCOMPORTS 2
#define MAXERRMSG 64 // max error msg size (MM.ErrMsg$ is truncated to this)
#define MAXSOUNDS 4
#define MAXKEYLEN 64
#define MAXPID 8
// define the maximum number of arguments to PRINT, INPUT, WRITE, ON, DIM, ERASE, DATA and READ
// each entry uses zero bytes. The number is limited by the length of a command line
#define MAX_ARG_COUNT 75
#define STR_AUTO_PRECISION 999
#define STR_FLOAT_PRECISION 998
#define STR_SIG_DIGITS 9 // number of significant digits to use when converting MMFLOAT to a string
#define STR_FLOAT_DIGITS 6 // number of significant digits to use when converting MMFLOAT to a string
#define NBRSETTICKS 4 // the number of SETTICK interrupts available
#ifndef PICOMITEWEB
#ifdef rp2350
#define PIOMAX 3
#define NBRPINS 62
#define PSRAMbase 0x11000000
#define PSRAMblock (PSRAMbase+PSRAMsize+0x40000)
#define PSRAMblocksize 0x1C0000
#else
#define PIOMAX 2
#define NBRPINS 44
#endif
#else
#ifdef rp2350
#define PIOMAX 3
#else
#define PIOMAX 2
#endif
#define NBRPINS 40
#endif
#define MAXPROMPTLEN 49 // max length of a prompt incl the terminating null
#define BREAK_KEY 3 // the default value (CTRL-C) for the break key. Reset at the command prompt.
#define FNV_prime 16777619
#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 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
#define MAXCFUNCTION 20
#define SAVEDVARS_FLASH_SIZE 16384
#define FLASH_ERASE_SIZE 4096
#define MAX3D 8
#define MAXCAM 3
#define MAX_POLYGON_VERTICES 10
#ifdef rp2350
#define FreqDefault 150000
#else
#define FreqDefault 200000
#endif
#define MAXBLITBUF 64
#define MAXRESTORE 8
#define CONFIG_TITLE 0
#define CONFIG_LOWER 1
#define CONFIG_UPPER 2
#define UNUSED (1 << 0)
#define ANALOG_IN (1 << 1)
#define DIGITAL_IN (1 << 2)
#define DIGITAL_OUT (1 << 3)
#define UART1TX (1 << 4)
#define UART1RX (1 << 5)
#define UART0TX (1 << 6)
#define UART0RX (1 << 7)
#define I2C0SDA (1 << 8)
#define I2C0SCL (1 << 9)
#define I2C1SDA (1 << 10)
#define I2C1SCL (1 << 11)
#define SPI0RX (1 << 12)
#define SPI0TX (1 << 13)
#define SPI0SCK (1 << 14)
#define SPI1RX (1 << 15)
#define SPI1TX (1 << 16)
#define SPI1SCK (1 << 17)
#define PWM0A (1 << 18)
#define PWM0B (1 << 19)
#define PWM1A (1 << 20)
#define PWM1B (1 << 21)
#define PWM2A (1 << 22)
#define PWM2B (1 << 23)
#define PWM3A (1 << 24)
#define PWM3B (1 << 25)
#define PWM4A (1 << 26)
#define PWM4B (1 << 27)
#define PWM5A (1 << 28)
#define PWM5B (1 << 29)
#define PWM6A (1 << 30)
#define PWM6B 2147483648
#define PWM7A 4294967296
#define PWM7B 8589934592
#ifdef rp2350
#define PWM8A 17179869184
#define PWM8B 34359738368
#define PWM9A 68719476736
#define PWM9B 137438953472
#define PWM10A 274877906944
#define PWM10B 549755813888
#define PWM11A 1099511627776
#define PWM11B 2199023255552
#define FAST_TIMER 4398046511104
#define FAST_TIMER_PIN 2
#endif
#define MAXCOLLISIONS 4
#define MAXLAYER 4
#define MAXCONTROLS 200
#define MAXDEFINES 16
//#define DO_NOT_RESET (1 << 5)
//#define HEARTBEAT (1 << 6)
#define HEARTBEATpin Option.heartbeatpin
#define PATH_MAX 1024
// QVGA PIO and state machines
#define QVGA_PIO_NUM 0
#ifdef rp2350
#define QVGA_PIO (QVGA_PIO_NUM==0 ? pio0: (QVGA_PIO_NUM==1 ? pio1: pio2))
#else
#define QVGA_PIO (QVGA_PIO_NUM==0 ? pio0: pio1)
#endif
// QVGA PIO
#define QVGA_SM 0 // QVGA state machine
#define QVGA_I2S_SM 1 //I2S state machine when running VGA
#define MIPS16 __attribute__ ((optimize("-Os")))
#define MIPS32 __attribute__ ((optimize("-O2")))
#define MIPS64 __attribute__ ((optimize("-O3")))
// QVGA DMA channel
#define QVGA_DMA_CB 0 // DMA control block of base layer
#define QVGA_DMA_PIO 1 // DMA copy data to PIO (raises IRQ0 on quiet)
#define ADC_DMA 2
#define ADC_DMA2 7
#define PIO_RX_DMA 8
#define PIO_TX_DMA 4
#define PIO_RX_DMA2 9
#define PIO_TX_DMA2 6
#define ADC_CLK_SPEED (Option.CPU_Speed*500)
#define PROGSTART (FLASH_TARGET_OFFSET + FLASH_ERASE_SIZE + SAVEDVARS_FLASH_SIZE + ((MAXFLASHSLOTS) * MAX_PROG_SIZE))
#define TOP_OF_SYSTEM_FLASH (FLASH_TARGET_OFFSET + FLASH_ERASE_SIZE + SAVEDVARS_FLASH_SIZE + ((MAXFLASHSLOTS+1) * MAX_PROG_SIZE))
#define RoundUpK4(a) (((a) + (4096 - 1)) & (~(4096 - 1)))// round up to the nearest page size [position 131:9]
typedef enum {
MMHRES,
MMVRES,
MMVER,
MMI2C,
MMFONTHEIGHT,
MMFONTWIDTH,
#ifndef USBKEYBOARD
MMPS2,
#endif
MMHPOS,
MMVPOS,
MMONEWIRE,
MMERRNO,
MMERRMSG,
MMWATCHDOG,
MMDEVICE,
MMCMDLINE,
#ifdef PICOMITEWEB
MMMESSAGE,
MMTOPIC,
MMADDRESS,
#endif
MMFLAG,
MMDISPLAY,
MMWIDTH,
MMHEIGHT,
MMPERSISTENT,
MMEND
} Operation;
extern const char* overlaid_functions[];
#ifdef __cplusplus
}
#endif
#endif /* __CONFIGURATION_H */
/* @endcond */

View File

@ -0,0 +1,90 @@
/*
* @cond
* The following section will be excluded from the documentation.
*/
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2019 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
/* MMC card type flags (MMC_GET_TYPE) */
#define CT_MMC 0x01 /* MMC ver 3 */
#define CT_SD1 0x02 /* SD ver 1 */
#define CT_SD2 0x04 /* SD ver 2 */
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
#define CT_BLOCK 0x08 /* Block addressing */
#ifdef __cplusplus
}
#endif
#endif
/* @endcond */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More