///////////////////////////////////////////////////////////////////////////////
//
// IAR C/C++ Compiler V2.10.4.157 for STM8                10/Aug/2020  13:50:18
// Copyright 2010-2015 IAR Systems AB.
//
//    Source file  =  F:\2-Lora\Code\stm8l151K6T6-WLAN\BSP\IIC.c
//    Command line =  
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\BSP\IIC.c -e -Ol --no_cse
//        --no_unroll --no_inline --no_code_motion --no_tbaa --no_cross_call
//        --debug --code_model small --data_model medium -o
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\Debug\Obj\ --dlib_config
//        E:\IAR\stm8\LIB\dlstm8smf.h -lB
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\Debug\List\ -I
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\FWLIB\inc\ -I
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\FWLIB\src\ -I
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\USER\ -I
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\BSP\ -I
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\radio\ -I
//        F:\2-Lora\Code\stm8l151K6T6-WLAN\SX1278\ --vregs 16
//    List file    =  F:\2-Lora\Code\stm8l151K6T6-WLAN\Debug\List\IIC.s
//
///////////////////////////////////////////////////////////////////////////////

        EXTERN ?b0
        EXTERN ?b1
        EXTERN ?b10
        EXTERN ?b11
        EXTERN ?b12
        EXTERN ?b8
        EXTERN ?b9
        EXTERN ?epilogue_l2
        EXTERN ?epilogue_w4
        EXTERN ?push_l2
        EXTERN ?push_w4
        EXTERN ?w4
        EXTERN ?w5
        EXTERN GPIO_Init

        PUBLIC Delay5us
        PUBLIC HMC5883_InitPin
        PUBLIC HMC5883_RecvByte
        PUBLIC HMC5883_SendACK
        PUBLIC HMC5883_SendByte
        PUBLIC HMC5883_Start
        PUBLIC HMC5883_Stop
        PUBLIC HMC5883_WaitACK
        PUBLIC I2C_NoAck
        PUBLIC Init_HMC5883
        PUBLIC Multiple_Read_HMC5883
        PUBLIC Single_Read_HMC5883
        PUBLIC Single_Write_HMC5883
        PUBLIC T
        PUBLIC count1
        PUBLIC error_id
        PUBLIC hhj

// F:\2-Lora\Code\stm8l151K6T6-WLAN\BSP\IIC.c
//    1 #include "IIC.h"
//    2 //frequent 400kHZ

        SECTION `.near.bss`:DATA:REORDER:NOROOT(0)
//    3 uint32_t T = 0;
T:
        DS8 4

        SECTION `.near_func.text`:CODE:NOROOT(0)
        CODE
I2C_NoAck:
        BRES      L:0x5005, #0x3
        CALL      L:Delay5us
        BSET      L:0x5005, #0x2
        CALL      L:Delay5us
        BSET      L:0x5005, #0x3
        CALL      L:Delay5us
        BRES      L:0x5005, #0x3
        JP        L:Delay5us

        SECTION `.near_func.text`:CODE:NOROOT(0)
        CODE
HMC5883_SendACK:
        CP        A, #0x1
        JRNE      L:??HMC5883_SendACK_0
        BSET      L:0x5005, #0x2
        JRA       L:??HMC5883_SendACK_1
??HMC5883_SendACK_0:
        BRES      L:0x5005, #0x2
??HMC5883_SendACK_1:
        CALL      L:Delay5us
        BSET      L:0x5005, #0x3
        CALL      L:Delay5us
        BRES      L:0x5005, #0x3
        JP        L:Delay5us

        SECTION `.near_func.text`:CODE:NOROOT(0)
        CODE
