Skip to content

Commit 78a80a0

Browse files
authored
Merge pull request #254 from Joe7M/master
Improved Teensy implementation
2 parents 53595d6 + 438b245 commit 78a80a0

25 files changed

+1321
-198
lines changed

src/common/fs_serial.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <unistd.h>
2020
#include <sys/select.h>
2121
#include <errno.h>
22+
#include <sys/ioctl.h>
2223

2324
/**
2425
* terminal speed
@@ -129,20 +130,9 @@ int serial_read(dev_file_t *f, byte *data, uint32_t size) {
129130

130131
// Returns the number of the available data on serial port
131132
uint32_t serial_length(dev_file_t *f) {
132-
fd_set readfs;
133-
struct timeval tv;
134-
135-
FD_ZERO(&readfs);
136-
FD_SET(f->handle, &readfs);
137-
138-
tv.tv_usec = 250; // milliseconds
139-
tv.tv_sec = 0; // seconds
140-
141-
select(f->handle + 1, &readfs, NULL, NULL, &tv);
142-
if (FD_ISSET(f->handle, &readfs)) {
143-
return 1;
144-
}
145-
return 0;
133+
uint32_t bytes;
134+
ioctl(f->handle, FIONREAD, &bytes);
135+
return bytes;
146136
}
147137

148138
#elif defined(_Win32)

src/common/var_eval.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ var_p_t v_get_tmp(var_p_t map) {
2323
var_p_t result = map_get(map, MAP_TMP_FIELD);
2424
if (result == NULL) {
2525
result = map_add_var(map, MAP_TMP_FIELD, 0);
26+
} else {
27+
v_free(result);
2628
}
2729
return result;
2830
}

src/platform/teensy/CMakeLists.txt

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,33 @@
66
#
77

88
cmake_minimum_required(VERSION 3.10)
9+
option(TEENSY40 "Build for teensy 4.0 instead of 4.1" OFF)
910
project(SmallBASIC)
1011
include(ExternalProject)
1112
set(CMAKE_SYSTEM_NAME Generic)
1213
set(TARGET "smallbasic")
1314

14-
# settings for teensy 4.0
15-
set(MODULES ${CMAKE_CURRENT_SOURCE_DIR}/build/modules)
16-
set(TEENSY_SRC ${MODULES}/cores/teensy4)
17-
set(MCU "IMXRT1062")
18-
set(MCU_LD ${TEENSY_SRC}/imxrt1062.ld)
19-
set(CPU_OPTIONS "-mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb")
15+
if(TEENSY40)
16+
message("Building for TEENSY 4.0")
17+
set(MODULES ${CMAKE_CURRENT_SOURCE_DIR}/build/modules)
18+
set(TEENSY_SRC ${MODULES}/cores/teensy4)
19+
set(MCU "IMXRT1062")
20+
set(MCU_LD ${TEENSY_SRC}/imxrt1062.ld)
21+
set(MCU_DEF "ARDUINO_TEENSY40")
22+
set(CPU_OPTIONS "-mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb")
23+
else()
24+
message("Building for TEENSY 4.1")
25+
set(MODULES ${CMAKE_CURRENT_SOURCE_DIR}/build/modules)
26+
set(TEENSY_SRC ${MODULES}/cores/teensy4)
27+
set(MCU "IMXRT1062")
28+
set(MCU_LD ${TEENSY_SRC}/imxrt1062_t41.ld)
29+
set(MCU_DEF "ARDUINO_TEENSY41")
30+
set(CPU_OPTIONS "-mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb")
31+
endif()
2032

2133
# Preprocessor flags for both C and C++
2234
add_compile_options(-g -O2 -ffunction-sections -fdata-sections -DENABLE_LOGGING
23-
-DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -D__${MCU}__ -DARDUINO=10813 -DTEENSYDUINO=159 -DARDUINO_TEENSY40)
35+
-DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -D__${MCU}__ -DARDUINO=10813 -DTEENSYDUINO=159 -D${MCU_DEF})
2436

2537
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CPU_OPTIONS}")
2638
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CPU_OPTIONS} -std=gnu++17 -felide-constructors -fno-exceptions -fpermissive -fno-rtti -Wno-error=narrowing")
@@ -44,6 +56,8 @@ include_directories(${MODULES}/SPI)
4456
include_directories(${MODULES}/Adafruit_SSD1306)
4557
include_directories(${MODULES}/USBHost_t36)
4658
include_directories(${MODULES}/Wire)
59+
include_directories(${MODULES}/SD/src)
60+
include_directories(${MODULES}/SdFat/src)
4761

4862
# include config.h and common headers
4963
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..)
@@ -59,17 +73,9 @@ set(SOURCES
5973
src/ssd1306.cpp
6074
)
6175

62-
option(INTERACTIVE "Whether to run programs via serial" OFF)
63-
6476
# Add executable with the list of source files
6577
add_executable(${TARGET}.elf ${SOURCES})
6678

67-
if (INTERACTIVE)
68-
target_compile_definitions(${TARGET}.elf PRIVATE INTERACTIVE=1)
69-
else()
70-
target_compile_definitions(${TARGET}.elf PRIVATE INTERACTIVE=0)
71-
endif()
72-
7379
# enable all warnings in main.cpp
7480
target_compile_options(${TARGET}.elf PRIVATE -Wall)
7581

src/platform/teensy/Makefile.am

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#
77

88
tidy:
9-
@cd build && make tidy
9+
@cd build && make tidy
1010

1111
build/modules/cores/teensy4/Makefile:
1212
./setup.sh
@@ -31,6 +31,11 @@ build/smallbasic.elf : \
3131
all: build/smallbasic.elf
3232

3333
install: build/smallbasic.elf
34-
@build/modules/teensy_loader_cli/teensy_loader_cli --mcu=IMXRT1062 -w -v build/smallbasic.hex && \
34+
@build/modules/teensy_loader_cli/teensy_loader_cli --mcu=TEENSY41 -w -v -s build/smallbasic.hex && \
35+
sleep 1 && \
36+
lsusb | grep -i teensy
37+
38+
install40: build/smallbasic.elf
39+
@build/modules/teensy_loader_cli/teensy_loader_cli --mcu=TEENSY40 -w -v -s build/smallbasic.hex && \
3540
sleep 1 && \
3641
lsusb | grep -i teensy

src/platform/teensy/README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Build
2+
3+
## Build SmallBASIC
4+
5+
Teensy 4.0 and Teensy 4.1 are supported. Both using the same processor and running at the same speed.
6+
But Teensy 4.1 offers more features than Teensy 4.0. The standard build is for Teensy 4.1.
7+
8+
Download and build SmallBASIC as described [here](https://github.com/smallbasic/SmallBASIC).
9+
10+
## Build Teensy firmware
11+
12+
### Initial setup
13+
14+
Install the following packages (Manjaro (arch)):
15+
16+
```
17+
$ sudo pacman -S arm-none-eabi-binutils arm-none-eabi-gcc arm-none-eabi-newlib libusb-compat
18+
```
19+
20+
Add udev rules for serial USB:
21+
22+
```
23+
curl -sLO https://www.pjrc.com/teensy/00-teensy.rules
24+
sudo cp 00-teensy.rules /etc/udev/rules.d/
25+
```
26+
27+
Download and build core libraries:
28+
29+
```
30+
$ ./configure --enable-teensy
31+
$ cd src/platform/teensy
32+
$ ./setup.sh
33+
```
34+
35+
### Build firmware for Teensy 4.1
36+
37+
The following instructions will build and install the firmware for Teensy 4.1.
38+
39+
```
40+
$ make
41+
```
42+
43+
> If setup.sh displays an error massage that cmake minimum version is not set,
44+
> open `build/modules/CMSIS-DSP/CMakeLists.txt`
45+
> and add in the beginning of the file `cmake_minimum_required(VERSION 4.1)`
46+
47+
Upload firmware:
48+
49+
```
50+
make install
51+
```
52+
53+
or
54+
55+
```
56+
build/modules/teensy_loader_cli/teensy_loader_cli --mcu=TEENSY41 -w -v -s build/smallbasic.hex
57+
```
58+
59+
### Build firmware for Tennsy 4.0
60+
61+
If you want to build the firmware for Tennsy 4.0, you have to run the following commands after
62+
initial setup:
63+
64+
```
65+
cd build
66+
cmake .. -DTEENSY40=ON
67+
```
68+
69+
and run `./configure --enable-teensy` again. Next you can build the firmware:
70+
71+
```
72+
$ make
73+
```
74+
75+
> If setup.sh displays an error massage that cmake minimum version is not set,
76+
> open `build/modules/CMSIS-DSP/CMakeLists.txt`
77+
> and add in the beginning of the file `cmake_minimum_required(VERSION 4.1)`
78+
79+
Upload firmware:
80+
81+
```
82+
make install40
83+
```
84+
85+
or
86+
87+
```
88+
build/modules/teensy_loader_cli/teensy_loader_cli --mcu=TEENSY40 -w -v -s build/smallbasic.hex
89+
```
90+
91+
# Run your SMALLBASIC program
92+
93+
SMALLBASIC for Teensy offers three ways to upload and run a program.
94+
95+
1. Format a SD card using FAT32. Rename your program to `MAIN.BAS` and copy it to the SD card.
96+
2. Include your program in the firmware. Replace `main.bas` in `src/platform/teensy` by your program and build
97+
the firmware.
98+
3. Send your program via USB-serial connection to the Teensy. In Linux use ` cat YourProgram.bas > /dev/ttyACM0`
99+
Change `/dev/ttyACM0` to the USB-serial port of your Teensy.
100+
4. Goto 3.
101+
102+
When the Teensy starts up, it will check in the above indicated order for your program. If it finds
103+
a SD card and the SD card contains a file `MAIN.BAS`, it will execute it. Otherwise it will check, if a program
104+
was included in the firmware. If no program was included, the Teensy will switch to interactive mode and waits
105+
for a program upload via USB-serial.
106+
107+
While your program is running, the Teensy will check continuously if data is available at the USB-serial port.
108+
If data is available for longer than one second your running program will be terminated and the queued data of the
109+
USB-serial port will be interpreted as the new program. Once the upload is finished, the new program will be executed.
110+
If you are using the USB-serial port for communication, read the queued data within one second. Alternately, you
111+
can turn on/off this behavior during runtime.
112+
113+
If an error occurred, for example a syntax error, execution will stop and you have to read the error message from
114+
the USB-serial port.
115+
116+
If the execution of your program comes to an end, for example when reaching the end of the program or when `STOP` is
117+
called, the program is terminated and the next section in the above list is performed.
118+
119+
# Read output from your running program
120+
121+
The `PRINT` command can be used to print to the USB-serial port. To access the output, connect to the serial
122+
port using, i.e. `PUTTY` or any other serial-port monitor / terminal. Using Linux, the easiest way is to run
123+
`cat /dev/ttyACM0`
124+
125+
# Debugging the Teensy crash screen
126+
127+
To find the line that failed (but no stack) run:
128+
129+
```
130+
arm-none-eabi-addr2line -e smallbasic.elf ADDRESS
131+
```
132+
133+
Where `ADDRESS` is the address shown in the crash screen, for example `0x17D04`

src/platform/teensy/libs/CMakeLists.txt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ set(SPI_DIR ${MODULES_DIR}/SPI)
1414
set(SSD_DIR ${MODULES_DIR}/Adafruit_SSD1306)
1515
set(USB_DIR ${MODULES_DIR}/USBHost_t36)
1616
set(WIRE_DIR ${MODULES_DIR}/Wire)
17+
set(SD_DIR ${MODULES_DIR}/SD/src)
18+
set(SDFAT_DIR ${MODULES_DIR}/SdFat/src)
1719

1820
set(SOURCES
1921
${ADC_DIR}/ADC.cpp
@@ -115,6 +117,51 @@ set(SOURCES
115117
${WIRE_DIR}/Wire.cpp
116118
${WIRE_DIR}/WireIMXRT.cpp
117119
${WIRE_DIR}/WireKinetis.cpp
120+
${SD_DIR}/SD.cpp
121+
${SDFAT_DIR}/SdCard/SdCardInfo.cpp
122+
${SDFAT_DIR}/SdCard/SdioTeensy.cpp
123+
${SDFAT_DIR}/SdCard/SdSpiCard.cpp
124+
${SDFAT_DIR}/SpiDriver/SdSpiChipSelect.cpp
125+
${SDFAT_DIR}/SpiDriver/SdSpiArtemis.cpp
126+
${SDFAT_DIR}/SpiDriver/SdSpiDue.cpp
127+
${SDFAT_DIR}/SpiDriver/SdSpiESP.cpp
128+
${SDFAT_DIR}/SpiDriver/SdSpiParticle.cpp
129+
${SDFAT_DIR}/SpiDriver/SdSpiSTM32.cpp
130+
${SDFAT_DIR}/SpiDriver/SdSpiSTM32Core.cpp
131+
${SDFAT_DIR}/SpiDriver/SdSpiTeensy3.cpp
132+
${SDFAT_DIR}/iostream/istream.cpp
133+
${SDFAT_DIR}/iostream/ostream.cpp
134+
${SDFAT_DIR}/iostream/StdioStream.cpp
135+
${SDFAT_DIR}/iostream/StreamBaseClass.cpp
136+
${SDFAT_DIR}/FsLib/FsFile.cpp
137+
${SDFAT_DIR}/FsLib/FsNew.cpp
138+
${SDFAT_DIR}/FsLib/FsVolume.cpp
139+
${SDFAT_DIR}/FatLib/FatDbg.cpp
140+
${SDFAT_DIR}/FatLib/FatFile.cpp
141+
${SDFAT_DIR}/FatLib/FatFileLFN.cpp
142+
${SDFAT_DIR}/FatLib/FatFilePrint.cpp
143+
${SDFAT_DIR}/FatLib/FatFileSFN.cpp
144+
${SDFAT_DIR}/FatLib/FatFormatter.cpp
145+
${SDFAT_DIR}/FatLib/FatName.cpp
146+
${SDFAT_DIR}/FatLib/FatPartition.cpp
147+
${SDFAT_DIR}/FatLib/FatVolume.cpp
148+
${SDFAT_DIR}/ExFatLib/ExFatDbg.cpp
149+
${SDFAT_DIR}/ExFatLib/ExFatFile.cpp
150+
${SDFAT_DIR}/ExFatLib/ExFatFilePrint.cpp
151+
${SDFAT_DIR}/ExFatLib/ExFatFileWrite.cpp
152+
${SDFAT_DIR}/ExFatLib/ExFatFormatter.cpp
153+
${SDFAT_DIR}/ExFatLib/ExFatName.cpp
154+
${SDFAT_DIR}/ExFatLib/ExFatPartition.cpp
155+
${SDFAT_DIR}/ExFatLib/ExFatVolume.cpp
156+
${SDFAT_DIR}/ExFatLib/upcase.cpp
157+
${SDFAT_DIR}/common/FmtNumber.cpp
158+
${SDFAT_DIR}/common/FsCache.cpp
159+
${SDFAT_DIR}/common/FsDateTime.cpp
160+
${SDFAT_DIR}/common/FsName.cpp
161+
${SDFAT_DIR}/common/FsStructs.cpp
162+
${SDFAT_DIR}/common/FsUtf.cpp
163+
${SDFAT_DIR}/common/PrintBasic.cpp
164+
${SDFAT_DIR}/common/upcase.cpp
118165
)
119166

120167
add_library(libs STATIC ${SOURCES})
@@ -127,4 +174,6 @@ target_include_directories(libs PRIVATE ${MODULES_DIR}/SdFat/src)
127174
target_include_directories(libs PRIVATE ${SPI_DIR})
128175
target_include_directories(libs PRIVATE ${TEENSY_DIR})
129176
target_include_directories(libs PRIVATE ${WIRE_DIR})
177+
target_include_directories(libs PRIVATE ${SD_DIR})
178+
target_include_directories(libs PRIVATE ${SDFAT_DIR})
130179

src/platform/teensy/main.bas

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +0,0 @@
1-
import teensy
2-
import ssd1306 as display
3-
4-
const welcome = "Hello SmallBASIC!!"
5-
display.init()
6-
display.dim(1)
7-
display.print(welcome)
8-
9-
const sz = display.getTextSize(welcome)
10-
display.setCursor(0, sz.height + 2)
11-
display.flush()
12-
13-
const out = teensy.openDigitalOutput(13)
14-
const usb = teensy.openSerial()
15-
16-
sub show_data(byref s)
17-
display.clear()
18-
display.setCursor(0,0)
19-
display.print("Received:")
20-
display.setCursor(0, sz.height + 2)
21-
display.print(s)
22-
display.flush()
23-
end
24-
25-
sub blink
26-
local i
27-
for i = 0 to 5
28-
out.write(value)
29-
value = !value
30-
delay 10 + (i * 10)
31-
next
32-
out.write(0)
33-
end
34-
35-
while 1
36-
if usb.ready() then
37-
s = usb.receive()
38-
if (len(s) > 0) then
39-
show_data(s)
40-
usb.send(sbver)
41-
blink
42-
endif
43-
else
44-
delay 10
45-
endif
46-
wend

src/platform/teensy/run.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
# Allows you to edit your SmallBASIC code in your favourite editor.
55
# When you save, the program is transferred to the teensy and run.
66
#
7-
# This works with the INTERACTIVE mode build
8-
# $ cd build && cmake .. -DINTERACTIVE=ON
9-
#
107
# Requires inotify-tools available via:
118
# $ sudo apt install inotify-tools
129
#

0 commit comments

Comments
 (0)