/******************************************************************************* * Filename: OSAL_Math.s51 * Revised: $Date: 2010-02-23 10:47:02 -0800 (Tue, 23 Feb 2010) $ * Revision: $Revision: 21759 $ * * Description: This module contains optimized math routines needed to * perform efficient as possible calculations for BLE operations * such as timer drift adjustments. * * Copyright 2010 Texas Instruments Incorporated. All rights reserved. * * IMPORTANT: Your use of this Software is limited to those specific rights * granted under the terms of a software license agreement between the user * who downloaded the software, his/her employer (which must be your employer) * and Texas Instruments Incorporated (the "License"). You may not use this * Software unless you agree to abide by the terms of the License. The License * limits your use, and you acknowledge, that the Software may not be modified, * copied or distributed unless embedded on a Texas Instruments microcontroller * or used solely and exclusively in conjunction with a Texas Instruments radio * frequency transceiver, which is integrated into your product. Other than for * the foregoing purpose, you may not use, reproduce, copy, prepare derivative * works of, modify, distribute, perform, display or sell this Software and/or * its documentation for any purpose. * YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE * PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, * NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL * TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, * NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER * LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES * INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE * OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT * OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES * (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. * * Should you have any questions regarding your right to use this Software, * contact Texas Instruments Incorporated at www.TI.com. *******************************************************************************/ MODULE OSAL_Math.s51 /******************************************************************************* * * @fn osalMcuDivide31By16To16 * * @brief This function is used to divide a 31 bit dividend by a 16 bit * divisor and return a packed 16 bit quotient and 16 bit * remainder. * * C Syntax * uint32 osalMcuDivide31By16To16( uint32 dividend, uint16 divisor ); * * Preserved registers used: * R7:R6 * * Note: This routine takes ~25.6us @32MHz. With C overhead, the * time is ~32us. * * input parameters * * @param R5:R4:R3:R2 - 31 bit dividend. * @param XDATA Stack - 16 bit divisor. * * After initialization, the following register mapping is used: * R7:R6 - divisor * R5:R4 - quotient * R3:R2 - upper half of dividend; will become the remainder * R1:R0 - lower half of dividend * B - loop counter * * output parameters * * @param None. * * @return R5:R4:R3:R2 - The 16 bit quotient is in R5:R4 and the 16 bit * remainder is in R3:R2. * ******************************************************************************/ PUBLIC osalMcuDivide31By16To16 FUNCTION osalMcuDivide31By16To16,0201H EXTERN ?XSP RSEG DATA_Z:DATA:NOROOT(0) savedR6: DS 1 savedR7: DS 1 savedRemHi: DS 1 savedRemLow: DS 1 savedDPH: DS 1 savedDPL: DS 1 RSEG NEAR_CODE:CODE:NOROOT(2) osalMcuDivide31By16To16: #ifdef DEBUG_GPIO //SETB P0.1 #endif // initialize loop counter MOV B,#16 // save preserved registers R6 and R7 MOV savedR6,R6 MOV savedR7,R7 // save DPTR (which ever one is currently selected) MOV savedDPL,DPL MOV savedDPH,DPH // get divisor from the XDATA stack MOV DPL,?XSP MOV DPH,?XSP+1 MOVX A,@DPTR XCH A,R6 INC DPTR MOVX A,@DPTR XCH A,R7 // restore DPTR MOV DPL,savedDPL MOV DPH,savedDPH // move lower dividend R3:R2 to R1:R0 MOV A,R3 XCH A,R1 MOV A,R2 XCH A,R0 // move upper dividend R5:R4 to what will be the remainder R3:R2 MOV A,R5 XCH A,R3 MOV A,R4 XCH A,R2 TopOfLoop: // Step 1: Shift dividend and remainder left, feeding dividend into remainder. CLR C MOV A,R0 RLC A XCH A,R0 MOV A,R1 RLC A XCH A,R1 MOV A,R2 RLC A XCH A,R2 MOV A,R3 RLC A XCH A,R3 // Step 2: Subtract divisor from remainder. If there is a borrow, then restore // the remainder. CLR C MOV A,R2 SUBB A,R6 MOV savedRemLow,A ; save remainder in case it needs to be restored MOV A,R3 SUBB A,R7 MOV savedRemHi,A ; save remainder in case it needs to be restored // Step 3: Shift quotient left, feeding complement of borrow bit // Note: Remainder is left unchanged if there was a borrow. CPL C JNC ShiftQuotient // MOV R3,savedRemHi MOV R2,savedRemLow ShiftQuotient: MOV A,R4 RLC A XCH A,R4 MOV A,R5 RLC A XCH A,R5 // Step 4: Decrement count and loop if not zero. DJNZ B,TopOfLoop // restore R6 and R7 MOV R6,savedR6 MOV R7,savedR7 #ifdef DEBUG_GPIO //CLR P0.1 #endif RET /******************************************************************************* *******************************************************************************/ END