struct FrameBufferInfo * InitializeFrameBuffer(uint32_t width, uint32_t height, uint32_t depth) { if (width > 4096 || height > 4096 || depth > 32) return 0; FrameBufferInfo.width = width; FrameBufferInfo.height = height; FrameBufferInfo.vWidth = width; FrameBufferInfo.vHeight = height; FrameBufferInfo.pitch = 0; FrameBufferInfo.depth = depth; FrameBufferInfo.x = 0; FrameBufferInfo.y = 0; FrameBufferInfo.pointer = 0; FrameBufferInfo.size = 0; uart_puts("MailboxWrite\r\n"); uint32_t value = (uint32_t)(&FrameBufferInfo) | 0x40000000; MailboxWrite(value, CHANNEL_GPU); uint32_t mail = 0; do { uart_puts("MailboxRead\r\n"); mail = MailboxRead(CHANNEL_GPU); } while ((mail != 0) && (FrameBufferInfo.pointer == 0)); return &FrameBufferInfo; }
/*------------------------------------------------------------------------------------ The main program ------------------------------------------------------------------------------------*/ void main(uint32_t r0, uint32_t r1, uint32_t atags) { UNUSED(r0); UNUSED(r1); UNUSED(atags); // Write and read from the mailbox and then display the color image MailboxWrite(&FrameBufferInfo,1); MailboxRead(1); uint16_t *p = FrameBufferInfo.vBuffPointer; displayImage16(&colorImage, p); } // End kernel_main
unsigned int InitGraphics(unsigned int screenWidth, unsigned int screenHeight, unsigned int bitDepth) { //set global parameters m_screenWidth = screenWidth; m_screenHeight = screenHeight; m_bitDepth = bitDepth; //Set up the frame buffer info //physical width of the screen PutUInt32(0x40040000, m_screenWidth); //physical height of the screen PutUInt32(0x40040004, m_screenHeight); //virtual width of the screen PutUInt32(0x40040008, m_screenWidth); // virtual height of the screen PutUInt32(0x4004000C, m_screenHeight); //pitch ( number of bytes between each row of the frame buffer) set by the GPU ( set to 0 for now ) PutUInt32(0x40040010, 0); //bit depth PutUInt32(0x40040014, m_bitDepth); // X offset PutUInt32(0x40040018, 0); // Y offset PutUInt32(0x4004001C, 0); // pointer returned by the GPU ( set to 0 for now )r PutUInt32(0x40040020, 0); // size of the frame buffer, set by the GPU ( set to 0 for now ) PutUInt32(0x40040024, 0); // !!!! This seems to break the system, looks like we dont need to add on 0x40000000. !!!! // add on 0x40000000 into the value in the frame buffer to specify how to write it to the structure, this will make the GPU clear its cache so we can see the result //PutUInt32(0x40040000, (GetUInt32(0x40040000) + 0x40000000)); // send the frame buffer info to channel 1 if (MailboxWrite(0x40040000, 1) == 0) { return 0; } unsigned int frameBufferResponce; frameBufferResponce = MailboxRead(1); if (frameBufferResponce == 0) { m_framebufferAddress = GetUInt32(0x40040020); return 1; } return 0; }
//------------------------------------------------------------------------ int notmain ( void ) { unsigned int ra,rb; unsigned int ry,rx; uart_init(); hexstring(0x12345678); hexstring(GETPC()); timer_init(); PUT32(0x40040000, 640); /* #0 Physical Width */ PUT32(0x40040004, 480); /* #4 Physical Height */ PUT32(0x40040008, 640); /* #8 Virtual Width */ PUT32(0x4004000C, 480); /* #12 Virtual Height */ PUT32(0x40040010, 0); /* #16 GPU - Pitch */ PUT32(0x40040014, 32); /* #20 Bit Depth */ PUT32(0x40040018, 0); /* #24 X */ PUT32(0x4004001C, 0); /* #28 Y */ PUT32(0x40040020, 0); /* #32 GPU - Pointer */ PUT32(0x40040024, 0); /* #36 GPU - Size */ hexstring(MailboxWrite(0x40040000,1)); hexstring(MailboxRead(1)); rb=0x40040000; for(ra=0;ra<10;ra++) { hexstrings(rb); hexstring(GET32(rb)); rb+=4; } rb=GET32(0x40040020); hexstring(rb); for(ra=0;ra<10000;ra++) { PUT32(rb,~((ra&0xFF)<<0)); rb+=4; } for(ra=0;ra<10000;ra++) { PUT32(rb,~((ra&0xFF)<<8)); rb+=4; } for(ra=0;ra<10000;ra++) { PUT32(rb,~((ra&0xFF)<<16)); rb+=4; } for(ra=0;ra<10000;ra++) { PUT32(rb,~((ra&0xFF)<<24)); rb+=4; } rb=GET32(0x40040020); hexstring(rb); ra=0; for(ry=0;ry<480;ry++) { for(rx=0;rx<480;rx++) { PUT32(rb,image_data[ra++]); rb+=4; } for(;rx<640;rx++) { PUT32(rb,0); rb+=4; } } return(0); }
int FramebufferInitialize() { uint32 retval=0; volatile unsigned int mb[100] __attribute__ ((aligned(16))); depth = 24; // // Tout d'abord, on veut récupérer l'adresse en mémoire du framebuffer // mb[0] = 8 * 4; // Taille du buffer i.e. de notre message à envoyer dans la mailbox mb[1] = 0; // On spécifie qu'on demande quelque chose mb[2] = 0x00040003; // La question que l'on pose: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface mb[3] = 2*4; // La taille de la réponse mb[4] = 0; // On indique que c'est une question ou un réponse (0 question) mb[5] = 0; // Largeur mb[6] = 0; // Hauteur mb[7] = 0; // Marqueur de fin MailboxWrite((uint32)(mb+0x40000000), 8); // On écrit le message dans la mailbox if(((retval = MailboxRead(8)) == 0) || (mb[1] != 0x80000000)){ // On vérifie que le message est passé return 0; } fb_x = mb[5]; // On récupére la largeur en pixel de l'écran fb_y = mb[6]; // On récupére la hauteur en pixel de l'écran uint32 mb_pos=1; mb[mb_pos++] = 0; // C'est une requête mb[mb_pos++] = 0x00048003; // On définit la hauteur et la largeur du framebuffer mb[mb_pos++] = 2*4; // On envoi 2 int pour la taille donc on spécifie la taille du buffer mb[mb_pos++] = 2*4; // Taille du message (tag + indicateur de requête) mb[mb_pos++] = fb_x; // On passe la largeur mb[mb_pos++] = fb_y; // On passe la hauteur mb[mb_pos++] = 0x00048004; // On définit la hauteur et la largeur virtuel du framebuffer mb[mb_pos++] = 2*4; // On envoi 2 int pour la taille donc on spécifie la taille du buffer mb[mb_pos++] = 2*4; // Taille du message (tag + indicateur de requête) mb[mb_pos++] = fb_x; // On passe la largeur mb[mb_pos++] = fb_y; // On passe la hauteur mb[mb_pos++] = 0x00048005; // On définit la profondeur du frame buffer mb[mb_pos++] = 1*4; mb[mb_pos++] = 1*4; mb[mb_pos++] = depth; // Profondeur i.e. nombre de couleur (24bit dans notre cas) mb[mb_pos++] = 0x00040001; // On demande l'allocation du buffer mb[mb_pos++] = 2*4; mb[mb_pos++] = 2*4; mb[mb_pos++] = 16; mb[mb_pos++] = 0; mb[mb_pos++] = 0; // Tag de fin de message mb[0] = mb_pos*4; // Taille du message dans son entier MailboxWrite((uint32)(mb+0x40000000), 8); // On écrit dans la mailbox if(((retval = MailboxRead(8)) == 0) || (mb[1] != 0x80000000)){ // On vérifie que le message a bien été passé return 0; } /* * On récupére les différente information récupérer de la requête pour pouvoir reconstruire l'adresse du framebuffer et sa taille */ mb_pos = 2; unsigned int val_buff_len=0; while(mb[mb_pos] != 0){ switch(mb[mb_pos++]) { case 0x00048003: val_buff_len = mb[mb_pos++]; mb_pos+= (val_buff_len/4)+1; break; case 0x00048004: val_buff_len = mb[mb_pos++]; mb_pos+= (val_buff_len/4)+1; break; case 0x00048005: val_buff_len = mb[mb_pos++]; mb_pos+= (val_buff_len/4)+1; break; case 0x00040001: val_buff_len = mb[mb_pos++]; mb_pos++; fb_address = mb[mb_pos++]; fb_size_bytes = mb[mb_pos++]; break; } } // // Récupére le pitch (This indicates the number of bytes between rows. Usually it will be related to the width, but there are exceptions such as when drawing only part of an image.) // mb[0] = 8 * 4; // Taille du buffer mb[1] = 0; // C'est une requête mb[2] = 0x00040008; // On veut récupérer le pitch mb[3] = 4; // Taille du buffer mb[4] = 0; // Taille de la demande mb[5] = 0; // Le pitch sera stocké ici mb[6] = 0; // Tag de fin de message mb[7] = 0; MailboxWrite((uint32)(mb+0x40000000), 8); if(((retval = MailboxRead(8)) == 0) || (mb[1] != 0x80000000)){ return 0; } pitch = mb[5]; fb_x--; fb_y--; return 1; }
int notmain ( void ) { static volatile unsigned int FB[] __attribute__((aligned (16))) = { 640, 480, 640, 480, 0, 24, 0, 0, 0, 0 }; MailboxWrite(((unsigned int)FB)+0x40000000, 1); assert(MailboxRead(1) == 0); // TODO: check? { unsigned int ptr = FB[8]; int i; for(i=0;i<640*480;i++) { PUT8(ptr++,0x00); PUT8(ptr++,0xFF); PUT8(ptr++,0x00); } } /* { unsigned int ptr = FB[8]; ptr += 640*10*3 + 50; int idx = 0; int i, j; for(i=0;i<10;i++) { for(j=0;j<10;j++) { PUT8(ptr++,image_smile[idx++]); PUT8(ptr++,image_smile[idx++]); PUT8(ptr++,image_smile[idx++]); } for(;j<640;j++) { PUT8(ptr++, 0x00); PUT8(ptr++, 0x00); PUT8(ptr++, 0x00); } } } { unsigned int ptr = FB[8]; ptr += 640*30*3 + 50; int idx = 0; int i, j; for(i=0;i<105;i++) { for(j=0;j<288;j++) { PUT8(ptr++,image_ceu[idx+0]); PUT8(ptr++,image_ceu[idx+2]); // TODO: why? PUT8(ptr++,image_ceu[idx+1]); // TODO: why? idx += 3; } for(;j<640;j++) { PUT8(ptr++, 0x00); PUT8(ptr++, 0x00); PUT8(ptr++, 0x00); } } } */ return(0); }