/* GPIO PIN access via memory mapping file to Controller */
/* This example sets GPI0 13 (number is hard-coded into the assembler code) */
/* 
	Assemble  gcc -o gpio13on_annot gpio13on_annot.s
	Run       sudo ./gpio13on_annot
*/
	.global main

main:	@ boiler-plate code: initialise and perform memory-mapping
	SUB	SP, SP, #16		@ Create 16 bytes storage
	LDR	R0, .addr_file		@ get GPIO Controller addr
	LDR	R1, .flags		@ set flag permissions
	BL	open			@ call to get file handle

	STR	R0, [SP, #12]		@ File handle number
	LDR	R3, [SP, #12]		@ Get File handle
	STR	R3, [sp, #0]		@ Store file handle on top stack
	LDR	R3, .gpiobase		@ get GPIO_Base address (gpiobase)
	STR	R3, [sp, #4]		@ store on SP+4
	MOV	R0, #0			@ R0=0
	MOV	R1, #4096		@ R1=page
	MOV	R2, #3			@ R2=3
	MOV	R3, #1			@ R3=1 (stdouts)
	BL	mmap

	STR	R0, [SP, #16]		@ store virtual mem addr
	LDR	R1, [SP, #16]		@ get virtual mem addr (gpio)

fctsel:	@ section: set function select register
	@ R1 = gpio base reg, R0, R2 available
	LDR	R0, [R1, #4]		@ read GPFSEL1
	MOV	R2, #0b111		@ create bit-mask
	MOV	R3, #9			@ in bits 9-11 (for pin 13, 3*3)
	LSL	R2, R3			@ left-shift to bits 9-11
	BIC	R0, R2			@ perform combined and-not: R0 = R0 & ~R2
	MOV	R2, #0b001		@ mode = 1 for output
	MOV	R3, #9			@ same location as above
	LSL	R2, R3			@ left-shift to bits 9-11
	ORR	R0, R2			@ put the 0b001 value into this position
	STR	R0, [R1, #4]		@ write the result back to GPFSEL1 (NB: R1 hasn't changed)
	
on:	@ section: turn on a pin
	@ gpio base reg is on stack slot #16, R0, R1, R2 available
	LDR R1, [SP, #16]		@ retrieve GPIO reg from stack
	MOV R2, #0b1			@ construct bitmask
	LSL R2, #13			@ bit 13 for pin 13
	STR R2, [R1, #28]		@ write bitmask to GPSET0 (7-th reg)
	
	@ clean-up
	LDR	R0, [SP, #12]		@ get file handle
	BL	close			@ close file

	ADD	SP, SP, #16		@ restore SP
	
	MOV R7, #1
	SWI 0


.addr_file:	.word	.file
.flags:		.word	1576962
@.gpiobase:	.word	0x20200000	@ GPIO_Base for Pi 1
.gpiobase:	.word	0x3F200000	@ GPIO_Base for Pi 2

.data
.file:	.ascii "/dev/mem\000"

	
