1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

Compare commits

...

2 Commits

Author SHA1 Message Date
Asbelos
d3d6cc97fb Neopixel <o> cmd 2024-09-06 13:25:44 +01:00
Asbelos
03d8d5f93d Its working!! 2024-09-06 08:08:18 +01:00
2 changed files with 53 additions and 23 deletions

View File

@ -72,7 +72,7 @@ Once a new OPCODE is decided upon, update this list.
M, Write DCC packet M, Write DCC packet
n, Reserved for SensorCam n, Reserved for SensorCam
N, Reserved for Sensorcam N, Reserved for Sensorcam
o, o, Neopixel driver (see also IO_NeoPixel.h)
O, Output broadcast O, Output broadcast
p, Broadcast power state p, Broadcast power state
P, Write DCC packet P, Write DCC packet
@ -394,6 +394,33 @@ void DCCEXParser::parseOne(Print *stream, byte *com, RingStream * ringStream)
return; return;
break; break;
#ifndef IO_NO_HAL
case 'o': // Neopixel pin manipulation
if (p[0]==0) break;
{
VPIN vpin=p[0]>0 ? p[0]:-p[0];
bool setON=p[0]>0;
if (params==1) { // <o [-]vpin>
IODevice::write(vpin,setON);
return;
}
if (params==2) { // <o [-]vpin count>
for (auto pix=vpin;pix<=vpin+p[1];pix++) IODevice::write(pix,setON);
return;
}
if (params==4 || params==5) { // <z [-]vpin r g b [count]>
uint16_t colourcode=((p[1] & 0x1F)<<11) |
((p[2] & 0x1F)<<6) |
((p[3] & 0x1F)<<1);
if (setON) colourcode |= 0x0001;
// driver treats count 0 as 1
for (auto pix=vpin;pix<=vpin+p[4];pix++) IODevice::writeAnalogue(pix,colourcode,0,0);
return;
}
}
break;
#endif
case 'z': // direct pin manipulation case 'z': // direct pin manipulation
if (p[0]==0) break; if (p[0]==0) break;
if (params==1) { // <z vpin | -vpin> if (params==1) { // <z vpin | -vpin>

View File

@ -153,12 +153,15 @@ private:
_nPins=nPins; _nPins=nPins;
_I2CAddress = i2cAddress; _I2CAddress = i2cAddress;
_brightness=2; // TODO 0,1,2,3 _brightness=2; // TODO 0,1,2,3
_redOffset=mode >> 4 & 0x03; _redOffset=4+(mode >> 4 & 0x03);
_greenOffset=mode >> 2 & 0x03; _greenOffset=4+(mode >> 2 & 0x03);
_blueOffset=mode & 0x03; _blueOffset=4+(mode & 0x03);
if ((mode >>6 & 0x03) == _redOffset) _bytesPerPixel=3; if (4+(mode >>6 & 0x03) == _redOffset) _bytesPerPixel=3;
else _bytesPerPixel=4; // string has a white byte. else _bytesPerPixel=4; // string has a white byte.
_kHz800=(mode & NEO_KHZ400)==0; _kHz800=(mode & NEO_KHZ400)==0;
_showPendimg=false;
// In dccex there are only 2 bytes per pixel
pixelBuffer=(uint16_t *) calloc(_nPins,sizeof(uint16_t)); // all pixels off
addDevice(this); addDevice(this);
} }
@ -183,11 +186,17 @@ private:
const byte pinbuffer[] = {SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_PIN,SEESAW_PIN15}; const byte pinbuffer[] = {SEESAW_NEOPIXEL_BASE, SEESAW_NEOPIXEL_PIN,SEESAW_PIN15};
I2CManager.write(_I2CAddress, pinbuffer, sizeof(pinbuffer)); I2CManager.write(_I2CAddress, pinbuffer, sizeof(pinbuffer));
// but in dccex there are only 2 bytes per pixel for (auto pin=0;pin<_nPins;pin++) transmit(pin);
pixelBuffer=(uint16_t *) calloc(_nPins,sizeof(uint16_t)); // all pixels off
_display(); _display();
} }
// loop called by HAL supervisor
void _loop(unsigned long currentMicros) override {
if (!_showPendimg) return;
byte showBuffer[]={SEESAW_NEOPIXEL_BASE,SEESAW_NEOPIXEL_SHOW};
I2CManager.write(_I2CAddress,showBuffer,sizeof(showBuffer));
_showPendimg=false;
}
// read back pixel colour (rarely needed I suspect) // read back pixel colour (rarely needed I suspect)
int _readAnalogue(VPIN vpin) override { int _readAnalogue(VPIN vpin) override {
@ -222,8 +231,8 @@ private:
void _writeAnalogue(VPIN vpin, int colour, uint8_t ignore1, uint16_t ignore2) override { void _writeAnalogue(VPIN vpin, int colour, uint8_t ignore1, uint16_t ignore2) override {
(void) ignore1; (void) ignore1;
(void) ignore2; (void) ignore2;
auto newColour=(uint16_t)colour;
if (_deviceState == DEVSTATE_FAILED) return; if (_deviceState == DEVSTATE_FAILED) return;
auto newColour=(uint16_t)colour;
auto pin=vpin-_firstVpin; auto pin=vpin-_firstVpin;
if (pixelBuffer[pin]==newColour) return; if (pixelBuffer[pin]==newColour) return;
pixelBuffer[pin]=newColour; pixelBuffer[pin]=newColour;
@ -248,7 +257,7 @@ private:
void transmit(uint16_t pin, bool show=true) { void transmit(uint16_t pin, bool show=true) {
byte buffer[8]={SEESAW_NEOPIXEL_BASE,SEESAW_NEOPIXEL_BUF,0x00,0x00,0x00,0x00,0x00}; byte buffer[]={SEESAW_NEOPIXEL_BASE,SEESAW_NEOPIXEL_BUF,0x00,0x00,0x00,0x00,0x00};
uint16_t offset= pin * _bytesPerPixel; uint16_t offset= pin * _bytesPerPixel;
buffer[2]=(byte)(offset>>8); buffer[2]=(byte)(offset>>8);
buffer[3]=(byte)(offset & 0xFF); buffer[3]=(byte)(offset & 0xFF);
@ -261,14 +270,8 @@ private:
// Transmit pixel to driver // Transmit pixel to driver
I2CManager.write(_I2CAddress,buffer,4 +_bytesPerPixel); I2CManager.write(_I2CAddress,buffer,4 +_bytesPerPixel);
_showPendimg=true;
if (show) {
// Show, but only if after previous 300uS
while((micros() - lastShowTime) < 300L);
byte showBuffer[]={SEESAW_NEOPIXEL_BASE,SEESAW_NEOPIXEL_SHOW};
I2CManager.write(_I2CAddress,showBuffer,sizeof(showBuffer));
lastShowTime=micros();
}
} }
uint16_t* pixelBuffer = nullptr; uint16_t* pixelBuffer = nullptr;
byte _brightness; byte _brightness;
@ -276,7 +279,7 @@ private:
byte _redOffset; byte _redOffset;
byte _greenOffset; byte _greenOffset;
byte _blueOffset; byte _blueOffset;
unsigned long lastShowTime=0; bool _showPendimg;
bool _kHz800; bool _kHz800;
}; };