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);
        }
    }
Exemple #3
0
        /// <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");
                }
            }
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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;
        }
Exemple #6
0
        /// <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);
 }
Exemple #8
0
        /// <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;
 }
Exemple #10
0
    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);
    }
Exemple #11
0
    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);
    }
Exemple #12
0
 private string GetReturnString(ws2811_return_t ret)
 {
     return(rpi_ws281x.ws2811_get_return_t_str(ret));
 }