HMC5883_WaitACK:
        BSET      L:0x5005, #0x2
        MOV       S:?b0, #0x40
        LD        A, #0x4
        LDW       X, #0x5005
        CALL      L:GPIO_Init
        CALL      L:Delay5us
        BSET      L:0x5005, #0x3
        CALL      L:Delay5us
        BTJF      L:0x5006, #0x2, L:??HMC5883_WaitACK_0
        BRES      L:0x5005, #0x3
        MOV       S:?b0, #0xf0
        LD        A, #0x4
        LDW       X, #0x5005
        CALL      L:GPIO_Init
        CLR       A
        RET
??HMC5883_WaitACK_0:
        CALL      L:Delay5us
        BRES      L:0x5005, #0x3
        MOV       S:?b0, #0xf0
        LD        A, #0x4
        LDW       X, #0x5005
        CALL      L:GPIO_Init
        LD        A, #0x1
        RET

        SECTION `.near_func.text`:CODE:NOROOT(0)
        CODE
HMC5883_Stop:
        BRES      L:0x5005, #0x2
        BSET      L:0x5005, #0x3
        CALL      L:Delay5us
        BSET      L:0x5005, #0x2
        CALL      L:Delay5us
        BRES      L:0x5005, #0x3
        JP        L:Delay5us

        SECTION `.near_func.text`:CODE:NOROOT(0)
        CODE
HMC5883_Start:
        BSET      L:0x5005, #0x2
        BSET      L:0x5005, #0x3
        CALL      L:Delay5us
        BRES      L:0x5005, #0x2
        CALL      L:Delay5us
        BRES      L:0x5005, #0x3
        CALL      L:Delay5us
        LD        A, #0x1
        RET

        SECTION `.near_func.text`:CODE:NOROOT(0)
        CODE
HMC5883_InitPin:
        LD        A, L:0x5007
        OR        A, #0xc
        LD        L:0x5007, A
        LD        A, L:0x5008
        OR        A, #0xc
        LD        L:0x5008, A
        LD        A, L:0x5009
        OR        A, #0xc
        LD        L:0x5009, A
        LD        A, L:0x5005
        AND       A, #0xf3
        LD        L:0x5005, A
        BRES      L:0x5005, #0x3
        CALL      L:Delay5us
        NOP;
        RET
//    4 //void Delay5us(void)//2.5us
//    5 //{
//    6 //    nop();nop(); nop();nop(); nop();nop(); nop();nop();
//    7 //    nop();nop(); nop();nop(); nop();nop(); nop();nop();
//    8 //    //nop();nop(); nop();nop(); nop();nop();
//    9 //    nop();nop(); nop();nop(); nop();nop(); nop();nop();
//   10 //    nop();nop(); nop();nop(); nop();nop();
//   11 //}

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//   12 void Delay5us(void)//2.5us
//   13 {
//   14     nop();nop(); nop();nop(); nop();nop(); nop();nop();
Delay5us:
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
//   15     nop();nop(); nop();nop(); nop();nop(); nop();nop();
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
//   16     nop();nop(); nop();nop(); nop();nop(); nop();nop();
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
//   17     nop();nop(); nop();nop(); nop();nop();
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
//   18 
//   19 }
        RET
