// File: /workspace/github_c_makefile_star2_O1/lupyuen[P]lora-sx1262/src/radio.c
// Function: RadioSetTxConfig
void RadioSetTxConfig( RadioModems_t modem, int8_t power, uint32_t fdev,
                        uint32_t bandwidth, uint32_t datarate,
                        uint8_t coderate, uint16_t preambleLen,
                        bool fixLen, bool crcOn, bool freqHopOn,
                        uint8_t hopPeriod, bool iqInverted, uint32_t timeout )
{
    printf("RadioSetTxConfig: modem=%d, power=%d, fdev=%d, bandwidth=%d, datarate=%d, coderate=%d, preambleLen=%d, fixLen=%d, crcOn=%d, freqHopOn=%d, hopPeriod=%d, iqInverted=%d, timeout=%d\r\n", (int) modem, (int) power, (int) fdev, (int) bandwidth, (int) datarate, (int) coderate, (int) preambleLen, (int) fixLen, (int) crcOn, (int) freqHopOn, (int) hopPeriod, (int) iqInverted, (int) timeout);
    switch( modem )
    {
        case MODEM_FSK:
            SX126x.ModulationParams.PacketType = PACKET_TYPE_GFSK;
            SX126x.ModulationParams.Params.Gfsk.BitRate = datarate;

            SX126x.ModulationParams.Params.Gfsk.ModulationShaping = MOD_SHAPING_G_BT_1;
            SX126x.ModulationParams.Params.Gfsk.Bandwidth = RadioGetFskBandwidthRegValue( bandwidth << 1 ); // SX126x badwidth is double sided
            SX126x.ModulationParams.Params.Gfsk.Fdev = fdev;

            SX126x.PacketParams.PacketType = PACKET_TYPE_GFSK;
            SX126x.PacketParams.Params.Gfsk.PreambleLength = ( preambleLen << 3 ); // convert byte into bit
            SX126x.PacketParams.Params.Gfsk.PreambleMinDetect = RADIO_PREAMBLE_DETECTOR_08_BITS;
            SX126x.PacketParams.Params.Gfsk.SyncWordLength = 3 << 3 ; // convert byte into bit
            SX126x.PacketParams.Params.Gfsk.AddrComp = RADIO_ADDRESSCOMP_FILT_OFF;
            SX126x.PacketParams.Params.Gfsk.HeaderType = ( fixLen == true ) ? RADIO_PACKET_FIXED_LENGTH : RADIO_PACKET_VARIABLE_LENGTH;

            if( crcOn == true )
            {
                SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_2_BYTES_CCIT;
            }
            else
            {
                SX126x.PacketParams.Params.Gfsk.CrcLength = RADIO_CRC_OFF;
            }
            SX126x.PacketParams.Params.Gfsk.DcFree = RADIO_DC_FREEWHITENING;

            RadioStandby( );
            RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
            SX126xSetModulationParams( &SX126x.ModulationParams );
            SX126xSetPacketParams( &SX126x.PacketParams );
            SX126xSetSyncWord( ( uint8_t[] ){ 0xC1, 0x94, 0xC1, 0x00, 0x00, 0x00, 0x00, 0x00 } );
            SX126xSetWhiteningSeed( 0x01FF );
            break;

        case MODEM_LORA:
            SX126x.ModulationParams.PacketType = PACKET_TYPE_LORA;
            SX126x.ModulationParams.Params.LoRa.SpreadingFactor = ( RadioLoRaSpreadingFactors_t ) datarate;
            SX126x.ModulationParams.Params.LoRa.Bandwidth =  Bandwidths[bandwidth];
            SX126x.ModulationParams.Params.LoRa.CodingRate= ( RadioLoRaCodingRates_t )coderate;

            if( ( ( bandwidth == 0 ) && ( ( datarate == 11 ) || ( datarate == 12 ) ) ) ||
            ( ( bandwidth == 1 ) && ( datarate == 12 ) ) )
            {
                SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x01;
            }
            else
            {
                SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize = 0x00;
            }

            SX126x.PacketParams.PacketType = PACKET_TYPE_LORA;

            if( ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF5 ) ||
                ( SX126x.ModulationParams.Params.LoRa.SpreadingFactor == LORA_SF6 ) )
            {
                if( preambleLen < 12 )
                {
                    SX126x.PacketParams.Params.LoRa.PreambleLength = 12;
                }
                else
                {
                    SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;
                }
            }
            else
            {
                SX126x.PacketParams.Params.LoRa.PreambleLength = preambleLen;
            }

            SX126x.PacketParams.Params.LoRa.HeaderType = ( RadioLoRaPacketLengthsMode_t )fixLen;
            SX126x.PacketParams.Params.LoRa.PayloadLength = MaxPayloadLength;
            SX126x.PacketParams.Params.LoRa.CrcMode = ( RadioLoRaCrcModes_t )crcOn;
            SX126x.PacketParams.Params.LoRa.InvertIQ = ( RadioLoRaIQModes_t )iqInverted;

            ///////////////////////////

            //// TODO
            printf("RadioSetTxConfig: SpreadingFactor=%d, Bandwidth=%d, CodingRate=%d, LowDatarateOptimize=%d, PreambleLength=%d, HeaderType=%d, PayloadLength=%d, CrcMode=%d, InvertIQ=%d\r\n", (int) SX126x.ModulationParams.Params.LoRa.SpreadingFactor, (int) SX126x.ModulationParams.Params.LoRa.Bandwidth, (int) SX126x.ModulationParams.Params.LoRa.CodingRate, (int) SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize, (int) SX126x.PacketParams.Params.LoRa.PreambleLength, (int) SX126x.PacketParams.Params.LoRa.HeaderType, (int) SX126x.PacketParams.Params.LoRa.PayloadLength, (int) SX126x.PacketParams.Params.LoRa.CrcMode, (int) SX126x.PacketParams.Params.LoRa.InvertIQ); //// TODO

            // SX126x.ModulationParams.Params.LoRa.SpreadingFactor;
            // SX126x.ModulationParams.Params.LoRa.Bandwidth;
            // SX126x.ModulationParams.Params.LoRa.CodingRate;
            // SX126x.ModulationParams.Params.LoRa.LowDatarateOptimize;

            // SX126x.PacketParams.Params.LoRa.PreambleLength;
            // SX126x.PacketParams.Params.LoRa.HeaderType;
            // SX126x.PacketParams.Params.LoRa.PayloadLength;
            // SX126x.PacketParams.Params.LoRa.CrcMode;
            // SX126x.PacketParams.Params.LoRa.InvertIQ;

            ///////////////////////////

            RadioStandby( );
            RadioSetModem( ( SX126x.ModulationParams.PacketType == PACKET_TYPE_GFSK ) ? MODEM_FSK : MODEM_LORA );
            SX126xSetModulationParams( &SX126x.ModulationParams );
            SX126xSetPacketParams( &SX126x.PacketParams );
            break;
    }

    // WORKAROUND - Modulation Quality with 500 kHz LoRa Bandwidth, see DS_SX1261-2_V1.2 datasheet chapter 15.1
    if( ( modem == MODEM_LORA ) && ( SX126x.ModulationParams.Params.LoRa.Bandwidth == LORA_BW_500 ) )
    {
        SX126xWriteRegister( REG_TX_MODULATION, SX126xReadRegister( REG_TX_MODULATION ) & ~( 1 << 2 ) );
    }
    else
    {
        SX126xWriteRegister( REG_TX_MODULATION, SX126xReadRegister( REG_TX_MODULATION ) | ( 1 << 2 ) );
    }
    // WORKAROUND END

    SX126xSetRfTxPower( power );
    TxTimeout = timeout;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %r9d, %ebx
