Skip to content

Commit

Permalink
Some composite stuff
Browse files Browse the repository at this point in the history
First addressable LEDs implementation
  • Loading branch information
bitluni committed Dec 30, 2019
1 parent 775f481 commit 222d953
Show file tree
Hide file tree
Showing 16 changed files with 873 additions and 90 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"files.associations": {
"random": "cpp"
"random": "cpp",
"algorithm": "cpp",
"ios": "cpp",
"*.tcc": "cpp"
}
}
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"maintainer": true
}
],
"version": "0.3.0",
"version": "0.3.1",
"frameworks": "arduino",
"platforms": "espressif32"
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=bitluni ESP32Lib
version=0.3.0
version=0.3.1
author=bitluni <[email protected]>
maintainer=bitluni <[email protected]>
sentence=Multimedia library for the ESP32
Expand Down
118 changes: 54 additions & 64 deletions src/Composite/Composite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,27 @@
*/
#include "Composite.h"

const ModeComposite Composite::MODE400x300(0, 32, 76, 388, 8, 24, 278, 2, 1, 16, 8000000);
const ModeComposite Composite::MODE400x300(32, 76, 380, 8, 8, 24, 278, 2, 1, 16, 8000000);

//1136 per line
//920 visible
//84 sync
//132 front
//312 total lines

//856
const ModeComposite Composite::MODEPAL312P(64, 96, 640, 56, 8, 23, 272, 9, 1, 32, 13333333, 70, 38, 4433619);
//const ModeComposite Composite::MODEPAL312P(84, 152, 840, 60, 8, 23, 272, 9, 1, 42, 17734475, 99, 40, 4433619);
//const ModeComposite Composite::MODEPAL312P(44, 76, 420, 28, 8, 23, 272, 9, 1, 20, 8867238, 50, 20, 4433619);
//const ModeComposite Composite::MODENTSC312P(64, 96, 640, 56, 8, 23, 272, 9, 1, 32, 13333333, 70, 38, 4433619);

//4.43361875 * 4
const PinConfigComposite Composite::GameWing(22, 14, 32, 15, 33, 27, 12, 13);
const PinConfigComposite Composite::XPlayer(32, 27, 14, 12, 13, 4, 21, 22);

Composite::Composite(const int i2sIndex)
: I2S(i2sIndex)
{
lineBufferCount = 8;
dmaBufferDescriptors = 0;
}

