/** 
 * @brief          GPIO Assembler Function
 * @author         AXELL CORPORATION
 * @description    Assembler Function  for ExeGCC.
 * @note           none
 * @history        2017_02_22  初版
 * @history        2017_10_26  Ver2.0
 * @history        2021_01_29  [SDK3.2] GPIOポートの排他制御を有効にしたときのアセンブラルーチンを修正 (#2844)
*/

/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2021 AXELL CORPORATION, all rights reserved.
 */

        .code 32
        .text
        .align  2

/*
 * fn			void GPIOPrm_ModifyBit(uint32_t *r0, uint32_t r1, uint32_t r2)
 * brief		GPIO出力の排他的な変更
 * param		r0 [in] GPIOnDTOUTレジスタのアドレス
 * param		r1 [in] 出力データのorビット
 * param		r2 [in] 出力データのandビット
 * description	排他的にGPIOポート出力を更新します。
 *				更新後の出力は現在出力しているデータをr1でorしてからr2でandした値になります。
 * return		void
 */
        .globl  GPIOPrm_ModifyBit
        .type   GPIOPrm_ModifyBit, %function
GPIOPrm_ModifyBit:

		/* CPUステータスを保存し強制的に割り込み禁止状態にする */
		mrs		r3, cpsr
		cpsid	i

		ldr		r12, [r0]	/* reg = *GPIOnDTOUT */
		orr		r1, r12, r1	/* reg |= set */
		and		r1, r1, r2	/* reg &= clr */
		str		r1, [r0]	/* *GPIOnDTOUT = reg */

		/* 割り込み状態をCPUステータス保存時に戻す */
		tst		r3, #(1<<7)
		bxne	lr
		cpsie	i
		bx		lr
