Skip to content

Commit

Permalink
ビデオ出力対応
Browse files Browse the repository at this point in the history
  • Loading branch information
shuichitakano committed Aug 31, 2019
1 parent 314a956 commit b2ba04e
Show file tree
Hide file tree
Showing 14 changed files with 1,153 additions and 83 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ add_source_files(
std_file.cpp
lcd.cpp
audio.cpp
spi_dma.cpp
video.cpp
video_out.cpp
chrono.cpp
)

include(${SDK_ROOT}/cmake/executable.cmake)
Expand Down
2 changes: 1 addition & 1 deletion audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void play()
play();
return 0;
};
irq.priority = 1;
irq.priority = 2;
active_ = true;
i2s_handle_data_dma(I2S_DEVICE_0, data, &irq);
}
Expand Down
47 changes: 47 additions & 0 deletions chrono.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* author : Shuichi TAKANO
* since : Thu Aug 29 2019 1:19:5
*/

#include "chrono.h"
#include <encoding.h> // read_cycle()
#include <sysctl.h>
#include <bsp.h>

namespace
{

constexpr int CORE_COUNT = 2;

uint64_t cpuClock_ = 0;
clock_t prevClock_[CORE_COUNT];

} // namespace

void initChrono()
{
cpuClock_ = sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
prevClock_[0] = prevClock_[1] = read_cycle();

printf("cpu clock: %d\n", (int)cpuClock_);
}

clock_t getClockCounter()
{
return read_cycle();
}

uint32_t clockToMicroSec(clock_t v)
{
return v * 1000000 / cpuClock_;
}

uint32_t getTickTimeInMicroSec()
{
uint64_t core = current_coreid();
auto prev = prevClock_[core];
auto clk = read_cycle();
auto r = clockToMicroSec(clk - prev);
prevClock_[core] = clk;
return r;
}
28 changes: 28 additions & 0 deletions chrono.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* author : Shuichi TAKANO
* since : Thu Aug 29 2019 1:18:1
*/
#ifndef _69B08F22_6134_1654_1202_ECAB715778AD
#define _69B08F22_6134_1654_1202_ECAB715778AD

#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef uint64_t clock_t;

void initChrono();

clock_t getClockCounter();
uint32_t clockToMicroSec(clock_t v);

uint32_t getTickTimeInMicroSec();

#ifdef __cplusplus
}
#endif

#endif /* _69B08F22_6134_1654_1202_ECAB715778AD */
47 changes: 39 additions & 8 deletions fmsx_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,20 @@
#include <sound.h>
#include "lcd.h"
#include "audio.h"
#include "video_out.h"

#include <sysctl.h>
#include <encoding.h> // read_cycle()

#define WIDTH 272 /* Buffer width */
#define HEIGHT 228 /* Buffer height */

static VideoOutMode videoOutMode = VIDEOOUTMODE_LCD;
void setFMSXVideoOutMode(VideoOutMode m)
{
videoOutMode = m;
}

static Image NormScreen;
static Image WideScreen;
static pixel *WBuf;
Expand Down Expand Up @@ -115,7 +122,8 @@ int InitMachine(void)

InitSound(44100, 150);
int SndSwitch = (1 << MAXCHANNELS) - 1;
int SndVolume = 2;
// int SndVolume = 2;
int SndVolume = 100;
SetChannels(SndVolume, SndSwitch);

return 1;
Expand Down Expand Up @@ -149,21 +157,44 @@ int ShowVideo(void)
{
const Image *img = VideoImg;
if (!img)
{
return 1;
}

while (1)
if (videoOutMode == VIDEOOUTMODE_LCD)
{
while (1)
{
uint64_t cy = read_cycle();
uint64_t delta = cy - prevCycle_;
if (delta >= frameCycles_)
{
prevCycle_ = cy;
printf("%d%%\n", (int)(delta * 100 / frameCycles_));
break;
}
}
lcdDrawHScaleImage(0, (240 - img->H) >> 1, 320,
img->W, img->H, img->L, img->Data);
}
else
{
waitVBlank();

uint64_t cy = read_cycle();
uint64_t delta = cy - prevCycle_;
if (delta >= frameCycles_)
prevCycle_ = cy;

if (img->W == WIDTH)
{
setVideoImagex4(img->W, img->H, img->L, img->Data);
}
else
{
prevCycle_ = cy;
printf("%d%%\n", (int)(delta * 100 / frameCycles_));
break;
setVideoImagex2(img->W, img->H, img->L, img->Data);
}
printf("%d%%\n", (int)(delta * 100 / frameCycles_));
}
lcdDrawHScaleImage(0, (240 - img->H) >> 1, 320,
img->W, img->H, img->L, img->Data);
return 1;
}

