Click here to Skip to main content
14,163,348 members

C / C++ / MFC

 
GeneralRe: volatile misbehaves Pin
Vaclav_17-May-18 4:26
memberVaclav_17-May-18 4:26 
GeneralRe: volatile misbehaves Pin
Richard MacCutchan17-May-18 4:42
protectorRichard MacCutchan17-May-18 4:42 
GeneralRe: volatile misbehaves Pin
Vaclav_17-May-18 5:39
memberVaclav_17-May-18 5:39 
GeneralRe: volatile misbehaves Pin
supercat930-May-18 12:20
membersupercat930-May-18 12:20 
AnswerRe: volatile misbehaves Pin
Joe Woodbury17-May-18 5:48
professionalJoe Woodbury17-May-18 5:48 
GeneralRe: volatile misbehaves Pin
Vaclav_17-May-18 6:04
memberVaclav_17-May-18 6:04 
GeneralRe: volatile misbehaves Pin
Vaclav_17-May-18 7:24
memberVaclav_17-May-18 7:24 
AnswerRe: volatile misbehaves Pin
leon de boer18-May-18 8:16
memberleon de boer18-May-18 8:16 
Allow me to help you out ... you are trying to map all the GPIO hardware registers so here is the struct from the manual
#include <stdbool.h>
#include <stdint.h>
/*--------------------------------------------------------------------------}
{    RASPBERRY PI GPIO HARDWARE REGISTERS - BCM2835.PDF Manual Section 6	}
{--------------------------------------------------------------------------*/
struct __attribute__((__packed__, aligned(4))) GPIORegisters {
	uint32_t GPFSEL[6];												// 0x00  GPFSEL0 - GPFSEL5
	uint32_t reserved1;												// 0x18  reserved
	uint32_t GPSET[2];												// 0x1C  GPSET0 - GPSET1;
	uint32_t reserved2;												// 0x24  reserved
	uint32_t GPCLR[2];												// 0x28  GPCLR0 - GPCLR1
	uint32_t reserved3;												// 0x30  reserved
	const uint32_t GPLEV[2];										// 0x34  GPLEV0 - GPLEV1   ** Read only hence const
	uint32_t reserved4;												// 0x3C  reserved
	uint32_t GPEDS[2];												// 0x40  GPEDS0 - GPEDS1 
	uint32_t reserved5;												// 0x48  reserved
	uint32_t GPREN[2];												// 0x4C  GPREN0 - GPREN1;	 
	uint32_t reserved6;												// 0x54  reserved
	uint32_t GPFEN[2];												// 0x58  GPFEN0 - GPFEN1;
	uint32_t reserved7;												// 0x60  reserved
	uint32_t GPHEN[2];												// 0x64  GPHEN0 - GPHEN1;
	uint32_t reserved8;												// 0x6c  reserved
	uint32_t GPLEN[2];												// 0x70  GPLEN0 - GPLEN1;
	uint32_t reserved9;												// 0x78  reserved
	uint32_t GPAREN[2];												// 0x7C  GPAREN0 - GPAREN1;
	uint32_t reserved10;											// 0x84  reserved
	uint32_t GPAFEN[2]; 											// 0x88  GPAFEN0 - GPAFEN1;
	uint32_t reserved11;											// 0x90  reserved
	uint32_t GPPUD; 												// 0x94  GPPUD 
	uint32_t GPPUDCLK[2]; 											// 0x98  GPPUDCLK0 - GPPUDCLK1;
};

Now you define the base address of the Pi .. for a Pi1 its 0x20000000, for other models 0x3F000000
#define RPi_IO_Base_Addr 0x20000000

Now what you want is to map the ALL THE REGISTERS to an address with a volatile on the pointer
#define GPIO ((volatile __attribute__((aligned(4))) struct GPIORegisters*)(uintptr_t)(RPi_IO_Base_Addr + 0x200000))

Thats it now its all done you can simply use the pointer to hit the registers ... so lets show you a function
/*-[gpio_output]------------------------------------------------------------}
. Given a valid GPIO port number the output is set high(true) or Low (false)
. RETURN: true for success, false for any failure
.--------------------------------------------------------------------------*/
bool gpio_output (uint8_t gpio, bool on) 
{
	if (gpio < 54) 													// Check GPIO pin number valid, return false if invalid
	{
		uint_fast32_t regnum = gpio / 32;							// Register number
		uint_fast32_t bit = 1 << (gpio % 32);						// Create mask bit
		volatile uint32_t* p;										// Create temp pointer
		if (on) p = &GPIO->GPSET[regnum];							// On == true means set
		else p = &GPIO->GPCLR[regnum];								// On == false means clear
		*p = bit;													// Output bit	
		return true;												// Return true
	}
	return false;													// Return false
}

Now we can go on from there lets enumerate the GPIO port functions
/*--------------------------------------------------------------------------}
;{	      ENUMERATED FSEL REGISTERS ... BCM2835.PDF MANUAL see page 92		}
;{-------------------------------------------------------------------------*/
/* In binary so any error is obvious */
typedef enum {
	GPIO_INPUT = 0b000,									// 0
	GPIO_OUTPUT = 0b001,								// 1
	GPIO_ALTFUNC5 = 0b010,								// 2
	GPIO_ALTFUNC4 = 0b011,								// 3
	GPIO_ALTFUNC0 = 0b100,								// 4
	GPIO_ALTFUNC1 = 0b101,								// 5
	GPIO_ALTFUNC2 = 0b110,								// 6
	GPIO_ALTFUNC3 = 0b111,								// 7
} GPIOMODE;

