Skip to main content
fixed grammar
Source Link
goldilocks
  • 60.1k
  • 17
  • 115
  • 230

There are no error messages. When I tested my code on RPi, i got very unexpected result. Pins worked very unexpectedly.

There are no error messages. When I tested my code on RPi, i got very unexpected result. Pins worked very unexpectedly.

There are no error messages.

Hellow everyone! Just few days ago I boightbought Rasberry Pi 3 for education, and try my best at low-level programming. For now I wrote a simple GPIO code to set low and high level on controller's pin. My functions can write digital high and low on pins, by GPIO number (0-53). Without with functions to set high/low on pin I must find required register to set pin to output as GPFSEL0-GPFSEL5 and find required bit (every 3 bit refers to next pin). Then I need to find required GPSET register (GPSET0-GPSET1), every bit of this refers to next pin. So it will looks like:

There are no error messages. When I tested my code on RPi, i got very unexpected result. Pins worked very unexpectedly.

Hellow everyone! Just few days ago I boight Rasberry Pi 3 for education, and try my best at low-level programming. For now I wrote a simple GPIO code to set low and high level on controller's pin. My functions can write digital high and low on pins, by GPIO number (0-53). Without with functions to set high/low on pin I must find required register to set pin to output as GPFSEL0-GPFSEL5 and find required bit (every 3 bit refers to next pin). Then I need to find required GPSET register (GPSET0-GPSET1), every bit of this refers to next pin. So it will looks like:

Just few days ago I bought Rasberry Pi 3 for education, and try my best at low-level programming. For now I wrote a simple GPIO code to set low and high level on controller's pin. My functions can write digital high and low on pins, by GPIO number (0-53). Without with functions to set high/low on pin I must find required register to set pin to output as GPFSEL0-GPFSEL5 and find required bit (every 3 bit refers to next pin). Then I need to find required GPSET register (GPSET0-GPSET1), every bit of this refers to next pin. So it will looks like:

There are no error messages. When I tested my code on RPi, i got very unexpected result. Pins worked very unexpectedly.

Source Link

Raspberry Pi Baremetal Programming

Hellow everyone! Just few days ago I boight Rasberry Pi 3 for education, and try my best at low-level programming. For now I wrote a simple GPIO code to set low and high level on controller's pin. My functions can write digital high and low on pins, by GPIO number (0-53). Without with functions to set high/low on pin I must find required register to set pin to output as GPFSEL0-GPFSEL5 and find required bit (every 3 bit refers to next pin). Then I need to find required GPSET register (GPSET0-GPSET1), every bit of this refers to next pin. So it will looks like:

     //To set high GPIO4 pin (GPFSEL0 and GPSET0 assumed to be adresses)
            #define GPIO4_GPFSEL 12
            #define GPIO4 4
            *GPFSEL0 |= (1 << GPIO4_GPFSEL);
            *GPSET0 |= (1 << 4);

So, I wrote more high-level functions to avoid remebering bits and registers:

gpio_set_mode(GPIO4, GPIO_OUTPUT);
gpio_set_high(GPIO4);

And how looks my functions:

void gpio_set_mode(uint32_t gpio, gpio_mode mode)
{
   uint32_t gpfsel_addr = GPIO_BASE;
   uint32_t gpfsel_num = (uint32_t)(gpio / 10);
   uint32_t gpio_bit = ((((uint32_t)(gpio % 10)) * 3));

   for (int i = 0; i < 6; i++)
   {
       if (i == gpfsel_num)
           break;
       else
           gpfsel_addr += 0x04;
   }

   volatile uint32_t* GPFSEL = (volatile uint32_t*) gpfsel_addr;
   switch (mode)
   {
       case GPIO_OUTPUT:
           *GPFSEL |= (1 << gpio_bit);
       case GPIO_INPUT:
       {
       *GPFSEL &= ~(1 << gpio_bit);
       *GPFSEL &= ~(1 << (gpio_bit+1));
       *GPFSEL &= ~(1 << (gpio_bit+2));
       }
   }
}

void gpio_set_high(uint32_t gpio)
{
    volatile uint32_t* GPSET = ((gpio < 32) ? ( (volatile uint32_t*)(GPSET0)) : ( (volatile uint32_t*)(GPSET1) ));
    uint32_t gpio_bit = (gpio < 32) ? gpio : (gpio - 32);
    *GPSET |= (1 << gpio_bit);
}


void gpio_set_low(uint32_t gpio)
{
   volatile uint32_t* GPCLR = ((gpio < 32) ? ( (volatile uint32_t*)(GPCLR0) ) : ( (volatile uint32_t*)(GPCLR1)));
   uint32_t gpio_bit = ((gpio < 32) ? gpio : (gpio - 32));
   *GPCLR |= (1 << gpio_bit);
}

uint32_t gpio_status(uint32_t gpio)
{
   volatile  uint32_t* GPLEV = ((gpio < 32) ? ((volatile uint32_t*)(GPLEV0)) : ((volatile uint32_t*)(GPLEV1)));
   uint32_t  gpio_bit = ((gpio < 32) ? gpio : (gpio - 32));
   return (*GPLEV & (1 << gpio_bit));
}

And for some reason my code doesnt works. But I sure, it must work. I compile it with arm-none-eabi-gcc with args:

-Wall -O2 -nostdlib -nostartfiles -ffreestanding