internal static WS281xException Create(ws2811_return_t return_code, string status) { string errorMessage = GetErrorMessage(return_code); string message = $"An Error occurred while {status} - {errorMessage} ({(int)return_code})"; return(new WS281xException(return_code, message)); }
/// <summary> /// Return a user friendly message based on return code /// </summary> public static string GetErrorMessage(ws2811_return_t return_code) { string result = return_code switch { ws2811_return_t.WS2811_SUCCESS => "Operation Successful", ws2811_return_t.WS2811_ERROR_GENERIC => "Generic failure", ws2811_return_t.WS2811_ERROR_OUT_OF_MEMORY => "Out of memory", ws2811_return_t.WS2811_ERROR_HW_NOT_SUPPORTED => "Hardware revision is not supported", ws2811_return_t.WS2811_ERROR_MEM_LOCK => "Memory lock failed", ws2811_return_t.WS2811_ERROR_MMAP => "nmap() failed", ws2811_return_t.WS2811_ERROR_MAP_REGISTERS => "Unable to map registers to userspace", ws2811_return_t.WS2811_ERROR_GPIO_INIT => "Unable to initialize GPIO", ws2811_return_t.WS2811_ERROR_PWM_SETUP => "Unable to initialize PWM", ws2811_return_t.WS2811_ERROR_MAILBOX_DEVICE => "Failed to create mailbox device", ws2811_return_t.WS2811_ERROR_DMA => "DMA Error", ws2811_return_t.WS2811_ERROR_ILLEGAL_GPIO => "Selected GPIO not supported", ws2811_return_t.WS2811_ERROR_PCM_SETUP => "Unable to initialize PCM", ws2811_return_t.WS2811_ERROR_SPI_SETUP => "Unable to initialize SPI", ws2811_return_t.WS2811_ERROR_SPI_TRANSFER => "SPI transfer error", _ => "Unknown Error Occurred" }; return(result); } }
/// <summary> /// Renders the content of the channels /// </summary> /// <param name="force">Force LEDs to updated - default only updates if when a change is done</param> public void Render(bool force = false) { bool shouldRender = false; if (_controllers.ContainsKey(0) && (force || _controllers[0].IsDirty)) { int[] data = _controllers[0].GetColors(true); Marshal.Copy(data, 0, _ws2811.channel_0.leds, data.Length); shouldRender = true; } if (_controllers.ContainsKey(1) && (force || _controllers[1].IsDirty)) { int[] data = _controllers[1].GetColors(true); Marshal.Copy(data, 0, _ws2811.channel_1.leds, data.Length); shouldRender = true; } if (shouldRender) { ws2811_return_t result = PInvoke.ws2811_render(ref _ws2811); if (result != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(result, "rendering"); } } }
/// <summary> /// Renders the content of the channels /// </summary> /// <param name="force">Force LEDs to updated - default only updates if when a change is done</param> public async Task RenderAsync(bool force = false) { bool shouldRender = false; if (_controllers.ContainsKey(0) && (force || _controllers[0].IsDirty)) { int[] data = _controllers[0].GetColors(true); GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { IntPtr pointer = handle.AddrOfPinnedObject(); _ws2811.channel_0.leds = pointer; shouldRender = true; } finally { if (handle.IsAllocated) { handle.Free(); } } } if (_controllers.ContainsKey(1) && (force || _controllers[1].IsDirty)) { int[] data = _controllers[1].GetColors(true); GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { IntPtr pointer = handle.AddrOfPinnedObject(); _ws2811.channel_1.leds = pointer; shouldRender = true; } finally { if (handle.IsAllocated) { handle.Free(); } } } if (shouldRender) { ws2811_return_t result = PInvoke.ws2811_render(ref _ws2811); if (result != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(result, "rendering"); } } await Task.FromResult(true); }
/// <summary> /// Initialize the wrapper /// </summary> /// <param name="settings">Settings used for initialization</param> public WS281x(Settings settings) { _ws2811 = new ws2811_t { dmanum = settings.DMAChannel, freq = settings.Frequency, channel_0 = InitChannel(0, settings.Controllers), channel_1 = InitChannel(1, settings.Controllers) }; //Pin the object in memory. Otherwise GC will probably move the object to another memory location. //This would cause errors because the native library has a pointer on the memory location of the object. _ws2811Handle = GCHandle.Alloc(_ws2811, GCHandleType.Pinned); ws2811_return_t initResult = PInvoke.ws2811_init(ref _ws2811); if (initResult != ws2811_return_t.WS2811_SUCCESS) { throw WS281xException.Create(initResult, "initializing"); } // save a copy of the controllers - used to update LEDs _controllers = new Dictionary <int, Controller>(settings.Controllers); // if specified, apply gamma correction if (settings.GammaCorrection != null) { if (settings.Controllers.ContainsKey(0)) { Marshal.Copy(settings.GammaCorrection.ToArray(), 0, _ws2811.channel_0.gamma, settings.GammaCorrection.Count); } if (settings.Controllers.ContainsKey(1)) { Marshal.Copy(settings.GammaCorrection.ToArray(), 0, _ws2811.channel_1.gamma, settings.GammaCorrection.Count); } } //Disposing is only allowed if the init was successful. //Otherwise the native cleanup function throws an error. _isDisposingAllowed = true; }
/// <summary> /// Returns the error message for the given status code /// </summary> /// <param name="statusCode">Status code to resolve</param> /// <returns></returns> private string GetMessageForStatusCode(ws2811_return_t statusCode) { var strPointer = PInvoke.ws2811_get_return_t_str((int)statusCode); return(Marshal.PtrToStringAuto(strPointer)); }
internal WS281xException(ws2811_return_t return_code, string message) : base(message) { ErrorNumber = return_code; ErrorCode = Enum.GetName(typeof(ws2811_return_t), return_code); }
/// <summary> /// Return a user friendly message based on return code /// </summary> public static string GetErrorMessage(ws2811_return_t return_code) { var result = string.Empty; switch (return_code) { case ws2811_return_t.WS2811_SUCCESS: result = "Operation Successful"; break; case ws2811_return_t.WS2811_ERROR_GENERIC: result = "Generic failure"; break; case ws2811_return_t.WS2811_ERROR_OUT_OF_MEMORY: result = "Out of memory"; break; case ws2811_return_t.WS2811_ERROR_HW_NOT_SUPPORTED: result = "Hardware revision is not supported"; break; case ws2811_return_t.WS2811_ERROR_MEM_LOCK: result = "Memory lock failed"; break; case ws2811_return_t.WS2811_ERROR_MMAP: result = "nmap() failed"; break; case ws2811_return_t.WS2811_ERROR_MAP_REGISTERS: result = "Unable to map registers to userspace"; break; case ws2811_return_t.WS2811_ERROR_GPIO_INIT: result = "Unable to initialize GPIO"; break; case ws2811_return_t.WS2811_ERROR_PWM_SETUP: result = "Unable to initialize PWM"; break; case ws2811_return_t.WS2811_ERROR_MAILBOX_DEVICE: result = "Failed to create mailbox device"; break; case ws2811_return_t.WS2811_ERROR_DMA: result = "DMA Error"; break; case ws2811_return_t.WS2811_ERROR_ILLEGAL_GPIO: result = "Selected GPIO not supported"; break; case ws2811_return_t.WS2811_ERROR_PCM_SETUP: result = "Unable to initialize PCM"; break; case ws2811_return_t.WS2811_ERROR_SPI_SETUP: result = "Unable to initialize SPI"; break; case ws2811_return_t.WS2811_ERROR_SPI_TRANSFER: result = "SPI transfer error"; break; default: result = "Unknown Error Occurred"; break; } return(result); }
internal WS281xException(ws2811_return_t return_code, string return_error, string message) : base(message) { ErrorNumber = (int)return_code; ErrorCode = Enum.GetName(typeof(ws2811_return_t), ErrorNumber); ErrorMessage = return_error; }
public static string ws2811_get_return_t_str(ws2811_return_t state) { string ret = rpi_ws281xPINVOKE.ws2811_get_return_t_str((int)state); return(ret); }
public static ws2811_return_t ws2811_wait(ws2811_t ws2811) { ws2811_return_t ret = (ws2811_return_t)rpi_ws281xPINVOKE.ws2811_wait(ws2811_t.getCPtr(ws2811)); return(ret); }
private string GetReturnString(ws2811_return_t ret) { return(rpi_ws281x.ws2811_get_return_t_str(ret)); }