mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Ammeded timing to suit new revision of ws2812c (#439)
Should also work with WS2813 (but untested) Included comments on the timing calculations
This commit is contained in:
		| @@ -1,8 +1,43 @@ | ||||
| #include "LedDeviceWs2812SPI.h" | ||||
|  | ||||
| /* | ||||
| From the data sheet: | ||||
|  | ||||
| (TH+TL=1.25μs±600ns) | ||||
|  | ||||
| T0H,	 0 code, high level time,	 0.40µs ±0.150ns | ||||
| T0L,	 0 code, low level time,	 0.85µs ±0.150ns | ||||
| T1H,	 1 code, high level time,	 0.80µs ±0.150ns | ||||
| T1L,	 1 code, low level time,	 0.45µs ±0.150ns | ||||
| WT,	 Wait for the processing time,	 NA | ||||
| Trst,	 Reset code,low level time,	 50µs (not anymore... need 300uS for latest revision) | ||||
|  | ||||
| To normalise the pulse times so they fit in 4 SPI bits: | ||||
|  | ||||
| On the assumption that the "low" time doesnt matter much | ||||
|  | ||||
| A SPI bit time of 0.40uS = 2.5 Mbit/sec | ||||
| T0 is sent as 1000 | ||||
| T1 is sent as 1100 | ||||
|  | ||||
| With a bit of excel testing, we can work out the maximum and minimum speeds: | ||||
| 2106000 MIN | ||||
| 2590500 AVG | ||||
| 3075000 MAX | ||||
|  | ||||
| Wait time: | ||||
| Not Applicable for WS2812 | ||||
|  | ||||
| Reset time: | ||||
| using the max of 3075000, the bit time is 0.325 | ||||
| Reset time is 300uS = 923 bits = 116 bytes | ||||
|  | ||||
| */ | ||||
|  | ||||
| LedDeviceWs2812SPI::LedDeviceWs2812SPI(const QJsonObject &deviceConfig) | ||||
| 	: ProviderSpi() | ||||
| 	, SPI_BYTES_PER_COLOUR(4) | ||||
| 	, SPI_FRAME_END_LATCH_BYTES(116) | ||||
| 	, bitpair_to_byte { | ||||
| 		0b10001000, | ||||
| 		0b10001100, | ||||
| @@ -20,14 +55,13 @@ LedDevice* LedDeviceWs2812SPI::construct(const QJsonObject &deviceConfig) | ||||
|  | ||||
| bool LedDeviceWs2812SPI::init(const QJsonObject &deviceConfig) | ||||
| { | ||||
| 	_baudRate_Hz = 3000000; | ||||
| 	_baudRate_Hz = 2600000; | ||||
| 	if ( !ProviderSpi::init(deviceConfig) ) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 	WarningIf(( _baudRate_Hz < 2050000 || _baudRate_Hz > 4000000 ), _log, "SPI rate %d outside recommended range (2050000 -> 4000000)", _baudRate_Hz); | ||||
| 	WarningIf(( _baudRate_Hz < 2106000 || _baudRate_Hz > 3075000 ), _log, "SPI rate %d outside recommended range (2106000 -> 3075000)", _baudRate_Hz); | ||||
|  | ||||
| 	const int SPI_FRAME_END_LATCH_BYTES = 3; | ||||
| 	_ledBuffer.resize(_ledRGBCount * SPI_BYTES_PER_COLOUR + SPI_FRAME_END_LATCH_BYTES, 0x00); | ||||
|  | ||||
| 	return true; | ||||
| @@ -52,9 +86,10 @@ int LedDeviceWs2812SPI::write(const std::vector<ColorRgb> &ledValues) | ||||
| 		spi_ptr += SPI_BYTES_PER_LED; | ||||
| 	} | ||||
|  | ||||
| 	_ledBuffer[spi_ptr++] = 0; | ||||
| 	_ledBuffer[spi_ptr++] = 0; | ||||
| 	_ledBuffer[spi_ptr++] = 0; | ||||
| 	for (int j=0; j < SPI_FRAME_END_LATCH_BYTES; j++) | ||||
| 	{ | ||||
| 		_ledBuffer[spi_ptr++] = 0; | ||||
| 	} | ||||
|  | ||||
| 	return writeBytes(_ledBuffer.size(), _ledBuffer.data()); | ||||
| } | ||||
|   | ||||
| @@ -37,5 +37,7 @@ private: | ||||
|  | ||||
|         const int SPI_BYTES_PER_COLOUR; | ||||
|  | ||||
| 	const int SPI_FRAME_END_LATCH_BYTES; | ||||
|  | ||||
| 	uint8_t bitpair_to_byte[4]; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user