mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-30 01:04:13 +01:00
125 lines
3.3 KiB
C
125 lines
3.3 KiB
C
|
#include "fpga.h"
|
||
|
#include "hw.h"
|
||
|
|
||
|
|
||
|
uint8_t fpga_id_get (void) {
|
||
|
fpga_cmd_t cmd = CMD_IDENTIFY;
|
||
|
uint8_t id;
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(&id, 1, SPI_RX);
|
||
|
hw_spi_stop();
|
||
|
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
uint32_t fpga_reg_get (fpga_reg_t reg) {
|
||
|
fpga_cmd_t cmd = CMD_REG_READ;
|
||
|
uint32_t value;
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(®, 1, SPI_TX);
|
||
|
hw_spi_trx((uint8_t *) (&value), 4, SPI_RX);
|
||
|
hw_spi_stop();
|
||
|
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
void fpga_reg_set (fpga_reg_t reg, uint32_t value) {
|
||
|
fpga_cmd_t cmd = CMD_REG_WRITE;
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(®, 1, SPI_TX);
|
||
|
hw_spi_trx((uint8_t *) (&value), 4, SPI_TX);
|
||
|
hw_spi_stop();
|
||
|
}
|
||
|
|
||
|
void fpga_mem_read (uint32_t address, size_t length, uint8_t *buffer) {
|
||
|
fpga_cmd_t cmd = CMD_MEM_READ;
|
||
|
uint8_t buffer_address = 0;
|
||
|
size_t dma_length = length;
|
||
|
if ((dma_length % 2) != 0) {
|
||
|
dma_length += 1;
|
||
|
}
|
||
|
|
||
|
fpga_reg_set(REG_MEM_ADDRESS, address);
|
||
|
fpga_reg_set(REG_MEM_SCR, (dma_length << MEM_SCR_LENGTH_BIT) | MEM_SCR_START);
|
||
|
while (fpga_reg_get(REG_MEM_SCR) & MEM_SCR_BUSY);
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(&buffer_address, 1, SPI_TX);
|
||
|
hw_spi_trx(buffer, length, SPI_RX);
|
||
|
hw_spi_stop();
|
||
|
}
|
||
|
|
||
|
void fpga_mem_write (uint32_t address, size_t length, uint8_t *buffer) {
|
||
|
fpga_cmd_t cmd = CMD_MEM_WRITE;
|
||
|
uint8_t buffer_address = 0;
|
||
|
size_t dma_length = length;
|
||
|
if ((dma_length % 2) != 0) {
|
||
|
dma_length += 1;
|
||
|
}
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(&buffer_address, 1, SPI_TX);
|
||
|
hw_spi_trx(buffer, length, SPI_TX);
|
||
|
hw_spi_stop();
|
||
|
|
||
|
fpga_reg_set(REG_MEM_ADDRESS, address);
|
||
|
fpga_reg_set(REG_MEM_SCR, (dma_length << MEM_SCR_LENGTH_BIT) | MEM_SCR_DIRECTION | MEM_SCR_START);
|
||
|
while (fpga_reg_get(REG_MEM_SCR) & MEM_SCR_BUSY);
|
||
|
}
|
||
|
|
||
|
void fpga_mem_copy (uint32_t src, uint32_t dst, size_t length) {
|
||
|
size_t dma_length = length;
|
||
|
if ((dma_length % 2) != 0) {
|
||
|
dma_length += 1;
|
||
|
}
|
||
|
|
||
|
fpga_reg_set(REG_MEM_ADDRESS, src);
|
||
|
fpga_reg_set(REG_MEM_SCR, (dma_length << MEM_SCR_LENGTH_BIT) | MEM_SCR_START);
|
||
|
while (fpga_reg_get(REG_MEM_SCR) & MEM_SCR_BUSY);
|
||
|
|
||
|
fpga_reg_set(REG_MEM_ADDRESS, dst);
|
||
|
fpga_reg_set(REG_MEM_SCR, (dma_length << MEM_SCR_LENGTH_BIT) | MEM_SCR_DIRECTION | MEM_SCR_START);
|
||
|
while (fpga_reg_get(REG_MEM_SCR) & MEM_SCR_BUSY);
|
||
|
}
|
||
|
|
||
|
uint8_t fpga_usb_status_get (void) {
|
||
|
fpga_cmd_t cmd = CMD_USB_STATUS;
|
||
|
uint8_t status;
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(&status, 1, SPI_RX);
|
||
|
hw_spi_stop();
|
||
|
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
uint8_t fpga_usb_pop (void) {
|
||
|
fpga_cmd_t cmd = CMD_USB_READ;
|
||
|
uint8_t data;
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(&data, 1, SPI_RX);
|
||
|
hw_spi_stop();
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
void fpga_usb_push (uint8_t data) {
|
||
|
fpga_cmd_t cmd = CMD_USB_WRITE;
|
||
|
|
||
|
hw_spi_start();
|
||
|
hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX);
|
||
|
hw_spi_trx(&data, 1, SPI_TX);
|
||
|
hw_spi_stop();
|
||
|
}
|