part8 working - but gfx is way too slow with unoptimised clang

This commit is contained in:
Adam Greenwood-Byrne 2021-02-08 16:06:09 +00:00
parent 70c0c85c67
commit cf9bcd966e
10 changed files with 268 additions and 111 deletions

View file

@ -12,5 +12,4 @@ void startActiveScanning();
void stopScanning();
void startActiveAdvertising();
void connect(unsigned char *addr);
void bt_flushrx();
void sendACLsubscribe(unsigned int handle);

View file

@ -1,22 +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
LLVMPATH = /opt/homebrew/opt/llvm/bin
GCCFLAGS = -Wall -O0 -ffreestanding -nostdinc -nostdlib -mcpu=cortex-a72+nosimd
all: clean kernel8.img
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
$(GCCPATH)/aarch64-none-elf-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
$(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@
%.o: %.c
$(GCCPATH)/aarch64-none-elf-gcc $(GCCFLAGS) -c $< -o $@
clang --target=aarch64-elf $(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
$(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot.o $(OFILES) BCM4345C0.o -T link.ld -o kernel8.elf
$(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img
clean:
/bin/rm kernel8.elf *.o *.img > /dev/null 2> /dev/null || true

View 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

View file

@ -1,6 +1,8 @@
#include "io.h"
#include "fb.h"
unsigned char *params = (unsigned char *)SAFE_ADDRESS;
// UART0
enum {
@ -151,11 +153,12 @@ void bt_loadfirmware()
unsigned int size = (long)&_binary_BCM4345C0_hcd_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 *data = &(_binary_BCM4345C0_hcd_start[c+3]);
if (hciCommandBytes(opcodebytes, data, length)) {
if (hciCommandBytes(params, data, length)) {
uart_writeText("Firmware data load failed\n");
break;
}
@ -167,13 +170,23 @@ void bt_loadfirmware()
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");
}
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");
}
@ -213,7 +226,11 @@ void sendACLsubscribe(unsigned int handle)
bt_writeByte(lo(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;
while (c++<data_length) bt_writeByte(params[c-1]);
@ -221,51 +238,74 @@ void sendACLsubscribe(unsigned int handle)
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");
}
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");
}
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");
}
void setLEadvertenable(unsigned char state) {
unsigned char params[] = { state };
uart_writeText("doing the HCIcommand\n");
params[0] = state;
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) {
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 };
uart_writeText("doing the HCIcommand\n");
params[0] = linterval_min;
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");
}
void setLEadvertdata() {
static unsigned char params[] = { 0x19,
0x02, 0x01, 0x06,
0x03, 0x03, 0xAA, 0xFE,
0x11, 0x16, 0xAA, 0xFE, 0x10, 0x00, 0x03, 0x69, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6d, 0x2e, 0x65, 0x73,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
params[0] = 0x19;
params[1] = 0x02; params[2] = 0x01; params[3] = 0x06;
params[4] = 0x03; params[5] = 0x03; params[6] = 0xAA; params[7] = 0xFE;
params[8] = 0x11; params[9] = 0x16; params[10] = 0xAA; params[11] = 0xFE; params[12] = 0x10; params[13] = 0x00; params[14] = 0x03;
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");
}
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() {
setLEscanenable(0, 0);
}
@ -310,10 +350,44 @@ void connect(unsigned char *addr)
float BleGranularity = 1.25;
unsigned int p = BleScanInterval / BleScanDivisor;
unsigned char lp = lo(p);
unsigned char hp = hi(p);
unsigned int q = BleScanWindow / BleScanDivisor;
unsigned char lq = lo(q);
unsigned char hq = hi(q);
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 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");
}

View file

@ -6,6 +6,7 @@ void bt_getbdaddr(unsigned char *bdaddr);
void bt_init();
unsigned int bt_isReadByteReady();
unsigned char bt_readByte();
unsigned char bt_waitReadByte();
void setLEeventmask(unsigned char mask);
void startActiveScanning();
void stopScanning();

View file

@ -37,7 +37,7 @@ var ioHook = require('iohook');
var buf = Buffer.allocUnsafe(1);
var obuf = Buffer.allocUnsafe(1);
const scrwidth = 1680;
const scrwidth = 1440;
const divisor = scrwidth / 100;
ioHook.on( 'mousemove', event => {

View file

@ -5,6 +5,9 @@
unsigned int width, height, pitch, isrgb;
unsigned char *fb;
int curx = 0;
int cury = 0;
void fb_init()
{
mbox[0] = 35*4; // Length of message in bytes
@ -210,3 +213,47 @@ void wait_msec(unsigned int n)
t+=((f/1000)*n)/1000;
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(" ");
}

View file

@ -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 moveRectAbs(int oldx, int oldy, int width, int height, int newx, int newy, unsigned char attr);
void wait_msec(unsigned int n);
void debugstr(char *str);
void debugcrlf(void);
void debugch(unsigned char b);
void debughex(unsigned int d);

View file

@ -1,4 +1,5 @@
#define PERIPHERAL_BASE 0xFE000000
#define SAFE_ADDRESS 0x00210000 // Somewhere safe to store a lot of data
void uart_init();
void uart_writeText(char *buffer);

View file

@ -1,9 +1,7 @@
#include "fb.h"
#include "io.h"
#include "bt.h"
#include "fb.h"
// The BLE stuff
#define memcmp __builtin_memcmp
#define MAX_MSG_LEN 50
#define MAX_READ_RUN 100
@ -23,10 +21,22 @@ enum {
unsigned int got_echo_sid = 0;
unsigned int got_echo_name = 0;
unsigned char echo_addr[6];
unsigned int connected = 0;
unsigned int connection_handle = 0;
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)
{
switch (poll_state) {
@ -72,62 +82,51 @@ unsigned char *hci_poll()
return 0;
}
void bt_search()
{
void bt_search(void) {
unsigned char *buf;
while ( (buf = hci_poll()) ) {
if (data_len >= 2) {
if (buf[0] == LE_ADREPORT_CODE) {
unsigned char numreports = buf[1];
if (numreports == 1) {
unsigned char event_type = buf[2];
if (event_type == 0x00) {
unsigned char buf_len = buf[10];
if (buf[1] == 1) { // num_reports
if (buf[2] == 0) { // event_type
int bufindex = 0;
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[c];
buf += 11;
for (int c=9;c>=4;c--) echo_addr[9-c] = buf[bufindex + c]; // save the mac address
bufindex += 11;
got_echo_sid = 0; got_echo_name = 0; // Reset the search state machine
do {
ad_len = buf[0];
unsigned char ad_type = buf[1];
buf += 2;
got_echo_sid = 0; got_echo_name = 0; // Reset the search state machine
do {
ad_len = buf[bufindex];
unsigned char ad_type = buf[bufindex + 1];
bufindex += 2;
if (ad_len >= 2) {
if (ad_type == 0x03) {
unsigned int sid=0;
if (ad_len >= 2) {
if (ad_type == 0x03) {
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) {
sid = buf[d] | (buf[d+1] << 8);
if (sid == 0xEC00) {
uart_hex(sid); uart_writeText(" ");
got_echo_sid = 1;
}
}
} else if (ad_type == 0x09) {
char remote_name[ad_len - 1];
unsigned int d=0;
while (d<ad_len - 1) {
remote_name[d] = buf[bufindex + d];
d++;
}
if (!memcmp(remote_name,"echo",4)) {
got_echo_name = 1;
debugstr("got name... ");
}
}
}
while (d<ad_len - 1) {
remote_name[d] = buf[d];
d++;
}
if (!memcmp(remote_name,"echo",4)) {
uart_writeText(remote_name); uart_writeText(" ");
got_echo_name = 1;
}
}
}
buf += ad_len - 1;
} while (buf[1]);
}
}
bufindex += ad_len - 1;
} while (bufindex < data_len);
}
}
}
}
@ -142,9 +141,9 @@ void bt_conn()
if (data_len >= 2) {
if (buf[0] == LE_CONNECT_CODE && !connected) {
connected = !buf[1];
uart_hex(connected); uart_writeText(" ");
debughex(connected); debugstr(" ");
connection_handle = buf[2] | (buf[3] << 8);
uart_hex(connection_handle); uart_writeText(" ");
debughex(connection_handle); debugstr(" ");
}
}
}
@ -183,8 +182,11 @@ enum {
OBJ_BALL = 3
};
//#define OBJS_ADDRESS 0x02200000 // Somewhere safe to store a lot of data
unsigned int numobjs = 0;
struct Object objects[(ROWS * COLS) + (2 * NUM_LIVES)];
//struct Object *objects = (struct Object *)OBJS_ADDRESS;
struct Object *ball;
struct Object *paddle;
int paddlewidth = 80;
@ -226,7 +228,7 @@ void initBricks()
int brickwidth = 32;
int brickheight = 8;
int brickspacer = 20;
int brickcols[5] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
static int brickcols[] = { 0x11, 0x22, 0xEE, 0x44, 0x66 };
int ybrick = MARGIN + brickheight;
@ -288,13 +290,10 @@ void drawScoreboard(int score, int lives)
char tens = score / 10; score -= (10 * tens);
char ones = score;
char string[] = "Score: 0xx Lives: x\0\0";
string[8] = tens + 0x30;
string[9] = ones + 0x30;
string[20] = (char)lives + 0x30;
drawString((WIDTH/2)-252, MARGIN-25, string, 0x0f, 3);
drawString((WIDTH/2)-252, MARGIN-25, "Score: 0 Lives: ", 0x0f, 3);
drawChar(tens + 0x30, (WIDTH/2)-252 + (8*8*3), MARGIN-25, 0x0f, 3);
drawChar(ones + 0x30, (WIDTH/2)-252 + (8*9*3), MARGIN-25, 0x0f, 3);
drawChar((char)lives + 0x30, (WIDTH/2)-252 + (8*20*3), MARGIN-25, 0x0f, 3);
}
void acl_poll()
@ -370,7 +369,7 @@ void breakout()
}
}
wait_msec(0x186A);
//wait_msec(0x186A);
moveObjectAbs(ball, ball->x + velocity_x, ball->y + velocity_y);
// Check we're in the game arena still
@ -407,45 +406,55 @@ void breakout()
void main()
{
fb_init();
uart_init();
bt_init();
uart_writeText("Initialising Bluetooth: ");
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--) uart_byte(local_addr[c]);
uart_writeText("\n");
for (int c=5;c>=0;c--) debugch(local_addr[c]);
debugcrlf();
// Start scanning for echo
// Start scanning
debugstr("Setting event mask... ");
setLEeventmask(0xff);
debugstr("Starting scanning... ");
startActiveScanning();
uart_writeText("Waiting for echo: ");
// Search for the echo
debugstr("Waiting...");
debugcrlf();
while (!(got_echo_sid && got_echo_name)) bt_search();
stopScanning();
for (int c=0;c<=5;c++) uart_byte(echo_addr[c]);
uart_writeText("\n");
for (int c=0;c<=5;c++) debugch(echo_addr[c]);
debugcrlf();
// Ask to connect to the echo
uart_writeText("Connecting to echo: ");
// Connecting to echo
debugstr("Connecting to echo: ");
connect(echo_addr);
while (!connected) bt_conn();
uart_writeText("\n");
debugstr("Connected!");
debugcrlf();
// Subscribe to updates
uart_writeText("Sending subscribe request: ");
uart_hex(connection_handle); uart_writeText("\n");
debugstr("Sending read request: ");
debughex(connection_handle); debugcrlf();
sendACLsubscribe(connection_handle);
// Begin the game
uart_writeText("Let the game commence...\n");
debugstr("Let the game commence...\n");
wait_msec(0x100000); // Wait a second
fb_init();
while (1) breakout();
}