Having done that we can now set the port to any function
/*-[gpio_setup]-------------------------------------------------------------}
. Given a valid GPIO port number and mode sets GPIO to given mode
. RETURN: true for success, false for any failure
.--------------------------------------------------------------------------*/
bool gpio_setup (uint8_t gpio, GPIOMODE mode) 
{
	if (gpio > 54) return false;									// Check GPIO pin number valid, return false if invalid
	if (mode < 0 || mode > GPIO_ALTFUNC3) return false;				// Check requested mode is valid, return false if invalid
	uint_fast32_t bit = ((gpio % 10) * 3);							// Create bit mask
	uint32_t mem = GPIO->GPFSEL[gpio / 10];							// Read register
	mem &= ~(7 << bit);												// Clear GPIO mode bits for that port
	mem |= (mode << bit);											// Logical OR GPIO mode bits
	GPIO->GPFSEL[gpio / 10] = mem;									// Write value to register
	return true;													// Return true
}

If you want to try it then it all becomes pretty simple now.
 int main (void){
     gpio_setup(17, GPIO_OUTPUT);   // GPIO 17 to output
     gpio_output(17, true);         // GPIO 17 to a high
}

The assembler becomes reasonably optimal you will struggle to write faster .. if you want to try here is what it produces
gpio_output(unsigned char, bool):
  cmp r0, #53
  bhi .L5
  mov r2, #1
  and r3, r0, #31
  cmp r1, #0
  lsl r2, r2, r3
  lsr r0, r0, #5
  ldrne r3, .L7
  ldreq r3, .L7+4
  lsl r0, r0, #2
  add r3, r0, r3
  str r2, [r3]
  mov r0, #1
  bx lr
.L5:
  mov r0, #0
  bx lr
.L7:
  .word 538968092
  .word 538968104
gpio_setup(unsigned char, GPIOMODE):
  cmp r0, #54
  cmpls r1, #7
  bls .L16
  mov r0, #0
  bx lr
.L16:
  str lr, [sp, #-4]!
  mov lr, #7
  ldr ip, .L17
  umull r2, r3, r0, ip
  lsr ip, r3, #3
  and r3, ip, #255
  lsl r3, r3, #2
  add r3, r3, #536870912
  add ip, ip, ip, lsl #2
  add r3, r3, #2097152
  sub r0, r0, ip, lsl #1
  ldr r2, [r3]
  and r0, r0, #255
  add r0, r0, r0, lsl #1
  bic r2, r2, lr, lsl r0
  orr r0, r2, r1, lsl r0
  str r0, [r3]
  ldr lr, [sp], #4
  mov r0, #1
  bx lr
.L17:
  .word -858993459
main:
  mov r1, #131072
  ldr r2, .L20
  ldr r3, [r2, #4]
  bic r3, r3, #14680064
  orr r3, r3, #2097152
  str r3, [r2, #4]
  mov r0, #0
  str r1, [r2, #28]
  bx lr
.L20:
  .word 538968064

In vino veritas


modified 18-May-18 14:31pm.

GeneralRe: volatile misbehaves Pin
Vaclav_19-May-18 14:02
memberVaclav_19-May-18 14:02 
GeneralRe: volatile misbehaves Pin
Vaclav_19-May-18 14:36
memberVaclav_19-May-18 14:36 
GeneralRe: volatile misbehaves Pin
leon de boer20-May-18 4:41
memberleon de boer20-May-18 4:41 
GeneralRe: volatile misbehaves Pin
Vaclav_20-May-18 5:44
memberVaclav_20-May-18 5:44 
GeneralRe: volatile misbehaves Pin
leon de boer20-May-18 20:35
memberleon de boer20-May-18 20:35 
GeneralRe: volatile misbehaves Pin
Vaclav_21-May-18 3:18
memberVaclav_21-May-18 3:18 
GeneralRe: volatile misbehaves Pin
leon de boer21-May-18 4:33
memberleon de boer21-May-18 4:33 
Question__sync_synchronize stops processor ? Pin
Vaclav_16-May-18 10:31
memberVaclav_16-May-18 10:31 
AnswerRe: __sync_synchronize stops processor ? Pin
Randor 16-May-18 12:15
professional Randor 16-May-18 12:15 
GeneralRe: __sync_synchronize stops processor ? Pin
Vaclav_16-May-18 13:15
memberVaclav_16-May-18 13:15 
GeneralRe: __sync_synchronize stops processor ? Pin
Randor 16-May-18 14:10
professional Randor 16-May-18 14:10 
GeneralRe: __sync_synchronize stops processor ? Pin
Vaclav_17-May-18 3:22
memberVaclav_17-May-18 3:22 
QuestionTo install Visual Studio(2008 Pro,2010 Express and 2013 Express) in the same machine Pin
manoharbalu14-May-18 19:30
membermanoharbalu14-May-18 19:30 
AnswerRe: To install Visual Studio(2008 Pro,2010 Express and 2013 Express) in the same machine Pin
Victor Nijegorodov14-May-18 20:24
memberVictor Nijegorodov14-May-18 20:24 
GeneralRe: To install Visual Studio(2008 Pro,2010 Express and 2013 Express) in the same machine Pin
manoharbalu14-May-18 20:50
membermanoharbalu14-May-18 20:50 
GeneralRe: To install Visual Studio(2008 Pro,2010 Express and 2013 Express) in the same machine Pin
Victor Nijegorodov14-May-18 22:56
memberVictor Nijegorodov14-May-18 22:56 
GeneralRe: To install Visual Studio(2008 Pro,2010 Express and 2013 Express) in the same machine Pin
manoharbalu15-May-18 3:10
membermanoharbalu15-May-18 3:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.


Advertise | Privacy | Cookies | Terms of Service
Web01 | 2.8.190518.1 | Last Updated 24 May 2019
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid