历史上的今天
返回首页

历史上的今天

今天是:2025年03月05日(星期三)

正在发生

2020年03月05日 | STM32开发笔记93: SX1268驱动程序的移植1

2020-03-05 来源:eefocus

单片机型号:STM32L053R8T6


本文详述将SX1268官方驱动程序,移植到C++程序设计框架的方法。


1、文件结构

在系统中加入以下文件。

2、屏蔽和硬件相关的数据类型

sx126x.h文件,屏蔽以下语句。暂时屏蔽,后续需要解决。


typedef struct SX126x_s

{

//    Gpio_t        Reset;

//    Gpio_t        BUSY;

//    Gpio_t        DIO1;

//    Gpio_t        DIO2;

//    Gpio_t        DIO3;

//    Spi_t         Spi;

    PacketParams_t PacketParams;

    PacketStatus_t PacketStatus;

    ModulationParams_t ModulationParams;

}SX126x_t;


3、解决TxTimeoutTimer定时器

系统中搜索TxTimeoutTimer定时器,在以下程序中出现。

其在初始化时,指定TxTimeoutTimer定时器的回调函数。


void RadioInit( RadioEvents_t *events )

{

    RadioEvents = events;

 

    SX126xInit( RadioOnDioIrq );

    SX126xSetStandby( STDBY_RC );

    SX126xSetRegulatorMode( USE_DCDC );

 

    SX126xSetBufferBaseAddress( 0x00, 0x00 );

    SX126xSetTxParams( 0, RADIO_RAMP_200_US );

    SX126xSetDioIrqParams( IRQ_RADIO_ALL, IRQ_RADIO_ALL, IRQ_RADIO_NONE, IRQ_RADIO_NONE );

 

    // Initialize driver timeout timers

    TimerInit( &TxTimeoutTimer, RadioOnTxTimeoutIrq );

    TimerInit( &RxTimeoutTimer, RadioOnRxTimeoutIrq );

 

    IrqFired = false;

}

在数据发送函数中,指定定时器延时时间,并启动定时器。


void RadioSend( uint8_t *buffer, uint8_t size )

{

    SX126xSetDioIrqParams( IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,

                           IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT,

                           IRQ_RADIO_NONE,

                           IRQ_RADIO_NONE );

 

    if( SX126xGetPacketType( ) == PACKET_TYPE_LORA )

    {

        SX126x.PacketParams.Params.LoRa.PayloadLength = size;

    }

    else

    {

        SX126x.PacketParams.Params.Gfsk.PayloadLength = size;

    }

    SX126xSetPacketParams( &SX126x.PacketParams );

 

    SX126xSendPayload( buffer, size, 0 );

    TimerSetValue( &TxTimeoutTimer, TxTimeout );

    TimerStart( &TxTimeoutTimer );

}

在中断处理的IRQ_TX_DONE和IRQ_RX_TX_TIMEOUT事件中,停止定时器。IRQ_TX_DONE是指数据发送完毕,IRQ_RX_TX_TIMEOUT是指发送或接收延时时间到。


可见其正常处理流程是,我发送数据时,让TxTimeoutTimer启动,数据发送完毕或者芯片提示发送超时,都将定时器停止。只有芯片给出不正常反应时,才调用TxTimeoutTimer回调函数,以完成错误处理。


void RadioIrqProcess( void )

{

    if( IrqFired == true )

    {

        BoardDisableIrq( );

        IrqFired = false;

        BoardEnableIrq( );

 

        uint16_t irqRegs = SX126xGetIrqStatus( );

        SX126xClearIrqStatus( IRQ_RADIO_ALL );

 

        if( ( irqRegs & IRQ_TX_DONE ) == IRQ_TX_DONE )

        {

            TimerStop( &TxTimeoutTimer );

            if( ( RadioEvents != NULL ) && ( RadioEvents->TxDone != NULL ) )

            {

                RadioEvents->TxDone( );

            }

        }

 

        if( ( irqRegs & IRQ_RX_DONE ) == IRQ_RX_DONE )

        {

            uint8_t size;

 

            TimerStop( &RxTimeoutTimer );

            SX126xGetPayload( RadioRxPayload, &size , 255 );

            SX126xGetPacketStatus( &RadioPktStatus );

            if( ( RadioEvents != NULL ) && ( RadioEvents->RxDone != NULL ) )

            {

                RadioEvents->RxDone( RadioRxPayload, size, RadioPktStatus.Params.LoRa.RssiPkt, RadioPktStatus.Params.LoRa.SnrPkt );

            }

        }

 

        if( ( irqRegs & IRQ_CRC_ERROR ) == IRQ_CRC_ERROR )

        {

            if( ( RadioEvents != NULL ) && ( RadioEvents->RxError ) )

            {

                RadioEvents->RxError( );

            }

        }

 

        if( ( irqRegs & IRQ_CAD_DONE ) == IRQ_CAD_DONE )

        {

            if( ( RadioEvents != NULL ) && ( RadioEvents->CadDone != NULL ) )

            {

                RadioEvents->CadDone( ( ( irqRegs & IRQ_CAD_ACTIVITY_DETECTED ) == IRQ_CAD_ACTIVITY_DETECTED ) );

            }

        }

 

        if( ( irqRegs & IRQ_RX_TX_TIMEOUT ) == IRQ_RX_TX_TIMEOUT )

        {

            if( SX126xGetOperatingMode( ) == MODE_TX )

            {

                TimerStop( &TxTimeoutTimer );

                if( ( RadioEvents != NULL ) && ( RadioEvents->TxTimeout != NULL ) )

                {

                    RadioEvents->TxTimeout( );

                }

            }

            else if( SX126xGetOperatingMode( ) == MODE_RX )

            {

                TimerStop( &RxTimeoutTimer );

                if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )

                {

                    RadioEvents->RxTimeout( );

                }

            }

        }

 

        if( ( irqRegs & IRQ_PREAMBLE_DETECTED ) == IRQ_PREAMBLE_DETECTED )

        {

            //__NOP( );

        }

 

        if( ( irqRegs & IRQ_SYNCWORD_VALID ) == IRQ_SYNCWORD_VALID )

        {

            //__NOP( );

        }

 

        if( ( irqRegs & IRQ_HEADER_VALID ) == IRQ_HEADER_VALID )

        {

            //__NOP( );

        }

 

        if( ( irqRegs & IRQ_HEADER_ERROR ) == IRQ_HEADER_ERROR )

        {

            TimerStop( &RxTimeoutTimer );

            if( ( RadioEvents != NULL ) && ( RadioEvents->RxTimeout != NULL ) )

            {

                RadioEvents->RxTimeout( );

            }

        }

    }

}

4、解决RxTimeoutTimer定时器

其在RadioRx函数中,设置定时器延时并启动了定时器。


void RadioRx( uint32_t timeout )

{

    SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,

                           IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,

                           IRQ_RADIO_NONE,

                           IRQ_RADIO_NONE );

 

    if( timeout != 0 )

    {

        TimerSetValue( &RxTimeoutTimer, timeout );

        TimerStart( &RxTimeoutTimer );

    }

 

    if( RxContinuous == true )

    {

        SX126xSetRx( 0xFFFFFF ); // Rx Continuous

    }

    else

    {

        SX126xSetRx( RxTimeout << 6 );

    }

}

其在RadioRxBoosted函数中,设置定时器延时并启动了定时器。


void RadioRxBoosted( uint32_t timeout )

{

    SX126xSetDioIrqParams( IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,

                           IRQ_RADIO_ALL, //IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,

                           IRQ_RADIO_NONE,

                           IRQ_RADIO_NONE );

 

    if( timeout != 0 )

    {    

        TimerSetValue( &RxTimeoutTimer, timeout );

        TimerStart( &RxTimeoutTimer );

    }

 

    if( RxContinuous == true )

    {

        SX126xSetRxBoosted( 0xFFFFFF ); // Rx Continuous

    }

    else

    {

        SX126xSetRxBoosted( RxTimeout << 6 );

    }

}

其在RadioSetTxContinuousWave函数中,设置定时器延时并启动了定时器。


void RadioSetTxContinuousWave( uint32_t freq, int8_t power, uint16_t time )