//   20 //i2c pins initial
//   21 void HMC5883_InitPin(void)
//   22 {
//   23     I2C_GPIO->DDR |= (I2C_SCL_PIN)|(I2C_SDA_PIN);
//   24     I2C_GPIO->CR1 |= ((I2C_SCL_PIN)|(I2C_SDA_PIN));
//   25     I2C_GPIO->CR2 |= (I2C_SCL_PIN)|(I2C_SDA_PIN);
//   26     I2C_GPIO->ODR &= ~((I2C_SCL_PIN)|(I2C_SDA_PIN));
//   27     SCL_L;
//   28     Delay5us();
//   29     asm("NOP;");
//   30 }
//   31 
//   32 bool HMC5883_Start(void)
//   33 {
//   34 	SDA_H;
//   35 	SCL_H;
//   36         Delay5us();
//   37 	SDA_L;
//   38         Delay5us();
//   39 	SCL_L;
//   40         Delay5us();
//   41 	return TRUE;
//   42 }
//   43 
//   44 void HMC5883_Stop(void)
//   45 {
//   46 	SDA_L;
//   47         SCL_H;
//   48 	Delay5us();
//   49         SDA_H;
//   50         Delay5us();
//   51         SCL_L;
//   52         Delay5us();
//   53 }
//   54 
//   55 bool HMC5883_WaitACK(void)
//   56 {
//   57         SDA_H;
//   58         SDA_IN;
//   59         Delay5us();
//   60         SCL_H;
//   61         Delay5us();
//   62         if(SDA_read){SCL_L;SDA_OUT;return FALSE;}
//   63         Delay5us();
//   64         SCL_L;
//   65         SDA_OUT;
//   66         return TRUE;
//   67 }
//   68 
//   69 /**************************************
//   70 发送应答信号
//   71 入口参数:ack (0:ACK 1:NAK)
//   72 **************************************/
//   73 void HMC5883_SendACK(bool ack)
//   74 {
//   75 	if(ack==TRUE)SDA_H;
//   76 	else{SDA_L;}
//   77         Delay5us();
//   78 	SCL_H;
//   79         Delay5us();
//   80         SCL_L;
//   81         Delay5us();
//   82 }
//   83 
//   84 /*I2C的NoACK函数----------------------------------------*/
//   85 void I2C_NoAck(void)
//   86 {
//   87 	SCL_L;
//   88 	Delay5us();
//   89 	SDA_H;
//   90 	Delay5us();
//   91 	SCL_H;
//   92 	Delay5us();
//   93 	SCL_L;
//   94 	Delay5us();
//   95 }
//   96 
//   97 

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//   98 bool HMC5883_SendByte(BYTE dat)
//   99 {
HMC5883_SendByte:
        CALL      L:?push_w4
        LD        S:?b9, A
//  100     BYTE i;
//  101 
//  102     for (i=0; i<8; i++)         //8位计数器
        CLR       S:?b8
        JRA       L:??HMC5883_SendByte_0
//  103     {
//  104         if(dat&0x80)SDA_H;
//  105         else
//  106           SDA_L;
??HMC5883_SendByte_1:
        BRES      L:0x5005, #0x2
//  107         Delay5us();
??HMC5883_SendByte_2:
        CALL      L:Delay5us
//  108         SCL_H;
        BSET      L:0x5005, #0x3
//  109         Delay5us();
        CALL      L:Delay5us
//  110         SCL_L;
        BRES      L:0x5005, #0x3
//  111        // Delay5us();
//  112         dat<<=1;
        LD        A, S:?b9
        SLL       A
        LD        S:?b9, A
        LD        A, S:?b8
        ADD       A, #0x1
        LD        S:?b8, A
??HMC5883_SendByte_0:
        LD        A, S:?b8
        CP        A, #0x8
        JRNC      L:??HMC5883_SendByte_3
        LD        A, S:?b9
        AND       A, #0x80
        CP        A, #0x0
        JREQ      L:??HMC5883_SendByte_1
        BSET      L:0x5005, #0x2
        JRA       L:??HMC5883_SendByte_2
//  113     }
//  114     asm("NOP");
??HMC5883_SendByte_3:
        NOP
//  115     if(!HMC5883_WaitACK())return FALSE;
        CALL      L:HMC5883_WaitACK
        CP        A, #0x0
        JRNE      L:??HMC5883_SendByte_4
        CLR       A
        JP        L:?epilogue_w4
//  116     return TRUE;
??HMC5883_SendByte_4:
        LD        A, #0x1
        JP        L:?epilogue_w4
//  117 }
//  118 /**************************************
//  119 从IIC总线接收一个字节数据
//  120 **************************************/

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//  121 BYTE HMC5883_RecvByte()
//  122 {
HMC5883_RecvByte:
        CALL      L:?push_w4
//  123     BYTE i;
//  124     BYTE dat = 0;
        CLR       S:?b8
