4coder/test_data/lots_of_files/gpio.s

119 lines
2.9 KiB
ArmAsm

/******************************************************************************
* gpio.s
* by Alex Chadwick
*
* A sample assembly code implementation of the ok05 operating system.
* See main.s for details.
*
* gpio.s contains the rountines for manipulation of the GPIO ports.
******************************************************************************/
/* NEW
* According to the EABI, all method calls should use r0-r3 for passing
* parameters, should preserve registers r4-r8,r10-r11,sp between calls, and
* should return values in r0 (and r1 if needed).
* It does also stipulate many things about how methods should use the registers
* and stack during calls, but we're using hand coded assembly. All we need to
* do is obey the start and end conditions, and if all our methods do this, they
* would all work from C.
*/
/* NEW
* GetGpioAddress returns the base address of the GPIO region as a physical address
* in register r0.
* C++ Signature: void* GetGpioAddress()
*/
.globl GetGpioAddress
GetGpioAddress:
gpioAddr .req r0
ldr gpioAddr,=0x20200000
mov pc,lr
.unreq gpioAddr
/* NEW
* SetGpioFunction sets the function of the GPIO register addressed by r0 to the
* low 3 bits of r1.
* C++ Signature: void SetGpioFunction(u32 gpioRegister, u32 function)
*/
.globl SetGpioFunction
SetGpioFunction:
pinNum .req r0
pinFunc .req r1
cmp pinNum,#53
cmpls pinFunc,#7
movhi pc,lr
push {lr}
mov r2,pinNum
.unreq pinNum
pinNum .req r2
bl GetGpioAddress
gpioAddr .req r0
functionLoop$:
cmp pinNum,#9
subhi pinNum,#10
addhi gpioAddr,#4
bhi functionLoop$
add pinNum, pinNum,lsl #1
lsl pinFunc,pinNum
mask .req r3
mov mask,#7 /* r3 = 111 in binary */
lsl mask,pinNum /* r3 = 11100..00 where the 111 is in the same position as the function in r1 */
.unreq pinNum
mvn mask,mask /* r3 = 11..1100011..11 where the 000 is in the same poisiont as the function in r1 */
oldFunc .req r2
ldr oldFunc,[gpioAddr] /* r2 = existing code */
and oldFunc,mask /* r2 = existing code with bits for this pin all 0 */
.unreq mask
orr pinFunc,oldFunc /* r1 = existing code with correct bits set */
.unreq oldFunc
str pinFunc,[gpioAddr]
.unreq pinFunc
.unreq gpioAddr
pop {pc}
/* NEW
* SetGpio sets the GPIO pin addressed by register r0 high if r1 != 0 and low
* otherwise.
* C++ Signature: void SetGpio(u32 gpioRegister, u32 value)
*/
.globl SetGpio
SetGpio:
pinNum .req r0
pinVal .req r1
cmp pinNum,#53
movhi pc,lr
push {lr}
mov r2,pinNum
.unreq pinNum
pinNum .req r2
bl GetGpioAddress
gpioAddr .req r0
pinBank .req r3
lsr pinBank,pinNum,#5
lsl pinBank,#2
add gpioAddr,pinBank
.unreq pinBank
and pinNum,#31
setBit .req r3
mov setBit,#1
lsl setBit,pinNum
.unreq pinNum
teq pinVal,#0
.unreq pinVal
streq setBit,[gpioAddr,#40]
strne setBit,[gpioAddr,#28]
.unreq setBit
.unreq gpioAddr
pop {pc}