mirror of
https://github.com/isometimes/rpi4-osdev
synced 2024-11-22 10:10:45 +00:00
Merge pull request #2 from isometimes/clang-mbp-m1
Move build to clang and test to support building natively on Apple Silicon
This commit is contained in:
commit
96e64218e9
30 changed files with 738 additions and 288 deletions
|
@ -1,19 +1,19 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES)
|
kernel8.img: boot.o $(OFILES)
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
19
part2-building/Makefile.gcc
Normal file
19
part2-building/Makefile.gcc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES)
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
|
@ -1,19 +1,19 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES)
|
kernel8.img: boot.o $(OFILES)
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
19
part3-helloworld/Makefile.gcc
Normal file
19
part3-helloworld/Makefile.gcc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES)
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
|
@ -1,19 +1,19 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES)
|
kernel8.img: boot.o $(OFILES)
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
19
part4-miniuart/Makefile.gcc
Normal file
19
part4-miniuart/Makefile.gcc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES)
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
|
@ -1,19 +1,19 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES)
|
kernel8.img: boot.o $(OFILES)
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
19
part5-framebuffer/Makefile.gcc
Normal file
19
part5-framebuffer/Makefile.gcc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES)
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
|
@ -1,19 +1,19 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES)
|
kernel8.img: boot.o $(OFILES)
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
19
part6-breakout/Makefile.gcc
Normal file
19
part6-breakout/Makefile.gcc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES)
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
|
@ -147,8 +147,8 @@ void uart_writeByteBlocking(unsigned char ch) {
|
||||||
|
|
||||||
void uart_writeText(char *buffer) {
|
void uart_writeText(char *buffer) {
|
||||||
while (*buffer) {
|
while (*buffer) {
|
||||||
if (*buffer == '\n') uart_writeByteBlocking('\r');
|
if (*buffer == '\n') uart_writeByteBlockingActual('\r');
|
||||||
uart_writeByteBlocking(*buffer++);
|
uart_writeByteBlockingActual(*buffer++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,10 @@ enum {
|
||||||
OBJ_BALL = 3
|
OBJ_BALL = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define OBJS_ADDRESS 0x02100000 // Somewhere safe to store a lot of data
|
||||||
|
|
||||||
unsigned int numobjs = 0;
|
unsigned int numobjs = 0;
|
||||||
struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)];
|
struct Object *objects = (struct Object *)OBJS_ADDRESS;
|
||||||
struct Object *ball;
|
struct Object *ball;
|
||||||
struct Object *paddle;
|
struct Object *paddle;
|
||||||
|
|
||||||
|
@ -87,7 +89,7 @@ void initBricks()
|
||||||
int brickwidth = 32;
|
int brickwidth = 32;
|
||||||
int brickheight = 8;
|
int brickheight = 8;
|
||||||
int brickspacer = 20;
|
int brickspacer = 20;
|
||||||
int brickcols[5] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
|
static int brickcols[] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
|
||||||
|
|
||||||
int ybrick = MARGIN + brickheight;
|
int ybrick = MARGIN + brickheight;
|
||||||
|
|
||||||
|
@ -149,13 +151,10 @@ void drawScoreboard(int score, int lives)
|
||||||
char tens = score / 10; score -= (10 * tens);
|
char tens = score / 10; score -= (10 * tens);
|
||||||
char ones = score;
|
char ones = score;
|
||||||
|
|
||||||
char string[] = "Score: 0xx Lives: x\0\0";
|
drawString((WIDTH/2)-252, MARGIN-25, "Score: 0 Lives: ", 0x0f, 3);
|
||||||
|
drawChar(tens + 0x30, (WIDTH/2)-252 + (8*8*3), MARGIN-25, 0x0f, 3);
|
||||||
string[8] = tens + 0x30;
|
drawChar(ones + 0x30, (WIDTH/2)-252 + (8*9*3), MARGIN-25, 0x0f, 3);
|
||||||
string[9] = ones + 0x30;
|
drawChar((char)lives + 0x30, (WIDTH/2)-252 + (8*20*3), MARGIN-25, 0x0f, 3);
|
||||||
string[20] = (char)lives + 0x30;
|
|
||||||
|
|
||||||
drawString((WIDTH/2)-252, MARGIN-25, string, 0x0f, 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
BCM4345C0.o : BCM4345C0.hcd
|
BCM4345C0.o : BCM4345C0.hcd
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
$(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
22
part7-bluetooth/Makefile.gcc
Normal file
22
part7-bluetooth/Makefile.gcc
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
BCM4345C0.o : BCM4345C0.hcd
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
|
@ -1,6 +1,8 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "fb.h"
|
#include "fb.h"
|
||||||
|
|
||||||
|
volatile unsigned char *params = (unsigned char *)SAFE_ADDRESS;
|
||||||
|
|
||||||
// UART0
|
// UART0
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -91,7 +93,7 @@ enum {
|
||||||
|
|
||||||
unsigned char empty[] = {};
|
unsigned char empty[] = {};
|
||||||
|
|
||||||
int hciCommandBytes(unsigned char *opcodebytes, unsigned char *data, unsigned char length)
|
int hciCommandBytes(volatile unsigned char *opcodebytes, volatile unsigned char *data, unsigned char length)
|
||||||
{
|
{
|
||||||
unsigned char c=0;
|
unsigned char c=0;
|
||||||
|
|
||||||
|
@ -128,7 +130,7 @@ int hciCommandBytes(unsigned char *opcodebytes, unsigned char *data, unsigned ch
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hciCommand(unsigned short ogf, unsigned short ocf, unsigned char *data, unsigned char length)
|
int hciCommand(unsigned short ogf, unsigned short ocf, volatile unsigned char *data, unsigned char length)
|
||||||
{
|
{
|
||||||
unsigned short opcode = ogf << 10 | ocf;
|
unsigned short opcode = ogf << 10 | ocf;
|
||||||
unsigned char opcodebytes[2] = { lo(opcode), hi(opcode) };
|
unsigned char opcodebytes[2] = { lo(opcode), hi(opcode) };
|
||||||
|
@ -151,11 +153,12 @@ void bt_loadfirmware()
|
||||||
unsigned int size = (long)&_binary_BCM4345C0_hcd_size;
|
unsigned int size = (long)&_binary_BCM4345C0_hcd_size;
|
||||||
|
|
||||||
while (c < size) {
|
while (c < size) {
|
||||||
unsigned char opcodebytes[] = { _binary_BCM4345C0_hcd_start[c], _binary_BCM4345C0_hcd_start[c+1] };
|
params[0] = _binary_BCM4345C0_hcd_start[c];
|
||||||
|
params[1] = _binary_BCM4345C0_hcd_start[c+1];
|
||||||
unsigned char length = _binary_BCM4345C0_hcd_start[c+2];
|
unsigned char length = _binary_BCM4345C0_hcd_start[c+2];
|
||||||
unsigned char *data = &(_binary_BCM4345C0_hcd_start[c+3]);
|
unsigned char *data = &(_binary_BCM4345C0_hcd_start[c+3]);
|
||||||
|
|
||||||
if (hciCommandBytes(opcodebytes, data, length)) {
|
if (hciCommandBytes(params, data, length)) {
|
||||||
uart_writeText("Firmware data load failed\n");
|
uart_writeText("Firmware data load failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -167,13 +170,23 @@ void bt_loadfirmware()
|
||||||
|
|
||||||
void bt_setbaud()
|
void bt_setbaud()
|
||||||
{
|
{
|
||||||
static unsigned char params[] = { 0, 0, 0x00, 0xc2, 0x01, 0x00 }; // little endian, 115200
|
params[0] = 0;
|
||||||
|
params[1] = 0;
|
||||||
|
params[2] = 0x00;
|
||||||
|
params[3] = 0xc2;
|
||||||
|
params[4] = 0x01;
|
||||||
|
params[5] = 0x00; // little endian, 115200
|
||||||
if (hciCommand(OGF_VENDOR, COMMAND_SET_BAUD, params, 6)) uart_writeText("bt_setbaud() failed\n");
|
if (hciCommand(OGF_VENDOR, COMMAND_SET_BAUD, params, 6)) uart_writeText("bt_setbaud() failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_setbdaddr()
|
void bt_setbdaddr()
|
||||||
{
|
{
|
||||||
static unsigned char params[] = { 0xee, 0xff, 0xc0, 0xee, 0xff, 0xc0 }; // reversed
|
params[0] = 0xee;
|
||||||
|
params[1] = 0xff;
|
||||||
|
params[2] = 0xc0;
|
||||||
|
params[3] = 0xee;
|
||||||
|
params[4] = 0xff;
|
||||||
|
params[5] = 0xc0; // reversed
|
||||||
if (hciCommand(OGF_VENDOR, COMMAND_SET_BDADDR, params, 6)) uart_writeText("bt_setbdaddr() failed\n");
|
if (hciCommand(OGF_VENDOR, COMMAND_SET_BDADDR, params, 6)) uart_writeText("bt_setbdaddr() failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +226,11 @@ void sendACLsubscribe(unsigned int handle)
|
||||||
bt_writeByte(lo(channel));
|
bt_writeByte(lo(channel));
|
||||||
bt_writeByte(hi(channel));
|
bt_writeByte(hi(channel));
|
||||||
|
|
||||||
unsigned char params[] = { 0x12, 0x2b, 0x00, 0x01, 0x00 };
|
params[0] = 0x12;
|
||||||
|
params[1] = 0x2b;
|
||||||
|
params[2] = 0x00;
|
||||||
|
params[3] = 0x01;
|
||||||
|
params[4] = 0x00;
|
||||||
|
|
||||||
unsigned int c=0;
|
unsigned int c=0;
|
||||||
while (c++<data_length) bt_writeByte(params[c-1]);
|
while (c++<data_length) bt_writeByte(params[c-1]);
|
||||||
|
@ -221,51 +238,74 @@ void sendACLsubscribe(unsigned int handle)
|
||||||
|
|
||||||
void setLEeventmask(unsigned char mask)
|
void setLEeventmask(unsigned char mask)
|
||||||
{
|
{
|
||||||
unsigned char params[] = { mask, 0, 0, 0, 0, 0, 0, 0 };
|
params[0] = mask;
|
||||||
|
params[1] = 0;
|
||||||
|
params[2] = 0;
|
||||||
|
params[3] = 0;
|
||||||
|
params[4] = 0;
|
||||||
|
params[5] = 0;
|
||||||
|
params[6] = 0;
|
||||||
|
params[7] = 0;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x01, params, 8)) uart_writeText("setLEeventmask failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x01, params, 8)) uart_writeText("setLEeventmask failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEscanenable(unsigned char state, unsigned char duplicates) {
|
void setLEscanenable(unsigned char state, unsigned char duplicates) {
|
||||||
unsigned char params[] = { state, duplicates };
|
params[0] = state;
|
||||||
|
params[1] = duplicates;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0c, params, 2)) uart_writeText(" setLEscanenable failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x0c, params, 2)) uart_writeText(" setLEscanenable failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEscanparameters(unsigned char type, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy) {
|
void setLEscanparameters(unsigned char type, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy) {
|
||||||
unsigned char params[] = { type, linterval, hinterval, lwindow, hwindow, own_address_type, filter_policy };
|
params[0] = type;
|
||||||
|
params[1] = linterval;
|
||||||
|
params[2] = hinterval;
|
||||||
|
params[3] = lwindow;
|
||||||
|
params[4] = hwindow;
|
||||||
|
params[5] = own_address_type;
|
||||||
|
params[6] = filter_policy;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0b, params, 7)) uart_writeText("setLEscanparameters failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x0b, params, 7)) uart_writeText("setLEscanparameters failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEadvertenable(unsigned char state) {
|
void setLEadvertenable(unsigned char state) {
|
||||||
unsigned char params[] = { state };
|
params[0] = state;
|
||||||
uart_writeText("doing the HCIcommand\n");
|
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0a, params, 1)) uart_writeText("setLEadvertenable failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x0a, params, 1)) uart_writeText("setLEadvertenable failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEadvertparameters(unsigned char type, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max, unsigned char own_address_type, unsigned char filter_policy) {
|
void setLEadvertparameters(unsigned char type, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max, unsigned char own_address_type, unsigned char filter_policy) {
|
||||||
unsigned char params[16] = { linterval_min, hinterval_min, linterval_max, hinterval_max, type, own_address_type, 0, 0, 0, 0, 0, 0, 0, 0x07, filter_policy };
|
params[0] = linterval_min;
|
||||||
uart_writeText("doing the HCIcommand\n");
|
params[1] = hinterval_min;
|
||||||
|
params[2] = linterval_max;
|
||||||
|
params[3] = hinterval_max;
|
||||||
|
params[4] = type;
|
||||||
|
params[5] = own_address_type;
|
||||||
|
params[6] = 0;
|
||||||
|
params[7] = 0;
|
||||||
|
params[8] = 0;
|
||||||
|
params[9] = 0;
|
||||||
|
params[10] = 0;
|
||||||
|
params[11] = 0;
|
||||||
|
params[12] = 0;
|
||||||
|
params[13] = 0x07;
|
||||||
|
params[14] = filter_policy;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x06, params, 15)) uart_writeText("setLEadvertparameters failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x06, params, 15)) uart_writeText("setLEadvertparameters failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEadvertdata() {
|
void setLEadvertdata() {
|
||||||
static unsigned char params[] = { 0x19,
|
params[0] = 0x19;
|
||||||
0x02, 0x01, 0x06,
|
params[1] = 0x02; params[2] = 0x01; params[3] = 0x06;
|
||||||
0x03, 0x03, 0xAA, 0xFE,
|
params[4] = 0x03; params[5] = 0x03; params[6] = 0xAA; params[7] = 0xFE;
|
||||||
0x11, 0x16, 0xAA, 0xFE, 0x10, 0x00, 0x03, 0x69, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x2e, 0x65, 0x73,
|
params[8] = 0x11; params[9] = 0x16; params[10] = 0xAA; params[11] = 0xFE; params[12] = 0x10; params[13] = 0x00; params[14] = 0x03;
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
params[15] = 0x69; params[16] = 0x73; params[17] = 0x6f; params[18] = 0x6d; params[19] = 0x65; params[20] = 0x74; params[21] = 0x69; params[22] = 0x6d;
|
||||||
|
params[23] = 0x2e; params[24] = 0x65; params[25] = 0x73;
|
||||||
|
params[26] = 0x00;
|
||||||
|
params[27] = 0x00;
|
||||||
|
params[28] = 0x00;
|
||||||
|
params[29] = 0x00;
|
||||||
|
params[30] = 0x00;
|
||||||
|
params[31] = 0x00;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x08, params, 32)) uart_writeText("setLEadvertdata failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x08, params, 32)) uart_writeText("setLEadvertdata failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void createLEconnection(unsigned char a1, unsigned char a2, unsigned char a3, unsigned char a4, unsigned char a5, unsigned char a6, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max) {
|
|
||||||
unsigned char params[26] = { linterval, hinterval, lwindow, hwindow,
|
|
||||||
filter_policy,
|
|
||||||
0, a1, a2, a3, a4, a5, a6,
|
|
||||||
own_address_type,
|
|
||||||
linterval_min, hinterval_min, linterval_max, hinterval_max,
|
|
||||||
0, 0, 0x2a, 0x00, 0, 0, 0, 0 };
|
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0d, params, 25)) uart_writeText("createLEconnection failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopScanning() {
|
void stopScanning() {
|
||||||
setLEscanenable(0, 0);
|
setLEscanenable(0, 0);
|
||||||
}
|
}
|
||||||
|
@ -310,10 +350,44 @@ void connect(unsigned char *addr)
|
||||||
float BleGranularity = 1.25;
|
float BleGranularity = 1.25;
|
||||||
|
|
||||||
unsigned int p = BleScanInterval / BleScanDivisor;
|
unsigned int p = BleScanInterval / BleScanDivisor;
|
||||||
|
unsigned char lp = lo(p);
|
||||||
|
unsigned char hp = hi(p);
|
||||||
unsigned int q = BleScanWindow / BleScanDivisor;
|
unsigned int q = BleScanWindow / BleScanDivisor;
|
||||||
|
unsigned char lq = lo(q);
|
||||||
|
unsigned char hq = hi(q);
|
||||||
|
|
||||||
unsigned int min_interval = connMinFreq / BleGranularity;
|
unsigned int min_interval = connMinFreq / BleGranularity;
|
||||||
|
unsigned char lmini = lo(min_interval);
|
||||||
|
unsigned char hmini = hi(min_interval);
|
||||||
unsigned int max_interval = connMaxFreq / BleGranularity;
|
unsigned int max_interval = connMaxFreq / BleGranularity;
|
||||||
|
unsigned char lmaxi = lo(max_interval);
|
||||||
|
unsigned char hmaxi = hi(max_interval);
|
||||||
|
|
||||||
createLEconnection(addr[5], addr[4], addr[3], addr[2], addr[1], addr[0], lo(p), hi(p), lo(q), hi(q), 0, 0, lo(min_interval), hi(min_interval), lo(max_interval), hi(max_interval));
|
params[0] = lp;
|
||||||
|
params[1] = hp;
|
||||||
|
params[2] = lq;
|
||||||
|
params[3] = hq;
|
||||||
|
params[4] = 0;
|
||||||
|
params[5] = 0;
|
||||||
|
params[6] = addr[5];
|
||||||
|
params[7] = addr[4];
|
||||||
|
params[8] = addr[3];
|
||||||
|
params[9] = addr[2];
|
||||||
|
params[10] = addr[1];
|
||||||
|
params[11] = addr[0];
|
||||||
|
params[12] = 0;
|
||||||
|
params[13] = lmini;
|
||||||
|
params[14] = hmini;
|
||||||
|
params[15] = lmaxi;
|
||||||
|
params[16] = hmaxi;
|
||||||
|
params[17] = 0;
|
||||||
|
params[18] = 0;
|
||||||
|
params[19] = 0x2a;
|
||||||
|
params[20] = 0x00;
|
||||||
|
params[21] = 0;
|
||||||
|
params[22] = 0;
|
||||||
|
params[23] = 0;
|
||||||
|
params[24] = 0;
|
||||||
|
|
||||||
|
if (hciCommand(OGF_LE_CONTROL, 0x0d, params, 25)) uart_writeText("createLEconnection failed\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,5 +12,4 @@ void startActiveScanning();
|
||||||
void stopScanning();
|
void stopScanning();
|
||||||
void startActiveAdvertising();
|
void startActiveAdvertising();
|
||||||
void connect(unsigned char *addr);
|
void connect(unsigned char *addr);
|
||||||
void bt_flushrx();
|
|
||||||
void sendACLsubscribe(unsigned int handle);
|
void sendACLsubscribe(unsigned int handle);
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
unsigned int width, height, pitch, isrgb;
|
unsigned int width, height, pitch, isrgb;
|
||||||
unsigned char *fb;
|
unsigned char *fb;
|
||||||
|
|
||||||
|
int curx = 0;
|
||||||
|
int cury = 0;
|
||||||
|
|
||||||
void fb_init()
|
void fb_init()
|
||||||
{
|
{
|
||||||
mbox[0] = 35*4; // Length of message in bytes
|
mbox[0] = 35*4; // Length of message in bytes
|
||||||
|
@ -211,3 +214,47 @@ void wait_msec(unsigned int n)
|
||||||
t+=((f/1000)*n)/1000;
|
t+=((f/1000)*n)/1000;
|
||||||
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int strlen(const char *str) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
for (s = str; *s; ++s);
|
||||||
|
return (s - str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugstr(char *str) {
|
||||||
|
if (curx + (strlen(str) * 8) >= 1920) {
|
||||||
|
curx = 0; cury += 8;
|
||||||
|
}
|
||||||
|
if (cury + 8 >= 1080) {
|
||||||
|
cury = 0;
|
||||||
|
}
|
||||||
|
drawString(curx, cury, str, 0x0f, 1);
|
||||||
|
curx += (strlen(str) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugcrlf(void) {
|
||||||
|
curx = 0; cury += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugch(unsigned char b) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=4;c>=0;c-=4) {
|
||||||
|
n=(b>>c)&0xF;
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
debugstr((char *)&n);
|
||||||
|
}
|
||||||
|
debugstr(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void debughex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
debugstr((char *)&n);
|
||||||
|
}
|
||||||
|
debugstr(" ");
|
||||||
|
}
|
||||||
|
|
|
@ -7,3 +7,7 @@ void drawCircle(int x0, int y0, int radius, unsigned char attr, int fill);
|
||||||
void drawLine(int x1, int y1, int x2, int y2, unsigned char attr);
|
void drawLine(int x1, int y1, int x2, int y2, unsigned char attr);
|
||||||
void moveRect(int oldx, int oldy, int width, int height, int shiftx, int shifty, unsigned char attr);
|
void moveRect(int oldx, int oldy, int width, int height, int shiftx, int shifty, unsigned char attr);
|
||||||
void wait_msec(unsigned int n);
|
void wait_msec(unsigned int n);
|
||||||
|
void debugstr(char *str);
|
||||||
|
void debugcrlf(void);
|
||||||
|
void debugch(unsigned char b);
|
||||||
|
void debughex(unsigned int d);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#define PERIPHERAL_BASE 0xFE000000
|
#define PERIPHERAL_BASE 0xFE000000
|
||||||
|
#define SAFE_ADDRESS 0x00210000 // Somewhere safe to store a lot of data
|
||||||
|
|
||||||
void uart_init();
|
void uart_init();
|
||||||
void uart_writeText(char *buffer);
|
void uart_writeText(char *buffer);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "bt.h"
|
#include "bt.h"
|
||||||
|
#include "fb.h"
|
||||||
#define memcmp __builtin_memcmp
|
|
||||||
|
|
||||||
#define MAX_MSG_LEN 50
|
#define MAX_MSG_LEN 50
|
||||||
#define MAX_READ_RUN 100
|
#define MAX_READ_RUN 100
|
||||||
|
@ -26,6 +25,16 @@ unsigned char echo_addr[6];
|
||||||
unsigned int connected = 0;
|
unsigned int connected = 0;
|
||||||
unsigned int connection_handle = 0;
|
unsigned int connection_handle = 0;
|
||||||
|
|
||||||
|
int memcmp(const char *str1, const char *str2, int count) {
|
||||||
|
const char *s1 = (const char*)str1;
|
||||||
|
const char *s2 = (const char*)str2;
|
||||||
|
|
||||||
|
while (count-- > 0) {
|
||||||
|
if (*s1++ != *s2++) return s1[-1] < s2[-1] ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void hci_poll2(unsigned char byte)
|
void hci_poll2(unsigned char byte)
|
||||||
{
|
{
|
||||||
switch (poll_state) {
|
switch (poll_state) {
|
||||||
|
@ -71,62 +80,51 @@ unsigned char *hci_poll()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_search()
|
void bt_search(void) {
|
||||||
{
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
while ( (buf = hci_poll()) ) {
|
while ( (buf = hci_poll()) ) {
|
||||||
if (data_len >= 2) {
|
if (data_len >= 2) {
|
||||||
if (buf[0] == LE_ADREPORT_CODE) {
|
if (buf[0] == LE_ADREPORT_CODE) {
|
||||||
unsigned char numreports = buf[1];
|
if (buf[1] == 1) { // num_reports
|
||||||
|
if (buf[2] == 0) { // event_type
|
||||||
if (numreports == 1) {
|
int bufindex = 0;
|
||||||
unsigned char event_type = buf[2];
|
|
||||||
|
|
||||||
if (event_type == 0x00) {
|
|
||||||
unsigned char buf_len = buf[10];
|
|
||||||
unsigned char ad_len = buf[11];
|
unsigned char ad_len = buf[11];
|
||||||
|
|
||||||
if (ad_len < data_len && buf_len + 11 == data_len - 1) {
|
for (int c=9;c>=4;c--) echo_addr[9-c] = buf[bufindex + c]; // save the mac address
|
||||||
for (int c=9;c>=4;c--) echo_addr[9-c] = buf[c];
|
bufindex += 11;
|
||||||
buf += 11;
|
|
||||||
|
|
||||||
got_echo_sid = 0; got_echo_name = 0; // Reset the search state machine
|
got_echo_sid = 0; got_echo_name = 0; // Reset the search state machine
|
||||||
do {
|
do {
|
||||||
ad_len = buf[0];
|
ad_len = buf[bufindex];
|
||||||
unsigned char ad_type = buf[1];
|
unsigned char ad_type = buf[bufindex + 1];
|
||||||
buf += 2;
|
bufindex += 2;
|
||||||
|
|
||||||
if (ad_len >= 2) {
|
if (ad_len >= 2) {
|
||||||
if (ad_type == 0x03) {
|
if (ad_type == 0x03) {
|
||||||
unsigned int sid=0;
|
unsigned int sid = buf[bufindex] | (buf[bufindex + 1] << 8);
|
||||||
|
if (sid == 0xEC00) {
|
||||||
|
got_echo_sid = 1;
|
||||||
|
debugstr("got sid... ");
|
||||||
|
}
|
||||||
|
} else if (ad_type == 0x09) {
|
||||||
|
char remote_name[ad_len - 1];
|
||||||
|
unsigned int d=0;
|
||||||
|
|
||||||
for (int d=0;d<ad_len - 1;d+=2) {
|
while (d<ad_len - 1) {
|
||||||
sid = buf[d] | (buf[d+1] << 8);
|
remote_name[d] = buf[bufindex + d];
|
||||||
if (sid == 0xEC00) {
|
d++;
|
||||||
uart_hex(sid); uart_writeText(" ");
|
}
|
||||||
got_echo_sid = 1;
|
if (!memcmp(remote_name,"echo",4)) {
|
||||||
}
|
got_echo_name = 1;
|
||||||
}
|
debugstr("got name... ");
|
||||||
} else if (ad_type == 0x09) {
|
}
|
||||||
char remote_name[ad_len - 1];
|
}
|
||||||
unsigned int d=0;
|
}
|
||||||
|
|
||||||
while (d<ad_len - 1) {
|
bufindex += ad_len - 1;
|
||||||
remote_name[d] = buf[d];
|
} while (bufindex < data_len);
|
||||||
d++;
|
}
|
||||||
}
|
|
||||||
if (!memcmp(remote_name,"echo",4)) {
|
|
||||||
uart_writeText(remote_name); uart_writeText(" ");
|
|
||||||
got_echo_name = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf += ad_len - 1;
|
|
||||||
} while (buf[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,9 +139,9 @@ void bt_conn()
|
||||||
if (data_len >= 2) {
|
if (data_len >= 2) {
|
||||||
if (buf[0] == LE_CONNECT_CODE && !connected) {
|
if (buf[0] == LE_CONNECT_CODE && !connected) {
|
||||||
connected = !buf[1];
|
connected = !buf[1];
|
||||||
uart_hex(connected); uart_writeText(" ");
|
debughex(connected); debugstr(" ");
|
||||||
connection_handle = buf[2] | (buf[3] << 8);
|
connection_handle = buf[2] | (buf[3] << 8);
|
||||||
uart_hex(connection_handle); uart_writeText(" ");
|
debughex(connection_handle); debugstr(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,80 +153,109 @@ void acl_poll()
|
||||||
unsigned char byte = bt_readByte();
|
unsigned char byte = bt_readByte();
|
||||||
|
|
||||||
if (byte == HCI_EVENT_PKT) {
|
if (byte == HCI_EVENT_PKT) {
|
||||||
unsigned char opcode = bt_waitReadByte();
|
bt_waitReadByte(); // opcode
|
||||||
unsigned char length = bt_waitReadByte();
|
unsigned char length = bt_waitReadByte();
|
||||||
for (int i=0;i<length;i++) bt_waitReadByte();
|
for (int i=0;i<length;i++) bt_waitReadByte();
|
||||||
} else if (byte == HCI_ACL_PKT) {
|
} else if (byte == HCI_ACL_PKT) {
|
||||||
|
bt_waitReadByte(); // handle1
|
||||||
|
bt_waitReadByte(); // handle2
|
||||||
|
|
||||||
unsigned char h1 = bt_waitReadByte();
|
unsigned char h1 = bt_waitReadByte();
|
||||||
unsigned char h2 = bt_waitReadByte();
|
unsigned char h2 = bt_waitReadByte();
|
||||||
|
|
||||||
unsigned int handle = h1 | (h2 & 0x0f);
|
unsigned int dlen = h1 | (h2 << 8);
|
||||||
unsigned char flags = (h2 & 0xf0) >> 4;
|
unsigned char data[dlen];
|
||||||
|
|
||||||
h1 = bt_waitReadByte();
|
if (dlen > 7) {
|
||||||
h2 = bt_waitReadByte();
|
for (int i=0;i<dlen;i++) data[i] = bt_waitReadByte();
|
||||||
|
|
||||||
unsigned int length = h1 | (h2 << 8);
|
unsigned int length = data[0] | (data[1] << 8);
|
||||||
unsigned char data[length];
|
unsigned int channel = data[2] | (data[3] << 8);
|
||||||
|
unsigned char opcode = data[4];
|
||||||
|
|
||||||
for (int i=0;i<length;i++) data[i] = bt_waitReadByte();
|
if (length == 4 && opcode == 0x1b) {
|
||||||
|
if (channel == 4 && data[5] == 0x2a && data[6] == 0x00) {
|
||||||
length = data[0] | (data[1] << 8);
|
debugcrlf();
|
||||||
|
debugstr("Got ACL packet... ");
|
||||||
unsigned int channel = data[2] | (data[3] << 8);
|
debugch(data[7]);
|
||||||
unsigned char opcode = data[4];
|
}
|
||||||
|
}
|
||||||
if (opcode == 0x1b) {
|
}
|
||||||
unsigned int from_handle = data[5] | (data[6] << 8);
|
|
||||||
|
|
||||||
for (int c=0;c<length-3;c++) uart_byte(data[7+c]);
|
|
||||||
uart_writeText("\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main()
|
void run_search(void) {
|
||||||
{
|
// Start scanning
|
||||||
uart_init();
|
debugstr("Setting event mask... ");
|
||||||
bt_init();
|
|
||||||
|
|
||||||
uart_writeText("Initialising Bluetooth: ");
|
|
||||||
bt_reset();
|
|
||||||
bt_loadfirmware();
|
|
||||||
bt_setbaud();
|
|
||||||
bt_setbdaddr();
|
|
||||||
|
|
||||||
// Print the BD_ADDR
|
|
||||||
unsigned char local_addr[6];
|
|
||||||
bt_getbdaddr(local_addr);
|
|
||||||
for (int c=5;c>=0;c--) uart_byte(local_addr[c]);
|
|
||||||
uart_writeText("\n");
|
|
||||||
|
|
||||||
// Start scanning for echo
|
|
||||||
setLEeventmask(0xff);
|
setLEeventmask(0xff);
|
||||||
|
debugstr("Starting scanning... ");
|
||||||
startActiveScanning();
|
startActiveScanning();
|
||||||
uart_writeText("Waiting for echo: ");
|
|
||||||
|
// Search for the echo
|
||||||
|
debugstr("Waiting...");
|
||||||
|
debugcrlf();
|
||||||
while (!(got_echo_sid && got_echo_name)) bt_search();
|
while (!(got_echo_sid && got_echo_name)) bt_search();
|
||||||
stopScanning();
|
stopScanning();
|
||||||
for (int c=0;c<=5;c++) uart_byte(echo_addr[c]);
|
for (int c=0;c<=5;c++) debugch(echo_addr[c]);
|
||||||
uart_writeText("\n");
|
debugcrlf();
|
||||||
|
|
||||||
// Ask to connect to the echo
|
// Connecting to echo
|
||||||
uart_writeText("Connecting to echo: ");
|
debugstr("Connecting to echo: ");
|
||||||
connect(echo_addr);
|
connect(echo_addr);
|
||||||
while (!connected) bt_conn();
|
while (!connected) bt_conn();
|
||||||
uart_writeText("\n");
|
debugstr("Connected!");
|
||||||
|
debugcrlf();
|
||||||
|
|
||||||
// Get the characteristic value
|
// Get the characteristic value
|
||||||
uart_writeText("Sending read request: ");
|
debugstr("Sending read request: ");
|
||||||
uart_hex(connection_handle); uart_writeText("\n");
|
debughex(connection_handle); debugcrlf();
|
||||||
sendACLsubscribe(connection_handle);
|
sendACLsubscribe(connection_handle);
|
||||||
|
|
||||||
// Into the main infinite loop
|
// Enter an infinite loop
|
||||||
uart_writeText("Waiting for input...\n");
|
debugstr("Going loopy...");
|
||||||
while (1) {
|
while (1) {
|
||||||
acl_poll();
|
acl_poll();
|
||||||
uart_update();
|
uart_update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void run_eddystone(void) {
|
||||||
|
// Start advertising
|
||||||
|
debugstr("Setting event mask... ");
|
||||||
|
setLEeventmask(0xff);
|
||||||
|
debugstr("Starting advertsing... ");
|
||||||
|
startActiveAdvertising();
|
||||||
|
|
||||||
|
// Enter an infinite loop
|
||||||
|
debugstr("Going loopy...");
|
||||||
|
while (1) {
|
||||||
|
uart_update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
fb_init();
|
||||||
|
uart_init();
|
||||||
|
bt_init();
|
||||||
|
|
||||||
|
debugstr("Initialising Bluetooth: ");
|
||||||
|
debugstr(">> reset: ");
|
||||||
|
bt_reset();
|
||||||
|
debugstr(">> firmware load: ");
|
||||||
|
bt_loadfirmware();
|
||||||
|
debugstr(">> set baud: ");
|
||||||
|
bt_setbaud();
|
||||||
|
debugstr(">> set bdaddr: ");
|
||||||
|
bt_setbdaddr();
|
||||||
|
|
||||||
|
// Print the BD_ADDR
|
||||||
|
unsigned char local_addr[6];
|
||||||
|
bt_getbdaddr(local_addr);
|
||||||
|
for (int c=5;c>=0;c--) debugch(local_addr[c]);
|
||||||
|
debugcrlf();
|
||||||
|
|
||||||
|
// Test out the scanning
|
||||||
|
run_search();
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
CFILES = $(wildcard *.c)
|
CFILES = $(wildcard *.c)
|
||||||
OFILES = $(CFILES:.c=.o)
|
OFILES = $(CFILES:.c=.o)
|
||||||
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
LLVMPATH = /opt/homebrew/opt/llvm/bin
|
||||||
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
|
||||||
|
|
||||||
all: clean kernel8.img
|
all: clean kernel8.img
|
||||||
|
|
||||||
boot.o: boot.S
|
boot.o: boot.S
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
clang --target=aarch64-elf $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
BCM4345C0.o : BCM4345C0.hcd
|
BCM4345C0.o : BCM4345C0.hcd
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
$(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
clang --target=aarch64-elf $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
||||||
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
||||||
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
||||||
|
|
22
part8-breakout-ble/Makefile.gcc
Normal file
22
part8-breakout-ble/Makefile.gcc
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ../../gcc-arm-9.2-2019.12-x86_64-aarch64-none-elf/bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
BCM4345C0.o : BCM4345C0.hcd
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
||||||
|
$(GCCPATH)/aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)/aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true
|
22
part8-breakout-ble/Makefile.gcc.windows
Normal file
22
part8-breakout-ble/Makefile.gcc.windows
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
CFILES = $(wildcard *.c)
|
||||||
|
OFILES = $(CFILES:.c=.o)
|
||||||
|
GCCFLAGS = -Wall -O2 -ffreestanding -nostdinc -nostdlib -nostartfiles
|
||||||
|
GCCPATH = ..\..\gcc-arm-10.2-2020.11-mingw-w64-i686-aarch64-none-elf\bin
|
||||||
|
|
||||||
|
all: clean kernel8.img
|
||||||
|
|
||||||
|
boot.o: boot.S
|
||||||
|
$(GCCPATH)\aarch64-none-elf-gcc $(GCCFLAGS) -c boot.S -o boot.o
|
||||||
|
|
||||||
|
BCM4345C0.o : BCM4345C0.hcd
|
||||||
|
$(GCCPATH)\aarch64-none-elf-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(GCCPATH)\aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
kernel8.img: boot.o $(OFILES) BCM4345C0.o
|
||||||
|
$(GCCPATH)\aarch64-none-elf-ld -nostdlib -nostartfiles boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
|
||||||
|
$(GCCPATH)\aarch64-none-elf-objcopy -O binary kernel8.elf kernel8.img
|
||||||
|
|
||||||
|
clean:
|
||||||
|
del kernel8.elf *.o *.img
|
|
@ -1,6 +1,8 @@
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "fb.h"
|
#include "fb.h"
|
||||||
|
|
||||||
|
volatile unsigned char *params = (unsigned char *)SAFE_ADDRESS;
|
||||||
|
|
||||||
// UART0
|
// UART0
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -91,7 +93,7 @@ enum {
|
||||||
|
|
||||||
unsigned char empty[] = {};
|
unsigned char empty[] = {};
|
||||||
|
|
||||||
int hciCommandBytes(unsigned char *opcodebytes, unsigned char *data, unsigned char length)
|
int hciCommandBytes(volatile unsigned char *opcodebytes, volatile unsigned char *data, unsigned char length)
|
||||||
{
|
{
|
||||||
unsigned char c=0;
|
unsigned char c=0;
|
||||||
|
|
||||||
|
@ -128,7 +130,7 @@ int hciCommandBytes(unsigned char *opcodebytes, unsigned char *data, unsigned ch
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hciCommand(unsigned short ogf, unsigned short ocf, unsigned char *data, unsigned char length)
|
int hciCommand(unsigned short ogf, unsigned short ocf, volatile unsigned char *data, unsigned char length)
|
||||||
{
|
{
|
||||||
unsigned short opcode = ogf << 10 | ocf;
|
unsigned short opcode = ogf << 10 | ocf;
|
||||||
unsigned char opcodebytes[2] = { lo(opcode), hi(opcode) };
|
unsigned char opcodebytes[2] = { lo(opcode), hi(opcode) };
|
||||||
|
@ -151,11 +153,12 @@ void bt_loadfirmware()
|
||||||
unsigned int size = (long)&_binary_BCM4345C0_hcd_size;
|
unsigned int size = (long)&_binary_BCM4345C0_hcd_size;
|
||||||
|
|
||||||
while (c < size) {
|
while (c < size) {
|
||||||
unsigned char opcodebytes[] = { _binary_BCM4345C0_hcd_start[c], _binary_BCM4345C0_hcd_start[c+1] };
|
params[0] = _binary_BCM4345C0_hcd_start[c];
|
||||||
|
params[1] = _binary_BCM4345C0_hcd_start[c+1];
|
||||||
unsigned char length = _binary_BCM4345C0_hcd_start[c+2];
|
unsigned char length = _binary_BCM4345C0_hcd_start[c+2];
|
||||||
unsigned char *data = &(_binary_BCM4345C0_hcd_start[c+3]);
|
unsigned char *data = &(_binary_BCM4345C0_hcd_start[c+3]);
|
||||||
|
|
||||||
if (hciCommandBytes(opcodebytes, data, length)) {
|
if (hciCommandBytes(params, data, length)) {
|
||||||
uart_writeText("Firmware data load failed\n");
|
uart_writeText("Firmware data load failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -167,13 +170,23 @@ void bt_loadfirmware()
|
||||||
|
|
||||||
void bt_setbaud()
|
void bt_setbaud()
|
||||||
{
|
{
|
||||||
static unsigned char params[] = { 0, 0, 0x00, 0xc2, 0x01, 0x00 }; // little endian, 115200
|
params[0] = 0;
|
||||||
|
params[1] = 0;
|
||||||
|
params[2] = 0x00;
|
||||||
|
params[3] = 0xc2;
|
||||||
|
params[4] = 0x01;
|
||||||
|
params[5] = 0x00; // little endian, 115200
|
||||||
if (hciCommand(OGF_VENDOR, COMMAND_SET_BAUD, params, 6)) uart_writeText("bt_setbaud() failed\n");
|
if (hciCommand(OGF_VENDOR, COMMAND_SET_BAUD, params, 6)) uart_writeText("bt_setbaud() failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_setbdaddr()
|
void bt_setbdaddr()
|
||||||
{
|
{
|
||||||
static unsigned char params[] = { 0xee, 0xff, 0xc0, 0xee, 0xff, 0xc0 }; // reversed
|
params[0] = 0xee;
|
||||||
|
params[1] = 0xff;
|
||||||
|
params[2] = 0xc0;
|
||||||
|
params[3] = 0xee;
|
||||||
|
params[4] = 0xff;
|
||||||
|
params[5] = 0xc0; // reversed
|
||||||
if (hciCommand(OGF_VENDOR, COMMAND_SET_BDADDR, params, 6)) uart_writeText("bt_setbdaddr() failed\n");
|
if (hciCommand(OGF_VENDOR, COMMAND_SET_BDADDR, params, 6)) uart_writeText("bt_setbdaddr() failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,59 +226,87 @@ void sendACLsubscribe(unsigned int handle)
|
||||||
bt_writeByte(lo(channel));
|
bt_writeByte(lo(channel));
|
||||||
bt_writeByte(hi(channel));
|
bt_writeByte(hi(channel));
|
||||||
|
|
||||||
unsigned char params[] = { 0x12, 0x2b, 0x00, 0x01, 0x00 };
|
params[0] = 0x12;
|
||||||
|
params[1] = 0x2b;
|
||||||
|
params[2] = 0x00;
|
||||||
|
params[3] = 0x01;
|
||||||
|
params[4] = 0x00;
|
||||||
|
|
||||||
unsigned int c=0;
|
unsigned int c=0;
|
||||||
|
|
||||||
while (c++<data_length) bt_writeByte(params[c-1]);
|
while (c++<data_length) bt_writeByte(params[c-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEeventmask(unsigned char mask)
|
void setLEeventmask(unsigned char mask)
|
||||||
{
|
{
|
||||||
unsigned char params[] = { mask, 0, 0, 0, 0, 0, 0, 0 };
|
params[0] = mask;
|
||||||
|
params[1] = 0;
|
||||||
|
params[2] = 0;
|
||||||
|
params[3] = 0;
|
||||||
|
params[4] = 0;
|
||||||
|
params[5] = 0;
|
||||||
|
params[6] = 0;
|
||||||
|
params[7] = 0;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x01, params, 8)) uart_writeText("setLEeventmask failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x01, params, 8)) uart_writeText("setLEeventmask failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEscanenable(unsigned char state, unsigned char duplicates) {
|
void setLEscanenable(unsigned char state, unsigned char duplicates) {
|
||||||
unsigned char params[] = { state, duplicates };
|
params[0] = state;
|
||||||
|
params[1] = duplicates;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0c, params, 2)) uart_writeText(" setLEscanenable failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x0c, params, 2)) uart_writeText(" setLEscanenable failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEscanparameters(unsigned char type, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy) {
|
void setLEscanparameters(unsigned char type, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy) {
|
||||||
unsigned char params[] = { type, linterval, hinterval, lwindow, hwindow, own_address_type, filter_policy };
|
params[0] = type;
|
||||||
|
params[1] = linterval;
|
||||||
|
params[2] = hinterval;
|
||||||
|
params[3] = lwindow;
|
||||||
|
params[4] = hwindow;
|
||||||
|
params[5] = own_address_type;
|
||||||
|
params[6] = filter_policy;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0b, params, 7)) uart_writeText("setLEscanparameters failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x0b, params, 7)) uart_writeText("setLEscanparameters failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEadvertenable(unsigned char state) {
|
void setLEadvertenable(unsigned char state) {
|
||||||
unsigned char params[] = { state };
|
params[0] = state;
|
||||||
uart_writeText("doing the HCIcommand\n");
|
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0a, params, 1)) uart_writeText("setLEadvertenable failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x0a, params, 1)) uart_writeText("setLEadvertenable failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEadvertparameters(unsigned char type, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max, unsigned char own_address_type, unsigned char filter_policy) {
|
void setLEadvertparameters(unsigned char type, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max, unsigned char own_address_type, unsigned char filter_policy) {
|
||||||
unsigned char params[16] = { linterval_min, hinterval_min, linterval_max, hinterval_max, type, own_address_type, 0, 0, 0, 0, 0, 0, 0, 0x07, filter_policy };
|
params[0] = linterval_min;
|
||||||
uart_writeText("doing the HCIcommand\n");
|
params[1] = hinterval_min;
|
||||||
|
params[2] = linterval_max;
|
||||||
|
params[3] = hinterval_max;
|
||||||
|
params[4] = type;
|
||||||
|
params[5] = own_address_type;
|
||||||
|
params[6] = 0;
|
||||||
|
params[7] = 0;
|
||||||
|
params[8] = 0;
|
||||||
|
params[9] = 0;
|
||||||
|
params[10] = 0;
|
||||||
|
params[11] = 0;
|
||||||
|
params[12] = 0;
|
||||||
|
params[13] = 0x07;
|
||||||
|
params[14] = filter_policy;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x06, params, 15)) uart_writeText("setLEadvertparameters failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x06, params, 15)) uart_writeText("setLEadvertparameters failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLEadvertdata() {
|
void setLEadvertdata() {
|
||||||
static unsigned char params[] = { 0x19,
|
params[0] = 0x19;
|
||||||
0x02, 0x01, 0x06,
|
params[1] = 0x02; params[2] = 0x01; params[3] = 0x06;
|
||||||
0x03, 0x03, 0xAA, 0xFE,
|
params[4] = 0x03; params[5] = 0x03; params[6] = 0xAA; params[7] = 0xFE;
|
||||||
0x11, 0x16, 0xAA, 0xFE, 0x10, 0x00, 0x03, 0x69, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x2e, 0x65, 0x73,
|
params[8] = 0x11; params[9] = 0x16; params[10] = 0xAA; params[11] = 0xFE; params[12] = 0x10; params[13] = 0x00; params[14] = 0x03;
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
params[15] = 0x69; params[16] = 0x73; params[17] = 0x6f; params[18] = 0x6d; params[19] = 0x65; params[20] = 0x74; params[21] = 0x69; params[22] = 0x6d;
|
||||||
|
params[23] = 0x2e; params[24] = 0x65; params[25] = 0x73;
|
||||||
|
params[26] = 0x00;
|
||||||
|
params[27] = 0x00;
|
||||||
|
params[28] = 0x00;
|
||||||
|
params[29] = 0x00;
|
||||||
|
params[30] = 0x00;
|
||||||
|
params[31] = 0x00;
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x08, params, 32)) uart_writeText("setLEadvertdata failed\n");
|
if (hciCommand(OGF_LE_CONTROL, 0x08, params, 32)) uart_writeText("setLEadvertdata failed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void createLEconnection(unsigned char a1, unsigned char a2, unsigned char a3, unsigned char a4, unsigned char a5, unsigned char a6, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy, unsigned char linterval_min, unsigned char hinterval_min, unsigned char linterval_max, unsigned char hinterval_max) {
|
|
||||||
unsigned char params[26] = { linterval, hinterval, lwindow, hwindow,
|
|
||||||
filter_policy,
|
|
||||||
0, a1, a2, a3, a4, a5, a6,
|
|
||||||
own_address_type,
|
|
||||||
linterval_min, hinterval_min, linterval_max, hinterval_max,
|
|
||||||
0, 0, 0x2a, 0x00, 0, 0, 0, 0 };
|
|
||||||
if (hciCommand(OGF_LE_CONTROL, 0x0d, params, 25)) uart_writeText("createLEconnection failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopScanning() {
|
void stopScanning() {
|
||||||
setLEscanenable(0, 0);
|
setLEscanenable(0, 0);
|
||||||
}
|
}
|
||||||
|
@ -310,10 +351,44 @@ void connect(unsigned char *addr)
|
||||||
float BleGranularity = 1.25;
|
float BleGranularity = 1.25;
|
||||||
|
|
||||||
unsigned int p = BleScanInterval / BleScanDivisor;
|
unsigned int p = BleScanInterval / BleScanDivisor;
|
||||||
|
unsigned char lp = lo(p);
|
||||||
|
unsigned char hp = hi(p);
|
||||||
unsigned int q = BleScanWindow / BleScanDivisor;
|
unsigned int q = BleScanWindow / BleScanDivisor;
|
||||||
|
unsigned char lq = lo(q);
|
||||||
|
unsigned char hq = hi(q);
|
||||||
|
|
||||||
unsigned int min_interval = connMinFreq / BleGranularity;
|
unsigned int min_interval = connMinFreq / BleGranularity;
|
||||||
|
unsigned char lmini = lo(min_interval);
|
||||||
|
unsigned char hmini = hi(min_interval);
|
||||||
unsigned int max_interval = connMaxFreq / BleGranularity;
|
unsigned int max_interval = connMaxFreq / BleGranularity;
|
||||||
|
unsigned char lmaxi = lo(max_interval);
|
||||||
|
unsigned char hmaxi = hi(max_interval);
|
||||||
|
|
||||||
createLEconnection(addr[5], addr[4], addr[3], addr[2], addr[1], addr[0], lo(p), hi(p), lo(q), hi(q), 0, 0, lo(min_interval), hi(min_interval), lo(max_interval), hi(max_interval));
|
params[0] = lp;
|
||||||
|
params[1] = hp;
|
||||||
|
params[2] = lq;
|
||||||
|
params[3] = hq;
|
||||||
|
params[4] = 0;
|
||||||
|
params[5] = 0;
|
||||||
|
params[6] = addr[5];
|
||||||
|
params[7] = addr[4];
|
||||||
|
params[8] = addr[3];
|
||||||
|
params[9] = addr[2];
|
||||||
|
params[10] = addr[1];
|
||||||
|
params[11] = addr[0];
|
||||||
|
params[12] = 0;
|
||||||
|
params[13] = lmini;
|
||||||
|
params[14] = hmini;
|
||||||
|
params[15] = lmaxi;
|
||||||
|
params[16] = hmaxi;
|
||||||
|
params[17] = 0;
|
||||||
|
params[18] = 0;
|
||||||
|
params[19] = 0x2a;
|
||||||
|
params[20] = 0x00;
|
||||||
|
params[21] = 0;
|
||||||
|
params[22] = 0;
|
||||||
|
params[23] = 0;
|
||||||
|
params[24] = 0;
|
||||||
|
|
||||||
|
if (hciCommand(OGF_LE_CONTROL, 0x0d, params, 25)) uart_writeText("createLEconnection failed\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ void bt_getbdaddr(unsigned char *bdaddr);
|
||||||
void bt_init();
|
void bt_init();
|
||||||
unsigned int bt_isReadByteReady();
|
unsigned int bt_isReadByteReady();
|
||||||
unsigned char bt_readByte();
|
unsigned char bt_readByte();
|
||||||
|
unsigned char bt_waitReadByte();
|
||||||
void setLEeventmask(unsigned char mask);
|
void setLEeventmask(unsigned char mask);
|
||||||
void startActiveScanning();
|
void startActiveScanning();
|
||||||
void stopScanning();
|
void stopScanning();
|
||||||
|
|
|
@ -37,7 +37,7 @@ var ioHook = require('iohook');
|
||||||
|
|
||||||
var buf = Buffer.allocUnsafe(1);
|
var buf = Buffer.allocUnsafe(1);
|
||||||
var obuf = Buffer.allocUnsafe(1);
|
var obuf = Buffer.allocUnsafe(1);
|
||||||
const scrwidth = 1680;
|
const scrwidth = 1440;
|
||||||
const divisor = scrwidth / 100;
|
const divisor = scrwidth / 100;
|
||||||
|
|
||||||
ioHook.on( 'mousemove', event => {
|
ioHook.on( 'mousemove', event => {
|
||||||
|
|
|
@ -2,9 +2,14 @@
|
||||||
#include "mb.h"
|
#include "mb.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
|
#define DEBUG 1
|
||||||
|
|
||||||
unsigned int width, height, pitch, isrgb;
|
unsigned int width, height, pitch, isrgb;
|
||||||
unsigned char *fb;
|
unsigned char *fb;
|
||||||
|
|
||||||
|
int curx = 0;
|
||||||
|
int cury = 0;
|
||||||
|
|
||||||
void fb_init()
|
void fb_init()
|
||||||
{
|
{
|
||||||
mbox[0] = 35*4; // Length of message in bytes
|
mbox[0] = 35*4; // Length of message in bytes
|
||||||
|
@ -210,3 +215,47 @@ void wait_msec(unsigned int n)
|
||||||
t+=((f/1000)*n)/1000;
|
t+=((f/1000)*n)/1000;
|
||||||
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r<t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int strlen(const char *str) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
for (s = str; *s; ++s);
|
||||||
|
return (s - str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugstr(char *str) {
|
||||||
|
if (curx + (strlen(str) * 8) >= 1920) {
|
||||||
|
curx = 0; cury += 8;
|
||||||
|
}
|
||||||
|
if (cury + 8 >= 1080) {
|
||||||
|
cury = 0;
|
||||||
|
}
|
||||||
|
if (DEBUG == 1) drawString(curx, cury, str, 0x0f, 1);
|
||||||
|
curx += (strlen(str) * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugcrlf(void) {
|
||||||
|
curx = 0; cury += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debugch(unsigned char b) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=4;c>=0;c-=4) {
|
||||||
|
n=(b>>c)&0xF;
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
debugstr((char *)&n);
|
||||||
|
}
|
||||||
|
debugstr(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
void debughex(unsigned int d) {
|
||||||
|
unsigned int n;
|
||||||
|
int c;
|
||||||
|
for(c=28;c>=0;c-=4) {
|
||||||
|
n=(d>>c)&0xF;
|
||||||
|
n+=n>9?0x37:0x30;
|
||||||
|
debugstr((char *)&n);
|
||||||
|
}
|
||||||
|
debugstr(" ");
|
||||||
|
}
|
||||||
|
|
|
@ -7,3 +7,7 @@ void drawCircle(int x0, int y0, int radius, unsigned char attr, int fill);
|
||||||
void drawLine(int x1, int y1, int x2, int y2, unsigned char attr);
|
void drawLine(int x1, int y1, int x2, int y2, unsigned char attr);
|
||||||
void moveRectAbs(int oldx, int oldy, int width, int height, int newx, int newy, unsigned char attr);
|
void moveRectAbs(int oldx, int oldy, int width, int height, int newx, int newy, unsigned char attr);
|
||||||
void wait_msec(unsigned int n);
|
void wait_msec(unsigned int n);
|
||||||
|
void debugstr(char *str);
|
||||||
|
void debugcrlf(void);
|
||||||
|
void debugch(unsigned char b);
|
||||||
|
void debughex(unsigned int d);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#define PERIPHERAL_BASE 0xFE000000
|
#define PERIPHERAL_BASE 0xFE000000
|
||||||
|
#define SAFE_ADDRESS 0x00210000 // Somewhere safe to store a lot of data
|
||||||
|
|
||||||
void uart_init();
|
void uart_init();
|
||||||
void uart_writeText(char *buffer);
|
void uart_writeText(char *buffer);
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
#include "fb.h"
|
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "bt.h"
|
#include "bt.h"
|
||||||
|
#include "fb.h"
|
||||||
|
|
||||||
// The BLE stuff
|
|
||||||
#define memcmp __builtin_memcmp
|
|
||||||
#define MAX_MSG_LEN 50
|
#define MAX_MSG_LEN 50
|
||||||
#define MAX_READ_RUN 100
|
#define MAX_READ_RUN 100
|
||||||
|
|
||||||
|
@ -23,10 +21,22 @@ enum {
|
||||||
unsigned int got_echo_sid = 0;
|
unsigned int got_echo_sid = 0;
|
||||||
unsigned int got_echo_name = 0;
|
unsigned int got_echo_name = 0;
|
||||||
unsigned char echo_addr[6];
|
unsigned char echo_addr[6];
|
||||||
|
|
||||||
unsigned int connected = 0;
|
unsigned int connected = 0;
|
||||||
unsigned int connection_handle = 0;
|
unsigned int connection_handle = 0;
|
||||||
|
|
||||||
unsigned char dir = 50;
|
unsigned char dir = 50;
|
||||||
|
|
||||||
|
int memcmp(const char *str1, const char *str2, int count) {
|
||||||
|
const char *s1 = (const char*)str1;
|
||||||
|
const char *s2 = (const char*)str2;
|
||||||
|
|
||||||
|
while (count-- > 0) {
|
||||||
|
if (*s1++ != *s2++) return s1[-1] < s2[-1] ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void hci_poll2(unsigned char byte)
|
void hci_poll2(unsigned char byte)
|
||||||
{
|
{
|
||||||
switch (poll_state) {
|
switch (poll_state) {
|
||||||
|
@ -72,62 +82,51 @@ unsigned char *hci_poll()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_search()
|
void bt_search(void) {
|
||||||
{
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
while ( (buf = hci_poll()) ) {
|
while ( (buf = hci_poll()) ) {
|
||||||
if (data_len >= 2) {
|
if (data_len >= 2) {
|
||||||
if (buf[0] == LE_ADREPORT_CODE) {
|
if (buf[0] == LE_ADREPORT_CODE) {
|
||||||
unsigned char numreports = buf[1];
|
if (buf[1] == 1) { // num_reports
|
||||||
|
if (buf[2] == 0) { // event_type
|
||||||
if (numreports == 1) {
|
int bufindex = 0;
|
||||||
unsigned char event_type = buf[2];
|
|
||||||
|
|
||||||
if (event_type == 0x00) {
|
|
||||||
unsigned char buf_len = buf[10];
|
|
||||||
unsigned char ad_len = buf[11];
|
unsigned char ad_len = buf[11];
|
||||||
|
|
||||||
if (ad_len < data_len && buf_len + 11 == data_len - 1) {
|
for (int c=9;c>=4;c--) echo_addr[9-c] = buf[bufindex + c]; // save the mac address
|
||||||
for (int c=9;c>=4;c--) echo_addr[9-c] = buf[c];
|
bufindex += 11;
|
||||||
buf += 11;
|
|
||||||
|
|
||||||
got_echo_sid = 0; got_echo_name = 0; // Reset the search state machine
|
got_echo_sid = 0; got_echo_name = 0; // Reset the search state machine
|
||||||
do {
|
do {
|
||||||
ad_len = buf[0];
|
ad_len = buf[bufindex];
|
||||||
unsigned char ad_type = buf[1];
|
unsigned char ad_type = buf[bufindex + 1];
|
||||||
buf += 2;
|
bufindex += 2;
|
||||||
|
|
||||||
if (ad_len >= 2) {
|
if (ad_len >= 2) {
|
||||||
if (ad_type == 0x03) {
|
if (ad_type == 0x03) {
|
||||||
unsigned int sid=0;
|
unsigned int sid = buf[bufindex] | (buf[bufindex + 1] << 8);
|
||||||
|
if (sid == 0xEC00) {
|
||||||
|
got_echo_sid = 1;
|
||||||
|
debugstr("got sid... ");
|
||||||
|
}
|
||||||
|
} else if (ad_type == 0x09) {
|
||||||
|
char remote_name[ad_len - 1];
|
||||||
|
unsigned int d=0;
|
||||||
|
|
||||||
for (int d=0;d<ad_len - 1;d+=2) {
|
while (d<ad_len - 1) {
|
||||||
sid = buf[d] | (buf[d+1] << 8);
|
remote_name[d] = buf[bufindex + d];
|
||||||
if (sid == 0xEC00) {
|
d++;
|
||||||
uart_hex(sid); uart_writeText(" ");
|
}
|
||||||
got_echo_sid = 1;
|
if (!memcmp(remote_name,"echo",4)) {
|
||||||
}
|
got_echo_name = 1;
|
||||||
}
|
debugstr("got name... ");
|
||||||
} else if (ad_type == 0x09) {
|
}
|
||||||
char remote_name[ad_len - 1];
|
}
|
||||||
unsigned int d=0;
|
}
|
||||||
|
|
||||||
while (d<ad_len - 1) {
|
bufindex += ad_len - 1;
|
||||||
remote_name[d] = buf[d];
|
} while (bufindex < data_len);
|
||||||
d++;
|
}
|
||||||
}
|
|
||||||
if (!memcmp(remote_name,"echo",4)) {
|
|
||||||
uart_writeText(remote_name); uart_writeText(" ");
|
|
||||||
got_echo_name = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf += ad_len - 1;
|
|
||||||
} while (buf[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,9 +141,9 @@ void bt_conn()
|
||||||
if (data_len >= 2) {
|
if (data_len >= 2) {
|
||||||
if (buf[0] == LE_CONNECT_CODE && !connected) {
|
if (buf[0] == LE_CONNECT_CODE && !connected) {
|
||||||
connected = !buf[1];
|
connected = !buf[1];
|
||||||
uart_hex(connected); uart_writeText(" ");
|
debughex(connected); debugstr(" ");
|
||||||
connection_handle = buf[2] | (buf[3] << 8);
|
connection_handle = buf[2] | (buf[3] << 8);
|
||||||
uart_hex(connection_handle); uart_writeText(" ");
|
debughex(connection_handle); debugstr(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,8 +182,10 @@ enum {
|
||||||
OBJ_BALL = 3
|
OBJ_BALL = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define OBJS_ADDRESS 0x02200000 // Somewhere safe to store a lot of data
|
||||||
|
|
||||||
unsigned int numobjs = 0;
|
unsigned int numobjs = 0;
|
||||||
struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)];
|
struct Object *objects = (struct Object *)OBJS_ADDRESS;
|
||||||
struct Object *ball;
|
struct Object *ball;
|
||||||
struct Object *paddle;
|
struct Object *paddle;
|
||||||
int paddlewidth = 80;
|
int paddlewidth = 80;
|
||||||
|
@ -226,7 +227,7 @@ void initBricks()
|
||||||
int brickwidth = 32;
|
int brickwidth = 32;
|
||||||
int brickheight = 8;
|
int brickheight = 8;
|
||||||
int brickspacer = 20;
|
int brickspacer = 20;
|
||||||
int brickcols[5] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
|
static int brickcols[] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
|
||||||
|
|
||||||
int ybrick = MARGIN + brickheight;
|
int ybrick = MARGIN + brickheight;
|
||||||
|
|
||||||
|
@ -288,13 +289,10 @@ void drawScoreboard(int score, int lives)
|
||||||
char tens = score / 10; score -= (10 * tens);
|
char tens = score / 10; score -= (10 * tens);
|
||||||
char ones = score;
|
char ones = score;
|
||||||
|
|
||||||
char string[] = "Score: 0xx Lives: x\0\0";
|
drawString((WIDTH/2)-252, MARGIN-25, "Score: 0 Lives: ", 0x0f, 3);
|
||||||
|
drawChar(tens + 0x30, (WIDTH/2)-252 + (8*8*3), MARGIN-25, 0x0f, 3);
|
||||||
string[8] = tens + 0x30;
|
drawChar(ones + 0x30, (WIDTH/2)-252 + (8*9*3), MARGIN-25, 0x0f, 3);
|
||||||
string[9] = ones + 0x30;
|
drawChar((char)lives + 0x30, (WIDTH/2)-252 + (8*20*3), MARGIN-25, 0x0f, 3);
|
||||||
string[20] = (char)lives + 0x30;
|
|
||||||
|
|
||||||
drawString((WIDTH/2)-252, MARGIN-25, string, 0x0f, 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void acl_poll()
|
void acl_poll()
|
||||||
|
@ -407,45 +405,55 @@ void breakout()
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
fb_init();
|
||||||
uart_init();
|
uart_init();
|
||||||
|
|
||||||
bt_init();
|
bt_init();
|
||||||
uart_writeText("Initialising Bluetooth: ");
|
|
||||||
|
debugstr("Initialising Bluetooth: ");
|
||||||
|
debugstr(">> reset: ");
|
||||||
bt_reset();
|
bt_reset();
|
||||||
|
debugstr(">> firmware load: ");
|
||||||
bt_loadfirmware();
|
bt_loadfirmware();
|
||||||
|
debugstr(">> set baud: ");
|
||||||
bt_setbaud();
|
bt_setbaud();
|
||||||
|
debugstr(">> set bdaddr: ");
|
||||||
bt_setbdaddr();
|
bt_setbdaddr();
|
||||||
|
|
||||||
// Print the BD_ADDR
|
// Print the BD_ADDR
|
||||||
unsigned char local_addr[6];
|
unsigned char local_addr[6];
|
||||||
bt_getbdaddr(local_addr);
|
bt_getbdaddr(local_addr);
|
||||||
for (int c=5;c>=0;c--) uart_byte(local_addr[c]);
|
for (int c=5;c>=0;c--) debugch(local_addr[c]);
|
||||||
uart_writeText("\n");
|
debugcrlf();
|
||||||
|
|
||||||
// Start scanning for echo
|
// Start scanning
|
||||||
|
debugstr("Setting event mask... ");
|
||||||
setLEeventmask(0xff);
|
setLEeventmask(0xff);
|
||||||
|
debugstr("Starting scanning... ");
|
||||||
startActiveScanning();
|
startActiveScanning();
|
||||||
uart_writeText("Waiting for echo: ");
|
|
||||||
|
// Search for the echo
|
||||||
|
debugstr("Waiting...");
|
||||||
|
debugcrlf();
|
||||||
while (!(got_echo_sid && got_echo_name)) bt_search();
|
while (!(got_echo_sid && got_echo_name)) bt_search();
|
||||||
stopScanning();
|
stopScanning();
|
||||||
for (int c=0;c<=5;c++) uart_byte(echo_addr[c]);
|
for (int c=0;c<=5;c++) debugch(echo_addr[c]);
|
||||||
uart_writeText("\n");
|
debugcrlf();
|
||||||
|
|
||||||
// Ask to connect to the echo
|
// Connecting to echo
|
||||||
uart_writeText("Connecting to echo: ");
|
debugstr("Connecting to echo: ");
|
||||||
connect(echo_addr);
|
connect(echo_addr);
|
||||||
while (!connected) bt_conn();
|
while (!connected) bt_conn();
|
||||||
uart_writeText("\n");
|
debugstr("Connected!");
|
||||||
|
debugcrlf();
|
||||||
|
|
||||||
// Subscribe to updates
|
// Subscribe to updates
|
||||||
uart_writeText("Sending subscribe request: ");
|
debugstr("Sending read request: ");
|
||||||
uart_hex(connection_handle); uart_writeText("\n");
|
debughex(connection_handle); debugcrlf();
|
||||||
sendACLsubscribe(connection_handle);
|
sendACLsubscribe(connection_handle);
|
||||||
|
|
||||||
// Begin the game
|
// Begin the game
|
||||||
uart_writeText("Let the game commence...\n");
|
debugstr("Let the game commence...\n");
|
||||||
wait_msec(0x100000); // Wait a second
|
wait_msec(0x100000); // Wait a second
|
||||||
|
|
||||||
fb_init();
|
|
||||||
while (1) breakout();
|
while (1) breakout();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue