Compare commits
2 Commits
0c7206f186
...
e4936abb53
Author | SHA1 | Date | |
---|---|---|---|
e4936abb53 | |||
7f1f924331 |
@ -10,7 +10,7 @@ Gpio* gpio0;
|
|||||||
void sleep(int ms) {
|
void sleep(int ms) {
|
||||||
for (int m = 0; m < ms; m++) {
|
for (int m = 0; m < ms; m++) {
|
||||||
for (int i = 0; i < 10000; i++) {
|
for (int i = 0; i < 10000; i++) {
|
||||||
asm volatile ( "" );
|
asm volatile("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include "timer.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "bios.h"
|
#include "bios.h"
|
||||||
@ -5,7 +7,6 @@
|
|||||||
#include "intc.h"
|
#include "intc.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "pol0.h"
|
#include "pol0.h"
|
||||||
#include "timer.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -23,16 +23,11 @@ XUartLite* uart0 = &uart0_inst;
|
|||||||
|
|
||||||
volatile int incoming = 0;
|
volatile int incoming = 0;
|
||||||
|
|
||||||
void HandleUartRxFromIsr(void*, unsigned int) {
|
void HandleUartRxFromIsr(void*, unsigned int) { incoming += 1; }
|
||||||
incoming += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleUartTxFromIsr(void*, unsigned int) {
|
void HandleUartTxFromIsr(void*, unsigned int) {}
|
||||||
}
|
|
||||||
|
|
||||||
void Uart0Isr() {
|
void Uart0Isr() { XUartLite_InterruptHandler(uart0); }
|
||||||
XUartLite_InterruptHandler(uart0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitUarts() {
|
void InitUarts() {
|
||||||
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
|
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
|
||||||
@ -62,7 +57,8 @@ int main() {
|
|||||||
uint8_t c;
|
uint8_t c;
|
||||||
while (XUartLite_Recv(uart0, &c, 1) > 0) {
|
while (XUartLite_Recv(uart0, &c, 1) > 0) {
|
||||||
XUartLite_Send(uart0, &c, 1);
|
XUartLite_Send(uart0, &c, 1);
|
||||||
while (XUartLite_IsSending(uart0)) {}
|
while (XUartLite_IsSending(uart0)) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
leds->data = 0xa1;
|
leds->data = 0xa1;
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -71,10 +67,12 @@ int main() {
|
|||||||
counter += 1;
|
counter += 1;
|
||||||
leds->data = counter;
|
leds->data = counter;
|
||||||
XUartLite_Send(uart0, &c, 1);
|
XUartLite_Send(uart0, &c, 1);
|
||||||
while (XUartLite_IsSending(uart0)) {}
|
while (XUartLite_IsSending(uart0)) {
|
||||||
|
}
|
||||||
while (XUartLite_Recv(uart0, &c, 1) > 0) {
|
while (XUartLite_Recv(uart0, &c, 1) > 0) {
|
||||||
XUartLite_Send(uart0, &c, 1);
|
XUartLite_Send(uart0, &c, 1);
|
||||||
while (XUartLite_IsSending(uart0)) {}
|
while (XUartLite_IsSending(uart0)) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
incoming -= 1;
|
incoming -= 1;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,8 @@ uint8_t UartRead() {
|
|||||||
|
|
||||||
void UartWrite(uint8_t c) {
|
void UartWrite(uint8_t c) {
|
||||||
XUartLite_Send(uart0, &c, 1);
|
XUartLite_Send(uart0, &c, 1);
|
||||||
while (XUartLite_IsSending(uart0)) {}
|
while (XUartLite_IsSending(uart0)) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -59,10 +59,10 @@ void UartWriteUint8(uint8_t a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UartDump(uint32_t addr, int count) {
|
void UartDump(uint32_t addr, int count) {
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
UartWrite(' ');
|
UartWrite(' ');
|
||||||
UartWriteUint8(*reinterpret_cast<uint8_t*>(addr + i));
|
UartWriteUint8(*reinterpret_cast<uint8_t*>(addr + i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DumpHex(uint32_t addr) {
|
void DumpHex(uint32_t addr) {
|
||||||
@ -88,8 +88,7 @@ int FindChar(const char* buf, uint8_t c) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
__attribute__((used))
|
__attribute__((used)) void wozmon() {
|
||||||
void wozmon() {
|
|
||||||
uint32_t cur_addr = 0;
|
uint32_t cur_addr = 0;
|
||||||
uint32_t cur_data = 0;
|
uint32_t cur_data = 0;
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ void wozmon() {
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint8_t c = UartRead();
|
uint8_t c = UartRead();
|
||||||
UartWrite(c); // echo
|
UartWrite(c); // echo
|
||||||
if (c == '\r') {
|
if (c == '\r') {
|
||||||
*inptr = 0;
|
*inptr = 0;
|
||||||
if (inptr == inbuf) {
|
if (inptr == inbuf) {
|
||||||
|
@ -8,5 +8,4 @@ uint8_t BiosUartRead();
|
|||||||
void BiosUartWrite(uint8_t);
|
void BiosUartWrite(uint8_t);
|
||||||
void BiosWozmon();
|
void BiosWozmon();
|
||||||
void BiosUartWriteNibble(uint8_t);
|
void BiosUartWriteNibble(uint8_t);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,20 +7,17 @@ void BiosUartWrite(uint8_t);
|
|||||||
void BiosWozmon();
|
void BiosWozmon();
|
||||||
void BiosUartWriteNibble(uint8_t n);
|
void BiosUartWriteNibble(uint8_t n);
|
||||||
|
|
||||||
__attribute__((used))
|
__attribute__((used)) void UartWriteU32(uint32_t a) {
|
||||||
void UartWriteU32(uint32_t a) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
BiosUartWriteNibble(a >> 28);
|
BiosUartWriteNibble(a >> 28);
|
||||||
a <<= 4;
|
a <<= 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((used))
|
__attribute__((used)) void UartWriteString(const char* s) {
|
||||||
void UartWriteString(const char* s) {
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
BiosUartWrite(*s);
|
BiosUartWrite(*s);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,13 +39,9 @@ bool SetIrqEnabled(uint8_t irqn, bool enabled) {
|
|||||||
return was_enabled;
|
return was_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetIsr(uint8_t irqn, Isr isr) {
|
void SetIsr(uint8_t irqn, Isr isr) { isrs[irqn] = isr; }
|
||||||
isrs[irqn] = isr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnableInterrupts() {
|
void EnableInterrupts() { intc->MER = 0x3; }
|
||||||
intc->MER = 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InterruptHandler() {
|
void InterruptHandler() {
|
||||||
uint32_t ipr = intc->IPR;
|
uint32_t ipr = intc->IPR;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
namespace intc {
|
namespace intc {
|
||||||
|
|
||||||
using Isr = void(*)(void);
|
using Isr = void (*)(void);
|
||||||
|
|
||||||
/// Returns: true if the IRQ was previously enabled
|
/// Returns: true if the IRQ was previously enabled
|
||||||
bool SetIrqEnabled(uint8_t irqn, bool enabled);
|
bool SetIrqEnabled(uint8_t irqn, bool enabled);
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
#include "interrupts.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "bios.h"
|
#include "bios.h"
|
||||||
#include "interrupts.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -12,8 +13,7 @@ constexpr uint32_t kInterruptCauseMask = 0xff;
|
|||||||
|
|
||||||
Isr external_handler = nullptr;
|
Isr external_handler = nullptr;
|
||||||
|
|
||||||
__attribute__((interrupt))
|
__attribute__((interrupt)) void TrapHandler() {
|
||||||
void TrapHandler() {
|
|
||||||
uint32_t mcause;
|
uint32_t mcause;
|
||||||
uint32_t mip;
|
uint32_t mip;
|
||||||
asm volatile("csrr %0, mcause" : "=r"(mcause));
|
asm volatile("csrr %0, mcause" : "=r"(mcause));
|
||||||
@ -26,7 +26,7 @@ void TrapHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mip &= ~(kMieExternalInterruptMask);
|
mip &= ~(kMieExternalInterruptMask);
|
||||||
asm volatile("csrw mip, %0" :: "r"(mip));
|
asm volatile("csrw mip, %0" ::"r"(mip));
|
||||||
} else {
|
} else {
|
||||||
BiosWozmon();
|
BiosWozmon();
|
||||||
}
|
}
|
||||||
@ -34,18 +34,16 @@ void TrapHandler() {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void SetExternalInterruptHandler(Isr handler) {
|
void SetExternalInterruptHandler(Isr handler) { external_handler = handler; }
|
||||||
external_handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnableExternalInterrupts() {
|
void EnableExternalInterrupts() {
|
||||||
uint32_t mie;
|
uint32_t mie;
|
||||||
Isr trap = TrapHandler;
|
Isr trap = TrapHandler;
|
||||||
|
|
||||||
asm volatile("csrr %0, mie" : "=r"(mie));
|
asm volatile("csrr %0, mie" : "=r"(mie));
|
||||||
asm volatile("csrw mtvec, %0" :: "r"(trap));
|
asm volatile("csrw mtvec, %0" ::"r"(trap));
|
||||||
mie |= kMieExternalInterruptMask;
|
mie |= kMieExternalInterruptMask;
|
||||||
asm volatile("csrw mie, %0" :: "r"(mie));
|
asm volatile("csrw mie, %0" ::"r"(mie));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EnableInterrupts(bool on) {
|
bool EnableInterrupts(bool on) {
|
||||||
@ -61,6 +59,6 @@ bool EnableInterrupts(bool on) {
|
|||||||
mstatus &= ~kMstatusMieMask;
|
mstatus &= ~kMstatusMieMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
asm volatile("csrw mstatus, %0" :: "r"(mstatus));
|
asm volatile("csrw mstatus, %0" ::"r"(mstatus));
|
||||||
return was_on;
|
return was_on;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
using Isr = void(*)();
|
using Isr = void (*)();
|
||||||
|
|
||||||
void SetExternalInterruptHandler(Isr handler);
|
void SetExternalInterruptHandler(Isr handler);
|
||||||
void EnableExternalInterrupts();
|
void EnableExternalInterrupts();
|
||||||
|
@ -3,14 +3,13 @@
|
|||||||
extern "C" uint32_t _bss_begin, _bss_end, _initial_stack_pointer;
|
extern "C" uint32_t _bss_begin, _bss_end, _initial_stack_pointer;
|
||||||
extern "C" int main();
|
extern "C" int main();
|
||||||
|
|
||||||
__attribute__((section(".start"), used, naked))
|
__attribute__((section(".start"), used, naked)) void _start() {
|
||||||
void _start() {
|
|
||||||
// clear .bss
|
// clear .bss
|
||||||
for (uint32_t* ptr = &_bss_begin; ptr < &_bss_end; ptr++) {
|
for (uint32_t* ptr = &_bss_begin; ptr < &_bss_end; ptr++) {
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
asm volatile ( "la sp, _initial_stack_pointer" );
|
asm volatile("la sp, _initial_stack_pointer");
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
|
@ -59,9 +59,7 @@ struct Timer {
|
|||||||
TCSR0.ENT0 = 1;
|
TCSR0.ENT0 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearInterrupt() {
|
void ClearInterrupt() { TCSR0.T0INT = 0; }
|
||||||
TCSR0.T0INT = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Timer* Instance(uint32_t base) {
|
static Timer* Instance(uint32_t base) {
|
||||||
return reinterpret_cast<Timer*>(base);
|
return reinterpret_cast<Timer*>(base);
|
||||||
|
36
mbv/prog.py
36
mbv/prog.py
@ -6,33 +6,33 @@ import threading
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
offset = 0x80000000
|
offset = 0x80000000
|
||||||
tty = '/dev/ttyUSB1'
|
tty = "/dev/ttyUSB1"
|
||||||
baud = 115200
|
baud = 115200
|
||||||
chunksize = 1024
|
chunksize = 1024
|
||||||
|
|
||||||
|
|
||||||
def write(s, offset, dat):
|
def write(s, offset, dat):
|
||||||
for i in range(0, len(dat), chunksize):
|
for i in range(0, len(dat), chunksize):
|
||||||
chunk = dat[i: i + chunksize]
|
chunk = dat[i : i + chunksize]
|
||||||
cmd = struct.pack('<cII', b'c', offset + i, len(chunk))
|
cmd = struct.pack("<cII", b"c", offset + i, len(chunk))
|
||||||
|
|
||||||
print(f'Sending {len(chunk)} bytes @0x{offset + i:04x}')
|
print(f"Sending {len(chunk)} bytes @0x{offset + i:04x}")
|
||||||
|
|
||||||
s.write(cmd)
|
s.write(cmd)
|
||||||
s.write(chunk)
|
s.write(chunk)
|
||||||
|
|
||||||
ack = s.read(2)
|
ack = s.read(2)
|
||||||
if len(ack) < 2:
|
if len(ack) < 2:
|
||||||
raise RuntimeError(f'timeout waiting for full ack. got {ack}')
|
raise RuntimeError(f"timeout waiting for full ack. got {ack}")
|
||||||
if ack[0] != b'a'[0]:
|
if ack[0] != b"a"[0]:
|
||||||
raise RuntimeError(f'expected ack, got this instead: {ack}')
|
raise RuntimeError(f"expected ack, got this instead: {ack}")
|
||||||
print(f'Ack! len={ack[1]}')
|
print(f"Ack! len={ack[1]}")
|
||||||
|
|
||||||
|
|
||||||
def jump(s, offset):
|
def jump(s, offset):
|
||||||
cmd = struct.pack('<cI', b'j', offset)
|
cmd = struct.pack("<cI", b"j", offset)
|
||||||
print(f'Jumping to 0x{offset:04x}')
|
print(f"Jumping to 0x{offset:04x}")
|
||||||
s.write(cmd)
|
s.write(cmd)
|
||||||
|
|
||||||
|
|
||||||
def stream_logs(s):
|
def stream_logs(s):
|
||||||
@ -40,21 +40,25 @@ def stream_logs(s):
|
|||||||
dat = s.read()
|
dat = s.read()
|
||||||
if not dat:
|
if not dat:
|
||||||
continue
|
continue
|
||||||
sys.stdout.buffer.write(dat.replace(b'\r', b''))
|
sys.stdout.buffer.write(dat.replace(b"\r", b""))
|
||||||
sys.stdout.buffer.flush()
|
sys.stdout.buffer.flush()
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("binary")
|
parser.add_argument("binary")
|
||||||
parser.add_argument("--monitor", action="store_true",
|
parser.add_argument(
|
||||||
help="wait for and display program serial output")
|
"--monitor",
|
||||||
|
action="store_true",
|
||||||
|
help="wait for and display program serial output",
|
||||||
|
)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
|
||||||
with open(args.binary, 'rb') as f:
|
with open(args.binary, "rb") as f:
|
||||||
dat = f.read()
|
dat = f.read()
|
||||||
|
|
||||||
s = serial.Serial(tty, baud, timeout=1)
|
s = serial.Serial(tty, baud, timeout=1)
|
||||||
@ -67,7 +71,7 @@ def main():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
dat = input("") + '\r'
|
dat = input("") + "\r"
|
||||||
s.write(dat.encode())
|
s.write(dat.encode())
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Bye.")
|
print("Bye.")
|
||||||
|
Loading…
Reference in New Issue
Block a user