mathlizee
Posts: 4
Joined: Thu Jan 11, 2018 2:59 am

Get the state of the ACT LED on RPi 3

Sat Feb 17, 2018 2:40 am

Hello everyone,

I've been able to set the state of the ACT LED on the RPi 3 by using mailboxes. Here's the link to the tutorial I used:
https://adamransom.github.io/posts/rasp ... art-1.html

I have also tried to use the same mailboxes to get the state of the ACT LED. However, even if it seems to work, there's something that I'm not sure to understand... When the ACT LED is on, getting the state of that LED seems to return 0 and when it's off, the state that is returned is not zero.

I've looked everywhere to find documentation or an example on how to get the ACT LED state, but I haven't found anything. Like I said, event if it works, I would like to know why the state is somehow "reversed".

Here's the link to my code files: https://github.com/mathlizee/Rasperry-Pi-3

Does anybody knows why?
Thanks!

StevoD
Posts: 20
Joined: Tue Aug 29, 2017 11:37 am

Re: Get the state of the ACT LED on RPi 3

Sat Feb 17, 2018 10:32 am

mathlizee wrote:
Sat Feb 17, 2018 2:40 am
I've looked everywhere to find documentation or an example on how to get the ACT LED state, but I haven't found anything. Like I said, event if it works, I would like to know why the state is somehow "reversed".

Here's the link to my code files: https://github.com/mathlizee/Rasperry-Pi-3

Does anybody knows why?
Why are you passing a pointer to the state variable in your act_led_get_state function?

That isn't how it works, you pass a pointer to the property tags structure and the GPU will update it with the results, it doesn't use pointers embedded in your structure.

mathlizee
Posts: 4
Joined: Thu Jan 11, 2018 2:59 am

Re: Get the state of the ACT LED on RPi 3

Sat Feb 17, 2018 4:12 pm

Hi,

Thank you for your response! I pass a pointer in the structure because I based myself on the following post: viewtopic.php?f=43&t=109137&start=100#p989907

So, if I understand correctly what you're saying, instead of passing a pointer, I should pass nothing (or 0) to the state variable of the structure and read that varible once the mailbox_read and mailbox_write methods have been called? And the GPU should have updated that variable so that it's 0 if the LED is off, and 1 if it's on (or something like that)?

Thanks again!

LdB
Posts: 827
Joined: Wed Dec 07, 2016 2:29 pm

Re: Get the state of the ACT LED on RPi 3

Sun Feb 18, 2018 9:18 am

Try

Code: Select all

unsigned char act_led_get_state()
{
  // Property Info buffer
  volatile unsigned int __attribute__((aligned(16))) property_info[8];

  // Fill the message infos
  property_info[0] = ACT_LED_MESSAGE_SIZE; /* Not needed ... safer to use sizeof( property_info) */
  property_info[1] = ACT_LED_REQUEST_CODE;
  property_info[2] = ACT_LED_TAG_GET_STATE;
  property_info[3] = ACT_LED_VALUE_BUF_SIZE;
  property_info[4] = ACT_LED_RESPONSE_SIZE;
  property_info[5] = ACT_LED_PIN_NUMBER;
  property_info[6] = 0;  /* just zero the value the GPU will write it */
  property_info[7] = ACT_LED_END_TAG;

  // Send the message to the GPU by the mailbox 
  mailbox_write((unsigned long) &property_info, MAILBOX_CH_PROPERTY);

  // Read the response from the GPU
  mailbox_read(MAILBOX_CH_PROPERTY);

  // Return the state of the ACT LED
  // For unknown reasons, the status returned by the GPU is reversed
  return  (property_info[6]);    /* Return the value the GPU wrote into the struct */
}
So you know technically the line below is not correct, the address should be a GPU address as you are talking to the GPU.
I know it works on some versions of Pi firmware but not all

Code: Select all

  mailbox_write((unsigned long) &property_info, MAILBOX_CH_PROPERTY);
On a Pi2 or Pi3 It should be

Code: Select all

/*  OR of 0xC0000000 converts an ARM address to a GPU address */  
 mailbox_write((unsigned long) &property_info | 0xC0000000, MAILBOX_CH_PROPERTY);

mathlizee
Posts: 4
Joined: Thu Jan 11, 2018 2:59 am

Re: Get the state of the ACT LED on RPi 3

Thu Feb 22, 2018 10:05 pm

LdB wrote:
Sun Feb 18, 2018 9:18 am
Try