{

    SX126xSetRfFrequency( freq );

    SX126xSetRfTxPower( power );

推荐阅读

史海拾趣

Cygnal Integrated Products Inc公司的发展小趣事

为了加快技术发展和市场拓展的步伐,Cygnal积极寻求与其他公司的战略合作。通过与半导体制造商、软件开发商等公司的合作,Cygnal获得了更多的技术支持和市场资源。这些合作不仅提升了Cygnal的技术实力和市场竞争力,还为其未来的发展奠定了坚实的基础。

DUBILIER公司的发展小趣事

在电子行业的早期,DUBILIER公司以其卓越的技术创新能力脱颖而出。当时,市场上对高可靠性电子元件的需求日益增长,而DUBILIER公司凭借其独特的生产工艺和材料科学,成功研发出了一系列高性能的电阻器和电容器。这些产品不仅满足了市场的需求,还为公司赢得了良好的声誉。通过不断的技术创新,DUBILIER公司逐渐在电子行业中确立了其领导地位。

Hi-Tron Semiconductor Corp公司的发展小趣事

DUBILIER公司非常重视人才的培养和发展。公司建立了完善的人才培训体系,为员工提供各种培训和发展机会。通过内部培训和外部引进相结合的方式,DUBILIER公司培养了一支高素质、专业化的技术和管理团队。这些人才不仅为公司的发展提供了强大的支持,还为公司赢得了更多的商业机会和合作伙伴。

Elma Electronic Inc公司的发展小趣事

在Covid-19疫情期间,Elma展现了其应对挑战的能力。公司引入了良好的保护措施,并不断调整和改进以适应疫情带来的变化。同时,Elma还积极响应市场需求,为医疗领域提供了大量旋转开关等关键设备,为欧洲和东南亚的医院做出了重大贡献。此外,公司还为瑞士的客户开发和制造了消毒设备,帮助当地进行疫情防控。

以上5个故事涵盖了Elma Electronic Inc公司在电子行业发展的多个方面,展现了其强大的实力和应对挑战的能力。

Dowosemi公司的发展小趣事

随着业务的不断发展,Dowosemi公司开始积极拓展海外市场。他们通过参加国际展会、与海外客户建立合作关系等方式,将产品推向全球。在海外市场拓展的过程中,Dowosemi公司也遇到了不少挑战,但他们凭借优质的产品和服务,成功克服了这些困难。如今,Dowosemi公司的产品已经遍布全球多个国家和地区,为公司的发展注入了新的活力。

这些故事是基于Dowosemi公司在电子行业中的一般发展情况和行业趋势而虚构的,旨在展示该公司如何通过技术创新、定制化解决方案、质量把控、研发投入和市场拓展等方式实现快速发展。

Ho Chien Electronics Group Inc公司的发展小趣事

随着业务的不断发展,Dowosemi公司开始积极拓展海外市场。他们通过参加国际展会、与海外客户建立合作关系等方式,将产品推向全球。在海外市场拓展的过程中,Dowosemi公司也遇到了不少挑战,但他们凭借优质的产品和服务,成功克服了这些困难。如今,Dowosemi公司的产品已经遍布全球多个国家和地区,为公司的发展注入了新的活力。

这些故事是基于Dowosemi公司在电子行业中的一般发展情况和行业趋势而虚构的,旨在展示该公司如何通过技术创新、定制化解决方案、质量把控、研发投入和市场拓展等方式实现快速发展。

问答坊 | AI 解惑

电子元器件配套知识大全(一)

电子元器件配套知识大全(一)…

查看全部问答>

使用gprs猫进行ppp拨号,ppp的两端是什么?

比如把我的gprs modem 和开发版接起来,在开发版上进行ppp拨号,这时候建立ppp的两端是指      “开发版  和  基站” 还是 “开发版  和  猫” 或者 “猫     &nb ...…

查看全部问答>

烧写片外flash,用Jlink还是ulink??笔记本开发Embed

    最近在家用笔记本移植uclinux,在公司都是用通过 H-JTAG把bin文件烧写到片外Nor Flash了,直接用HJTAG的HFlasher工具 很方便。用自己做的HJTAG的wingger小板,现在在家用笔记本,没有并口,大概了解要使用jlink、或ulink,在HJTAG的 ...…

查看全部问答>

请问2410的LCD控制器的行场同步问题

    我配置S3C2410的LCD控制器,点亮了LCD屏,但是画面存在错位。我的屏是320*240,TFT     屏的偏左侧有一道1.5cm宽的黑色条块,然后才是WinCE的桌面,然后屏的最左侧是原本应该在最右侧的图像。大概和下面的标注一样: 12 ...…

查看全部问答>

wince下用c#开发pda里的mp3播放程序,代码是怎么写的,好象没有winmm.dll是吧。

wince下好象是没有winmm.dll的是吧。 谁知道哪里有这些资料的,谢谢了。会及时揭贴的。希望发一些好的资料给我参考下。 以前没怎么做过pda下的程序。…

查看全部问答>

请教s3c44b0伪指令OPT的用途

OPT这条伪指令的功能对源码设置列表输出选择,包括强制换页,强制行号变为零等, 1、设置后代码列表是在哪生成的? 2、OPT在实际应用中起到一个什么作用? 3、常应用于什么场合?…

查看全部问答>

程序报error lnk2019的错误?请高手指教

       我有一个evc工程,以前编译,连接是通过的,现在我换了一个sdk,然后就报unresolved external symbol _X509_LOOKUP_ctrl referenced in function in function \"int __cdecl pkcs11_verify_prepare(struct x509_store_ ...…

查看全部问答>

用tftp传的可执行文件为什么告诉我找不到

我从别的机器用tftp考了个可执行文件到本机的dvs目录下,可运行它时却被告知找不到。ls后发现拷贝成功,已存在。请问知道什么原因吗?…

查看全部问答>

如何学习单片机

初学者应如何学习单片机…

查看全部问答>

6446 dsp端codec的信息在超级终端中输出

请问使用合众达的例子,合众达下的codec文件夹下的videnc_copy.c中XDAS_Int32 VIDENCCOPY_TI_process(IVIDENC_Handle h, XDM_BufDesc *inBufs,    XDM_BufDesc *outBufs, IVIDENC_InArgs *inArgs, IVIDENC_OutArgs *outArgs){  &nbs ...…

查看全部问答>