//  125     SDA_H;
        BSET      L:0x5005, #0x2
//  126     SDA_IN;
        MOV       S:?b0, #0x40
        LD        A, #0x4
        LDW       X, #0x5005
        CALL      L:GPIO_Init
//  127     //使能内部上拉,准备读取数据,
//  128     for (i=0; i<8; i++)         //8位计数器
        CLR       S:?b9
        JRA       L:??HMC5883_RecvByte_0
//  129     {
//  130         dat <<= 1;
??HMC5883_RecvByte_1:
        LD        A, S:?b8
        SLL       A
        LD        S:?b8, A
//  131         SCL_H;             //拉高时钟线
        BSET      L:0x5005, #0x3
//  132         Delay5us();             //延时
        CALL      L:Delay5us
//  133         if(SDA_read)dat|=0x01;//读数据
        BTJF      L:0x5006, #0x2, L:??HMC5883_RecvByte_2
        LD        A, S:?b8
        OR        A, #0x1
        LD        S:?b8, A
//  134         SCL_L;                //拉低时钟线
??HMC5883_RecvByte_2:
        BRES      L:0x5005, #0x3
//  135         Delay5us();             //延时
        CALL      L:Delay5us
//  136     }
        LD        A, S:?b9
        ADD       A, #0x1
        LD        S:?b9, A
??HMC5883_RecvByte_0:
        LD        A, S:?b9
        CP        A, #0x8
        JRC       L:??HMC5883_RecvByte_1
//  137     SDA_OUT;
        MOV       S:?b0, #0xf0
        LD        A, #0x4
        LDW       X, #0x5005
        CALL      L:GPIO_Init
//  138     return dat;
        LD        A, S:?b8
        JP        L:?epilogue_w4
//  139 }
//  140 

        SECTION `.near.bss`:DATA:REORDER:NOROOT(0)
//  141 bool error_id = FALSE;
error_id:
        DS8 1

        SECTION `.near.bss`:DATA:REORDER:NOROOT(0)
//  142 uint8_t count1 = 0;
count1:
        DS8 1
//  143 //************************写入单字节数据***************************
//  144 

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//  145 bool Single_Write_HMC5883(uchar SlaveAddress,uchar REG_Address,uchar REG_data)
//  146 {
Single_Write_HMC5883:
        CALL      L:?push_l2
        LD        S:?b9, A
        MOV       S:?b10, S:?b0
        MOV       S:?b11, S:?b1
//  147 
//  148     uint8_t cnt = 0;
        CLR       S:?b8
//  149     while(cnt++<5)
??Single_Write_HMC5883_0:
        MOV       S:?b0, S:?b8
        LD        A, S:?b0
        ADD       A, #0x1
        LD        S:?b8, A
        LD        A, S:?b0
        CP        A, #0x5
        JRNC      L:??Single_Write_HMC5883_1
//  150     {
//  151           count1++;
        LD        A, L:count1
        ADD       A, #0x1
        LD        L:count1, A
//  152           HMC5883_Start();                  //起始信号
        CALL      L:HMC5883_Start
//  153           HMC5883_SendByte(SlaveAddress);   //发送设备地址+写信号
        LD        A, S:?b9
        CALL      L:HMC5883_SendByte
//  154           HMC5883_SendByte(REG_Address);    //内部寄存器地址，请参考中文pdf
        LD        A, S:?b10
        CALL      L:HMC5883_SendByte
//  155           error_id=HMC5883_SendByte(REG_data);       //内部寄存器数据，请参考中文pdf
        LD        A, S:?b11
        CALL      L:HMC5883_SendByte
        LD        L:error_id, A
//  156           HMC5883_Stop();
        CALL      L:HMC5883_Stop
//  157           if(!error_id)break;
        LD        A, L:error_id
        CP        A, #0x0
        JRNE      L:??Single_Write_HMC5883_0