Code: Select all

unsigned char act_led_get_state()
{
  // Property Info buffer
  volatile unsigned int __attribute__((aligned(16))) property_info[8];

  // Fill the message infos
  property_info[0] = ACT_LED_MESSAGE_SIZE; /* Not needed ... safer to use sizeof( property_info) */
  property_info[1] = ACT_LED_REQUEST_CODE;
  property_info[2] = ACT_LED_TAG_GET_STATE;
  property_info[3] = ACT_LED_VALUE_BUF_SIZE;
  property_info[4] = ACT_LED_RESPONSE_SIZE;
  property_info[5] = ACT_LED_PIN_NUMBER;
  property_info[6] = 0;  /* just zero the value the GPU will write it */
  property_info[7] = ACT_LED_END_TAG;

  // Send the message to the GPU by the mailbox 
  mailbox_write((unsigned long) &property_info, MAILBOX_CH_PROPERTY);

  // Read the response from the GPU
  mailbox_read(MAILBOX_CH_PROPERTY);

  // Return the state of the ACT LED
  // For unknown reasons, the status returned by the GPU is reversed
  return  (property_info[6]);    /* Return the value the GPU wrote into the struct */
}
So you know technically the line below is not correct, the address should be a GPU address as you are talking to the GPU.
I know it works on some versions of Pi firmware but not all

Code: Select all

  mailbox_write((unsigned long) &property_info, MAILBOX_CH_PROPERTY);
On a Pi2 or Pi3 It should be

Code: Select all

/*  OR of 0xC0000000 converts an ARM address to a GPU address */  
 mailbox_write((unsigned long) &property_info | 0xC0000000, MAILBOX_CH_PROPERTY);

Thanks! I just tried and it works!

As for the conversion from the ARM address to the GPU address, I'm not sure that it's needed since I use the property tags channel: https://github.com/raspberrypi/firmware ... -mailboxes

Are you sure that the address should be converted?

LdB
Posts: 827
Joined: Wed Dec 07, 2016 2:29 pm

Re: Get the state of the ACT LED on RPi 3

Fri Feb 23, 2018 12:57 am

They have now adjusted the tags channel so it is now the exception, it didn't start out like that and I don't know why they changed it.

However its a simple OR of the VC offset address and it doesn't matter how many times you do the OR the result is the same.
For example you start with 0x40 you OR 0x80 as many times as you like the answer is 0xC0
0x40 | 0x 80 | 0x 80 | 0x80 = 0xC0

That is why it doen't matter if you do OR the offset yourself as you found out.

So my answer is you have to do it on every other call (TAGS is now a strange exception) but it is inherently safe to do it so do it so it isn't the exception. All my VC memory structures when I am pounding the GL pipeline have VC addresses it would be strange to have a VC structure that had an arm address it will always look wrong to me when reading the code.

However, you are free to do whatever you feel is right but you have been warned about older Pi's with old firmware :-)

ISR
Posts: 6
Joined: Thu Apr 19, 2018 12:44 pm

Re: Get the state of the ACT LED on RPi 3

Thu Apr 19, 2018 12:59 pm

Bellow is the code which i have written to activate "ACT" Led in RPI3 .can someone Please check this I am not getting any output if I call mailbox_write() twice. Its working if i just want to enable it by calling mailbox_write once.


unsigned int msg[] = {32, 0, 0x00038041, 8, 0, 130, 1, 0};
const unsigned int MAILBOX = 0x3f00b880;
unsigned int num;
void delay();
void set(int set);
void mailbox_read();
void mailbox_write();
void dummy(int data);

void open_led()
{
unsigned int status;
while(1)
{
delay();
set(1);
mailbox_write();
mailbox_read();
delay();
set(0);

mailbox_write();
mailbox_read();
}

}
void set(int set)
{
msg[0]=32;
msg[1]=0;
msg[2]=0x00038041;
msg[3]=8;
msg[4]=0;
msg[5]=130;
msg[6]=set;
msg[7]=0;
}

void delay()
{
for(num=0;num<50000;num++);
}
void mailbox_write(unsigned int num)
{
unsigned int status;
do
{
status = *(unsigned int *)(MAILBOX + 0x18);
}while(status & 0x80000000);
msg[6] = num;
*(unsigned int *)(MAILBOX + 0x20) = (unsigned int)msg + 8;
}