movl %r8d, %r9d
movl %ecx, %r8d
movl %edx, %ecx
movl %esi, %edx
movl %edi, %esi
movzwl 0x10(%rbp), %r12d
movl 0x40(%rbp), %r15d
movzbl 0x30(%rbp), %eax
movq %rax, -0x38(%rbp)
movzbl 0x18(%rbp), %r14d
movzbl 0x20(%rbp), %r13d
movzbl 0x28(%rbp), %r11d
movzbl 0x38(%rbp), %r10d
leaq 0x3303(%rip), %rdi      # 0x62be
movl %edx, -0x40(%rbp)
movl %ecx, -0x3c(%rbp)
movl %r8d, -0x2c(%rbp)
movq %r9, -0x48(%rbp)
xorl %eax, %eax
pushq %r15
movl %esi, %r15d
movq %r10, -0x50(%rbp)
pushq %r10
pushq -0x38(%rbp)
pushq %r11
movq %r13, -0x58(%rbp)
pushq %r13
movq %r14, -0x60(%rbp)
pushq %r14
movq %r12, -0x38(%rbp)
pushq %r12
movq %rbx, %r14
pushq %rbx
callq 0x2050
addq $0x40, %rsp
movl %r15d, %ebx
cmpl $0x1, %r15d
je 0x3112
testl %ebx, %ebx
jne 0x3236
xorl %r15d, %r15d
movl %r15d, 0x7337(%rip)     # 0xa350
leaq 0x7330(%rip), %r12      # 0xa350
movq -0x48(%rbp), %rax
movl %eax, 0x732a(%rip)      # 0xa354
movl $0xb, 0x7328(%rip)      # 0xa35c
movl -0x2c(%rbp), %edi
addl %edi, %edi
callq 0x3ab5
movb %al, 0x731c(%rip)       # 0xa360
movl -0x3c(%rbp), %eax
movl %eax, 0x730b(%rip)      # 0xa358
movl %r15d, 0x72b0(%rip)     # 0xa304
leaq 0x72a9(%rip), %r14      # 0xa304
movq -0x38(%rbp), %rax
leal (,%rax,8), %eax
movw %ax, 0x729b(%rip)       # 0xa308
movl $0x4, 0x7295(%rip)      # 0xa30c
movb $0x18, 0x7292(%rip)     # 0xa310
movl %r15d, 0x728f(%rip)     # 0xa314
movb 0x18(%rbp), %al
xorb $0x1, %al
movzbl %al, %eax
movl %eax, 0x7285(%rip)      # 0xa318
cmpb $0x0, 0x20(%rbp)
movl $0xf2, %eax
movl $0x1, %ecx
cmovnel %eax, %ecx
movl %ecx, 0x7276(%rip)      # 0xa320
movl $0x1, 0x7270(%rip)      # 0xa324
leaq 0x34f1(%rip), %rdi      # 0x65ac
callq 0x2260
xorl %edi, %edi
callq 0x3b57
xorl %edi, %edi
cmpl %r15d, 0x7280(%rip)     # 0xa350
setne %dil
callq 0x2afc
movq %r12, %rdi
callq 0x43e9
movq %r14, %rdi
callq 0x44d1
leaq -0x68(%rbp), %rdi
movw $0x94c1, (%rdi)         # imm = 0x94C1
movb $-0x3f, 0x2(%rdi)
movl %r15d, 0x3(%rdi)
movb $0x0, 0x7(%rdi)
callq 0x3cbe
movl $0x1ff, %edi            # imm = 0x1FF
callq 0x3d48
jmp 0x3236
movl $0x1, %eax
movl %eax, 0x7233(%rip)      # 0xa350
leaq 0x722c(%rip), %r12      # 0xa350
movq -0x48(%rbp), %rsi
movl %esi, 0x7236(%rip)      # 0xa364
movl -0x2c(%rbp), %r9d
movl %r9d, %ecx
leaq 0x30a4(%rip), %rdx      # 0x61e0
movl (%rdx,%rcx,4), %edx
movl %edx, 0x7223(%rip)      # 0xa368
movq %r14, %rcx
movl %ecx, 0x721e(%rip)      # 0xa36c
testl %r9d, %r9d
sete %dil
leal -0xb(%rsi), %r8d
cmpl $0x2, %r8d
setb %r8b
andb %dil, %r8b
xorl %eax, %r9d
movl %esi, %edi
xorl $0xc, %edi
orl %r9d, %edi
sete %dil
orb %r8b, %dil
movb %dil, 0x71f3(%rip)      # 0xa370
movl %eax, 0x7181(%rip)      # 0xa304
leaq 0x717a(%rip), %r13      # 0xa304
movq -0x38(%rbp), %r9
cmpw $0xd, %r9w
movl $0xc, %eax
cmovael %r9d, %eax
leal -0x5(%rsi), %r8d
cmpl $0x2, %r8d
cmovael %r9d, %eax
movw %ax, 0x7179(%rip)       # 0xa328
movq -0x60(%rbp), %r11
movl %r11d, 0x7172(%rip)     # 0xa32c
movzbl 0x6fbe(%rip), %r10d     # 0xa180
movb %r10b, 0x7167(%rip)     # 0xa330
movq -0x58(%rbp), %r14
movl %r14d, 0x7160(%rip)     # 0xa334
movq -0x50(%rbp), %r15
movl %r15d, 0x7159(%rip)     # 0xa338
movzbl %dil, %r8d
movzwl %ax, %r9d
leaq 0x3184(%rip), %rdi      # 0x6372
xorl %eax, %eax
pushq %r15
pushq %r14
pushq %r10
pushq %r11
callq 0x2050
addq $0x20, %rsp
leaq 0x33a4(%rip), %rdi      # 0x65ac
callq 0x2260
xorl %edi, %edi
callq 0x3b57
xorl %edi, %edi
cmpl $0x0, 0x7133(%rip)      # 0xa350
setne %dil
callq 0x2afc
movq %r12, %rdi
callq 0x43e9
movq %r13, %rdi
callq 0x44d1
xorl $0x1, %ebx
movl 0x7129(%rip), %eax      # 0xa368
xorl $0x6, %eax
orl %ebx, %eax
setne %bl
movl $0x889, %edi            # imm = 0x889
callq 0x4dfc
andb $-0x5, %al
shlb $0x2, %bl
orb %al, %bl
movzbl %bl, %esi
movl $0x889, %edi            # imm = 0x889
callq 0x4d78
movsbl -0x40(%rbp), %edi
callq 0x4ecf
movl 0x40(%rbp), %eax
movl %eax, 0x6fb9(%rip)      # 0xa230
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq