SmartLeds.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #include "SmartLeds.h"
  2. IsrCore SmartLed::_interruptCore = CoreCurrent;
  3. intr_handle_t SmartLed::_interruptHandle = NULL;
  4. SmartLed*& IRAM_ATTR SmartLed::ledForChannel( int channel ) {
  5. static SmartLed* table[8] = { nullptr };
  6. assert( channel < 8 );
  7. return table[ channel ];
  8. }
  9. void IRAM_ATTR SmartLed::interruptHandler(void*) {
  10. for (int channel = 0; channel != 8; channel++) {
  11. auto self = ledForChannel( channel );
  12. if ( RMT.int_st.val & (1 << (24 + channel ) ) ) { // tx_thr_event
  13. if ( self )
  14. self->copyRmtHalfBlock();
  15. RMT.int_clr.val = RMT.int_clr.val | 1 << ( 24 + channel );
  16. } else if ( RMT.int_st.val & ( 1 << (3 * channel ) ) ) { // tx_end
  17. if ( self )
  18. xSemaphoreGiveFromISR( self->_finishedFlag, nullptr );
  19. RMT.int_clr.val = RMT.int_clr.val | 1 << ( 3 * channel );
  20. }
  21. }
  22. }
  23. void SmartLed::copyRmtHalfBlock() {
  24. int offset = detail::MAX_PULSES * _halfIdx;
  25. _halfIdx = !_halfIdx;
  26. int len = 3 - _componentPosition + 3 * ( _count - 1 );
  27. len = std::min( len, detail::MAX_PULSES / 8 );
  28. if ( !len ) {
  29. for ( int i = 0; i < detail::MAX_PULSES; i++) {
  30. RMTMEM.chan[ _channel].data32[i + offset ].val = 0;
  31. }
  32. }
  33. int i;
  34. for ( i = 0; i != len && _pixelPosition != _count; i++ ) {
  35. uint8_t val = _buffer[ _pixelPosition ].getGrb( _componentPosition );
  36. for ( int j = 0; j != 8; j++, val <<= 1 ) {
  37. int bit = val >> 7;
  38. int idx = i * 8 + offset + j;
  39. RMTMEM.chan[ _channel ].data32[ idx ].val = _bitToRmt[ bit & 0x01 ].value;
  40. }
  41. if ( _pixelPosition == _count - 1 && _componentPosition == 2 ) {
  42. RMTMEM.chan[ _channel ].data32[ i * 8 + offset + 7 ].duration1 =
  43. _timing.TRS / ( detail::RMT_DURATION_NS * detail::DIVIDER );
  44. }
  45. _componentPosition++;
  46. if ( _componentPosition == 3 ) {
  47. _componentPosition = 0;
  48. _pixelPosition++;
  49. }
  50. }
  51. for ( i *= 8; i != detail::MAX_PULSES; i++ ) {
  52. RMTMEM.chan[ _channel ].data32[ i + offset ].val = 0;
  53. }
  54. }