//  158     }
//  159     asm("NOP");
??Single_Write_HMC5883_1:
        NOP
//  160     if(cnt>=5)return FALSE;
        LD        A, S:?b8
        CP        A, #0x5
        JRC       L:??Single_Write_HMC5883_2
        CLR       A
        JP        L:?epilogue_l2
//  161     else
//  162       return TRUE;
??Single_Write_HMC5883_2:
        LD        A, #0x1
        JP        L:?epilogue_l2
//  163 }
//  164 
//  165 
//  166 
//  167 //************************读取内部寄存器*************************

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//  168 uchar Single_Read_HMC5883(uchar SlaveAddress,uchar REG_Address)
//  169 {
Single_Read_HMC5883:
        CALL      L:?push_w4
        LD        S:?b8, A
        MOV       S:?b9, S:?b0
//  170      uchar REG_data;
//  171      asm("NOP;");
        NOP;
//  172      HMC5883_Start();                          //起始信号
        CALL      L:HMC5883_Start
//  173      HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号
        LD        A, S:?b8
        CALL      L:HMC5883_SendByte
//  174      HMC5883_SendByte(REG_Address);            //发送存储单元地址，从0开始
        LD        A, S:?b9
        CALL      L:HMC5883_SendByte
//  175      HMC5883_Start();                          //起始信号
        CALL      L:HMC5883_Start
//  176      HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        LD        A, S:?b8
        ADD       A, #0x1
        CALL      L:HMC5883_SendByte
//  177      REG_data=HMC5883_RecvByte();              //读出寄存器数据
        CALL      L:HMC5883_RecvByte
        LD        S:?b8, A
//  178             HMC5883_SendACK(TRUE);
        LD        A, #0x1
        CALL      L:HMC5883_SendACK
//  179             HMC5883_Stop();                           //停止信号
        CALL      L:HMC5883_Stop
//  180      return REG_data;
        LD        A, S:?b8
        JP        L:?epilogue_w4
//  181 }
//  182 
//  183 //************************读取内部寄存器*************************
//  184 /*
//  185 uchar Single_Read_HMC5883(uchar SlaveAddress,uchar REG_Address)
//  186 {
//  187      uchar REG_data;
//  188      HMC5883_Start();                          //起始信号
//  189      HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号
//  190      HMC5883_SendByte(REG_Address);            //发送存储单元地址，从0开始
//  191      HMC5883_Start();                          //起始信号
//  192      HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号
//  193      REG_data=HMC5883_RecvByte();              //读出寄存器数据
//  194             HMC5883_SendACK(TRUE);
//  195             HMC5883_Stop();                           //停止信号
//  196      return REG_data;
//  197 }
//  198 */

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//  199 void Multiple_Read_HMC5883(uchar SlaveAddress,uchar *BUFF)
//  200 {   uchar i;
Multiple_Read_HMC5883:
        CALL      L:?push_l2
        PUSH      S:?b12
        LD        S:?b10, A
        LDW       S:?w4, X
//  201     HMC5883_Start();                          //起始信号
        CALL      L:HMC5883_Start
//  202     HMC5883_SendByte(SlaveAddress);           //发送设备地址+写信号
        LD        A, S:?b10
        CALL      L:HMC5883_SendByte
//  203     HMC5883_SendByte(0x00);                   //发送存储单元地址，从0x3开始
        CLR       A
        CALL      L:HMC5883_SendByte
//  204     HMC5883_Start();                          //起始信号
        CALL      L:HMC5883_Start
//  205     HMC5883_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        LD        A, S:?b10
        ADD       A, #0x1
        CALL      L:HMC5883_SendByte
//  206     for (i=0; i<6; i++)                      //连续读取6个地址数据，存储中BUF
        CLR       S:?b12
        JRA       L:??Multiple_Read_HMC5883_0
