Mcu.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "Mcu.hpp"
  2. #include <cstring>
  3. //Thanks to Sono and his research on MCU
  4. namespace FreeShop
  5. {
  6. MCU &MCU::getInstance()
  7. {
  8. static MCU mcu;
  9. return mcu;
  10. }
  11. Result MCU::mcuInit()
  12. {
  13. return srvGetServiceHandle(&m_mcuHandle, "mcu::HWC");
  14. }
  15. Result MCU::mcuExit()
  16. {
  17. return svcCloseHandle(m_mcuHandle);
  18. }
  19. Result MCU::mcuWriteRegister(u8 reg, void* data, u32 size)
  20. {
  21. u32* ipc = getThreadCommandBuffer();
  22. ipc[0] = 0x20082;
  23. ipc[1] = reg;
  24. ipc[2] = size;
  25. ipc[3] = size << 4 | 0xA;
  26. ipc[4] = (u32)data;
  27. Result ret = svcSendSyncRequest(m_mcuHandle);
  28. if(ret < 0) return ret;
  29. return ipc[1];
  30. }
  31. Result MCU::mcuReadRegister(u8 reg, void* data, u32 size)
  32. {
  33. u32* ipc = getThreadCommandBuffer();
  34. ipc[0] = 0x10082;
  35. ipc[1] = reg;
  36. ipc[2] = size;
  37. ipc[3] = size << 4 | 0xC;
  38. ipc[4] = (u32)data;
  39. Result ret = svcSendSyncRequest(m_mcuHandle);
  40. if(ret < 0) return ret;
  41. return ipc[1];
  42. }
  43. Result MCU::ptmSysmInit()
  44. {
  45. return srvGetServiceHandle(&m_ptmSysmHandle, "ptm:sysm");
  46. }
  47. Result MCU::ptmSysmExit()
  48. {
  49. return svcCloseHandle(m_ptmSysmHandle);
  50. }
  51. Result MCU::ptmSysmSetInfoLEDPattern(RGBLedPattern pattern)
  52. {
  53. u32* ipc = getThreadCommandBuffer();
  54. ipc[0] = 0x8010640;
  55. memcpy(&ipc[1], &pattern, 0x64);
  56. Result ret = svcSendSyncRequest(m_ptmSysmHandle);
  57. if(ret < 0) return ret;
  58. return ipc[1];
  59. }
  60. Result MCU::ledApply()
  61. {
  62. Result res;
  63. if (R_SUCCEEDED(res = mcuInit())) {
  64. mcuWriteRegister(0x2D, &m_ledPattern, sizeof(m_ledPattern));
  65. mcuExit();
  66. } else if (R_SUCCEEDED(res = ptmSysmInit())) {
  67. ptmSysmSetInfoLEDPattern(m_ledPattern);
  68. ptmSysmExit();
  69. }
  70. return res;
  71. }
  72. bool MCU::ledBlinkOnce(u32 col)
  73. {
  74. memset(&m_ledPattern.r[ 0], 0, 32);
  75. memset(&m_ledPattern.g[ 0], 0, 32);
  76. memset(&m_ledPattern.b[ 0], 0, 32);
  77. memset(&m_ledPattern.r[ 2], (col >> 0) & 0xFF, 16);
  78. memset(&m_ledPattern.g[ 2], (col >> 8) & 0xFF, 16);
  79. memset(&m_ledPattern.b[ 2], (col >> 16) & 0xFF, 16);
  80. m_ledPattern.ani = 0xFF2040;
  81. return R_SUCCEEDED(ledApply());
  82. }
  83. bool MCU::ledBlinkThrice(u32 col)
  84. {
  85. memset(&m_ledPattern.r[ 0], 0, 32);
  86. memset(&m_ledPattern.g[ 0], 0, 32);
  87. memset(&m_ledPattern.b[ 0], 0, 32);
  88. memset(&m_ledPattern.r[ 2], (col >> 0) & 0xFF, 5);
  89. memset(&m_ledPattern.g[ 2], (col >> 8) & 0xFF, 5);
  90. memset(&m_ledPattern.b[ 2], (col >> 16) & 0xFF, 5);
  91. memset(&m_ledPattern.r[ 7], 0, 2);
  92. memset(&m_ledPattern.g[ 7], 0, 2);
  93. memset(&m_ledPattern.b[ 7], 0, 2);
  94. memset(&m_ledPattern.r[ 9], (col >> 0) & 0xFF, 5);
  95. memset(&m_ledPattern.g[ 9], (col >> 8) & 0xFF, 5);
  96. memset(&m_ledPattern.b[ 9], (col >> 16) & 0xFF, 5);
  97. memset(&m_ledPattern.r[14], 0, 2);
  98. memset(&m_ledPattern.g[14], 0, 2);
  99. memset(&m_ledPattern.b[14], 0, 2);
  100. memset(&m_ledPattern.r[16], (col >> 0) & 0xFF, 5);
  101. memset(&m_ledPattern.g[16], (col >> 8) & 0xFF, 5);
  102. memset(&m_ledPattern.b[16], (col >> 16) & 0xFF, 5);
  103. m_ledPattern.ani = 0xFF1020;
  104. return R_SUCCEEDED(ledApply());
  105. }
  106. bool MCU::ledStay(u32 col)
  107. {
  108. memset(&m_ledPattern.r[0], (col >> 0) & 0xFF, 32);
  109. memset(&m_ledPattern.g[0], (col >> 8) & 0xFF, 32);
  110. memset(&m_ledPattern.b[0], (col >> 16) & 0xFF, 32);
  111. m_ledPattern.ani = 0xFF0201;
  112. return R_SUCCEEDED(ledApply());
  113. }
  114. bool MCU::ledReset()
  115. {
  116. memset(&m_ledPattern.r[0], 0, 32);
  117. memset(&m_ledPattern.g[0], 0, 32);
  118. memset(&m_ledPattern.b[0], 0, 32);
  119. m_ledPattern.ani = 0xFF0000;
  120. return R_SUCCEEDED(ledApply());
  121. }
  122. void MCU::dimLeds(u8 brightness)
  123. {
  124. mcuWriteRegister(0x28, &brightness, sizeof(brightness));
  125. }
  126. } // namespace FreeShop