blob: 073dada33c9e9160121a12833a453a45c62a1b17 [file] [log] [blame]
/*
* SPDX-FileCopyrightText: 2021 Andrea Nall
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include "verilog/dv/caravel/defs.h"
#define UART_BASE (size_t)0x30800000
bool uart_seen;
bool puzzle_done;
uint32_t *irq() {
if ( ! uart_seen ) {
volatile uint32_t *UART_DATA = (uint32_t*)(UART_BASE+0x4);
uint32_t value = (*UART_DATA);
if ( value == 'G' ) {
uart_seen = true;
}
} else {
reg_mprj_irq = 0b0000; // need to shut off the interrupt
puzzle_done = true; // hopefully?
}
}
void main() {
volatile uint32_t *UART_CLK_DIV = (uint32_t*)UART_BASE;
volatile uint32_t *UART_DATA = (uint32_t*)(UART_BASE+0x4);
volatile uint32_t *UART_CONFIG = (uint32_t*)(UART_BASE+0x8);
volatile uint32_t *PUZZLE_CTRL = (uint32_t*)((size_t)0x30000000);
volatile uint32_t *PUZZLE_IE = (uint32_t*)((size_t)0x30000008);
const uint32_t UART_ENABLE = 0b1;
const uint32_t UART_IE_HAS_DATA = 0b10;
const uint32_t UART_FIFO_HAS_DATA = 0x100;
const uint32_t CLOCK_FREQ = 25000000;
const uint32_t BAUD = 115200;
// enable UART pins
reg_mprj_io_15 = GPIO_MODE_USER_STD_OUTPUT;
reg_mprj_io_16 = GPIO_MODE_USER_STD_INPUT_NOPULL;
// Apply configuration
reg_mprj_xfer = 1;
while (reg_mprj_xfer == 1);
// reset design with 0bit of 1st bank of LA
reg_la0_oenb = 0;
reg_la0_iena = 0;
reg_la0_data = 1;
reg_la0_data = 0;
// enable UART
*UART_CLK_DIV = (CLOCK_FREQ/BAUD);
*UART_CONFIG = UART_ENABLE | UART_IE_HAS_DATA;
reg_mprj_irq = 0b0010;
// send ready signal
*UART_DATA = (uint32_t)'R';
uart_seen = false;
while ( ! uart_seen ) {}
*UART_CONFIG = UART_ENABLE;
reg_mprj_irq = 0b0000;
*UART_DATA = (uint32_t)'l';
uint32_t tmp = 0;
uint32_t tct = 0;
uint32_t row = 0;
uint32_t sub = 0;
(*(uint32_t*)((size_t)0x30001200)) = 0x010005;
(*(uint32_t*)((size_t)0x30001204)) = 0x000600;
(*(uint32_t*)((size_t)0x30001208)) = 0x040200;
(*(uint32_t*)((size_t)0x30001210)) = 0x000600;
(*(uint32_t*)((size_t)0x30001214)) = 0x000004;
(*(uint32_t*)((size_t)0x30001218)) = 0x030700;
(*(uint32_t*)((size_t)0x30001220)) = 0x000700;
(*(uint32_t*)((size_t)0x30001224)) = 0x000000;
(*(uint32_t*)((size_t)0x30001228)) = 0x050001;
(*(uint32_t*)((size_t)0x30001230)) = 0x000000;
(*(uint32_t*)((size_t)0x30001234)) = 0x070000;
(*(uint32_t*)((size_t)0x30001238)) = 0x080002;
(*(uint32_t*)((size_t)0x30001240)) = 0x020008;
(*(uint32_t*)((size_t)0x30001244)) = 0x000903;
(*(uint32_t*)((size_t)0x30001248)) = 0x070405;
(*(uint32_t*)((size_t)0x30001250)) = 0x000003;
(*(uint32_t*)((size_t)0x30001254)) = 0x040802;
(*(uint32_t*)((size_t)0x30001258)) = 0x000900;
(*(uint32_t*)((size_t)0x30001260)) = 0x050000;
(*(uint32_t*)((size_t)0x30001264)) = 0x000006;
(*(uint32_t*)((size_t)0x30001268)) = 0x000004;
(*(uint32_t*)((size_t)0x30001270)) = 0x000200;
(*(uint32_t*)((size_t)0x30001274)) = 0x000000;
(*(uint32_t*)((size_t)0x30001278)) = 0x000103;
(*(uint32_t*)((size_t)0x30001280)) = 0x060409;
(*(uint32_t*)((size_t)0x30001284)) = 0x010000;
(*(uint32_t*)((size_t)0x30001288)) = 0x000007;
/*for ( uint32_t i = 0; i < 81; ++i ) {
char ch = puzzle[i];
if ( ch >= '1' && ch <= '9' ) {
tmp = ((ch-'0')<<24|tmp)>>8;
} else {
tmp = tmp>>8;
}
if ( ++tct == 3 ) {
(*(volatile uint32_t*)((size_t)0x30001200|row<<4|sub<<2)) = tmp;
tct = 0;
tmp = 0;
if ( ++sub == 3 ) {
sub = 0;
++row;
}
}
}*/
*UART_DATA = (uint32_t)'L';
puzzle_done = false;
*PUZZLE_CTRL = 0b1;
*PUZZLE_IE = 0b1;
reg_mprj_irq = 0b0001;
while ( ! puzzle_done ) {}
*PUZZLE_IE = 0b0;
if ( ((*PUZZLE_CTRL) & 0b1111) == 0b0100 ) {
*UART_DATA = (uint32_t)'D';
} else {
*UART_DATA = (uint32_t)'?';
*UART_DATA = *PUZZLE_CTRL;
while (1);
}
int result = 1;
result = (*(uint32_t*)((size_t)0x30001200)) == 0x010805 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001204)) == 0x030607 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001208)) == 0x040209 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001210)) == 0x090602 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001214)) == 0x050104 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001218)) == 0x030708 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001220)) == 0x030704 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001224)) == 0x080209 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001228)) == 0x050601 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001230)) == 0x040906 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001234)) == 0x070501 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001238)) == 0x080302 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001240)) == 0x020108 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001244)) == 0x060903 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001248)) == 0x070405 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001250)) == 0x070503 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001254)) == 0x040802 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001258)) == 0x010906 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001260)) == 0x050301 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001264)) == 0x020706 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001268)) == 0x090804 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001270)) == 0x080207 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001274)) == 0x090405 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001278)) == 0x060103 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001280)) == 0x060409 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001284)) == 0x010308 ? result : 0;
result = (*(uint32_t*)((size_t)0x30001288)) == 0x020507 ? result : 0;
if ( result ) {
*UART_DATA = (uint32_t)'C';
} else {
*UART_DATA = (uint32_t)'I';
}
//while ( ct < 81 ) {
//while ( (*UART_CONFIG & UART_FIFO_HAS_DATA) != UART_FIFO_HAS_DATA );
//}
}