github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/soc/bcm2835/framebuffer/framebuffer.go (about) 1 // BCM2835 SoC FrameBuffer support 2 // https://github.com/usbarmory/tamago 3 // 4 // Copyright (c) the bcm2835 package authors 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 9 package framebuffer 10 11 import ( 12 "encoding/binary" 13 "fmt" 14 15 "github.com/usbarmory/tamago/soc/bcm2835" 16 ) 17 18 // EDID gets the raw EDID information from the attached monitor 19 func EDID() []byte { 20 outBuf := []byte{} 21 22 for block := uint32(0); true; block++ { 23 buf := make([]byte, bcm2835.VC_MEM_GET_EDID_BLOCK_LEN) 24 binary.LittleEndian.PutUint32(buf[0:], block) 25 26 msg := &bcm2835.MailboxMessage{ 27 Tags: []bcm2835.MailboxTag{ 28 { 29 ID: bcm2835.VC_MEM_GET_EDID_BLOCK, 30 Buffer: buf, 31 }, 32 }, 33 } 34 35 bcm2835.Mailbox.Call(bcm2835.VC_CH_PROPERTYTAGS_A_TO_VC, msg) 36 37 tag := msg.Tag(bcm2835.VC_MEM_GET_EDID_BLOCK) 38 39 if tag == nil || len(tag.Buffer) < 8 { 40 return outBuf 41 } 42 43 if binary.LittleEndian.Uint32(tag.Buffer[0:]) != block { 44 panic("Got EDID data for wrong block") 45 } 46 47 status := binary.LittleEndian.Uint32(tag.Buffer[4:]) 48 if status != 0 { 49 break 50 } 51 52 outBuf = append(outBuf, tag.Buffer[8:]...) 53 } 54 55 return outBuf 56 } 57 58 // PhysicalSize is the dimensions of the current framebuffer in pixels 59 func PhysicalSize() (width uint32, height uint32) { 60 buf := make([]byte, bcm2835.VC_FB_GET_PHYSICAL_SIZE_LEN) 61 62 msg := &bcm2835.MailboxMessage{ 63 Tags: []bcm2835.MailboxTag{ 64 { 65 ID: bcm2835.VC_FB_GET_PHYSICAL_SIZE, 66 Buffer: buf, 67 }, 68 }, 69 } 70 71 bcm2835.Mailbox.Call(bcm2835.VC_CH_PROPERTYTAGS_A_TO_VC, msg) 72 73 tag := msg.Tag(bcm2835.VC_FB_GET_PHYSICAL_SIZE) 74 75 if tag == nil || len(tag.Buffer) < 8 { 76 return 0, 0 77 } 78 79 return binary.LittleEndian.Uint32(tag.Buffer[0:]), binary.LittleEndian.Uint32(tag.Buffer[4:]) 80 } 81 82 // SetPhysicalSize changes the display resolution (in pixels) 83 func SetPhysicalSize(width uint32, height uint32) error { 84 buf := make([]byte, bcm2835.VC_FB_SET_PHYSICAL_SIZE_LEN) 85 binary.LittleEndian.PutUint32(buf[0:], width) 86 binary.LittleEndian.PutUint32(buf[4:], height) 87 88 msg := &bcm2835.MailboxMessage{ 89 Tags: []bcm2835.MailboxTag{ 90 { 91 ID: bcm2835.VC_FB_SET_PHYSICAL_SIZE, 92 Buffer: buf, 93 }, 94 }, 95 } 96 97 bcm2835.Mailbox.Call(bcm2835.VC_CH_PROPERTYTAGS_A_TO_VC, msg) 98 99 tag := msg.Tag(bcm2835.VC_FB_SET_PHYSICAL_SIZE) 100 101 if tag == nil || len(tag.Buffer) < 8 { 102 return fmt.Errorf("failed to set desired size") 103 } 104 105 newWidth := binary.LittleEndian.Uint32(tag.Buffer[0:]) 106 newHeight := binary.LittleEndian.Uint32(tag.Buffer[4:]) 107 108 if newWidth != width || newHeight != height { 109 return fmt.Errorf("failed to set desired size") 110 } 111 112 return nil 113 }