blob: f66fc40b65f35ece34a16802a90c0d6c53d0aeb1 [file] [log] [blame]
/*
* Copyright 2023 Google LLC
* Copyright lowRISC contributors
*
* 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.
*/
#include "sw/device/examples/demos.h"
#include "sw/device/lib/arch/device.h"
#include "sw/device/lib/dif/dif_gpio.h"
#include "sw/device/lib/dif/dif_pinmux.h"
#include "sw/device/lib/dif/dif_spi_device.h"
#include "sw/device/lib/dif/dif_uart.h"
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/runtime/print.h"
#include "sw/device/lib/testing/pinmux_testutils.h"
#include "sw/device/lib/testing/test_framework/check.h"
#include "sw/device/lib/testing/test_framework/ottf_test_config.h"
#include "hw/top_matcha/sw/autogen/top_matcha.h"
OTTF_DEFINE_TEST_CONFIG();
static dif_gpio_t gpio;
static dif_pinmux_t pinmux;
static dif_spi_device_handle_t spi;
static dif_uart_t uart;
static dif_pinmux_index_t leds[] = {
kTopMatchaPinmuxMioOutIoa8, kTopMatchaPinmuxMioOutIob0,
kTopMatchaPinmuxMioOutIob1, kTopMatchaPinmuxMioOutIob2,
kTopMatchaPinmuxMioOutIob3, kTopMatchaPinmuxMioOutIob4,
kTopMatchaPinmuxMioOutIob5, kTopMatchaPinmuxMioOutIob6,
};
static dif_pinmux_index_t switches[] = {
kTopMatchaPinmuxInselIor5,
kTopMatchaPinmuxInselIor6,
kTopMatchaPinmuxInselIor7,
kTopMatchaPinmuxInselIor10,
};
void configure_pinmux(void) {
pinmux_testutils_init(&pinmux);
// Hook up some LEDs.
for (size_t i = 0; i < ARRAYSIZE(leds); ++i) {
dif_pinmux_index_t gpio = kTopMatchaPinmuxOutselGpioGpio0 + i;
CHECK_DIF_OK(dif_pinmux_output_select(&pinmux, leds[i], gpio));
}
// Hook up DIP switches.
for (size_t i = 0; i < ARRAYSIZE(switches); ++i) {
dif_pinmux_index_t gpio = kTopMatchaPinmuxPeripheralInGpioGpio8 + i;
CHECK_DIF_OK(dif_pinmux_input_select(&pinmux, gpio, switches[i]));
}
}
void _ottf_main(void) {
CHECK_DIF_OK(dif_pinmux_init(
mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
configure_pinmux();
CHECK_DIF_OK(dif_uart_init(
mmio_region_from_addr(TOP_MATCHA_UART0_BASE_ADDR), &uart));
CHECK(kUartBaudrate <= UINT32_MAX, "kUartBaudrate must fit in uint32_t");
CHECK(kClockFreqPeripheralHz <= UINT32_MAX,
"kClockFreqPeripheralHz must fit in uint32_t");
CHECK_DIF_OK(dif_uart_configure(
&uart, (dif_uart_config_t){
.baudrate = (uint32_t)kUartBaudrate,
.clk_freq_hz = (uint32_t)kClockFreqPeripheralHz,
.parity_enable = kDifToggleDisabled,
.parity = kDifUartParityEven,
.tx_enable = kDifToggleEnabled,
.rx_enable = kDifToggleEnabled,
}));
base_uart_stdout(&uart);
CHECK_DIF_OK(dif_spi_device_init_handle(
mmio_region_from_addr(TOP_MATCHA_SPI_DEVICE_BASE_ADDR), &spi));
dif_spi_device_config_t spi_config = {
.clock_polarity = kDifSpiDeviceEdgePositive,
.data_phase = kDifSpiDeviceEdgeNegative,
.tx_order = kDifSpiDeviceBitOrderMsbToLsb,
.rx_order = kDifSpiDeviceBitOrderMsbToLsb,
.device_mode = kDifSpiDeviceModeGeneric,
.mode_cfg =
{
.generic =
{
.rx_fifo_commit_wait = 63,
.rx_fifo_len = kDifSpiDeviceBufferLen / 2,
.tx_fifo_len = kDifSpiDeviceBufferLen / 2,
},
},
};
CHECK_DIF_OK(dif_spi_device_configure(&spi, spi_config));
CHECK_DIF_OK(
dif_gpio_init(mmio_region_from_addr(TOP_MATCHA_GPIO_BASE_ADDR), &gpio));
// Enable GPIO: 0-7 is output; 8-11 is input.
CHECK_DIF_OK(dif_gpio_output_set_enabled_all(&gpio, 0xFF));
// Add DATE and TIME because I keep fooling myself with old versions
LOG_INFO("Hello World!");
LOG_INFO("Built at: " __DATE__ ", " __TIME__);
demo_gpio_startup(&gpio);
// Now have UART <-> Buttons/LEDs demo
// all LEDs off
CHECK_DIF_OK(dif_gpio_write_all(&gpio, 0x0000));
if (kDeviceType == kDeviceFpgaNexus) {
LOG_INFO("Try out the switches on the board");
} else if (kDeviceType == kDeviceSimVerilator) {
LOG_INFO("Try out the GPIO switches 28, 29, 31");
}
LOG_INFO("or type anything into the console window.");
LOG_INFO(
"The LEDs show the bits of the ASCII code of the last "
"character.");
CHECK_DIF_OK(dif_spi_device_send(&spi, "SPI!", 4,
/*bytes_sent=*/NULL));
uint32_t gpio_state;
CHECK_DIF_OK(dif_gpio_read_all(&gpio, &gpio_state));
while (true) {
busy_spin_micros(10 * 1000); // 10 ms
gpio_state = demo_gpio_to_log_echo(&gpio, gpio_state);
demo_spi_to_log_echo(&spi);
demo_uart_to_uart_and_gpio_echo(&uart, &gpio);
}
}