diff --git a/platformio.ini b/platformio.ini index 96febe7..d8a46d7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,3 +12,6 @@ platform = atmelavr board = nanoatmega328 framework = arduino +lib_deps = + stevemarple/AsyncDelay @ ^1.1.2 + stevemarple/SoftWire @ ^2.0.4 diff --git a/src/cea861.h b/src/cea861.h deleted file mode 100644 index 9f77e4e..0000000 --- a/src/cea861.h +++ /dev/null @@ -1,255 +0,0 @@ -/* vim: set et fde fdm=syntax ft=c.doxygen ts=4 sts=4 sw=4 : */ -/* - * Copyright © 2010-2011 Saleem Abdulrasool . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef eds_cea861_h -#define eds_cea861_h - -#define CEA861_NO_DTDS_PRESENT (0x04) - -enum cea861_data_block_type { - CEA861_DATA_BLOCK_TYPE_RESERVED0, - CEA861_DATA_BLOCK_TYPE_AUDIO, - CEA861_DATA_BLOCK_TYPE_VIDEO, - CEA861_DATA_BLOCK_TYPE_VENDOR_SPECIFIC, - CEA861_DATA_BLOCK_TYPE_SPEAKER_ALLOCATION, - CEA861_DATA_BLOCK_TYPE_VESA_DTC, - CEA861_DATA_BLOCK_TYPE_RESERVED6, - CEA861_DATA_BLOCK_TYPE_EXTENDED, -}; - -enum cea861_audio_format { - CEA861_AUDIO_FORMAT_RESERVED, - CEA861_AUDIO_FORMAT_LPCM, - CEA861_AUDIO_FORMAT_AC_3, - CEA861_AUDIO_FORMAT_MPEG_1, - CEA861_AUDIO_FORMAT_MP3, - CEA861_AUDIO_FORMAT_MPEG2, - CEA861_AUDIO_FORMAT_AAC_LC, - CEA861_AUDIO_FORMAT_DTS, - CEA861_AUDIO_FORMAT_ATRAC, - CEA861_AUDIO_FORMAT_DSD, - CEA861_AUDIO_FORMAT_E_AC_3, - CEA861_AUDIO_FORMAT_DTS_HD, - CEA861_AUDIO_FORMAT_MLP, - CEA861_AUDIO_FORMAT_DST, - CEA861_AUDIO_FORMAT_WMA_PRO, - CEA861_AUDIO_FORMAT_EXTENDED, -}; - -struct __attribute__ (( packed )) cea861_timing_block { - /* CEA Extension Header */ - uint8_t tag; - uint8_t revision; - uint8_t dtd_offset; - - /* Global Declarations */ - unsigned native_dtds : 4; - unsigned yuv_422_supported : 1; - unsigned yuv_444_supported : 1; - unsigned basic_audio_supported : 1; - unsigned underscan_supported : 1; - - uint8_t data[123]; - - uint8_t checksum; -}; - -struct __attribute__ (( packed )) cea861_data_block_header { - unsigned length : 5; - unsigned tag : 3; -}; - -struct __attribute__ (( packed )) cea861_short_video_descriptor { - unsigned video_identification_code : 7; - unsigned native : 1; -}; - -struct __attribute__ (( packed )) cea861_video_data_block { - struct cea861_data_block_header header; - struct cea861_short_video_descriptor svd[]; -}; - -struct __attribute__ (( packed )) cea861_short_audio_descriptor { - unsigned channels : 3; /* = value + 1 */ - unsigned audio_format : 4; - unsigned : 1; - - unsigned sample_rate_32_kHz : 1; - unsigned sample_rate_44_1_kHz : 1; - unsigned sample_rate_48_kHz : 1; - unsigned sample_rate_88_2_kHz : 1; - unsigned sample_rate_96_kHz : 1; - unsigned sample_rate_176_4_kHz : 1; - unsigned sample_rate_192_kHz : 1; - unsigned : 1; - - union { - struct __attribute__ (( packed )) { - unsigned bitrate_16_bit : 1; - unsigned bitrate_20_bit : 1; - unsigned bitrate_24_bit : 1; - unsigned : 5; - } lpcm; - - uint8_t maximum_bit_rate; /* formats 2-8; = value * 8 kHz */ - - uint8_t format_dependent; /* formats 9-13; */ - - struct __attribute__ (( packed )) { - unsigned profile : 3; - unsigned : 5; - } wma_pro; - - struct __attribute__ (( packed )) { - unsigned : 3; - unsigned code : 5; - } extension; - } flags; -}; - -struct __attribute__ (( packed )) cea861_audio_data_block { - struct cea861_data_block_header header; - struct cea861_short_audio_descriptor sad[]; -}; - -struct __attribute__ (( packed )) cea861_speaker_allocation { - unsigned front_left_right : 1; - unsigned front_lfe : 1; /* low frequency effects */ - unsigned front_center : 1; - unsigned rear_left_right : 1; - unsigned rear_center : 1; - unsigned front_left_right_center : 1; - unsigned rear_left_right_center : 1; - unsigned front_left_right_wide : 1; - - unsigned front_left_right_high : 1; - unsigned top_center : 1; - unsigned front_center_high : 1; - unsigned : 5; - - unsigned : 8; -}; - -struct __attribute__ (( packed )) cea861_speaker_allocation_data_block { - struct cea861_data_block_header header; - struct cea861_speaker_allocation payload; -}; - -struct __attribute__ (( packed )) cea861_vendor_specific_data_block { - struct cea861_data_block_header header; - uint8_t ieee_registration[3]; - uint8_t data[30]; -}; - -static const struct cea861_timing { - const uint16_t hactive; - const uint16_t vactive; - const enum { - INTERLACED, - PROGRESSIVE, - } mode; - const uint16_t htotal; - const uint16_t hblank; - const uint16_t vtotal; - const double vblank; - const double hfreq; - const double vfreq; - const double pixclk; -} cea861_timings[] = { - [1] = { 640, 480, PROGRESSIVE, 800, 160, 525, 45.0, 31.469, 59.940, 25.175 }, - [2] = { 720, 480, PROGRESSIVE, 858, 138, 525, 45.0, 31.469, 59.940, 27.000 }, - [3] = { 720, 480, PROGRESSIVE, 858, 138, 525, 45.0, 31.469, 59.940, 27.000 }, - [4] = { 1280, 720, PROGRESSIVE, 1650, 370, 750, 30.0, 45.000, 60.000, 74.250 }, - [5] = { 1920, 1080, INTERLACED, 2200, 280, 1125, 22.5, 33.750, 60.000, 72.250 }, - [6] = { 1440, 480, INTERLACED, 1716, 276, 525, 22.5, 15.734, 59.940, 27.000 }, - [7] = { 1440, 480, INTERLACED, 1716, 276, 525, 22.5, 15.734, 59.940, 27.000 }, - [8] = { 1440, 240, PROGRESSIVE, 1716, 276, 262, 22.0, 15.734, 60.054, 27.000 }, /* 9 */ - [9] = { 1440, 240, PROGRESSIVE, 1716, 276, 262, 22.0, 15.734, 59.826, 27.000 }, /* 8 */ - [10] = { 2880, 480, INTERLACED, 3432, 552, 525, 22.5, 15.734, 59.940, 54.000 }, - [11] = { 2880, 480, INTERLACED, 3432, 552, 525, 22.5, 15.734, 59.940, 54.000 }, - [12] = { 2880, 240, PROGRESSIVE, 3432, 552, 262, 22.0, 15.734, 60.054, 54.000 }, /* 13 */ - [13] = { 2880, 240, PROGRESSIVE, 3432, 552, 262, 22.0, 15.734, 59.826, 54.000 }, /* 12 */ - [14] = { 1440, 480, PROGRESSIVE, 1716, 276, 525, 45.0, 31.469, 59.940, 54.000 }, - [15] = { 1440, 480, PROGRESSIVE, 1716, 276, 525, 45.0, 31.469, 59.940, 54.000 }, - [16] = { 1920, 1080, PROGRESSIVE, 2200, 280, 1125, 45.0, 67.500, 60.000, 148.500 }, - [17] = { 720, 576, PROGRESSIVE, 864, 144, 625, 49.0, 31.250, 50.000, 27.000 }, - [18] = { 720, 576, PROGRESSIVE, 864, 144, 625, 49.0, 31.250, 50.000, 27.000 }, - [19] = { 1280, 720, PROGRESSIVE, 1980, 700, 750, 30.0, 37.500, 50.000, 74.250 }, - [20] = { 1920, 1080, INTERLACED, 2640, 720, 1125, 22.5, 28.125, 50.000, 74.250 }, - [21] = { 1440, 576, INTERLACED, 1728, 288, 625, 24.5, 15.625, 50.000, 27.000 }, - [22] = { 1440, 576, INTERLACED, 1728, 288, 625, 24.5, 15.625, 50.000, 27.000 }, - [23] = { 1440, 288, PROGRESSIVE, 1728, 288, 312, 24.0, 15.625, 50.080, 27.000 }, /* 24 */ - [24] = { 1440, 288, PROGRESSIVE, 1728, 288, 313, 25.0, 15.625, 49.920, 27.000 }, /* 23 */ - // [24] = { 1440, 288, PROGRESSIVE, 1728, 288, 314, 26.0, 15.625, 49.761, 27.000 }, - [25] = { 2880, 576, INTERLACED, 3456, 576, 625, 24.5, 15.625, 50.000, 54.000 }, - [26] = { 2880, 576, INTERLACED, 3456, 576, 625, 24.5, 15.625, 50.000, 54.000 }, - [27] = { 2880, 288, PROGRESSIVE, 3456, 576, 312, 24.0, 15.625, 50.080, 54.000 }, /* 28 */ - [28] = { 2880, 288, PROGRESSIVE, 3456, 576, 313, 25.0, 15.625, 49.920, 54.000 }, /* 27 */ - // [28] = { 2880, 288, PROGRESSIVE, 3456, 576, 314, 26.0, 15.625, 49.761, 54.000 }, - [29] = { 1440, 576, PROGRESSIVE, 1728, 288, 625, 49.0, 31.250, 50.000, 54.000 }, - [30] = { 1440, 576, PROGRESSIVE, 1728, 288, 625, 49.0, 31.250, 50.000, 54.000 }, - [31] = { 1920, 1080, PROGRESSIVE, 2640, 720, 1125, 45.0, 56.250, 50.000, 148.500 }, - [32] = { 1920, 1080, PROGRESSIVE, 2750, 830, 1125, 45.0, 27.000, 24.000, 74.250 }, - [33] = { 1920, 1080, PROGRESSIVE, 2640, 720, 1125, 45.0, 28.125, 25.000, 74.250 }, - [34] = { 1920, 1080, PROGRESSIVE, 2200, 280, 1125, 45.0, 33.750, 30.000, 74.250 }, - [35] = { 2880, 480, PROGRESSIVE, 3432, 552, 525, 45.0, 31.469, 59.940, 108.500 }, - [36] = { 2880, 480, PROGRESSIVE, 3432, 552, 525, 45.0, 31.469, 59.940, 108.500 }, - [37] = { 2880, 576, PROGRESSIVE, 3456, 576, 625, 49.0, 31.250, 50.000, 108.000 }, - [38] = { 2880, 576, PROGRESSIVE, 3456, 576, 625, 49.0, 31.250, 50.000, 108.000 }, - [39] = { 1920, 1080, INTERLACED, 2304, 384, 1250, 85.0, 31.250, 50.000, 72.000 }, - [40] = { 1920, 1080, INTERLACED, 2640, 720, 1125, 22.5, 56.250, 100.000, 148.500 }, - [41] = { 1280, 720, PROGRESSIVE, 1980, 700, 750, 30.0, 75.000, 100.000, 148.500 }, - [42] = { 720, 576, PROGRESSIVE, 864, 144, 625, 49.0, 62.500, 100.000, 54.000 }, - [43] = { 720, 576, PROGRESSIVE, 864, 144, 625, 49.0, 62.500, 100.000, 54.000 }, - [44] = { 1440, 576, INTERLACED, 1728, 288, 625, 24.5, 31.250, 100.000, 54.000 }, - [45] = { 1440, 576, INTERLACED, 1728, 288, 625, 24.5, 31.250, 100.000, 54.000 }, - [46] = { 1920, 1080, INTERLACED, 2200, 280, 1125, 22.5, 67.500, 120.000, 148.500 }, - [47] = { 1280, 720, PROGRESSIVE, 1650, 370, 750, 30.0, 90.000, 120.000, 148.500 }, - [48] = { 720, 480, PROGRESSIVE, 858, 138, 525, 45.0, 62.937, 119.880, 54.000 }, - [49] = { 720, 480, PROGRESSIVE, 858, 138, 525, 45.0, 62.937, 119.880, 54.000 }, - [50] = { 1440, 480, INTERLACED, 1716, 276, 525, 22.5, 31.469, 119.880, 54.000 }, - [51] = { 1440, 480, INTERLACED, 1716, 276, 525, 22.5, 31.469, 119.880, 54.000 }, - [52] = { 720, 576, PROGRESSIVE, 864, 144, 625, 49.0, 125.000, 200.000, 108.000 }, - [53] = { 720, 576, PROGRESSIVE, 864, 144, 625, 49.0, 125.000, 200.000, 108.000 }, - [54] = { 1440, 576, INTERLACED, 1728, 288, 625, 24.5, 62.500, 200.000, 108.000 }, - [55] = { 1440, 576, INTERLACED, 1728, 288, 625, 24.5, 62.500, 200.000, 108.000 }, - [56] = { 720, 480, PROGRESSIVE, 858, 138, 525, 45.0, 125.874, 239.760, 108.000 }, - [57] = { 720, 480, PROGRESSIVE, 858, 138, 525, 45.0, 125.874, 239.760, 108.000 }, - [58] = { 1440, 480, INTERLACED, 1716, 276, 525, 22.5, 62.937, 239.760, 108.000 }, - [59] = { 1440, 480, INTERLACED, 1716, 276, 525, 22.5, 62.937, 239.760, 108.000 }, - [60] = { 1280, 720, PROGRESSIVE, 3300, 2020, 750, 30.0, 18.000, 24.000, 59.400 }, - [61] = { 1280, 720, PROGRESSIVE, 3960, 2680, 750, 30.0, 18.750, 25.000, 74.250 }, - [62] = { 1280, 720, PROGRESSIVE, 3300, 2020, 750, 30.0, 22.500, 30.000, 74.250 }, - [63] = { 1920, 1080, PROGRESSIVE, 2200, 280, 1125, 45.0, 135.000, 120.000, 297.000 }, - [64] = { 1920, 1080, PROGRESSIVE, 2640, 720, 1125, 45.0, 112.500, 100.000, 297.000 }, -}; - -#endif - diff --git a/src/edid.h b/src/edid.h deleted file mode 100644 index b3d75f9..0000000 --- a/src/edid.h +++ /dev/null @@ -1,506 +0,0 @@ -/* vim: set et fde fdm=syntax ft=c.doxygen ts=4 sts=4 sw=4 : */ -/* - * Copyright © 2010-2011 Saleem Abdulrasool . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef eds_edid_h -#define eds_edid_h - -#include -#include -#include - -#define EDID_I2C_DDC_DATA_ADDRESS (0x50) - -#define EDID_BLOCK_SIZE (0x80) -#define EDID_MAX_EXTENSIONS (0xfe) - - -static const uint8_t EDID_HEADER[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; -static const uint8_t EDID_STANDARD_TIMING_DESCRIPTOR_INVALID[] = { 0x01, 0x01 }; - - -enum edid_extension_type { - EDID_EXTENSION_TIMING = 0x01, // Timing Extension - EDID_EXTENSION_CEA = 0x02, // Additional Timing Block Data (CEA EDID Timing Extension) - EDID_EXTENSION_VTB = 0x10, // Video Timing Block Extension (VTB-EXT) - EDID_EXTENSION_EDID_2_0 = 0x20, // EDID 2.0 Extension - EDID_EXTENSION_DI = 0x40, // Display Information Extension (DI-EXT) - EDID_EXTENSION_LS = 0x50, // Localised String Extension (LS-EXT) - EDID_EXTENSION_MI = 0x60, // Microdisplay Interface Extension (MI-EXT) - EDID_EXTENSION_DTCDB_1 = 0xa7, // Display Transfer Characteristics Data Block (DTCDB) - EDID_EXTENSION_DTCDB_2 = 0xaf, - EDID_EXTENSION_DTCDB_3 = 0xbf, - EDID_EXTENSION_BLOCK_MAP = 0xf0, // Block Map - EDID_EXTENSION_DDDB = 0xff, // Display Device Data Block (DDDB) -}; - -enum edid_display_type { - EDID_DISPLAY_TYPE_MONOCHROME, - EDID_DISPLAY_TYPE_RGB, - EDID_DISPLAY_TYPE_NON_RGB, - EDID_DISPLAY_TYPE_UNDEFINED, -}; - -enum edid_aspect_ratio { - EDID_ASPECT_RATIO_16_10, - EDID_ASPECT_RATIO_4_3, - EDID_ASPECT_RATIO_5_4, - EDID_ASPECT_RATIO_16_9, -}; - -enum edid_signal_sync { - EDID_SIGNAL_SYNC_ANALOG_COMPOSITE, - EDID_SIGNAL_SYNC_BIPOLAR_ANALOG_COMPOSITE, - EDID_SIGNAL_SYNC_DIGITAL_COMPOSITE, - EDID_SIGNAL_SYNC_DIGITAL_SEPARATE, -}; - -enum edid_stereo_mode { - EDID_STEREO_MODE_NONE, - EDID_STEREO_MODE_RESERVED, - EDID_STEREO_MODE_FIELD_SEQUENTIAL_RIGHT, - EDID_STEREO_MODE_2_WAY_INTERLEAVED_RIGHT, - EDID_STEREO_MODE_FIELD_SEQUENTIAL_LEFT, - EDID_STEREO_MODE_2_WAY_INTERLEAVED_LEFT, - EDID_STEREO_MODE_4_WAY_INTERLEAVED, - EDID_STEREO_MODE_SIDE_BY_SIDE_INTERLEAVED, -}; - -enum edid_monitor_descriptor_type { - EDID_MONTIOR_DESCRIPTOR_MANUFACTURER_DEFINED = 0x0f, - EDID_MONITOR_DESCRIPTOR_STANDARD_TIMING_IDENTIFIERS = 0xfa, - EDID_MONITOR_DESCRIPTOR_COLOR_POINT = 0xfb, - EDID_MONITOR_DESCRIPTOR_MONITOR_NAME = 0xfc, - EDID_MONITOR_DESCRIPTOR_MONITOR_RANGE_LIMITS = 0xfd, - EDID_MONITOR_DESCRIPTOR_ASCII_STRING = 0xfe, - EDID_MONITOR_DESCRIPTOR_MONITOR_SERIAL_NUMBER = 0xff, -}; - -enum edid_secondary_timing_support { - EDID_SECONDARY_TIMING_NOT_SUPPORTED, - EDID_SECONDARY_TIMING_GFT = 0x02, -}; - - -struct __attribute__ (( packed )) edid_detailed_timing_descriptor { - uint16_t pixel_clock; /* = value * 10000 */ - - uint8_t horizontal_active_lo; - uint8_t horizontal_blanking_lo; - - unsigned horizontal_blanking_hi : 4; - unsigned horizontal_active_hi : 4; - - uint8_t vertical_active_lo; - uint8_t vertical_blanking_lo; - - unsigned vertical_blanking_hi : 4; - unsigned vertical_active_hi : 4; - - uint8_t horizontal_sync_offset_lo; - uint8_t horizontal_sync_pulse_width_lo; - - unsigned vertical_sync_pulse_width_lo : 4; - unsigned vertical_sync_offset_lo : 4; - - unsigned vertical_sync_pulse_width_hi : 2; - unsigned vertical_sync_offset_hi : 2; - unsigned horizontal_sync_pulse_width_hi : 2; - unsigned horizontal_sync_offset_hi : 2; - - uint8_t horizontal_image_size_lo; - uint8_t vertical_image_size_lo; - - unsigned vertical_image_size_hi : 4; - unsigned horizontal_image_size_hi : 4; - - uint8_t horizontal_border; - uint8_t vertical_border; - - unsigned stereo_mode_lo : 1; - unsigned signal_pulse_polarity : 1; /* pulse on sync, composite/horizontal polarity */ - unsigned signal_serration_polarity : 1; /* serrate on sync, vertical polarity */ - unsigned signal_sync : 2; - unsigned stereo_mode_hi : 2; - unsigned interlaced : 1; -}; - -static inline uint32_t -edid_detailed_timing_pixel_clock(const struct edid_detailed_timing_descriptor * const dtb) -{ - return dtb->pixel_clock * 10000; -} - -static inline uint16_t -edid_detailed_timing_horizontal_blanking(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->horizontal_blanking_hi << 8) | dtb->horizontal_blanking_lo; -} - -static inline uint16_t -edid_detailed_timing_horizontal_active(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->horizontal_active_hi << 8) | dtb->horizontal_active_lo; -} - -static inline uint16_t -edid_detailed_timing_vertical_blanking(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->vertical_blanking_hi << 8) | dtb->vertical_blanking_lo; -} - -static inline uint16_t -edid_detailed_timing_vertical_active(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->vertical_active_hi << 8) | dtb->vertical_active_lo; -} - -static inline uint8_t -edid_detailed_timing_vertical_sync_offset(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->vertical_sync_offset_hi << 4) | dtb->vertical_sync_offset_lo; -} - -static inline uint8_t -edid_detailed_timing_vertical_sync_pulse_width(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->vertical_sync_pulse_width_hi << 4) | dtb->vertical_sync_pulse_width_lo; -} - -static inline uint8_t -edid_detailed_timing_horizontal_sync_offset(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->horizontal_sync_offset_hi << 4) | dtb->horizontal_sync_offset_lo; -} - -static inline uint8_t -edid_detailed_timing_horizontal_sync_pulse_width(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->horizontal_sync_pulse_width_hi << 4) | dtb->horizontal_sync_pulse_width_lo; -} - -static inline uint16_t -edid_detailed_timing_horizontal_image_size(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->horizontal_image_size_hi << 8) | dtb->horizontal_image_size_lo; -} - -static inline uint16_t -edid_detailed_timing_vertical_image_size(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->vertical_image_size_hi << 8) | dtb->vertical_image_size_lo; -} - -static inline uint8_t -edid_detailed_timing_stereo_mode(const struct edid_detailed_timing_descriptor * const dtb) -{ - return (dtb->stereo_mode_hi << 2 | dtb->stereo_mode_lo); -} - - -struct __attribute__ (( packed )) edid_monitor_descriptor { - uint16_t flag0; - uint8_t flag1; - uint8_t tag; - uint8_t flag2; - uint8_t data[13]; -}; - -typedef char edid_monitor_descriptor_string[sizeof(((struct edid_monitor_descriptor *)0)->data) + 1]; - - -struct __attribute__ (( packed )) edid_monitor_range_limits { - uint8_t minimum_vertical_rate; /* Hz */ - uint8_t maximum_vertical_rate; /* Hz */ - uint8_t minimum_horizontal_rate; /* kHz */ - uint8_t maximum_horizontal_rate; /* kHz */ - uint8_t maximum_supported_pixel_clock; /* = (value * 10) Mhz (round to 10 MHz) */ - - /* secondary timing formula */ - uint8_t secondary_timing_support; - uint8_t reserved; - uint8_t secondary_curve_start_frequency; /* horizontal frequency / 2 kHz */ - uint8_t c; /* = (value >> 1) */ - uint16_t m; - uint8_t k; - uint8_t j; /* = (value >> 1) */ -}; - - -struct __attribute__ (( packed )) edid_standard_timing_descriptor { - uint8_t horizontal_active_pixels; /* = (value + 31) * 8 */ - - unsigned refresh_rate : 6; /* = value + 60 */ - unsigned image_aspect_ratio : 2; -}; - -const inline uint32_t -edid_standard_timing_horizontal_active(const struct edid_standard_timing_descriptor * const desc) -{ - return ((desc->horizontal_active_pixels + 31) << 3); -} - -const inline uint32_t -edid_standard_timing_vertical_active(const struct edid_standard_timing_descriptor * const desc) -{ - const uint32_t hres = edid_standard_timing_horizontal_active(desc); - - switch (desc->image_aspect_ratio) { - case EDID_ASPECT_RATIO_16_10: - return ((hres * 10) >> 4); - case EDID_ASPECT_RATIO_4_3: - return ((hres * 3) >> 2); - case EDID_ASPECT_RATIO_5_4: - return ((hres << 2) / 5); - case EDID_ASPECT_RATIO_16_9: - return ((hres * 9) >> 4); - } - - return hres; -} - -const inline uint32_t -edid_standard_timing_refresh_rate(const struct edid_standard_timing_descriptor * const desc) -{ - return (desc->refresh_rate + 60); -} - - -struct __attribute__ (( packed )) edid { - /* header information */ - uint8_t header[8]; - - /* vendor/product identification */ - uint16_t manufacturer; - - uint8_t product[2]; - uint8_t serial_number[4]; - uint8_t manufacture_week; - uint8_t manufacture_year; /* = value + 1990 */ - - /* EDID version */ - uint8_t version; - uint8_t revision; - - /* basic display parameters and features */ - union { - struct __attribute__ (( packed )) { - unsigned dfp_1x : 1; /* VESA DFP 1.x */ - unsigned : 6; - unsigned digital : 1; - } digital; - struct __attribute__ (( packed )) { - unsigned vsync_serration : 1; - unsigned green_video_sync : 1; - unsigned composite_sync : 1; - unsigned separate_sync : 1; - unsigned blank_to_black_setup : 1; - unsigned signal_level_standard : 2; - unsigned digital : 1; - } analog; - } video_input_definition; - - uint8_t maximum_horizontal_image_size; /* cm */ - uint8_t maximum_vertical_image_size; /* cm */ - - uint8_t display_transfer_characteristics; /* gamma = (value + 100) / 100 */ - - struct __attribute__ (( packed )) { - unsigned default_gtf : 1; /* generalised timing formula */ - unsigned preferred_timing_mode : 1; - unsigned standard_default_color_space : 1; - unsigned display_type : 2; - unsigned active_off : 1; - unsigned suspend : 1; - unsigned standby : 1; - } feature_support; - - /* color characteristics block */ - unsigned green_y_low : 2; - unsigned green_x_low : 2; - unsigned red_y_low : 2; - unsigned red_x_low : 2; - - unsigned white_y_low : 2; - unsigned white_x_low : 2; - unsigned blue_y_low : 2; - unsigned blue_x_low : 2; - - uint8_t red_x; - uint8_t red_y; - uint8_t green_x; - uint8_t green_y; - uint8_t blue_x; - uint8_t blue_y; - uint8_t white_x; - uint8_t white_y; - - /* established timings */ - struct __attribute__ (( packed )) { - unsigned timing_800x600_60 : 1; - unsigned timing_800x600_56 : 1; - unsigned timing_640x480_75 : 1; - unsigned timing_640x480_72 : 1; - unsigned timing_640x480_67 : 1; - unsigned timing_640x480_60 : 1; - unsigned timing_720x400_88 : 1; - unsigned timing_720x400_70 : 1; - - unsigned timing_1280x1024_75 : 1; - unsigned timing_1024x768_75 : 1; - unsigned timing_1024x768_70 : 1; - unsigned timing_1024x768_60 : 1; - unsigned timing_1024x768_87 : 1; - unsigned timing_832x624_75 : 1; - unsigned timing_800x600_75 : 1; - unsigned timing_800x600_72 : 1; - } established_timings; - - struct __attribute__ (( packed )) { - unsigned reserved : 7; - unsigned timing_1152x870_75 : 1; - } manufacturer_timings; - - /* standard timing id */ - struct edid_standard_timing_descriptor standard_timing_id[8]; - - /* detailed timing */ - union { - struct edid_monitor_descriptor monitor; - struct edid_detailed_timing_descriptor timing; - } detailed_timings[4]; - - uint8_t extensions; - uint8_t checksum; -}; - -static inline void -edid_manufacturer(const struct edid * const edid, char manufacturer[4]) -{ - manufacturer[0] = '@' + ((edid->manufacturer & 0x007c) >> 2); - manufacturer[1] = '@' + (((edid->manufacturer & 0x0003) >> 00) << 3) - | (((edid->manufacturer & 0xe000) >> 13) << 0); - manufacturer[2] = '@' + ((edid->manufacturer & 0x1f00) >> 8); - manufacturer[3] = '\0'; -} - -static inline double -edid_gamma(const struct edid * const edid) -{ - return (edid->display_transfer_characteristics + 100) / 100.0; -} - -static inline bool -edid_detailed_timing_is_monitor_descriptor(const struct edid * const edid, - const uint8_t timing) -{ - const struct edid_monitor_descriptor * const mon = - &edid->detailed_timings[timing].monitor; - - assert(timing < ARRAY_SIZE(edid->detailed_timings)); - - return mon->flag0 == 0x0000 && mon->flag1 == 0x00 && mon->flag2 == 0x00; -} - - -struct __attribute__ (( packed )) edid_color_characteristics_data { - struct { - uint16_t x; - uint16_t y; - } red, green, blue, white; -}; - -static inline struct edid_color_characteristics_data -edid_color_characteristics(const struct edid * const edid) -{ - const struct edid_color_characteristics_data characteristics = { - .red = { - .x = (edid->red_x << 2) | edid->red_x_low, - .y = (edid->red_y << 2) | edid->red_y_low, - }, - .green = { - .x = (edid->green_x << 2) | edid->green_x_low, - .y = (edid->green_y << 2) | edid->green_y_low, - }, - .blue = { - .x = (edid->blue_x << 2) | edid->blue_x_low, - .y = (edid->blue_y << 2) | edid->blue_y_low, - }, - .white = { - .x = (edid->white_x << 2) | edid->white_x_low, - .y = (edid->white_y << 2) | edid->white_y_low, - }, - }; - - return characteristics; -} - - -struct __attribute__ (( packed )) edid_block_map { - uint8_t tag; - uint8_t extension_tag[126]; - uint8_t checksum; -}; - - -struct __attribute__ (( packed )) edid_extension { - uint8_t tag; - uint8_t revision; - uint8_t extension_data[125]; - uint8_t checksum; -}; - - -static inline bool -edid_verify_checksum(const uint8_t * const block) -{ - uint8_t checksum = 0; - int i; - - for (i = 0; i < EDID_BLOCK_SIZE; i++) - checksum += block[i]; - - return (checksum == 0); -} - -static inline double -edid_decode_fixed_point(uint16_t value) -{ - double result = 0.0; - - assert((~value & 0xfc00) == 0xfc00); /* edid fraction is 10 bits */ - - for (uint8_t i = 0; value && (i < 10); i++, value >>= 1) - result = result + ((value & 0x1) * (1.0 / (1 << (10 - i)))); - - return result; -} - -#endif - diff --git a/src/hdmi.h b/src/hdmi.h deleted file mode 100644 index 19278ba..0000000 --- a/src/hdmi.h +++ /dev/null @@ -1,77 +0,0 @@ -/* vim: set et fde fdm=syntax ft=c.doxygen ts=4 sts=4 sw=4 : */ -/* - * Copyright © 2010-2011 Saleem Abdulrasool . - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef eds_hdmi_h -#define eds_hdmi_h - -#include "cea861.h" - -/*! \todo figure out a better way to determine the offsets */ -#define HDMI_VSDB_EXTENSION_FLAGS_OFFSET (0x06) -#define HDMI_VSDB_MAX_TMDS_OFFSET (0x07) -#define HDMI_VSDB_LATENCY_FIELDS_OFFSET (0x08) - -static const uint8_t HDMI_OUI[] = { 0x00, 0x0C, 0x03 }; - -struct __attribute__ (( packed )) hdmi_vendor_specific_data_block { - struct cea861_data_block_header header; - - uint8_t ieee_registration_id[3]; /* LSB */ - - unsigned port_configuration_b : 4; - unsigned port_configuration_a : 4; - unsigned port_configuration_d : 4; - unsigned port_configuration_c : 4; - - /* extension fields */ - unsigned dvi_dual_link : 1; - unsigned : 2; - unsigned yuv_444_supported : 1; - unsigned colour_depth_30_bit : 1; - unsigned colour_depth_36_bit : 1; - unsigned colour_depth_48_bit : 1; - unsigned audio_info_frame : 1; - - uint8_t max_tmds_clock; /* = value * 5 */ - - unsigned : 6; - unsigned interlaced_latency_fields : 1; - unsigned latency_fields : 1; - - uint8_t video_latency; /* = (value - 1) * 2 */ - uint8_t audio_latency; /* = (value - 1) * 2 */ - uint8_t interlaced_video_latency; - uint8_t interlaced_audio_latency; - - uint8_t reserved[]; -}; - -#endif - diff --git a/src/main.cpp b/src/main.cpp index 58b344c..612f283 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,109 @@ #include +//#include +//#include +#include //Patch wire.h: BUFFER_LENGTH = 256 TWI_BUFFER_LENGTH 256 +// ToDo: Eigene Wire.h einbinden mit vorgepatchen Werten -void setup() { - // put your setup code here, to run once: +/*uint8_t edid[256] = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x4C, 0x2D, 0xF4, 0x0C, 0x45, 0x52, 0x46, 0x31, 0x15, 0x19, 0x01, 0x03, 0x80, 0x3C, 0x22, 0x78, 0x2A, 0x52, 0x95, 0xA5, 0x56, 0x54, 0x9D, 0x25, 0x0E, 0x50, 0x54, 0xBF, 0xEF, 0x80, 0x71, 0x4F, 0x81, 0xC0, 0x81, 0x00, 0x81, 0x80, 0x95, 0x00, 0xA9, 0xC0, 0xB3, 0x00, 0x01, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x56, 0x50, 0x21, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28, 0x55, 0x00, 0x56, 0x50, 0x21, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x32, 0x4B, 0x1E, 0x51, 0x11, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x53, 0x32, 0x37, 0x45, 0x33, 0x37, 0x30, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x62, 0x02, 0x03, 0x1B, 0xF1, 0x46, 0x90, 0x04, 0x1F, 0x13, 0x03, 0x12, 0x67, 0x03, 0x0C, 0x00, 0x10, 0x00, 0x80, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x01, 0x1D, 0x00, 0xBC, 0x52, 0xD0, 0x1E, 0x20, 0xB8, 0x28, 0x55, 0x40, 0x56, 0x50, 0x21, 0x00, 0x00, 0x1E, 0x8C, 0x0A, 0xD0, 0x90, 0x20, 0x40, 0x31, 0x20, 0x0C, 0x40, 0x55, 0x00, 0x56, 0x50, 0x21, 0x00, 0x00, 0x18, 0x8C, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10, 0x10, 0x3E, 0x96, 0x00, 0x56, 0x50, 0x21, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D +};*/ + +#define EDID_LENGTH 128 + +// 800x600 +uint8_t edid[EDID_LENGTH] = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1E, 0x6D, 0x7D, 0x58, 0xC1, 0x90, 0x02, 0x00, + 0x08, 0x16, 0x01, 0x03, 0x80, 0x33, 0x1D, 0x78, 0xEA, 0x5E, 0xA5, 0xA2, 0x55, 0x4D, 0xA0, 0x26, + 0x11, 0x50, 0x54, 0x27, 0x4B, 0x00, 0xB3, 0x00, 0x81, 0x80, 0x81, 0x40, 0x71, 0x4F, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xE8, 0x0D, 0x20, 0xA0, 0x30, 0x58, 0x12, 0x20, 0x30, 0x20, + 0x34, 0x00, 0xC8, 0x96, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x49, 0x50, 0x53, + 0x32, 0x33, 0x35, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7}; + +// IPS235 1920x1080 +/*uint8_t edid[128] = { +0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1E, 0x6D, 0x7E, 0x58, 0xC1, 0x90, 0x02, 0x00, +0x08, 0x16, 0x01, 0x03, 0x80, 0x33, 0x1D, 0x78, 0xEA, 0x5E, 0xA5, 0xA2, 0x55, 0x4D, 0xA0, 0x26, +0x11, 0x50, 0x54, 0x21, 0x08, 0x00, 0xB3, 0x00, 0x81, 0x80, 0x81, 0x40, 0x71, 0x40, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, +0x45, 0x00, 0xE0, 0x0E, 0x11, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x49, 0x50, 0x53, +0x32, 0x33, 0x35, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA8 +};*/ + +unsigned int c; +//SoftWire sw(A2, A3); + +void receiveEvent(int receivedByte) +{ + while (0 < Wire.available()) + { + c = Wire.read(); /* receive start position */ + //Serial.print(c, HEX); /* print the requested position */ + } + //Serial.println(); /* to newline */ + return; } -void loop() { - // put your main code here, to run repeatedly: -} \ No newline at end of file +void requestEvent() +{ + // Send virtual EEPROM in full length from start position + Wire.write(edid + c, EDID_LENGTH - c); +} + +void setup() +{ + Serial.begin(9600); + Serial.println("**** HDMI ****"); + pinMode(4, OUTPUT); //Hot plug detection + Wire.begin(0x50); // EDID Register + digitalWrite(4, LOW); + delay(20); + + Wire.onReceive(receiveEvent); + Wire.onRequest(requestEvent); + + digitalWrite(4, HIGH); //Source knows that a screen is attached and want to read the edid of the screen + + /*sw.setTimeout_ms(40); + sw.begin(); + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); + + // Set how long we are willing to wait for a device to respond + sw.setTimeout_ms(200); + + const uint8_t firstAddr = 1; + const uint8_t lastAddr = 0x7F; + Serial.println(); + Serial.print("Interrogating all addresses in range 0x"); + Serial.print(firstAddr, HEX); + Serial.print(" - 0x"); + Serial.print(lastAddr, HEX); + Serial.println(" (inclusive) ..."); + + for (uint8_t addr = firstAddr; addr <= lastAddr; addr++) { + digitalWrite(LED_BUILTIN, HIGH); + delayMicroseconds(50); + + uint8_t startResult = sw.llStart((addr << 1) + 1); // Signal a read + sw.stop(); + + if (startResult == 0) { + Serial.print("\rDevice found at 0x"); + Serial.println(addr, HEX); + Serial.flush(); + } + digitalWrite(LED_BUILTIN, LOW); + + delay(50); + } + Serial.println("Finished");*/ +} + +void loop() +{ +}