/* ______ _ / _____) _ | | ( (____ _____ ____ _| |_ _____ ____| |__ \____ \| ___ | (_ _) ___ |/ ___) _ \ _____) ) ____| | | || |_| ____( (___| | | | (______/|_____)_|_|_| \__)_____)\____)_| |_| (C)2016 Semtech Description: Handling of the node configuration protocol License: Revised BSD License, see LICENSE.TXT file include in the project Maintainer: Miguel Luis, Matthieu Verdy and Benjamin Boulet */ #include "ch592_board.h" #include "sx1280-hal.h" #include "radio.h" #include #include /*! * \brief Define the size of tx and rx hal buffers * * The Tx and Rx hal buffers are used for SPI communication to * store data to be sent/receive to/from the chip. * * \warning The application must ensure the maximal useful size to be much lower * than the MAX_HAL_BUFFER_SIZE */ #define MAX_HAL_BUFFER_SIZE 0xFFF #define IRQ_HIGH_PRIORITY 0 /*! * Radio driver structure initialization */ const struct Radio_s Radio = { SX1280Init, SX1280HalReset, SX1280GetStatus, SX1280HalWriteCommand, SX1280HalReadCommand, SX1280HalWriteRegisters, SX1280HalWriteRegister, SX1280HalReadRegisters, SX1280HalReadRegister, SX1280HalWriteBuffer, SX1280HalReadBuffer, SX1280HalGetDioStatus, SX1280GetFirmwareVersion, SX1280SetRegulatorMode, SX1280SetStandby, SX1280SetPacketType, SX1280SetModulationParams, SX1280SetPacketParams, SX1280SetRfFrequency, SX1280SetBufferBaseAddresses, SX1280SetTxParams, SX1280SetDioIrqParams, SX1280SetSyncWord, SX1280SetRx, SX1280GetPayload, SX1280SendPayload, SX1280SetRangingRole, SX1280SetPollingMode, SX1280SetInterruptMode, SX1280SetRegistersDefault, SX1280GetOpMode, SX1280SetSleep, SX1280SetFs, SX1280SetTx, SX1280SetRxDutyCycle, SX1280SetCad, SX1280SetTxContinuousWave, SX1280SetTxContinuousPreamble, SX1280GetPacketType, SX1280SetCadParams, SX1280GetRxBufferStatus, SX1280GetPacketStatus, SX1280GetRssiInst, SX1280GetIrqStatus, SX1280ClearIrqStatus, SX1280Calibrate, SX1280SetSaveContext, SX1280SetAutoTx, SX1280StopAutoTx, SX1280SetAutoFS, SX1280SetLongPreamble, SX1280SetPayload, SX1280SetSyncWordErrorTolerance, SX1280SetCrcSeed, SX1280SetBleAccessAddress, SX1280SetBleAdvertizerAccessAddress, SX1280SetCrcPolynomial, SX1280SetWhiteningSeed, SX1280EnableManualGain, SX1280DisableManualGain, SX1280SetManualGainValue, SX1280SetLNAGainSetting, SX1280SetRangingIdLength, SX1280SetDeviceRangingAddress, SX1280SetRangingRequestAddress, SX1280GetRangingResult, SX1280SetRangingCalibration, SX1280GetRangingPowerDeltaThresholdIndicator, SX1280RangingClearFilterResult, SX1280RangingSetFilterNumSamples, SX1280GetFrequencyError, SX1280HalWakeup, }; static uint8_t halTxBuffer[MAX_HAL_BUFFER_SIZE] = {0x00}; static uint8_t halRxBuffer[MAX_HAL_BUFFER_SIZE] = {0x00}; /*! * \brief Used to block execution waiting for low state on radio busy pin. * Essentially used in SPI communications */ void SX1280HalWaitOnBusy( void ) { // while( GPIOA_ReadPortPin( RADIO_BUSY_PIN ) == 1 ); uint32_t u32_count = 0; while (GPIOB_ReadPortPin(RADIO_BUSY_PIN) > 0) { if (u32_count++ > 1000) { printf("wait busy pin timeout\r\n"); u32_count = 0; } } } void SX1280HalInit( DioIrqHandler **irqHandlers ) { SX1280HalReset( ); SX1280HalIoIrqInit( irqHandlers ); } /*这个函数是用来配置 GPIO的硬件中断;需要自己重新写成 CH592单片机的 * * * */ void SX1280HalIoIrqInit( DioIrqHandler **irqHandlers ) // { #if( RADIO_DIO1_ENABLE ) // GpioSetIrq( RADIO_DIO1_GPIO_Port, RADIO_DIO1_Pin, IRQ_HIGH_PRIORITY, irqHandlers[0] ); #endif #if( RADIO_DIO2_ENABLE ) GpioSetIrq( RADIO_DIO2_GPIO_Port, RADIO_DIO2_Pin, IRQ_HIGH_PRIORITY, irqHandlers[0] ); #endif #if( RADIO_DIO3_ENABLE ) GpioSetIrq( RADIO_DIO3_GPIO_Port, RADIO_DIO3_Pin, IRQ_HIGH_PRIORITY, irqHandlers[0] ); #endif #if( !RADIO_DIO1_ENABLE && !RADIO_DIO2_ENABLE && !RADIO_DIO3_ENABLE ) #error "Please define a DIO" #endif } void SX1280HalReset( void ) { mDelaymS( 20 ); GPIOB_ResetBits( RADIO_nRESET_PIN ); mDelaymS( 50 ); GPIOB_SetBits( RADIO_nRESET_PIN ); mDelaymS( 20 ); } void SX1280HalClearInstructionRam( void ) { uint16_t halSize = 3 + IRAM_SIZE; halTxBuffer[0] = RADIO_WRITE_REGISTER; halTxBuffer[1] = ( IRAM_START_ADDRESS >> 8 ) & 0x00FF; halTxBuffer[2] = IRAM_START_ADDRESS & 0x00FF; for( uint16_t index = 0; index < IRAM_SIZE; index++ ) { halTxBuffer[3+index] = 0x00; } SX1280HalWaitOnBusy( ); GPIOA_ResetBits( RADIO_NSS_PIN ); // sx1280SpiInOut( halTxBuffer[0] ); // sx1280SpiInOut( halTxBuffer[1] ); // sx1280SpiInOut( halTxBuffer[2] ); for( uint8_t i = 0; i < halSize; i++ ){ sx1280SpiInOut(halTxBuffer[i]); } GPIOA_SetBits( RADIO_NSS_PIN ); SX1280HalWaitOnBusy( ); } void SX1280HalWakeup( void ) { PFIC_DisableAllIRQ(); uint16_t halSize = 2; halTxBuffer[0] = RADIO_GET_STATUS; halTxBuffer[1] = 0x00; SX1280HalWaitOnBusy( ); GPIOA_ResetBits( RADIO_NSS_PIN ); for( uint8_t i = 0; i < halSize; i++ ){ sx1280SpiInOut(halTxBuffer[i]); } GPIOA_SetBits( RADIO_NSS_PIN ); // Wait for chip to be ready. SX1280HalWaitOnBusy( ); PFIC_EnableAllIRQ(); // __enable_irq( ); } void SX1280HalWriteCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) //ok { uint16_t halSize = size + 1; halTxBuffer[0] = command; memcpy( halTxBuffer + 1, ( uint8_t * )buffer, size * sizeof( uint8_t ) ); SX1280HalWaitOnBusy( ); GPIOA_ResetBits( RADIO_NSS_PIN ); for( uint8_t i = 0; i < halSize; i++ ) { sx1280SpiInOut(halTxBuffer[i]); } GPIOA_SetBits( RADIO_NSS_PIN ); if( command != RADIO_SET_SLEEP ) { SX1280HalWaitOnBusy( ); } } void SX1280HalReadCommand( RadioCommands_t command, uint8_t *buffer, uint16_t size ) //ok { uint16_t halSize = 2 + size; halTxBuffer[0] = command; halTxBuffer[1] = 0x00; for( uint16_t index = 0; index < size; index++ ) { halTxBuffer[2+index] = 0x00; } SX1280HalWaitOnBusy( );// GPIOA_ResetBits( RADIO_NSS_PIN ); for( uint8_t i = 0; i < halSize; i++ ){ halRxBuffer[i] = sx1280SpiInOut(halTxBuffer[i]); } memcpy( buffer, halRxBuffer + 2, size ); GPIOA_SetBits( RADIO_NSS_PIN ); SX1280HalWaitOnBusy( ); } void SX1280HalWriteRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) ////已经调试ok { uint16_t halSize = size + 3; halTxBuffer[0] = RADIO_WRITE_REGISTER; halTxBuffer[1] = ( address & 0xFF00 ) >> 8; halTxBuffer[2] = address & 0x00FF; memcpy( halTxBuffer + 3, buffer, size ); SX1280HalWaitOnBusy( ); GPIOA_ResetBits( RADIO_NSS_PIN ); for(uint8_t i = 0; i < halSize; i++ ){ sx1280SpiInOut(halTxBuffer[i] ); } GPIOA_SetBits( RADIO_NSS_PIN ); SX1280HalWaitOnBusy( ); } void SX1280HalWriteRegister( uint16_t address, uint8_t value )//已经调试ok { SX1280HalWriteRegisters( address, &value, 1 ); } void SX1280HalReadRegisters( uint16_t address, uint8_t *buffer, uint16_t size ) //已经调试ok { uint16_t halSize = 4 + size; halTxBuffer[0] = RADIO_READ_REGISTER; halTxBuffer[1] = ( address & 0xFF00 ) >> 8; halTxBuffer[2] = (address & 0x00FF); halTxBuffer[3] = 0x00; for( uint16_t index = 0; index < size; index++ ) { halTxBuffer[4+index] = 0x00; } GPIOA_ResetBits( RADIO_NSS_PIN ); // for(int8_t i = 0; i < halSize; i++ ){ // buffer[i] = sx1280SpiInOut(halTxBuffer[i]); // } for(int8_t i = 0; i < halSize; i++ ){ halRxBuffer[i] = sx1280SpiInOut(halTxBuffer[i]); } memcpy( buffer, halRxBuffer + 4, size ); GPIOA_SetBits( RADIO_NSS_PIN ); SX1280HalWaitOnBusy( ); } uint8_t SX1280HalReadRegister( uint16_t address ) { uint8_t data; SX1280HalReadRegisters( address, &data, 1 ); return data; } void SX1280HalWriteBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) { uint16_t halSize = size + 2; halTxBuffer[0] = RADIO_WRITE_BUFFER; halTxBuffer[1] = (offset)>>8; memcpy( halTxBuffer + 2, buffer, size ); SX1280HalWaitOnBusy( ); GPIOA_ResetBits( RADIO_NSS_PIN ); for(int8_t i = 0; i < halSize; i++ ){ sx1280SpiInOut(halTxBuffer[i] ); } GPIOA_SetBits( RADIO_NSS_PIN ); SX1280HalWaitOnBusy( ); } void SX1280HalReadBuffer( uint8_t offset, uint8_t *buffer, uint8_t size ) { uint16_t halSize = size + 3; halTxBuffer[0] = RADIO_READ_BUFFER; halTxBuffer[1] = offset; halTxBuffer[2] = 0x00; for( uint16_t index = 0; index < size; index++ ) { halTxBuffer[3+index] = 0x00; } SX1280HalWaitOnBusy( ); GPIOA_ResetBits( RADIO_NSS_PIN ); for(uint8_t i = 0; i < halSize; i++ ){ halRxBuffer[i] = sx1280SpiInOut(halTxBuffer[i]); } memcpy( buffer, halRxBuffer + 3, size ); GPIOA_SetBits( RADIO_NSS_PIN ); SX1280HalWaitOnBusy( ); } uint8_t SX1280HalGetDioStatus( void ) { uint8_t Status = GPIOB_ReadPortPin( RADIO_BUSY_PIN ); #if( RADIO_DIO1_ENABLE ) Status |= (GPIOA_ReadPortPin( RADIO_DIO1_PIN ) << 1); #endif #if( RADIO_DIO2_ENABLE ) Status |= (GpioRead( RADIO_DIO2_GPIO_Port, RADIO_DIO2_Pin ) << 2); #endif #if( RADIO_DIO3_ENABLE ) Status |= (GpioRead( RADIO_DIO3_GPIO_Port, RADIO_DIO3_Pin ) << 3); #endif #if( !RADIO_DIO1_ENABLE && !RADIO_DIO2_ENABLE && !RADIO_DIO3_ENABLE ) #error "Please define a DIO" #endif return Status; }