/*******************************************************************************
 * (c) Copyright 2008 Actel Corporation.  All rights reserved.
 * 
 * Cortex-M1 hardware access functions.
 *
 * SVN $Revision: 190 $
 * SVN $Date: 2008-03-13 16:23:03 +0000 (Thu, 13 Mar 2008) $
 */

	.text
	.global HW_set_32bit_reg
	.global HW_get_32bit_reg
	.global HW_set_32bit_reg_field
	.global HW_get_32bit_reg_field
	.global HW_set_16bit_reg
	.global HW_get_16bit_reg
	.global HW_set_16bit_reg_field
	.global HW_get_16bit_reg_field
	.global HW_set_8bit_reg
	.global HW_get_8bit_reg
	.global HW_set_8bit_reg_field
	.global HW_get_8bit_reg_field
	.code 16
	.syntax unified
	.type HW_set_32bit_reg, function
	.type HW_get_32bit_reg, function
	.type HW_set_32bit_reg_field, function
	.type HW_get_32bit_reg_field, function
	.type HW_set_16bit_reg, function
	.type HW_get_16bit_reg, function
	.type HW_set_16bit_reg_field, function
	.type HW_get_16bit_reg_field, function
	.type HW_set_8bit_reg, function
	.type HW_get_8bit_reg, function
	.type HW_set_8bit_reg_field, function
	.type HW_get_8bit_reg_field, function
	
	        
/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   uint32_t value
 */
HW_set_32bit_reg: 	
	STR R1, [R0]
	BX LR

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 */      
HW_get_32bit_reg:
	LDR R0, [R0]
	BX LR

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   int_fast8_t shift
 * R2:   uint32_t mask
 * R3:   uint32_t value
 */
HW_set_32bit_reg_field:
    PUSH {R1,R2,R3,LR}
    LSLS R3, R3, R1
    ANDS R3, R3, R2
    LDR R1, [R0]
    MVNS R2, R2
    ANDS R1, R1, R2
    ORRS R1, R1, R3
    STR R1, [R0]
    POP {R1,R2,R3,PC}

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   int_fast8_t shift
 * R2:   uint32_t mask
 */
HW_get_32bit_reg_field:
    LDR R0, [R0]
    ANDS R0, R0, R2
    LSRS R0, R0, R1
    BX LR

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   uint_fast16_t value
 */
HW_set_16bit_reg: 	
	STRH R1, [R0]
	BX LR
        
/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 */
HW_get_16bit_reg:
	LDRH R0, [R0]
	BX LR

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   int_fast8_t shift
 * R2:   uint_fast16_t mask
 * R3:   uint_fast16_t value
 */
HW_set_16bit_reg_field:
    PUSH {R1,R2,R3,LR}
    LSLS R3, R3, R1
    ANDS R3, R3, R2
    LDRH R1, [R0]
    MVNS R2, R2
    ANDS R1, R1, R2
    ORRS R1, R1, R3
    STRH R1, [R0]
    POP {R1,R2,R3,PC}

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   int_fast8_t shift
 * R2:   uint_fast16_t mask
 */
HW_get_16bit_reg_field:
    LDRH R0, [R0]
    ANDS R0, R0, R2
    LSRS R0, R0, R1
    BX LR

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   uint_fast8_t value
 */
HW_set_8bit_reg: 	
	STRB R1, [R0]
	BX LR
        
/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 */
HW_get_8bit_reg:
	LDRB R0, [R0]
	BX LR

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr,
 * R1:   int_fast8_t shift
 * R2:   uint_fast8_t mask
 * R3:   uint_fast8_t value
 */
HW_set_8bit_reg_field:
    PUSH {R1,R2,R3,LR}
    LSLS R3, R3, R1
    ANDS R3, R3, R2
    LDRB R1, [R0]
    MVNS R2, R2
    ANDS R1, R1, R2
    ORRS R1, R1, R3
    STRB R1, [R0]
    POP {R1,R2,R3,PC}

/*------------------------------------------------------------------------------
 * R0:   addr_t reg_addr
 * R1:   int_fast8_t shift
 * R2:   uint_fast8_t mask
 */
HW_get_8bit_reg_field:
    LDRB R0, [R0]
    ANDS R0, R0, R2
    LSRS R0, R0, R1
    BX LR

.end