void mailbox_read()
{
unsigned int status;
do
{
do
{
status = *(unsigned int *)(MAILBOX + 0x18);
}while(status & 0x40000000);
}while(MAILBOX & 0b1111)

User avatar
Ultibo
Posts: 135
Joined: Wed Sep 30, 2015 10:29 am
Location: Australia
Contact: Website

Re: Get the state of the ACT LED on RPi 3

Fri Apr 20, 2018 12:34 am

ISR wrote:
Thu Apr 19, 2018 12:59 pm
Bellow is the code which i have written to activate "ACT" Led in RPI3 .can someone Please check this I am not getting any output if I call mailbox_write() twice. Its working if i just want to enable it by calling mailbox_write once.
I think you might be tripping yourself over with your use of global variables.

You code does this to turn the LED on:
ISR wrote:
Thu Apr 19, 2018 12:59 pm

Code: Select all

	delay();
	set(1);
	mailbox_write();
	mailbox_read();
The call to set(1) does this:
ISR wrote:
Thu Apr 19, 2018 12:59 pm

Code: Select all

	msg[6]=set;
But then in mailboxwrite() you do this:
ISR wrote:
Thu Apr 19, 2018 12:59 pm

Code: Select all

	msg[6] = num;
And that effectively overwrites whatever value you passed to set().

Even worse the delay() function uses num as the loop counter so the value is always guaranteed to be 50000.

There are other issues, like the msg buffer has to be 16 byte aligned to pass it to the mailbox but start with the obvious ones and see what result you get.
Ultibo.org | Make something amazing
https://ultibo.org

Threads, multi-core, OpenGL, Camera, FAT, NTFS, TCP/IP, USB and more in 3MB with 2 second boot!

User avatar
Paeryn
Posts: 2110
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Get the state of the ACT LED on RPi 3

Fri Apr 20, 2018 12:58 am

Ultibo wrote:
Fri Apr 20, 2018 12:34 am
But then in mailboxwrite() you do this:
ISR wrote:
Thu Apr 19, 2018 12:59 pm

Code: Select all

	msg[6] = num;
And that effectively overwrites whatever value you passed to set().

Even worse the delay() function uses num as the loop counter so the value is always guaranteed to be 50000.
In mailboxwrite the variable num is a local which is shadowing the global (it's the parameter of the function), but when mailboxwrite is called no parameters are passed so it will have some potentially random value.

One good case for not declaring functions with empty parameter lists - the compiler won't notice that you use an incorrect number of parameters since you effectively said it will take zero or more parameters, each being of any type.
She who travels light — forgot something.

ISR
Posts: 6
Joined: Thu Apr 19, 2018 12:44 pm

Re: Get the state of the ACT LED on RPi 3

Fri Apr 20, 2018 4:21 am

Thank you :) so much for the reply
I followed this link https://zhuohua.me/2018/01/01/Raspberry ... l-in-Rust/ this is to enable ACT led but I need to blink ACT led so I modified code and can u please tell what value should be given in delay () function ?

ISR
Posts: 6
Joined: Thu Apr 19, 2018 12:44 pm

Re: Get the state of the ACT LED on RPi 3

Fri Apr 20, 2018 4:55 am

This code is working fine to enable ACT led but if I uncomment the following lines its not working :(

unsigned int msg[] = {32, 0, 0x00038041, 8, 0, 130, 1, 0};
const unsigned int MAILBOX = 0x3f00b880;
unsigned int num;

void delay();
void set(unsigned int set);
void mailbox_read();
void mailbox_write();


void open_led()
{

while(1)
{
set(1);
mailbox_write();
mailbox_read();
/* delay();
set(0);

mailbox_write();
mailbox_read();
delay();*/
}

}
void set(unsigned int set)
{
msg[0]=32;
msg[1]=0;
msg[2]=0x00038041;
msg[3]=8;
msg[4]=0;
msg[5]=130;
msg[6]=set;
msg[7]=0;
}

void delay()
{
for(num=0;num<50000;num++);
}
void mailbox_write()
{
unsigned int status;
do
{
status = *(unsigned int *)(MAILBOX + 0x18);
}while(status & 0x80000000);
*(unsigned int *)(MAILBOX + 0x20) = (unsigned int)msg + 8;
}

void mailbox_read()
{
unsigned int status,buffer_msg;
do
{
do
{
status = *(unsigned int *)(MAILBOX + 0x18);
}while(status & 0x40000000);
buffer_msg = *(unsigned int *)(MAILBOX + 0x00);
}while(MAILBOX & 0b1111);
}

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 7 guests