Expand All @@ -28,6 +40,9 @@ bool Composite::init(const ModeComposite &mode, const int *pinMap, const int bit
this->mode = mode;
int xres = mode.hRes;
int yres = mode.vRes / mode.vDiv;
blankLevel = 72;
burstAmp = 32;
syncLevel = 0;
propagateResolution(xres, yres);
totalLines = mode.linesPerField();
allocateLineBuffers();
Expand All @@ -38,57 +53,51 @@ bool Composite::init(const ModeComposite &mode, const int *pinMap, const int bit
return true;
}

void Composite::setLineBufferCount(int lineBufferCount)
int Composite::burst(int sampleNumber, bool even)
{
this->lineBufferCount = lineBufferCount;
return blankLevel;
}

void Composite::allocateLineBuffers()
{
allocateLineBuffers(lineBufferCount);
}

/// simple ringbuffer of blocks of size bytes each
void Composite::allocateLineBuffers(const int lines)
///complete ringbuffer from frame
void Composite::allocateLineBuffers(void **frameBuffer)
{
dmaBufferDescriptorCount = lines;
//simple buffers
dmaBufferDescriptorCount = totalLines;
dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(dmaBufferDescriptorCount);
int bytes = (mode.hFront + mode.hSync + mode.hBack + mode.hRes) * bytesPerSample();
for (int i = 0; i < dmaBufferDescriptorCount; i++)
dmaBufferDescriptors[i].next(dmaBufferDescriptors[(i + 1) % dmaBufferDescriptorCount]);
for (int i = 0; i < totalLines; i++)
{
dmaBufferDescriptors[i].setBuffer(DMABufferDescriptor::allocateBuffer(bytes, true), bytes); //front porch + hsync + back porch + pixels
if (i)
dmaBufferDescriptors[i - 1].next(dmaBufferDescriptors[i]);
dmaBufferDescriptors[i].setBuffer(frameBuffer[i], 856);
}
dmaBufferDescriptors[dmaBufferDescriptorCount - 1].next(dmaBufferDescriptors[0]);
}
return;

///complete ringbuffer from frame
void Composite::allocateLineBuffers(void **frameBuffer)
{
dmaBufferDescriptorCount = totalLines * 2;
int inactiveSamples = mode.hFront + mode.hSync + mode.hBack;
dmaBufferDescriptorCount = totalLines * 2 + mode.vRes;
int inactiveSamples = mode.hFront + mode.hSync;
int activeSamples = mode.hRes;
int syncSamples = mode.pixelsPerLine() / 2;
Serial.println(syncSamples);
const int blankLevel = 75;
const int syncLevel = 0;

shortSyncBuffer = DMABufferDescriptor::allocateBuffer(syncSamples * bytesPerSample(), true);
longSyncBuffer = DMABufferDescriptor::allocateBuffer(syncSamples * bytesPerSample(), true);
lineSyncBuffer = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
lineBlankBuffer = DMABufferDescriptor::allocateBuffer(mode.hRes * bytesPerSample(), true, blankLevel);
lineSyncBuffer[0] = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
lineSyncBuffer[1] = DMABufferDescriptor::allocateBuffer(inactiveSamples * bytesPerSample(), true);
lineBlankBuffer = DMABufferDescriptor::allocateBuffer(mode.hRes * bytesPerSample() + mode.hBack, true, blankLevel * 0x1010101);
lineBackBlankBuffer = DMABufferDescriptor::allocateBuffer(mode.hBack * bytesPerSample(), true, blankLevel * 0x1010101);

if(bytesPerSample() == 1)
{
int i = 0;
for (int j = 0; j < mode.hBack; j++)
((unsigned char *)lineSyncBuffer)[i++ ^ 2] = blankLevel;
for (int j = 0; j < mode.hSync; j++)
((unsigned char *)lineSyncBuffer)[i++ ^ 2] = syncLevel;
{
((unsigned char *)(lineSyncBuffer[0]))[i ^ 2] = syncLevel;
((unsigned char *)(lineSyncBuffer[1]))[i++ ^ 2] = syncLevel;
}
for (int j = 0; j < mode.hFront; j++)
((unsigned char *)lineSyncBuffer)[i++ ^ 2] = blankLevel;

{
((unsigned char *)(lineSyncBuffer[0]))[i ^ 2] = burst(j + mode.hSync, true);
((unsigned char *)(lineSyncBuffer[1]))[i++ ^ 2] = burst(j + mode.hSync, false);
}

for (int i = 0; i < syncSamples; i++)
{
if(i < mode.shortSync)
Expand All @@ -100,36 +109,14 @@ void Composite::allocateLineBuffers(void **frameBuffer)
else
((unsigned char *)longSyncBuffer)[i ^ 2] = syncLevel;
}
for (int i = 0; i < mode.hRes; i++)
for (int i = 0; i < mode.hRes + mode.hBack; i++)
((unsigned char *)lineBlankBuffer)[i ^ 2] = blankLevel;
}
else if(bytesPerSample() == 2)
{
int i = 0;
for (int j = 0; j < mode.hBack; j++)
((unsigned short *)lineSyncBuffer)[i++ ^ 1] = blankLevel;
for (int j = 0; j < mode.hSync; j++)
((unsigned short *)lineSyncBuffer)[i++ ^ 1] = syncLevel;
for (int j = 0; j < mode.hFront; j++)
((unsigned short *)lineSyncBuffer)[i++ ^ 1] = blankLevel;

for (int i = 0; i < syncSamples; i++)
{
if(i < mode.shortSync)
((unsigned short *)shortSyncBuffer)[i++ ^ 1] = blankLevel;
else
((unsigned short *)shortSyncBuffer)[i++ ^ 1] = syncLevel;
if(i < syncSamples - mode.shortSync)
((unsigned short *)longSyncBuffer)[i++ ^ 1] = blankLevel;
else
((unsigned short *)longSyncBuffer)[i++ ^ 1] = syncLevel;
}
for (int i = 0; i < mode.hRes; i++)
((unsigned short *)lineBlankBuffer)[i ^ 1] = blankLevel;
}

//bytesPerSample() == 2 is not implemented

dmaBufferDescriptors = DMABufferDescriptor::allocateDescriptors(dmaBufferDescriptorCount);
//dmaBufferDescriptorCount = 2;

for (int i = 0; i < dmaBufferDescriptorCount; i++)
dmaBufferDescriptors[i].next(dmaBufferDescriptors[(i + 1) % dmaBufferDescriptorCount]);
int d = 0;
Expand All @@ -139,20 +126,23 @@ void Composite::allocateLineBuffers(void **frameBuffer)
dmaBufferDescriptors[d++].setBuffer(longSyncBuffer, syncSamples * bytesPerSample());
for(int i = 0; i < 5; i++)
dmaBufferDescriptors[d++].setBuffer(shortSyncBuffer, syncSamples * bytesPerSample());

for (int i = 0; i < mode.vFront; i++)
{
dmaBufferDescriptors[d++].setBuffer(lineSyncBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineBlankBuffer, mode.hRes * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineSyncBuffer[i & 1], inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineBlankBuffer, (mode.hRes + mode.hBack) * bytesPerSample());
}

for (int i = 0; i < mode.vRes; i++)
{
dmaBufferDescriptors[d++].setBuffer(lineSyncBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineSyncBuffer[(i + mode.vFront) & 1], inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(frameBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineBackBlankBuffer, mode.hBack * bytesPerSample());
}
for (int i = 0; i < mode.vBack; i++)
{
dmaBufferDescriptors[d++].setBuffer(lineSyncBuffer, inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineBlankBuffer, mode.hRes * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineSyncBuffer[(i + mode.vFront + mode.vBack) & 1], inactiveSamples * bytesPerSample());
dmaBufferDescriptors[d++].setBuffer(lineBlankBuffer, (mode.hRes + mode.hBack) * bytesPerSample());
}
}

Expand Down
12 changes: 9 additions & 3 deletions src/Composite/Composite.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ class Composite : public I2S
{
public:
Composite(const int i2sIndex = 0);
void setLineBufferCount(int lineBufferCount);
bool init(const ModeComposite &mode, const int *pinMap, const int bitCount);
virtual bool init(const ModeComposite &mode, const PinConfigComposite &pinConfig) = 0;

static const ModeComposite MODE400x300;
static const ModeComposite MODEPAL312P;


static const PinConfigComposite GameWing;
static const PinConfigComposite XPlayer;
Expand All @@ -37,19 +38,24 @@ class Composite : public I2S
int currentLine;
int totalLines;
volatile bool vSyncPassed;
int syncLevel;
int blankLevel;
int burstAmp;

void *shortSyncBuffer;
void *longSyncBuffer;
void *lineSyncBuffer;
void *lineSyncBuffer[2];
void *lineBlankBuffer;
void *lineBackBlankBuffer;

void allocateLineBuffers(const int lines);
virtual void allocateLineBuffers();
virtual void allocateLineBuffers() = 0;
virtual void allocateLineBuffers(void **frameBuffer);
virtual void propagateResolution(const int xres, const int yres) = 0;

protected:
virtual void interrupt();
virtual void vSync();
virtual void interruptPixelLine(int y, unsigned long *pixels);
virtual int burst(int sampleNumber, bool even = true);
};
126 changes: 126 additions & 0 deletions src/Composite/CompositePAL8.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
Author: bitluni 2019
License:
Creative Commons Attribution ShareAlike 4.0
https://creativecommons.org/licenses/by-sa/4.0/
For further details check out:
https://youtube.com/bitlunislab
https://github.com/bitluni
http://bitluni.net
*/
#pragma once
#include "Composite.h"
#include "../Graphics/GraphicsPALColor.h"

class CompositePAL8 : public Composite, public GraphicsPALColor
{
public:
CompositePAL8() //8 bit based modes only work with I2S1
: Composite(1)
{
}


bool init(const ModeComposite &mode,
const int C0Pin, const int C1Pin,
const int C2Pin, const int C3Pin,
const int C4Pin, const int C5Pin,
const int C6Pin, const int C7Pin)
{
int pinMap[8] = {
C0Pin, C1Pin,
C2Pin, C3Pin,
C4Pin, C5Pin,
C6Pin, C7Pin
};

initLUTs(mode.pixelClock, mode.colorClock, mode.hSync + mode.hFront - mode.burstStart, mode.hRes);
return Composite::init(mode, pinMap, 8);
}

bool init(const ModeComposite &mode, const int *compositePins)
{
initLUTs(mode.pixelClock, mode.colorClock, mode.hSync + mode.hFront - mode.burstStart, mode.hRes);
return Composite::init(mode, compositePins, 8);
}

bool init(const ModeComposite &mode, const PinConfigComposite &pinConfig)
{
int pins[8];
pinConfig.fill(pins);
initLUTs(mode.pixelClock, mode.colorClock, mode.hSync + mode.hFront - mode.burstStart, mode.hRes);
return Composite::init(mode, pins, 8);
}

virtual int bytesPerSample() const
{
return 1;
}

virtual float pixelAspect() const
{
return 1;
}

virtual void propagateResolution(const int xres, const int yres)
{
setResolution(xres, yres);
}

void *vSyncInactiveBuffer;
void *vSyncActiveBuffer;
void *inactiveBuffer;
void *blankActiveBuffer;

virtual Color **allocateFrameBuffer()
{
return (Color **)DMABufferDescriptor::allocateDMABufferArray(312, 856 * bytesPerSample(), true, blankLevel * 0x1010101);
// return (Color **)DMABufferDescriptor::allocateDMABufferArray(yres, mode.hRes * bytesPerSample(), true, blankLevel * 0x1010101);
}

virtual void allocateLineBuffers()
{
Composite::allocateLineBuffers((void **)frameBuffers[0]);
}

virtual void show(bool vSync = false)
{
if (!frameBufferCount)
return;
if (vSync)
{
//TODO read the I2S docs to find out
}
Graphics::show(vSync);
if(dmaBufferDescriptors)
for (int i = 0; i < yres * mode.vDiv; i++)
dmaBufferDescriptors[(mode.vFront + mode.vSync + mode.vBack + i) * 2 + 1].setBuffer(frontBuffer[i / mode.vDiv], mode.hRes * bytesPerSample());
}

virtual void scroll(int dy, Color color)
{
Graphics::scroll(dy, color);
if (frameBufferCount == 1)
show();
}

virtual int burst(int sampleNumber, bool even = true)
{
if(sampleNumber >= mode.burstStart && sampleNumber < mode.burstStart + mode.burstLength)
{
const float burstPhase = M_PI / 4 * 3;
const float burstPerSample = (2 * M_PI) / (double(mode.pixelClock) / mode.colorClock);
int i = sampleNumber - mode.burstStart;
// return blankLevel + sin(i * burstPerSample + (even ? burstPhase : -burstPhase)) * burstAmp;
return blankLevel + sin(i * burstPerSample + burstPhase) * burstAmp;
}
else
return blankLevel;
}

protected:
virtual void interrupt()
{
}
};
Loading

0 comments on commit 222d953

Please sign in to comment.