Expand Down
8 changes: 8 additions & 0 deletions fmsx_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ extern "C"
{
#endif

typedef enum
{
VIDEOOUTMODE_LCD,
VIDEOOUTMODE_COMPOSITE_VIDEO,
} VideoOutMode;

void setFMSXVideoOutMode(VideoOutMode m);

int start_fMSX();

#ifdef __cplusplus
Expand Down
61 changes: 10 additions & 51 deletions lcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
#include "lcd.h"
#include <gpio.h>
#include <sleep.h>

#include <dmac.h>
#include <utils.h>
#include <sysctl.h>
#include "spi_dma.h"

namespace
{
Expand Down Expand Up @@ -122,6 +119,8 @@ void LCD::init(spi_device_num_t spi_num,
gpio_set_drive_mode(dcx, GPIO_DM_OUTPUT);
gpio_set_pin(gpioDCX_, GPIO_PV_HIGH);

SPIDMA::instance().init(spiNum_, dmaCh_, ss_pin, ss, 1 /* prio */);

if (rst >= 0)
{
fpioa_set_function(rst_pin, (fpioa_function_t)(FUNC_GPIO0 + rst));
Expand Down Expand Up @@ -286,6 +285,7 @@ void LCD::drawHScaleImage(int dx, int dy, int dw, int sw, int h,

void LCD::writeCommand(uint8_t cmd)
{
SPIDMA::instance().waitDone();
setDCXControl();
spi_init(spiNum_, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_init_non_standard(spiNum_, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
Expand All @@ -295,6 +295,7 @@ void LCD::writeCommand(uint8_t cmd)

void LCD::writeByte(const uint8_t *data_buf, uint32_t length)
{
SPIDMA::instance().waitDone();
setDCXData();
spi_init(spiNum_, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_init_non_standard(spiNum_, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
Expand All @@ -304,6 +305,7 @@ void LCD::writeByte(const uint8_t *data_buf, uint32_t length)

void LCD::writeHalf(const uint16_t *data_buf, uint32_t length)
{
SPIDMA::instance().waitDone();
setDCXData();
spi_init(spiNum_, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0);
spi_init_non_standard(spiNum_, 16 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
Expand All @@ -313,54 +315,11 @@ void LCD::writeHalf(const uint16_t *data_buf, uint32_t length)

void LCD::writeWord(const uint32_t *data_buf, uint32_t length)
{
auto &dma = SPIDMA::instance();
dma.waitDone();
setDCXData();
spi_init(spiNum_, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);

spi_init_non_standard(spiNum_, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/,
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
#if 1

// spi_send_data_normal_dma(dmaCh_, spiNum_, cs_, data_buf, length, SPI_TRANS_INT);

auto spi_handle = (volatile spi_t *)SPI0_BASE_ADDR;
set_bit(&spi_handle->ctrlr0, 3 << 8, SPI_TMOD_TRANS << 8);
spi_handle->dmacr = 0x2; /*enable dma transmit*/
spi_handle->ssienr = 0x01;
// spi_set_tmod(SPI_CHANNEL, SPI_TMOD_TRANS);

sysctl_dma_select((sysctl_dma_channel_t)dmaCh_, SYSCTL_DMA_SELECT_SSI0_TX_REQ);

dmac_set_single_mode(dmaCh_, data_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, length);
spi_handle->ser = 1U << cs_;
#else
printf("ts.");
//static volatile bool idle = true;
// while (!idle)
// ;
dmac_wait_done(dmaCh_);
spi_data_t spiData;
spiData.tx_channel = dmaCh_;
spiData.fill_mode = false;
spiData.tx_buf = (uint32_t *)data_buf;
spiData.tx_len = length;
spiData.transfer_mode = SPI_TMOD_TRANS;
plic_interrupt_t ir;
ir.callback = [](void *param) -> int {
printf("trans\n");
// idle = true;
return 0;
};
ir.priority = 2;
//idle = false;
spi_handle_data_dma(spiNum_, cs_, spiData, &ir);
//spi_handle_data_dma(spiNum_, cs_, spiData, nullptr);
printf("te %zd\n", spiData.tx_len);
#endif
dma.resetCallback();
dma.transferBE(data_buf, length);
}

void LCD::fillData(const uint32_t *data_buf, uint32_t length)
Expand Down
36 changes: 13 additions & 23 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <i2s.h>
#include <gpio.h>
#include "audio.h"
#include "video_out.h"
#include "chrono.h"

#include <sd_card/ff.h>
#include <sd_card/sdcard.h>
Expand Down Expand Up @@ -84,25 +86,15 @@ void initI2S()
gpio_set_pin(AUDIO_ENABLE_GPIONUM, GPIO_PV_HIGH);

initAudio(44100);
//initAudio(22050);
}

int core1_function(void *ctx)
{
uint64_t core = current_coreid();
printf("Core %ld Hello world\n", core);
while (1)
;
}

int main()
{
// auto cpuFreq = sysctl_cpu_set_freq(600000000);
sysctl_pll_set_freq(SYSCTL_PLL0, 800000000);
printf("hello.\n");
// printf("hello.\n");

uint64_t core = current_coreid();
printf("Core %ld Hello world\n", core);
register_core1(core1_function, NULL);
initChrono();

sd_test();

Expand All @@ -116,20 +108,18 @@ int main()
LCD_SCLK_PIN);

lcd.setDirection(LCD::DIR_XY_RLDU);

// lcd.clear(0xfd20);
lcd.clear(0);

initI2S();

#if 0
auto fp = fopen("boot.py_", "rb");
printf("fp = %p\n", fp);
char buf[1024] = {};
auto readSize = fread(buf, 1, sizeof(buf), fp);
printf("read size = %d, str = '%s'\n", (int)readSize, buf);
fclose(fp);
#endif
if (1)
{
initVideo(390000000 * 2, 390000000 / 18, 228 * 2,
272 * 4, 228);
//setInterlaceMode(true);
startVideoTransfer();
setFMSXVideoOutMode(VIDEOOUTMODE_COMPOSITE_VIDEO);
}

start_fMSX();

Expand Down
Loading

0 comments on commit b2ba04e

Please sign in to comment.