// // File: foldhaus_uart.cpp // Author: Peter Slattery // Creation Date: 2020-10-10 // #ifndef FOLDHAUS_UART_CPP internal void UART_SetChannelBuffer_Create(gs_memory_cursor* WriteCursor, uart_channel ChannelSettings, v2_strip Strip, led_buffer LedBuffer) { // NOTE(pjs): This is just here because the information is duplicated and I want to be sure // to catch the error where they are different Assert(ChannelSettings.PixelsCount == Strip.LedCount); uart_header* Header = PushStructOnCursor(WriteCursor, uart_header); UART_FillHeader(Header, Strip.UARTAddr.Channel, UART_SET_CHANNEL_WS2812); uart_channel* Channel = PushStructOnCursor(WriteCursor, uart_channel); *Channel = ChannelSettings; for (u32 i = 0; i < Channel->PixelsCount; i++) { u32 LedIndex = Strip.LedLUT[i]; pixel Color = LedBuffer.Colors[LedIndex]; u8* OutputPixel = PushArrayOnCursor(WriteCursor, u8, 3); // TODO(pjs): Use the Output mask OutputPixel[0] = Color.R; OutputPixel[1] = Color.G; OutputPixel[2] = Color.B; if (Channel->ElementsCount == 4) { // TODO(pjs): Calculate white from the RGB components? // Generally we just need a good way to handle the white channel, // both in the renderer and in output //OutputPixel[Channel->WhiteIndex] = Color.W; } } uart_footer* Footer = PushStructOnCursor(WriteCursor, uart_footer); UART_FillFooter(Footer, (u8*)Header); } internal void UART_DrawAll_Create(gs_memory_cursor* WriteCursor) { uart_header* Header = PushStructOnCursor(WriteCursor, uart_header); UART_FillHeader(Header, 1, UART_DRAW_ALL); uart_footer* Footer = PushStructOnCursor(WriteCursor, uart_footer); UART_FillFooter(Footer, (u8*)Header); } internal void UART_BuildOutputData(addressed_data_buffer_list* Output, assembly_array Assemblies, led_system* LedSystem) { uart_channel ChannelSettings = {0}; ChannelSettings.ElementsCount = 3; ChannelSettings.ColorPackingOrder = 36; // NOTE(pjs): This is the minimum size of every UART message. SetChannelBuffer messages will // be bigger than this, but their size is based on the number of pixels in each channel u32 MessageBaseSize = sizeof(uart_header) + sizeof(uart_channel) + sizeof(uart_footer); for (u32 AssemblyIdx = 0; AssemblyIdx < Assemblies.Count; AssemblyIdx++) { assembly Assembly = Assemblies.Values[AssemblyIdx]; led_buffer* LedBuffer = LedSystemGetBuffer(LedSystem, Assembly.LedBufferIndex); u32 TotalBufferSize = MessageBaseSize * Assembly.StripCount; // SetChannelBuffer messages TotalBufferSize += MessageBaseSize; // DrawAll message TotalBufferSize += ChannelSettings.ElementsCount * Assembly.LedCountTotal; // pixels * channels per pixel addressed_data_buffer* Buffer = AddressedDataBufferList_Push(Output, TotalBufferSize); AddressedDataBuffer_SetCOMPort(Buffer, Assembly.UARTComPort.ConstString); gs_memory_cursor WriteCursor = CreateMemoryCursor(Buffer->Data); for (u32 StripIdx = 0; StripIdx < Assembly.StripCount; StripIdx++) { v2_strip StripAt = Assembly.Strips[StripIdx]; ChannelSettings.PixelsCount = StripAt.LedCount; UART_SetChannelBuffer_Create(&WriteCursor, ChannelSettings, StripAt, *LedBuffer); } UART_DrawAll_Create(&WriteCursor); } } #define FOLDHAUS_UART_CPP #endif // FOLDHAUS_UART_CPP