//  207     {
//  208         BUFF[i] = HMC5883_RecvByte();          //BUF[0]存储数据
//  209         if (i == 5)
//  210         {
//  211            HMC5883_SendACK(TRUE);                //最后一个数据需要回NOACK
//  212         }
//  213         else
//  214         {
//  215           HMC5883_SendACK(FALSE);                //回应ACK
??Multiple_Read_HMC5883_1:
        CLR       A
        CALL      L:HMC5883_SendACK
//  216         }
??Multiple_Read_HMC5883_2:
        LD        A, S:?b12
        ADD       A, #0x1
        LD        S:?b12, A
??Multiple_Read_HMC5883_0:
        LD        A, S:?b12
        CP        A, #0x6
        JRNC      L:??Multiple_Read_HMC5883_3
        CLRW      X
        EXG       A, XL
        LD        A, S:?b12
        EXG       A, XL
        ADDW      X, S:?w4
        LDW       S:?w5, X
        CALL      L:HMC5883_RecvByte
        LD        [S:?w5.w], A
        LD        A, S:?b12
        CP        A, #0x5
        JRNE      L:??Multiple_Read_HMC5883_1
        LD        A, #0x1
        CALL      L:HMC5883_SendACK
        JRA       L:??Multiple_Read_HMC5883_2
//  217    }
//  218     HMC5883_Stop();                          //停止信号
??Multiple_Read_HMC5883_3:
        CALL      L:HMC5883_Stop
//  219 }
        POP       S:?b12
        JP        L:?epilogue_l2
//  220 
//  221 //初始化HMC5883，根据需要请参考pdf进行修改****
//  222 

        SECTION `.near.bss`:DATA:REORDER:NOROOT(0)
//  223 uint8_t hhj = 0;
hhj:
        DS8 1

        SECTION `.near_func.text`:CODE:REORDER:NOROOT(0)
        CODE
//  224 bool Init_HMC5883()
//  225 {
Init_HMC5883:
        CALL      L:?push_w4
//  226      int temp = 0;
        CLR       S:?b9
        CLR       S:?b8
//  227      HMC5883_InitPin();
        CALL      L:HMC5883_InitPin
//  228      temp += Single_Write_HMC5883(SLAVE_ADD,0x0a,0x00);
        CLR       S:?b1
        MOV       S:?b0, #0xa
        LD        A, #0x1a
        CALL      L:Single_Write_HMC5883
        CLRW      X
        LD        XL, A
        ADDW      X, S:?w4
        LDW       S:?w4, X
//  229      temp += Single_Write_HMC5883(SLAVE_ADD,0x09,0x11);
        MOV       S:?b1, #0x11
        MOV       S:?b0, #0x9
        LD        A, #0x1a
        CALL      L:Single_Write_HMC5883
        CLRW      X
        LD        XL, A
        ADDW      X, S:?w4
        LDW       S:?w4, X
//  230      temp += Single_Write_HMC5883(SLAVE_ADD,0x0B,0x01);
        MOV       S:?b1, #0x1
        MOV       S:?b0, #0xb
        LD        A, #0x1a
        CALL      L:Single_Write_HMC5883
        CLRW      X
        LD        XL, A
        ADDW      X, S:?w4
        LDW       S:?w4, X
//  231      asm("NOP");
        NOP
//  232      if(temp<3)return FALSE;
        LDW       X, S:?w4
        CPW       X, #0x3
        JRSGE     L:??Init_HMC5883_0
        CLR       A
        JP        L:?epilogue_w4
//  233      else
//  234        return TRUE;
??Init_HMC5883_0:
        LD        A, #0x1
        JP        L:?epilogue_w4
//  235 }

        SECTION VREGS:DATA:REORDER:NOROOT(0)

        END
//  236 
//  237 
//  238 
// 
//   7 bytes in section .near.bss
// 726 bytes in section .near_func.text
// 
// 726 bytes of CODE memory
//   7 bytes of DATA memory
//
//Errors: none
//Warnings: none
