| | |
| | | |
| | | int dwt_initialise(uint16 config) |
| | | { |
| | | uint8 plllockdetect = EC_CTRL_PLLLCK; |
| | | uint16 otp_addr = 0; |
| | | uint32 ldo_tune = 0; |
| | | uint8 plllockdetect = EC_CTRL_PLLLCK; |
| | | uint16 otp_addr = 0; |
| | | uint32 ldo_tune = 0; |
| | | |
| | | dw1000local.dblbuffon = 0; // Double buffer mode off by default |
| | | dw1000local.prfIndex = 0; // 16MHz |
| | |
| | | |
| | | _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: set system clock to XTI - this is necessary to make sure the values read by _dwt_otpread are reliable |
| | | |
| | | dwt_write32bitreg(TX_POWER_ID, 0x1f1f1f1f); |
| | | // Configure the CPLL lock detect |
| | | dwt_writetodevice(EXT_SYNC_ID, EC_CTRL_OFFSET, 1, &plllockdetect); |
| | | dwt_write32bitreg(TX_POWER_ID, 0x1f1f1f1f); |
| | | // Configure the CPLL lock detect |
| | | dwt_writetodevice(EXT_SYNC_ID, EC_CTRL_OFFSET, 1, &plllockdetect); |
| | | |
| | | // Read OTP revision number |
| | | otp_addr = _dwt_otpread(XTRIM_ADDRESS) & 0xffff; // Read 32 bit value, XTAL trim val is in low octet-0 (5 bits) |
| | | dw1000local.otprev = (otp_addr >> 8) & 0xff; // OTP revision is next byte |
| | | // Read OTP revision number |
| | | otp_addr = _dwt_otpread(XTRIM_ADDRESS) & 0xffff; // Read 32 bit value, XTAL trim val is in low octet-0 (5 bits) |
| | | dw1000local.otprev = (otp_addr >> 8) & 0xff; // OTP revision is next byte |
| | | |
| | | // Load LDO tune from OTP and kick it if there is a value actually programmed. |
| | | ldo_tune = _dwt_otpread(LDOTUNE_ADDRESS); |
| | | if((ldo_tune & 0xFF) != 0) |
| | | { |
| | | uint8 ldok = OTP_SF_LDO_KICK; |
| | | // Kick LDO tune |
| | | dwt_writetodevice(OTP_IF_ID, OTP_SF, 1, &ldok); // Set load LDE kick bit |
| | | dw1000local.sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up |
| | | } |
| | | if((ldo_tune & 0xFF) != 0) |
| | | { |
| | | uint8 ldok = OTP_SF_LDO_KICK; |
| | | // Kick LDO tune |
| | | dwt_writetodevice(OTP_IF_ID, OTP_SF, 1, &ldok); // Set load LDE kick bit |
| | | dw1000local.sleep_mode |= AON_WCFG_ONW_LLDO; // LDO tune must be kicked at wake-up |
| | | } |
| | | |
| | | // Load Part and Lot ID from OTP |
| | | dw1000local.partID = _dwt_otpread(PARTID_ADDRESS); |
| | |
| | | |
| | | // Load leading edge detect code |
| | | if(config & DWT_LOADUCODE) |
| | | { |
| | | { |
| | | _dwt_loaducodefromrom(); |
| | | dw1000local.sleep_mode |= AON_WCFG_ONW_LLDE; // microcode must be loaded at wake-up |
| | | } |
| | | else // Should disable the LDERUN enable bit in 0x36, 0x4 |
| | | { |
| | | uint16 rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1) ; |
| | | rega &= 0xFDFF ; // Clear LDERUN bit |
| | | dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET+1, rega) ; |
| | | } |
| | | } |
| | | else // Should disable the LDERUN enable bit in 0x36, 0x4 |
| | | { |
| | | uint16 rega = dwt_read16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET + 1) ; |
| | | rega &= 0xFDFF ; // Clear LDERUN bit |
| | | dwt_write16bitoffsetreg(PMSC_ID, PMSC_CTRL1_OFFSET + 1, rega) ; |
| | | } |
| | | |
| | | _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing |
| | | |
| | |
| | | */ |
| | | uint8 dwt_otprevision(void) |
| | | { |
| | | return dw1000local.otprev ; |
| | | return dw1000local.otprev ; |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | */ |
| | | void dwt_setGPIOdirection(uint32 gpioNum, uint32 direction) |
| | | { |
| | | uint8 buf[GPIO_DIR_LEN]; |
| | | uint32 command = direction | gpioNum; |
| | | uint8 buf[GPIO_DIR_LEN]; |
| | | uint32 command = direction | gpioNum; |
| | | |
| | | buf[0] = command & 0xff; |
| | | buf[1] = (command >> 8) & 0xff; |
| | | buf[2] = (command >> 16) & 0xff; |
| | | buf[0] = command & 0xff; |
| | | buf[1] = (command >> 8) & 0xff; |
| | | buf[2] = (command >> 16) & 0xff; |
| | | |
| | | dwt_writetodevice(GPIO_CTRL_ID, GPIO_DIR_OFFSET, GPIO_DIR_LEN, buf); |
| | | dwt_writetodevice(GPIO_CTRL_ID, GPIO_DIR_OFFSET, GPIO_DIR_LEN, buf); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | */ |
| | | void dwt_setGPIOvalue(uint32 gpioNum, uint32 value) |
| | | { |
| | | uint8 buf[GPIO_DOUT_LEN]; |
| | | uint32 command = value | gpioNum; |
| | | uint8 buf[GPIO_DOUT_LEN]; |
| | | uint32 command = value | gpioNum; |
| | | |
| | | buf[0] = command & 0xff; |
| | | buf[1] = (command >> 8) & 0xff; |
| | | buf[2] = (command >> 16) & 0xff; |
| | | buf[0] = command & 0xff; |
| | | buf[1] = (command >> 8) & 0xff; |
| | | buf[2] = (command >> 16) & 0xff; |
| | | |
| | | dwt_writetodevice(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, GPIO_DOUT_LEN, buf); |
| | | dwt_writetodevice(GPIO_CTRL_ID, GPIO_DOUT_OFFSET, GPIO_DOUT_LEN, buf); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | */ |
| | | uint32 dwt_readdevid(void) |
| | | { |
| | | return dwt_read32bitoffsetreg(DEV_ID_ID,0); |
| | | return dwt_read32bitoffsetreg(DEV_ID_ID, 0); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | #ifdef DWT_API_ERROR_CHECK |
| | | if (config->dataRate > DWT_BR_6M8) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | }// validate datarate parameter |
| | | if ((config->prf > DWT_PRF_64M) || (config->prf < DWT_PRF_16M)) |
| | | { |
| | | return DWT_ERROR ; // validate Pulse Repetition Frequency |
| | | return DWT_ERROR ; // validate Pulse Repetition Frequency |
| | | } |
| | | if (config->rxPAC > DWT_PAC64) |
| | | { |
| | | return DWT_ERROR ; // validate PAC size |
| | | return DWT_ERROR ; // validate PAC size |
| | | } |
| | | if ((chan < 1) || (chan > 7) || (6 == chan)) |
| | | { |
| | | return DWT_ERROR ; // validate channel number parameter |
| | | return DWT_ERROR ; // validate channel number parameter |
| | | } |
| | | |
| | | // validate TX and TX pre-amble codes selections |
| | |
| | | case DWT_PLEN_512 : |
| | | case DWT_PLEN_256 : |
| | | case DWT_PLEN_128 : |
| | | case DWT_PLEN_64 : break ; // all okay |
| | | default : return DWT_ERROR ; // not a good preamble length parameter |
| | | case DWT_PLEN_64 : |
| | | break ; // all okay |
| | | default : |
| | | return DWT_ERROR ; // not a good preamble length parameter |
| | | } |
| | | |
| | | if(config->phrMode > DWT_PHRMODE_EXT) |
| | |
| | | |
| | | dw1000local.sysCFGreg |= (SYS_CFG_PHR_MODE_11 & (config->phrMode << 16)) ; |
| | | |
| | | dwt_write32bitreg(SYS_CFG_ID,dw1000local.sysCFGreg) ; |
| | | dwt_write32bitreg(SYS_CFG_ID, dw1000local.sysCFGreg) ; |
| | | // Set the lde_replicaCoeff |
| | | dwt_write16bitoffsetreg(LDE_IF_ID, LDE_REPC_OFFSET, reg16) ; |
| | | |
| | |
| | | // Set (non-standard) user SFD for improved performance, |
| | | if(config->nsSFD) |
| | | { |
| | | // Write non standard (DW) SFD length |
| | | dwt_writetodevice(USR_SFD_ID,0x00,1,&dwnsSFDlen[config->dataRate]); |
| | | nsSfd_result = 3 ; |
| | | useDWnsSFD = 1 ; |
| | | // Write non standard (DW) SFD length |
| | | dwt_writetodevice(USR_SFD_ID, 0x00, 1, &dwnsSFDlen[config->dataRate]); |
| | | nsSfd_result = 3 ; |
| | | useDWnsSFD = 1 ; |
| | | } |
| | | regval = (CHAN_CTRL_TX_CHAN_MASK & (chan << CHAN_CTRL_TX_CHAN_SHIFT)) | // Transmit Channel |
| | | (CHAN_CTRL_RX_CHAN_MASK & (chan << CHAN_CTRL_RX_CHAN_SHIFT)) | // Receive Channel |
| | | (CHAN_CTRL_RXFPRF_MASK & (config->prf << CHAN_CTRL_RXFPRF_SHIFT)) | // RX PRF |
| | | ((CHAN_CTRL_TNSSFD|CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX |
| | | ((CHAN_CTRL_TNSSFD | CHAN_CTRL_RNSSFD) & (nsSfd_result << CHAN_CTRL_TNSSFD_SHIFT)) | // nsSFD enable RX&TX |
| | | (CHAN_CTRL_DWSFD & (useDWnsSFD << CHAN_CTRL_DWSFD_SHIFT)) | // Use DW nsSFD |
| | | (CHAN_CTRL_TX_PCOD_MASK & (config->txCode << CHAN_CTRL_TX_PCOD_SHIFT)) | // TX Preamble Code |
| | | (CHAN_CTRL_RX_PCOD_MASK & (config->rxCode << CHAN_CTRL_RX_PCOD_SHIFT)) ; // RX Preamble Code |
| | | |
| | | dwt_write32bitreg(CHAN_CTRL_ID,regval) ; |
| | | dwt_write32bitreg(CHAN_CTRL_ID, regval) ; |
| | | |
| | | // Set up TX Preamble Size and TX PRF |
| | | // Set up TX Ranging Bit and Data Rate |
| | | dw1000local.txFCTRL = (config->txPreambLength | config->prf) << 16; |
| | | dw1000local.txFCTRL |= (config->dataRate << TX_FCTRL_TXBR_SHFT) | TX_FCTRL_TR; // Always set ranging bit !!! |
| | | dwt_write32bitoffsetreg(TX_FCTRL_ID,0,dw1000local.txFCTRL) ; |
| | | dwt_write32bitoffsetreg(TX_FCTRL_ID, 0, dw1000local.txFCTRL) ; |
| | | |
| | | return DWT_SUCCESS ; |
| | | |
| | |
| | | { |
| | | if (txFrameLength > 1023) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (txFrameLength > 127) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | } |
| | | } |
| | | if (txFrameLength < 2) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | } |
| | | #endif |
| | | |
| | |
| | | return DWT_ERROR ; |
| | | } |
| | | // Write the data to the IC TX buffer, (-2 bytes for auto generated CRC) |
| | | dwt_writetodevice( TX_BUFFER_ID, txBufferOffset, txFrameLength-2, txFrameBytes) ; |
| | | dwt_writetodevice( TX_BUFFER_ID, txBufferOffset, txFrameLength - 2, txFrameBytes) ; |
| | | |
| | | |
| | | return DWT_SUCCESS ; |
| | |
| | | { |
| | | if (txFrameLength > 1023) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (txFrameLength > 127) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | } |
| | | } |
| | | if (txFrameLength < 2) |
| | | { |
| | | return DWT_ERROR ; |
| | | return DWT_ERROR ; |
| | | } |
| | | #endif |
| | | |
| | | // Write the frame length to the TX frame control register |
| | | // dw1000local.txFCTRL has kept configured bit rate information |
| | | uint32 reg32 = dw1000local.txFCTRL | txFrameLength | (txBufferOffset << 22); |
| | | dwt_write32bitoffsetreg(TX_FCTRL_ID,0,reg32) ; |
| | | dwt_write32bitoffsetreg(TX_FCTRL_ID, 0, reg32) ; |
| | | |
| | | return DWT_SUCCESS ; |
| | | |
| | |
| | | */ |
| | | void dwt_readrxdata(uint8 *buffer, uint16 length, uint16 rxBufferOffset) |
| | | { |
| | | dwt_readfromdevice(RX_BUFFER_ID,rxBufferOffset,length,buffer) ; |
| | | dwt_readfromdevice(RX_BUFFER_ID, rxBufferOffset, length, buffer) ; |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | // Force on the ACC clocks if we are sequenced |
| | | _dwt_enableclocks(READ_ACC_ON); |
| | | |
| | | dwt_readfromdevice(ACC_MEM_ID,accOffset,len,buffer) ; |
| | | dwt_readfromdevice(ACC_MEM_ID, accOffset, len, buffer) ; |
| | | |
| | | _dwt_enableclocks(READ_ACC_OFF); // Revert clocks back |
| | | } |
| | |
| | | diagnostics->maxNoise = dwt_read16bitoffsetreg(LDE_IF_ID, LDE_THRESH_OFFSET); |
| | | |
| | | // Read all 8 bytes in one SPI transaction |
| | | dwt_readfromdevice(RX_FQUAL_ID, 0x0, 8, (uint8*)&diagnostics->stdNoise); |
| | | dwt_readfromdevice(RX_FQUAL_ID, 0x0, 8, (uint8 *)&diagnostics->stdNoise); |
| | | //diagnostics->stdNoise = dwt_read16bitoffsetreg(RX_FQUAL_ID, 0x0) ; |
| | | //diagnostics->firstPathAmp2 = dwt_read16bitoffsetreg(RX_FQUAL_ID, 0x2) ; |
| | | //diagnostics->firstPathAmp3 = dwt_read16bitoffsetreg(RX_FQUAL_ID, 0x4) ; |
| | |
| | | * |
| | | * no return value |
| | | */ |
| | | void dwt_readtxtimestamp(uint8 * timestamp) |
| | | void dwt_readtxtimestamp(uint8 *timestamp) |
| | | { |
| | | dwt_readfromdevice(TX_TIME_ID, 0, TX_TIME_TX_STAMP_LEN, timestamp) ; // Read bytes directly into buffer |
| | | } |
| | |
| | | * |
| | | * no return value |
| | | */ |
| | | void dwt_readrxtimestamp(uint8 * timestamp) |
| | | void dwt_readrxtimestamp(uint8 *timestamp) |
| | | { |
| | | dwt_readfromdevice(RX_TIME_ID, 0, RX_TIME_RX_STAMP_LEN, timestamp) ; // Get the adjusted time of arrival |
| | | } |
| | |
| | | * |
| | | * no return value |
| | | */ |
| | | void dwt_readsystime(uint8 * timestamp) |
| | | void dwt_readsystime(uint8 *timestamp) |
| | | { |
| | | dwt_readfromdevice(SYS_TIME_ID, 0, SYS_TIME_LEN, timestamp) ; |
| | | } |
| | |
| | | { |
| | | return DWT_ERROR ; // Index is limited to 15-bits. |
| | | } |
| | | if ((index + length)> 0x7FFF) |
| | | if ((index + length) > 0x7FFF) |
| | | { |
| | | return DWT_ERROR ; // Sub-addressable area is limited to 15-bits. |
| | | } |
| | |
| | | } |
| | | |
| | | // Write it to the SPI |
| | | return writetospi(cnt,header,length,buffer); |
| | | return writetospi(cnt, header, length, buffer); |
| | | |
| | | } // end dwt_writetodevice() |
| | | |
| | |
| | | { |
| | | return DWT_ERROR ; // Index is limited to 15-bits. |
| | | } |
| | | if ((index + length)> 0x7FFF) |
| | | if ((index + length) > 0x7FFF) |
| | | { |
| | | return DWT_ERROR ; // Sub-addressable area is limited to 15-bits. |
| | | } |
| | |
| | | * |
| | | * returns 32 bit register value (success), or DWT_ERROR for error |
| | | */ |
| | | uint32 dwt_read32bitoffsetreg(int regFileID,int regOffset) |
| | | uint32 dwt_read32bitoffsetreg(int regFileID, int regOffset) |
| | | { |
| | | uint32 regval = DWT_ERROR ; |
| | | int j ; |
| | | uint8 buffer[4] ; |
| | | |
| | | int result = dwt_readfromdevice(regFileID,regOffset,4,buffer); // Read 4 bytes (32-bits) register into buffer |
| | | int result = dwt_readfromdevice(regFileID, regOffset, 4, buffer); // Read 4 bytes (32-bits) register into buffer |
| | | |
| | | if(result == DWT_SUCCESS) |
| | | { |
| | |
| | | * |
| | | * returns 16 bit register value (success), or DWT_ERROR for error |
| | | */ |
| | | uint16 dwt_read16bitoffsetreg(int regFileID,int regOffset) |
| | | uint16 dwt_read16bitoffsetreg(int regFileID, int regOffset) |
| | | { |
| | | uint16 regval = DWT_ERROR ; |
| | | uint8 buffer[2] ; |
| | | |
| | | int result = dwt_readfromdevice(regFileID,regOffset,2,buffer); // Read 2 bytes (16-bits) register into buffer |
| | | int result = dwt_readfromdevice(regFileID, regOffset, 2, buffer); // Read 2 bytes (16-bits) register into buffer |
| | | |
| | | if(result == DWT_SUCCESS) |
| | | { |
| | |
| | | * |
| | | * returns DWT_SUCCESS for success, or DWT_ERROR for error |
| | | */ |
| | | int dwt_write16bitoffsetreg(int regFileID,int regOffset,uint16 regval) |
| | | int dwt_write16bitoffsetreg(int regFileID, int regOffset, uint16 regval) |
| | | { |
| | | int reg; |
| | | uint8 buffer[2] ; |
| | |
| | | buffer[0] = regval & 0xFF; |
| | | buffer[1] = regval >> 8 ; |
| | | |
| | | reg = dwt_writetodevice(regFileID,regOffset,2,buffer); |
| | | reg = dwt_writetodevice(regFileID, regOffset, 2, buffer); |
| | | |
| | | return reg; |
| | | |
| | |
| | | * |
| | | * returns DWT_SUCCESS for success, or DWT_ERROR for error |
| | | */ |
| | | int dwt_write32bitoffsetreg(int regFileID,int regOffset,uint32 regval) |
| | | int dwt_write32bitoffsetreg(int regFileID, int regOffset, uint32 regval) |
| | | { |
| | | int j ; |
| | | int reg; |
| | |
| | | regval >>= 8 ; |
| | | } |
| | | |
| | | reg = dwt_writetodevice(regFileID,regOffset,4,buffer); |
| | | reg = dwt_writetodevice(regFileID, regOffset, 4, buffer); |
| | | |
| | | return reg; |
| | | |
| | |
| | | } |
| | | |
| | | dw1000local.sysCFGreg = sysconfig ; |
| | | dwt_write32bitreg(SYS_CFG_ID,sysconfig) ; |
| | | dwt_write32bitreg(SYS_CFG_ID, sysconfig) ; |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | |
| | | _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: Set system clock to XTAL - this is necessary to make sure the values read by _dwt_otpread are reliable |
| | | |
| | | for(i=0; i<length; i++) |
| | | for(i = 0; i < length; i++) |
| | | { |
| | | array[i] = _dwt_otpread(address + i) ; |
| | | } |
| | |
| | | uint8 buf[4]; |
| | | uint32 ret_data; |
| | | |
| | | buf[1] = (address>>8) & 0xff; |
| | | buf[1] = (address >> 8) & 0xff; |
| | | buf[0] = address & 0xff; |
| | | |
| | | // Write the address |
| | | dwt_writetodevice(OTP_IF_ID,OTP_ADDR,2,buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_ADDR, 2, buf); |
| | | |
| | | // Assert OTP Read (self clearing) |
| | | buf[0] = 0x03; // 0x03 for manual drive of OTP_READ |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL,1,buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, buf); |
| | | buf[0] = 0x00; // Bit0 is not autoclearing, so clear it (Bit 1 is but we clear it anyway). |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL,1,buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, buf); |
| | | |
| | | // Read read data, available 40ns after rising edge of OTP_READ |
| | | ret_data=dwt_read32bitoffsetreg(OTP_IF_ID,OTP_RDAT); |
| | | ret_data = dwt_read32bitoffsetreg(OTP_IF_ID, OTP_RDAT); |
| | | |
| | | // Return the 32bit of read data |
| | | return (ret_data); |
| | |
| | | { |
| | | uint8 rd_buf[4]; |
| | | uint8 wr_buf[4]; |
| | | uint32 mra=0,mrb=0,mr=0; |
| | | uint32 mra = 0, mrb = 0, mr = 0; |
| | | //printf("OTP SET MR: Setting MR,MRa,MRb for mode %2x\n",mode); |
| | | |
| | | // PROGRAMME MRA |
| | | // Set MRA, MODE_SEL |
| | | wr_buf[0] = 0x03; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | |
| | | // Load data |
| | | switch(mode&0x0f) { |
| | | switch(mode & 0x0f) |
| | | { |
| | | case 0x0 : |
| | | mr =0x0000; |
| | | mra=0x0000; |
| | | mrb=0x0000; |
| | | mr = 0x0000; |
| | | mra = 0x0000; |
| | | mrb = 0x0000; |
| | | break; |
| | | case 0x1 : |
| | | mr =0x1024; |
| | | mra=0x9220; // Enable CPP mon |
| | | mrb=0x000e; |
| | | mr = 0x1024; |
| | | mra = 0x9220; // Enable CPP mon |
| | | mrb = 0x000e; |
| | | break; |
| | | case 0x2 : |
| | | mr =0x1824; |
| | | mra=0x9220; |
| | | mrb=0x0003; |
| | | mr = 0x1824; |
| | | mra = 0x9220; |
| | | mrb = 0x0003; |
| | | break; |
| | | case 0x3 : |
| | | mr =0x1824; |
| | | mra=0x9220; |
| | | mrb=0x004e; |
| | | mr = 0x1824; |
| | | mra = 0x9220; |
| | | mrb = 0x004e; |
| | | break; |
| | | case 0x4 : |
| | | mr =0x0000; |
| | | mra=0x0000; |
| | | mrb=0x0003; |
| | | mr = 0x0000; |
| | | mra = 0x0000; |
| | | mrb = 0x0003; |
| | | break; |
| | | case 0x5 : |
| | | mr =0x0024; |
| | | mra=0x0000; |
| | | mrb=0x0003; |
| | | mr = 0x0024; |
| | | mra = 0x0000; |
| | | mrb = 0x0003; |
| | | break; |
| | | default : |
| | | // printf("OTP SET MR: ERROR : Invalid mode selected\n",mode); |
| | | // printf("OTP SET MR: ERROR : Invalid mode selected\n",mode); |
| | | return DWT_ERROR; |
| | | } |
| | | |
| | | wr_buf[0] = mra & 0x00ff; |
| | | wr_buf[1] = (mra & 0xff00)>>8; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT,2,wr_buf); |
| | | wr_buf[1] = (mra & 0xff00) >> 8; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT, 2, wr_buf); |
| | | |
| | | |
| | | // Set WRITE_MR |
| | | wr_buf[0] = 0x08; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | |
| | | // Wait? |
| | | |
| | | // Set Clear Mode sel |
| | | wr_buf[0] = 0x02; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | |
| | | // Set AUX update, write MR |
| | | wr_buf[0] = 0x88; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | // Clear write MR |
| | | wr_buf[0] = 0x80; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | // Clear AUX update |
| | | wr_buf[0] = 0x00; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | |
| | | /////////////////////////////////////////// |
| | | // PROGRAM MRB |
| | | // Set SLOW, MRB, MODE_SEL |
| | | wr_buf[0] = 0x05; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | |
| | | wr_buf[0] = mrb & 0x00ff; |
| | | wr_buf[1] = (mrb & 0xff00)>>8; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT,2,wr_buf); |
| | | wr_buf[1] = (mrb & 0xff00) >> 8; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT, 2, wr_buf); |
| | | |
| | | // Set WRITE_MR |
| | | wr_buf[0] = 0x08; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | |
| | | // Wait? |
| | | |
| | | // Set Clear Mode sel |
| | | wr_buf[0] = 0x04; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | |
| | | // Set AUX update, write MR |
| | | wr_buf[0] = 0x88; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | // Clear write MR |
| | | wr_buf[0] = 0x80; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | // Clear AUX update |
| | | wr_buf[0] = 0x00; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | |
| | | /////////////////////////////////////////// |
| | | // PROGRAM MR |
| | | // Set SLOW, MODE_SEL |
| | | wr_buf[0] = 0x01; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | // Load data |
| | | |
| | | wr_buf[0] = mr & 0x00ff; |
| | | wr_buf[1] = (mr & 0xff00)>>8; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT,2,wr_buf); |
| | | wr_buf[1] = (mr & 0xff00) >> 8; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT, 2, wr_buf); |
| | | |
| | | // Set WRITE_MR |
| | | wr_buf[0] = 0x08; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | |
| | | // Wait? |
| | | deca_sleep(10); |
| | | // Set Clear Mode sel |
| | | wr_buf[0] = 0x00; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | |
| | | // Read confirm mode writes. |
| | | // Set man override, MRA_SEL |
| | | wr_buf[0] = OTP_CTRL_OTPRDEN; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | wr_buf[0] = 0x02; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | // MRB_SEL |
| | | wr_buf[0] = 0x04; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | deca_sleep(100); |
| | | |
| | | // Clear mode sel |
| | | wr_buf[0] = 0x00; |
| | | dwt_writetodevice(OTP_IF_ID,OTP_CTRL+1,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL + 1, 1, wr_buf); |
| | | // Clear MAN_OVERRIDE |
| | | wr_buf[0] = 0x00; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL,1,wr_buf); |
| | | dwt_writetodevice(OTP_IF_ID, OTP_CTRL, 1, wr_buf); |
| | | |
| | | deca_sleep(10); |
| | | |
| | | if (((mode&0x0f) == 0x1)||((mode&0x0f) == 0x2)) |
| | | { |
| | | if (((mode & 0x0f) == 0x1) || ((mode & 0x0f) == 0x2)) |
| | | { |
| | | // Read status register |
| | | dwt_readfromdevice(OTP_IF_ID, OTP_STAT,1,rd_buf); |
| | | dwt_readfromdevice(OTP_IF_ID, OTP_STAT, 1, rd_buf); |
| | | } |
| | | |
| | | return DWT_SUCCESS; |
| | |
| | | |
| | | if((rd_buf[0] & 0x02) != 0x02) |
| | | { |
| | | // printf("OTP PROG 32: ERROR VPP NOT OK, programming will fail. Are MR/MRA/MRB set?\n"); |
| | | // printf("OTP PROG 32: ERROR VPP NOT OK, programming will fail. Are MR/MRA/MRB set?\n"); |
| | | return DWT_ERROR; |
| | | } |
| | | |
| | | // Write the data |
| | | wr_buf[3] = (data>>24) & 0xff; |
| | | wr_buf[2] = (data>>16) & 0xff; |
| | | wr_buf[1] = (data>>8) & 0xff; |
| | | wr_buf[3] = (data >> 24) & 0xff; |
| | | wr_buf[2] = (data >> 16) & 0xff; |
| | | wr_buf[1] = (data >> 8) & 0xff; |
| | | wr_buf[0] = data & 0xff; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_WDAT, 4, wr_buf); |
| | | |
| | | // Write the address [10:0] |
| | | wr_buf[1] = (address>>8) & 0x07; |
| | | wr_buf[1] = (address >> 8) & 0x07; |
| | | wr_buf[0] = address & 0xff; |
| | | dwt_writetodevice(OTP_IF_ID, OTP_ADDR, 2, wr_buf); |
| | | |
| | |
| | | break; |
| | | } |
| | | retry++; |
| | | if(retry==5) |
| | | if(retry == 5) |
| | | { |
| | | break; |
| | | } |
| | |
| | | uint8 buf[1]; |
| | | |
| | | buf[0] = 0x04; |
| | | dwt_writetodevice(AON_ID,AON_CTRL_OFFSET,1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | buf[0] = 0x00; |
| | | dwt_writetodevice(AON_ID,AON_CTRL_OFFSET,1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | uint8 buf[1]; |
| | | |
| | | buf[0] = 0x00; |
| | | dwt_writetodevice(AON_ID,AON_CTRL_OFFSET,1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | buf[0] = 0x02; |
| | | dwt_writetodevice(AON_ID,AON_CTRL_OFFSET,1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | uint8 buf[2]; |
| | | |
| | | buf[0] = 0x01; |
| | | dwt_writetodevice(PMSC_ID,PMSC_CTRL0_OFFSET,1,buf); |
| | | dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 1, buf); |
| | | |
| | | buf[0] = 0; |
| | | dwt_writetodevice(AON_ID, AON_CFG0_OFFSET, 1, buf); // To make sure we don't accidentaly go to sleep |
| | |
| | | // Set new value |
| | | buf[0] = sleepcnt & 0xFF; |
| | | buf[1] = (sleepcnt >> 8) & 0xFF; |
| | | dwt_writetodevice(AON_ID, (AON_CFG0_OFFSET+2) , 2, buf); |
| | | dwt_writetodevice(AON_ID, (AON_CFG0_OFFSET + 2) , 2, buf); |
| | | _dwt_aonconfigupload(); |
| | | |
| | | // Enable the sleep counter |
| | |
| | | _dwt_aonconfigupload(); |
| | | |
| | | buf[0] = 0x00; |
| | | dwt_writetodevice(PMSC_ID,PMSC_CTRL0_OFFSET,1,buf); |
| | | dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 1, buf); |
| | | } |
| | | |
| | | |
| | |
| | | _dwt_aonconfigupload(); |
| | | |
| | | buf[0] = 0x01; |
| | | dwt_writetodevice(PMSC_ID,PMSC_CTRL0_OFFSET,1,buf); |
| | | dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 1, buf); |
| | | deca_sleep(1); |
| | | |
| | | // Read the number of XTAL/2 cycles one lposc cycle took. |
| | | // Set up address |
| | | buf[0] = 118; |
| | | dwt_writetodevice(AON_ID, AON_ADDR_OFFSET, 1,buf); |
| | | dwt_writetodevice(AON_ID, AON_ADDR_OFFSET, 1, buf); |
| | | |
| | | // Enable manual override |
| | | buf[0] = 0x80; // OVR EN |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | |
| | | // Read confirm data that was written |
| | | buf[0] = 0x88; // OVR EN, OVR_RD |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | |
| | | // Read back byte from AON |
| | | dwt_readfromdevice(AON_ID, AON_RDAT_OFFSET, 1,buf); |
| | | dwt_readfromdevice(AON_ID, AON_RDAT_OFFSET, 1, buf); |
| | | result = buf[0]; |
| | | result = result << 8; |
| | | |
| | | // Set up address |
| | | buf[0] = 117; |
| | | dwt_writetodevice(AON_ID, AON_ADDR_OFFSET, 1,buf); |
| | | dwt_writetodevice(AON_ID, AON_ADDR_OFFSET, 1, buf); |
| | | |
| | | // Enable manual override |
| | | buf[0] = 0x80; // OVR EN |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | |
| | | // Read confirm data that was written |
| | | buf[0] = 0x88; // OVR EN, OVR_RD |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | |
| | | // Read back byte from AON |
| | | dwt_readfromdevice(AON_ID, AON_RDAT_OFFSET, 1,buf); |
| | | dwt_readfromdevice(AON_ID, AON_RDAT_OFFSET, 1, buf); |
| | | result |= buf[0]; |
| | | |
| | | buf[0] = 0x00; // Disable OVR EN |
| | | dwt_writetodevice(AON_ID,AON_CTRL_OFFSET,1,buf); |
| | | dwt_writetodevice(AON_ID, AON_CTRL_OFFSET, 1, buf); |
| | | |
| | | buf[0] = 0x00; |
| | | dwt_writetodevice(PMSC_ID,PMSC_CTRL0_OFFSET,1,buf); |
| | | dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 1, buf); |
| | | |
| | | // Returns the number of XTAL/2 cycles per one LP OSC cycle |
| | | // This can be converted into LP OSC frequency by 19.2 MHz/result |
| | |
| | | dw1000local.sysCFGreg |= SYS_CFG_DIS_STXP ; |
| | | } |
| | | |
| | | dwt_write32bitreg(SYS_CFG_ID,dw1000local.sysCFGreg) ; |
| | | dwt_write32bitreg(SYS_CFG_ID, dw1000local.sysCFGreg) ; |
| | | } |
| | | |
| | | |
| | |
| | | dwt_write16bitoffsetreg(ACK_RESP_T_ID, 0x2, (responseDelayTime << 8) ) ; //in symbols |
| | | // Enable auto ACK |
| | | dw1000local.sysCFGreg |= SYS_CFG_AUTOACK; |
| | | dwt_write32bitreg(SYS_CFG_ID,dw1000local.sysCFGreg) ; |
| | | dwt_write32bitreg(SYS_CFG_ID, dw1000local.sysCFGreg) ; |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | dw1000local.dblbuffon = 0; |
| | | } |
| | | |
| | | dwt_write32bitreg(SYS_CFG_ID,dw1000local.sysCFGreg) ; |
| | | dwt_write32bitreg(SYS_CFG_ID, dw1000local.sysCFGreg) ; |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | */ |
| | | void dwt_setautorxreenable(int enable) |
| | | { |
| | | uint8 byte = 0; |
| | | uint8 byte = 0; |
| | | |
| | | if(enable) |
| | | { |
| | | // Enable auto re-enable of the receiver |
| | | dw1000local.sysCFGreg |= SYS_CFG_RXAUTR; |
| | | dw1000local.sysCFGreg |= SYS_CFG_RXAUTR; |
| | | } |
| | | else |
| | | { |
| | |
| | | dw1000local.sysCFGreg &= ~SYS_CFG_RXAUTR; |
| | | } |
| | | |
| | | byte = dw1000local.sysCFGreg >> 24; |
| | | byte = dw1000local.sysCFGreg >> 24; |
| | | |
| | | dwt_writetodevice(SYS_CFG_ID, 3, 1, &byte) ; |
| | | } |
| | |
| | | { |
| | | uint8 temp; |
| | | |
| | | dwt_readfromdevice(SYS_STATUS_ID, 0, 1, &temp); |
| | | dwt_readfromdevice(SYS_STATUS_ID, 0, 1, &temp); |
| | | |
| | | return (temp & 0x1) ; |
| | | return (temp & 0x1) ; |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | uint32 clear = 0; // Will clear any events seen |
| | | |
| | | dw1000local.cdata.event = 0; |
| | | dw1000local.cdata.dblbuff = dw1000local.dblbuffon ; |
| | | dw1000local.cdata.dblbuff = dw1000local.dblbuffon ; |
| | | |
| | | status = dw1000local.cdata.status = dwt_read32bitreg(SYS_STATUS_ID) ; // Read status register low 32bits |
| | | status = dw1000local.cdata.status = dwt_read32bitreg(SYS_STATUS_ID) ; // Read status register low 32bits |
| | | |
| | | //NOTES: |
| | | //1. TX Event - if DWT_INT_TFRS is enabled, then when the frame has completed transmission the interrupt will be triggered. |
| | |
| | | // This function will clear the rx event and call the dwt_rxcallback function, notifying the application that ACK req is set. |
| | | // If using auto-ACK, the AAT indicates that ACK frame transmission is in progress. Once the ACK has been sent the TXFRS bit will be set and TX event triggered. |
| | | // If the auto-ACK is not enabled, the application can format/configure and start transmission of its own ACK frame. |
| | | // |
| | | // |
| | | |
| | | // Fix for bug 622 - LDE done flag gets latched on a bad frame |
| | | if((status & SYS_STATUS_LDEDONE) && (dw1000local.dblbuffon == 0)) |
| | | { |
| | | if((status & (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) != (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) |
| | | { |
| | | // Fix for bug 622 - LDE done flag gets latched on a bad frame |
| | | if((status & SYS_STATUS_LDEDONE) && (dw1000local.dblbuffon == 0)) |
| | | { |
| | | if((status & (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) != (SYS_STATUS_LDEDONE | SYS_STATUS_RXPHD | SYS_STATUS_RXSFDD)) |
| | | { |
| | | |
| | | // Got LDE done but other flags SFD and PHR are clear - this is a bad frame - reset the transceiver |
| | | dwt_forcetrxoff(); //this will clear all events |
| | | // Got LDE done but other flags SFD and PHR are clear - this is a bad frame - reset the transceiver |
| | | dwt_forcetrxoff(); //this will clear all events |
| | | |
| | | dwt_rxreset(); |
| | | // Leave any TX events for processing (e.g. if we TX a frame, and then enable RX, |
| | | // We can get into here before the TX frame done has been processed, when we are polling (i.e. slow to process the TX) |
| | | status &= SYS_STATUS_ALL_TX; |
| | | // Re-enable the receiver - if auto RX re-enable set |
| | | if(dw1000local.sysCFGreg & SYS_CFG_RXAUTR) |
| | | { |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID,0,(uint16)SYS_CTRL_RXENAB) ; |
| | | } |
| | | else |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | dwt_rxreset(); |
| | | // Leave any TX events for processing (e.g. if we TX a frame, and then enable RX, |
| | | // We can get into here before the TX frame done has been processed, when we are polling (i.e. slow to process the TX) |
| | | status &= SYS_STATUS_ALL_TX; |
| | | // Re-enable the receiver - if auto RX re-enable set |
| | | if(dw1000local.sysCFGreg & SYS_CFG_RXAUTR) |
| | | { |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID, 0, (uint16)SYS_CTRL_RXENAB) ; |
| | | } |
| | | else |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | } |
| | | } |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // |
| | | // 1st check for RX frame received or RX timeout and if so call the rx callback function |
| | | // |
| | | if(status & SYS_STATUS_RXFCG) // Receiver FCS Good |
| | | { |
| | | if(status & SYS_STATUS_LDEDONE) // LDE done/finished |
| | | { |
| | | // Bug 634 - overrun overwrites the frame info data... so both frames should be discarded |
| | | // Read frame info and other registers and check for overflow again |
| | | // If overflow set then discard both frames... |
| | | { |
| | | if(status & SYS_STATUS_LDEDONE) // LDE done/finished |
| | | { |
| | | // Bug 634 - overrun overwrites the frame info data... so both frames should be discarded |
| | | // Read frame info and other registers and check for overflow again |
| | | // If overflow set then discard both frames... |
| | | |
| | | uint16 len = 0; |
| | | uint16 len = 0; |
| | | |
| | | if (status & SYS_STATUS_RXOVRR) // NOTE when overrun both HS and RS pointers point to the same buffer |
| | | { |
| | | // When the overrun happens the frame info data of the buffer A (which contains the older frame e.g. seq. num = x) |
| | | // will be corrupted with the latest frame (seq. num = x + 2) data, both the host and IC are pointing to buffer A |
| | | // We are going to discard this frame - turn off transceiver and reset receiver |
| | | dwt_forcetrxoff(); |
| | | if (status & SYS_STATUS_RXOVRR) // NOTE when overrun both HS and RS pointers point to the same buffer |
| | | { |
| | | // When the overrun happens the frame info data of the buffer A (which contains the older frame e.g. seq. num = x) |
| | | // will be corrupted with the latest frame (seq. num = x + 2) data, both the host and IC are pointing to buffer A |
| | | // We are going to discard this frame - turn off transceiver and reset receiver |
| | | dwt_forcetrxoff(); |
| | | |
| | | dwt_rxreset(); |
| | | dwt_rxreset(); |
| | | |
| | | if(dw1000local.sysCFGreg & SYS_CFG_RXAUTR) // Re-enable of RX is ON, then re-enable here (ignore error) |
| | | { |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID,0,(uint16)SYS_CTRL_RXENAB) ; |
| | | } |
| | | else // The RX will be re-enabled by the application, report an error |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | if(dw1000local.sysCFGreg & SYS_CFG_RXAUTR) // Re-enable of RX is ON, then re-enable here (ignore error) |
| | | { |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID, 0, (uint16)SYS_CTRL_RXENAB) ; |
| | | } |
| | | else // The RX will be re-enabled by the application, report an error |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | } |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | } |
| | | |
| | | return; |
| | | } |
| | | else // No overrun condition - proceed to process the frame |
| | | { |
| | | return; |
| | | } |
| | | else // No overrun condition - proceed to process the frame |
| | | { |
| | | |
| | | len = dwt_read16bitoffsetreg(RX_FINFO_ID, 0) & 0x3FF; |
| | | dwt_readfromdevice(RX_BUFFER_ID,0,2,dw1000local.cdata.fctrl) ; |
| | | if (dw1000local.longFrames==0) |
| | | dwt_readfromdevice(RX_BUFFER_ID, 0, 2, dw1000local.cdata.fctrl) ; |
| | | if (dw1000local.longFrames == 0) |
| | | { |
| | | len &= 0x7F ; |
| | | } |
| | |
| | | |
| | | // Bug 627 workaround - clear the AAT bit if the ACK request bit in the FC is not set |
| | | if((status & SYS_STATUS_AAT) // AAT bit is set (ACK has been requested) |
| | | && (((dw1000local.cdata.fctrl[0] & 0x20) == 0) || (dw1000local.cdata.fctrl[0] == 0x02)) // But the data frame has it clear or it is an ACK frame |
| | | ) |
| | | && (((dw1000local.cdata.fctrl[0] & 0x20) == 0) || (dw1000local.cdata.fctrl[0] == 0x02)) // But the data frame has it clear or it is an ACK frame |
| | | ) |
| | | { |
| | | clear |= SYS_STATUS_AAT ; |
| | | dw1000local.cdata.aatset = 0 ; // ACK request is not set |
| | |
| | | { |
| | | // Clear all receive status bits (as we are finished with this receive event) |
| | | clear |= status & SYS_STATUS_ALL_RX_GOOD ; |
| | | dwt_write32bitreg(SYS_STATUS_ID,clear) ; // Write status register to clear event bits we have seen |
| | | dwt_write32bitreg(SYS_STATUS_ID, clear) ; // Write status register to clear event bits we have seen |
| | | |
| | | // NOTE: clear the event which caused interrupt means once the RX is enabled or TX is started |
| | | // New events can trigger and give rise to new interrupts |
| | |
| | | dwt_readfromdevice(SYS_STATUS_ID, 3, 1, &buff); |
| | | // If ICRBP is equal to HSRBP this means we've received another frame (both buffers have frames) |
| | | if((buff & (SYS_STATUS_ICRBP >> 24)) == // IC side Receive Buffer Pointer |
| | | ((buff & (SYS_STATUS_HSRBP >> 24)) << 1)) // Host Side Receive Buffer Pointer |
| | | ((buff & (SYS_STATUS_HSRBP >> 24)) << 1)) // Host Side Receive Buffer Pointer |
| | | { |
| | | // Clear all receive status bits (as we are finished with this receive event) |
| | | clear |= status & SYS_STATUS_ALL_DBLBUFF; |
| | | dwt_write32bitreg(SYS_STATUS_ID,clear); // Write status register to clear event bits we have seen |
| | | dwt_write32bitreg(SYS_STATUS_ID, clear); // Write status register to clear event bits we have seen |
| | | } |
| | | // If they are not aligned then there is a new frame in the other buffer, so we just need to toggle... |
| | | |
| | | if((dw1000local.sysCFGreg & SYS_CFG_RXAUTR) == 0) // Double buffer is on but no auto RX re-enable RX |
| | | { |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID,0,(uint16)SYS_CTRL_RXENAB) ; |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID, 0, (uint16)SYS_CTRL_RXENAB) ; |
| | | } |
| | | |
| | | // Call the RX call-back function to process the RX event |
| | |
| | | |
| | | if(dw1000local.sysCFGreg & SYS_CFG_RXAUTR) // Re-enable of RX is ON, then re-enable here |
| | | { |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID,0,(uint16)SYS_CTRL_RXENAB) ; |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID, 0, (uint16)SYS_CTRL_RXENAB) ; |
| | | } |
| | | } |
| | | } // end of else double buffer |
| | | |
| | | }// end of no overrun |
| | | } // If LDE_DONE is set (this means we have both SYS_STATUS_RXFCG and SYS_STATUS_LDEDONE) |
| | | else // No LDE_DONE ? |
| | | { |
| | | //printf("NO LDE done or LDE error\n"); |
| | | if(!(dw1000local.sysCFGreg & SYS_CFG_RXAUTR)) |
| | | { |
| | | dwt_forcetrxoff(); |
| | | } |
| | | dwt_rxreset(); // Reset the RX |
| | | dw1000local.wait4resp = 0; |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | } |
| | | } // end if CRC is good |
| | | else |
| | | // |
| | | // Check for TX frame sent event and signal to upper layer. |
| | | // |
| | | if (status & SYS_STATUS_TXFRS) // Transmit Frame Sent |
| | | { |
| | | clear |= SYS_STATUS_ALL_TX; //clear TX event bits |
| | | dwt_write32bitreg(SYS_STATUS_ID,clear); // Write status register to clear event bits we have seen |
| | | // NOTE: clear the event which caused interrupt means once the RX is enabled or TX is started |
| | | // New events can trigger and give rise to new interrupts |
| | | if(dw1000local.cdata.aatset) |
| | | }// end of no overrun |
| | | } // If LDE_DONE is set (this means we have both SYS_STATUS_RXFCG and SYS_STATUS_LDEDONE) |
| | | else // No LDE_DONE ? |
| | | { |
| | | dw1000local.cdata.aatset = 0; // The ACK has been sent |
| | | if(dw1000local.dblbuffon == 0) // If not double buffered |
| | | //printf("NO LDE done or LDE error\n"); |
| | | if(!(dw1000local.sysCFGreg & SYS_CFG_RXAUTR)) |
| | | { |
| | | if(dw1000local.wait4resp) // wait4response was set with the last TX start command |
| | | { |
| | | // If using wait4response and the ACK has been sent as the response requested it |
| | | // the receiver will be re-enabled, so issue a TRXOFF command to disable and prevent any |
| | | // unexpected interrupts |
| | | dwt_forcetrxoff(); |
| | | } |
| | | dwt_forcetrxoff(); |
| | | } |
| | | dwt_rxreset(); // Reset the RX |
| | | dw1000local.wait4resp = 0; |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | } |
| | | } // end if CRC is good |
| | | else |
| | | // |
| | | // Check for TX frame sent event and signal to upper layer. |
| | | // |
| | | if (status & SYS_STATUS_TXFRS) // Transmit Frame Sent |
| | | { |
| | | clear |= SYS_STATUS_ALL_TX; //clear TX event bits |
| | | dwt_write32bitreg(SYS_STATUS_ID, clear); // Write status register to clear event bits we have seen |
| | | // NOTE: clear the event which caused interrupt means once the RX is enabled or TX is started |
| | | // New events can trigger and give rise to new interrupts |
| | | if(dw1000local.cdata.aatset) |
| | | { |
| | | dw1000local.cdata.aatset = 0; // The ACK has been sent |
| | | if(dw1000local.dblbuffon == 0) // If not double buffered |
| | | { |
| | | if(dw1000local.wait4resp) // wait4response was set with the last TX start command |
| | | { |
| | | // If using wait4response and the ACK has been sent as the response requested it |
| | | // the receiver will be re-enabled, so issue a TRXOFF command to disable and prevent any |
| | | // unexpected interrupts |
| | | dwt_forcetrxoff(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | dw1000local.cdata.event = DWT_SIG_TX_DONE ; // Signal TX completed |
| | | dw1000local.cdata.event = DWT_SIG_TX_DONE ; // Signal TX completed |
| | | |
| | | // Call the TX call-back function to process the TX event |
| | | if(dw1000local.dwt_txcallback != NULL) |
| | | { |
| | | dw1000local.dwt_txcallback(&dw1000local.cdata); |
| | | } |
| | | // Call the TX call-back function to process the TX event |
| | | if(dw1000local.dwt_txcallback != NULL) |
| | | { |
| | | dw1000local.dwt_txcallback(&dw1000local.cdata); |
| | | } |
| | | |
| | | } |
| | | else if (status & SYS_STATUS_RXRFTO) // Receiver Frame Wait timeout |
| | | { |
| | | clear |= status & SYS_STATUS_RXRFTO ; |
| | | dwt_write32bitreg(SYS_STATUS_ID,clear) ; // Write status register to clear event bits we have seen |
| | | dw1000local.cdata.event = DWT_SIG_RX_TIMEOUT ; |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | dw1000local.wait4resp = 0; |
| | | else if (status & SYS_STATUS_RXRFTO) // Receiver Frame Wait timeout |
| | | { |
| | | clear |= status & SYS_STATUS_RXRFTO ; |
| | | dwt_write32bitreg(SYS_STATUS_ID, clear) ; // Write status register to clear event bits we have seen |
| | | dw1000local.cdata.event = DWT_SIG_RX_TIMEOUT ; |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | dw1000local.wait4resp = 0; |
| | | |
| | | } |
| | | else if(status & SYS_STATUS_ALL_RX_ERR) // Catches all other error events |
| | | { |
| | | clear |= status & SYS_STATUS_ALL_RX_ERR; |
| | | dwt_write32bitreg(SYS_STATUS_ID,clear) ; // Write status register to clear event bits we have seen |
| | | } |
| | | else if(status & SYS_STATUS_ALL_RX_ERR) // Catches all other error events |
| | | { |
| | | clear |= status & SYS_STATUS_ALL_RX_ERR; |
| | | dwt_write32bitreg(SYS_STATUS_ID, clear) ; // Write status register to clear event bits we have seen |
| | | |
| | | dw1000local.wait4resp = 0; |
| | | // NOTE: clear the event which caused interrupt means once the RX is enabled or TX is started |
| | | // New events can trigger and give rise to new interrupts |
| | | dw1000local.wait4resp = 0; |
| | | // NOTE: clear the event which caused interrupt means once the RX is enabled or TX is started |
| | | // New events can trigger and give rise to new interrupts |
| | | |
| | | // Fix for bug 622 - LDE done flag gets latched on a bad frame / reset receiver |
| | | if(!(dw1000local.sysCFGreg & SYS_CFG_RXAUTR)) |
| | | { |
| | | dwt_forcetrxoff(); // This will clear all events |
| | | } |
| | | dwt_rxreset(); // Reset the RX |
| | | // End of fix for bug 622 - LDE done flag gets latched on a bad frame |
| | | // Fix for bug 622 - LDE done flag gets latched on a bad frame / reset receiver |
| | | if(!(dw1000local.sysCFGreg & SYS_CFG_RXAUTR)) |
| | | { |
| | | dwt_forcetrxoff(); // This will clear all events |
| | | } |
| | | dwt_rxreset(); // Reset the RX |
| | | // End of fix for bug 622 - LDE done flag gets latched on a bad frame |
| | | |
| | | if(status & SYS_STATUS_RXPHE) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_PHR_ERROR ; |
| | | if(status & SYS_STATUS_RXPHE) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_PHR_ERROR ; |
| | | } |
| | | else if(status & SYS_STATUS_RXFCE) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | } |
| | | else if(status & SYS_STATUS_RXRFSL) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_SYNCLOSS ; |
| | | } |
| | | else if(status & SYS_STATUS_RXSFDTO) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_SFDTIMEOUT ; |
| | | } |
| | | else if(status & SYS_STATUS_RXPTO) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_PTOTIMEOUT ; |
| | | } |
| | | else |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | } |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | status &= SYS_STATUS_ALL_TX; |
| | | } |
| | | else if(status & SYS_STATUS_RXFCE) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | } |
| | | else if(status & SYS_STATUS_RXRFSL) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_SYNCLOSS ; |
| | | } |
| | | else if(status & SYS_STATUS_RXSFDTO) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_SFDTIMEOUT ; |
| | | } |
| | | else if(status & SYS_STATUS_RXPTO) |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_PTOTIMEOUT ; |
| | | } |
| | | else |
| | | { |
| | | dw1000local.cdata.event = DWT_SIG_RX_ERROR ; |
| | | } |
| | | if(dw1000local.dwt_rxcallback != NULL) |
| | | { |
| | | dw1000local.dwt_rxcallback(&dw1000local.cdata); |
| | | } |
| | | status &= SYS_STATUS_ALL_TX; |
| | | } |
| | | } // end dwt_isr() |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | if(test & 0x1) |
| | | { |
| | | // Set up MFIO for LED output |
| | | dwt_readfromdevice(GPIO_CTRL_ID,0x00,2,buf); |
| | | dwt_readfromdevice(GPIO_CTRL_ID, 0x00, 2, buf); |
| | | buf[1] &= ~0x3C; //clear the bits |
| | | buf[1] |= 0x14; |
| | | dwt_writetodevice(GPIO_CTRL_ID,0x01,1,&buf[1]); |
| | | dwt_writetodevice(GPIO_CTRL_ID, 0x01, 1, &buf[1]); |
| | | |
| | | // Enable LP Oscillator to run from counter, turn on debounce clock |
| | | dwt_readfromdevice(PMSC_ID,0x02,1,buf); |
| | | dwt_readfromdevice(PMSC_ID, 0x02, 1, buf); |
| | | buf[0] |= 0x84; // |
| | | dwt_writetodevice(PMSC_ID,0x02,1,buf); |
| | | dwt_writetodevice(PMSC_ID, 0x02, 1, buf); |
| | | |
| | | // Enable LEDs to blink |
| | | buf[0] = 0x10; // Blink period. |
| | | buf[1] = 0x01; // Enable blink counter |
| | | dwt_writetodevice(PMSC_ID,PMSC_LEDC_OFFSET,2,buf); |
| | | dwt_writetodevice(PMSC_ID, PMSC_LEDC_OFFSET, 2, buf); |
| | | |
| | | } |
| | | else if ((test & 0x1)== 0) |
| | | else if ((test & 0x1) == 0) |
| | | { |
| | | // Clear the GPIO bits that are used for LED control |
| | | dwt_readfromdevice(GPIO_CTRL_ID,0x00,2,buf); |
| | | dwt_readfromdevice(GPIO_CTRL_ID, 0x00, 2, buf); |
| | | buf[1] &= ~(0x14); |
| | | dwt_writetodevice(GPIO_CTRL_ID,0x00,2,buf); |
| | | dwt_writetodevice(GPIO_CTRL_ID, 0x00, 2, buf); |
| | | } |
| | | |
| | | // Test LEDs |
| | | if(test & 0x2) |
| | | { |
| | | buf[0] = 0x0f; // Fire a LED blink trigger |
| | | dwt_writetodevice(PMSC_ID,0x2a,1,buf); |
| | | dwt_writetodevice(PMSC_ID, 0x2a, 1, buf); |
| | | buf[0] = 0x00; // Clear forced trigger bits |
| | | dwt_writetodevice(PMSC_ID,0x2a,1,buf); |
| | | dwt_writetodevice(PMSC_ID, 0x2a, 1, buf); |
| | | } |
| | | |
| | | } // end _dwt_enableleds() |
| | |
| | | dwt_readfromdevice(PMSC_ID, PMSC_CTRL0_OFFSET, 2, reg); |
| | | switch(clocks) |
| | | { |
| | | case ENABLE_ALL_SEQ: |
| | | { |
| | | reg[0] = 0x00 ; |
| | | reg[1] = reg[1] & 0xfe; |
| | | } |
| | | break; |
| | | case FORCE_SYS_XTI: |
| | | { |
| | | // System and RX |
| | | reg[0] = 0x01 | (reg[0] & 0xfc); |
| | | } |
| | | break; |
| | | case FORCE_SYS_PLL: |
| | | { |
| | | // System |
| | | reg[0] = 0x02 | (reg[0] & 0xfc); |
| | | } |
| | | break; |
| | | case READ_ACC_ON: |
| | | { |
| | | reg[0] = 0x48 | (reg[0] & 0xb3); |
| | | reg[1] = 0x80 | reg[1]; |
| | | } |
| | | break; |
| | | case READ_ACC_OFF: |
| | | { |
| | | reg[0] = reg[0] & 0xb3; |
| | | reg[1] = 0x7f & reg[1]; |
| | | case ENABLE_ALL_SEQ: |
| | | { |
| | | reg[0] = 0x00 ; |
| | | reg[1] = reg[1] & 0xfe; |
| | | } |
| | | break; |
| | | case FORCE_SYS_XTI: |
| | | { |
| | | // System and RX |
| | | reg[0] = 0x01 | (reg[0] & 0xfc); |
| | | } |
| | | break; |
| | | case FORCE_SYS_PLL: |
| | | { |
| | | // System |
| | | reg[0] = 0x02 | (reg[0] & 0xfc); |
| | | } |
| | | break; |
| | | case READ_ACC_ON: |
| | | { |
| | | reg[0] = 0x48 | (reg[0] & 0xb3); |
| | | reg[1] = 0x80 | reg[1]; |
| | | } |
| | | break; |
| | | case READ_ACC_OFF: |
| | | { |
| | | reg[0] = reg[0] & 0xb3; |
| | | reg[1] = 0x7f & reg[1]; |
| | | |
| | | } |
| | | break; |
| | | case FORCE_OTP_ON: |
| | | { |
| | | reg[1] = 0x02 | reg[1]; |
| | | } |
| | | break; |
| | | case FORCE_OTP_OFF: |
| | | { |
| | | reg[1] = reg[1] & 0xfd; |
| | | } |
| | | break; |
| | | case FORCE_TX_PLL: |
| | | { |
| | | reg[0] = 0x20| (reg[0] & 0xcf); |
| | | } |
| | | break; |
| | | default: |
| | | } |
| | | break; |
| | | case FORCE_OTP_ON: |
| | | { |
| | | reg[1] = 0x02 | reg[1]; |
| | | } |
| | | break; |
| | | case FORCE_OTP_OFF: |
| | | { |
| | | reg[1] = reg[1] & 0xfd; |
| | | } |
| | | break; |
| | | case FORCE_TX_PLL: |
| | | { |
| | | reg[0] = 0x20 | (reg[0] & 0xcf); |
| | | } |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | |
| | | if(mode & DWT_RESPONSE_EXPECTED) |
| | | { |
| | | temp = (uint8)SYS_CTRL_WAIT4RESP ; // Set wait4response bit |
| | | dwt_writetodevice(SYS_CTRL_ID,0,1,&temp) ; |
| | | dwt_writetodevice(SYS_CTRL_ID, 0, 1, &temp) ; |
| | | dw1000local.wait4resp = 1; |
| | | } |
| | | |
| | |
| | | |
| | | // Both SYS_CTRL_TXSTRT and SYS_CTRL_TXDLYS to correctly enable TX |
| | | temp |= (uint8)(SYS_CTRL_TXDLYS | SYS_CTRL_TXSTRT) ; |
| | | dwt_writetodevice(SYS_CTRL_ID,0,1,&temp) ; |
| | | checkTxOK = dwt_read16bitoffsetreg(SYS_STATUS_ID,3) ; |
| | | dwt_writetodevice(SYS_CTRL_ID, 0, 1, &temp) ; |
| | | checkTxOK = dwt_read16bitoffsetreg(SYS_STATUS_ID, 3) ; |
| | | //status = dwt_read32bitreg(SYS_STATUS_ID) ; // Read status register |
| | | if ((checkTxOK & SYS_STATUS_TXERR) == 0) // Transmit Delayed Send set over Half a Period away or Power Up error (there is enough time to send but not to power up individual blocks). |
| | | { |
| | |
| | | // I am taking DSHP set to Indicate that the TXDLYS was set too late for the specified DX_TIME. |
| | | // Remedial Action - (a) cancel delayed send |
| | | temp = (uint8)SYS_CTRL_TRXOFF; // This assumes the bit is in the lowest byte |
| | | dwt_writetodevice(SYS_CTRL_ID,0,1,&temp) ; |
| | | dwt_writetodevice(SYS_CTRL_ID, 0, 1, &temp) ; |
| | | // Note event Delayed TX Time too Late |
| | | // Could fall through to start a normal send (below) just sending late..... |
| | | // ... instead return and assume return value of 1 will be used to detect and recover from the issue. |
| | |
| | | else |
| | | { |
| | | temp |= (uint8)SYS_CTRL_TXSTRT ; |
| | | dwt_writetodevice(SYS_CTRL_ID,0,1,&temp) ; |
| | | dwt_writetodevice(SYS_CTRL_ID, 0, 1, &temp) ; |
| | | } |
| | | |
| | | return retval; |
| | |
| | | */ |
| | | void dwt_forcetrxoff(void) |
| | | { |
| | | decaIrqStatus_t stat ; |
| | | decaIrqStatus_t stat ; |
| | | uint8 temp ; |
| | | uint32 mask; |
| | | uint32 mask; |
| | | |
| | | temp = (uint8)SYS_CTRL_TRXOFF ; // This assumes the bit is in the lowest byte |
| | | |
| | | mask = dwt_read32bitreg(SYS_MASK_ID) ; // Read set interrupt mask |
| | | mask = dwt_read32bitreg(SYS_MASK_ID) ; // Read set interrupt mask |
| | | |
| | | // Need to beware of interrupts occurring in the middle of following read modify write cycle |
| | | // We can disable the radio, but before the status is cleared an interrupt can be set (e.g. the |
| | | // event has just happened before the radio was disabled) |
| | | // thus we need to disable interrupt during this operation |
| | | // Need to beware of interrupts occurring in the middle of following read modify write cycle |
| | | // We can disable the radio, but before the status is cleared an interrupt can be set (e.g. the |
| | | // event has just happened before the radio was disabled) |
| | | // thus we need to disable interrupt during this operation |
| | | stat = decamutexon() ; |
| | | |
| | | dwt_write32bitreg(SYS_MASK_ID, 0) ; // Clear interrupt mask - so we don't get any unwanted events |
| | | dwt_write32bitreg(SYS_MASK_ID, 0) ; // Clear interrupt mask - so we don't get any unwanted events |
| | | |
| | | dwt_writetodevice(SYS_CTRL_ID,0,1,&temp) ; // Disable the radio |
| | | dwt_writetodevice(SYS_CTRL_ID, 0, 1, &temp) ; // Disable the radio |
| | | |
| | | // Forcing Transceiver off - so we do not want to see any new events that may have happened |
| | | dwt_write32bitreg(SYS_STATUS_ID,(SYS_STATUS_ALL_TX | SYS_STATUS_ALL_RX_ERR | SYS_STATUS_ALL_RX_GOOD)) ; |
| | | dwt_write32bitreg(SYS_STATUS_ID, (SYS_STATUS_ALL_TX | SYS_STATUS_ALL_RX_ERR | SYS_STATUS_ALL_RX_GOOD)) ; |
| | | |
| | | dwt_syncrxbufptrs(); |
| | | |
| | | dwt_write32bitreg(SYS_MASK_ID, mask) ; // Set interrupt mask to what it was |
| | | dwt_write32bitreg(SYS_MASK_ID, mask) ; // Set interrupt mask to what it was |
| | | |
| | | // Enable/restore interrupts again... |
| | | decamutexoff(stat) ; |
| | | // Enable/restore interrupts again... |
| | | decamutexoff(stat) ; |
| | | dw1000local.wait4resp = 0; |
| | | |
| | | } // end deviceforcetrxoff() |
| | |
| | | dwt_readfromdevice(SYS_STATUS_ID, 3, 1, &buff); |
| | | |
| | | if((buff & (SYS_STATUS_ICRBP >> 24)) != // IC side Receive Buffer Pointer |
| | | ((buff & (SYS_STATUS_HSRBP>>24)) << 1) ) // Host Side Receive Buffer Pointer |
| | | ((buff & (SYS_STATUS_HSRBP >> 24)) << 1) ) // Host Side Receive Buffer Pointer |
| | | { |
| | | uint8 hsrb = 0x01; |
| | | dwt_writetodevice(SYS_CTRL_ID, SYS_CTRL_HRBT_OFFSET , 1, &hsrb) ; // We need to swap RX buffer status reg (write one to toggle internally) |
| | |
| | | temp |= (uint16)SYS_CTRL_RXDLYE ; |
| | | } |
| | | |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID,0,temp) ; |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID, 0, temp) ; |
| | | |
| | | if (delayed) // Check for errors |
| | | { |
| | | //uint32 status1 = dwt_read32bitreg(SYS_STATUS_ID) ; // Read status register |
| | | |
| | | dwt_readfromdevice(SYS_STATUS_ID,3,1,&temp1) ; |
| | | dwt_readfromdevice(SYS_STATUS_ID, 3, 1, &temp1) ; |
| | | |
| | | if (temp1 & (SYS_STATUS_HPDWARN >> 24)) // If delay has not passed do delayed else immediate RX on |
| | | { |
| | | dwt_forcetrxoff(); // Turn the delayed receive off, and do immediate receive, return warning indication |
| | | temp = (uint16)SYS_CTRL_RXENAB; // Clear the delay bit |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID,0,temp) ; |
| | | dwt_write16bitoffsetreg(SYS_CTRL_ID, 0, temp) ; |
| | | return DWT_ERROR; |
| | | } |
| | | } |
| | |
| | | { |
| | | uint8 temp ; |
| | | |
| | | dwt_readfromdevice(SYS_CFG_ID,3,1,&temp) ; // Read register |
| | | dwt_readfromdevice(SYS_CFG_ID, 3, 1, &temp) ; // Read register |
| | | |
| | | if(time > 0) |
| | | { |
| | | dwt_write16bitoffsetreg(RX_FWTO_ID, 0x0, time) ; |
| | | |
| | | temp |= (uint8)(SYS_CFG_RXWTOE>>24); |
| | | temp |= (uint8)(SYS_CFG_RXWTOE >> 24); |
| | | // OR in 32bit value (1 bit set), I know this is in high byte. |
| | | dw1000local.sysCFGreg |= SYS_CFG_RXWTOE; |
| | | |
| | | dwt_writetodevice(SYS_CFG_ID,3,1,&temp) ; |
| | | dwt_writetodevice(SYS_CFG_ID, 3, 1, &temp) ; |
| | | } |
| | | else |
| | | { |
| | | temp &= ~((uint8)(SYS_CFG_RXWTOE>>24)); |
| | | temp &= ~((uint8)(SYS_CFG_RXWTOE >> 24)); |
| | | // AND in inverted 32bit value (1 bit clear), I know this is in high byte. |
| | | dw1000local.sysCFGreg &= ~(SYS_CFG_RXWTOE); |
| | | |
| | | dwt_writetodevice(SYS_CFG_ID,3,1,&temp) ; |
| | | dwt_writetodevice(SYS_CFG_ID, 3, 1, &temp) ; |
| | | |
| | | //dwt_write16bitoffsetreg(RX_FWTO_ID,0,0) ; // Clearing the time is not needed |
| | | } |
| | |
| | | { |
| | | mask &= ~bitmask ; // Clear the bit |
| | | } |
| | | dwt_write32bitreg(SYS_MASK_ID,mask) ; // New value |
| | | dwt_write32bitreg(SYS_MASK_ID, mask) ; // New value |
| | | |
| | | decamutexoff(stat) ; |
| | | } |
| | |
| | | { |
| | | uint32 temp; |
| | | |
| | | temp= dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_PHE_OFFSET); // Read sync loss (31-16), PHE (15-0) |
| | | temp = dwt_read32bitoffsetreg(DIG_DIAG_ID, EVC_PHE_OFFSET); // Read sync loss (31-16), PHE (15-0) |
| | | counters->PHE = temp & 0xFFF; |
| | | counters->RSL = (temp >> 16) & 0xFFF; |
| | | |
| | |
| | | */ |
| | | void dwt_rxreset(void) |
| | | { |
| | | uint8 resetrx = 0xe0; |
| | | // Set RX reset |
| | | dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); |
| | | uint8 resetrx = 0xe0; |
| | | // Set RX reset |
| | | dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); |
| | | |
| | | resetrx = 0xf0; // Clear RX reset |
| | | dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); |
| | | resetrx = 0xf0; // Clear RX reset |
| | | dwt_writetodevice(PMSC_ID, 0x3, 1, &resetrx); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | { |
| | | uint8 write_buf; |
| | | |
| | | dwt_readfromdevice(FS_CTRL_ID,FS_XTALT_OFFSET,1,&write_buf); |
| | | dwt_readfromdevice(FS_CTRL_ID, FS_XTALT_OFFSET, 1, &write_buf); |
| | | |
| | | write_buf &= ~FS_XTALT_MASK ; |
| | | |
| | | write_buf |= (FS_XTALT_MASK & value) ; // We should not change high bits, cause it will cause malfunction |
| | | |
| | | dwt_writetodevice(FS_CTRL_ID,FS_XTALT_OFFSET,1,&write_buf); |
| | | dwt_writetodevice(FS_CTRL_ID, FS_XTALT_OFFSET, 1, &write_buf); |
| | | } |
| | | |
| | | |
| | |
| | | #ifdef DWT_API_ERROR_CHECK |
| | | if ((chan < 1) || (chan > 7) || (6 == chan)) |
| | | { |
| | | return DWT_ERROR ; // validate channel number parameter |
| | | } |
| | | return DWT_ERROR ; // validate channel number parameter |
| | | } |
| | | #endif |
| | | |
| | | // |
| | |
| | | // Configure TX clocks |
| | | // |
| | | write_buf[0] = 0x22; |
| | | dwt_writetodevice(PMSC_ID,PMSC_CTRL0_OFFSET,1,write_buf); |
| | | dwt_writetodevice(PMSC_ID, PMSC_CTRL0_OFFSET, 1, write_buf); |
| | | write_buf[0] = 0x07; |
| | | dwt_writetodevice(PMSC_ID,0x1,1,write_buf); |
| | | dwt_writetodevice(PMSC_ID, 0x1, 1, write_buf); |
| | | |
| | | // Disable fine grain TX seq |
| | | dwt_write16bitoffsetreg(PMSC_ID, PMSC_TXFINESEQ_OFFSET, PMSC_TXFINESEQ_DIS_MASK); |
| | | |
| | | |
| | | write_buf[0] = TC_PGTEST_CW; |
| | | write_buf[0] = TC_PGTEST_CW; |
| | | |
| | | // Configure CW mode |
| | | dwt_writetodevice(TX_CAL_ID, TC_PGTEST_OFFSET, TC_PGTEST_LEN, write_buf); |
| | |
| | | // Configure continuous frame TX |
| | | // |
| | | write_buf[0] = (uint8)(DIAG_TMC_TX_PSTM) ; |
| | | dwt_writetodevice(DIG_DIAG_ID, DIAG_TMC_OFFSET, 1,write_buf); // Turn the tx power spectrum test mode - continuous sending of frames |
| | | dwt_writetodevice(DIG_DIAG_ID, DIAG_TMC_OFFSET, 1, write_buf); // Turn the tx power spectrum test mode - continuous sending of frames |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | |
| | | // These writes should be single writes and in sequence |
| | | wr_buf[0] = 0x80; // Enable TLD Bias |
| | | dwt_writetodevice(RF_CONF_ID,0x11,1,wr_buf); |
| | | dwt_writetodevice(RF_CONF_ID, 0x11, 1, wr_buf); |
| | | |
| | | wr_buf[0] = 0x0A; // Enable TLD Bias and ADC Bias |
| | | dwt_writetodevice(RF_CONF_ID,0x12,1,wr_buf); |
| | | dwt_writetodevice(RF_CONF_ID, 0x12, 1, wr_buf); |
| | | |
| | | wr_buf[0] = 0x0f; // Enable Outputs (only after Biases are up and running) |
| | | dwt_writetodevice(RF_CONF_ID,0x12,1,wr_buf); // |
| | | dwt_writetodevice(RF_CONF_ID, 0x12, 1, wr_buf); // |
| | | |
| | | // Reading All SAR inputs |
| | | wr_buf[0] = 0x00; |
| | | dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf); |
| | | dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C, 1, wr_buf); |
| | | wr_buf[0] = 0x01; // Set SAR enable |
| | | dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf); |
| | | dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C, 1, wr_buf); |
| | | |
| | | if(fastSPI == 1) |
| | | { |
| | | deca_sleep(1); // If using PLL clocks(and fast SPI rate) then this sleep is needed |
| | | // Read voltage and temperature. |
| | | dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET,2,wr_buf); |
| | | dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET, 2, wr_buf); |
| | | } |
| | | else //change to a slow clock |
| | | { |
| | | _dwt_enableclocks(FORCE_SYS_XTI); // NOTE: set system clock to XTI - this is necessary to make sure the values read are reliable |
| | | // Read voltage and temperature. |
| | | dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET,2,wr_buf); |
| | | dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET, 2, wr_buf); |
| | | // Default clocks (ENABLE_ALL_SEQ) |
| | | _dwt_enableclocks(ENABLE_ALL_SEQ); // Enable clocks for sequencing |
| | | } |
| | |
| | | temp_raw = wr_buf[1]; |
| | | |
| | | wr_buf[0] = 0x00; // Clear SAR enable |
| | | dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C,1,wr_buf); |
| | | dwt_writetodevice(TX_CAL_ID, TC_SARL_SAR_C, 1, wr_buf); |
| | | |
| | | return ((temp_raw<<8)|(vbat_raw)); |
| | | return ((temp_raw << 8) | (vbat_raw)); |
| | | } |
| | | |
| | | /*! ------------------------------------------------------------------------------------------------------------------ |
| | |
| | | uint8 dwt_readwakeuptemp(void) |
| | | { |
| | | uint8 temp_raw; |
| | | dwt_readfromdevice(TX_CAL_ID,TC_SARL_SAR_LTEMP_OFFSET,1,&temp_raw); |
| | | dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LTEMP_OFFSET, 1, &temp_raw); |
| | | return (temp_raw); |
| | | } |
| | | |
| | |
| | | uint8 dwt_readwakeupvbat(void) |
| | | { |
| | | uint8 vbat_raw; |
| | | dwt_readfromdevice(TX_CAL_ID,TC_SARL_SAR_LVBAT_OFFSET,1,&vbat_raw); |
| | | dwt_readfromdevice(TX_CAL_ID, TC_SARL_SAR_LVBAT_OFFSET, 1, &vbat_raw); |
| | | return (vbat_raw); |
| | | } |
| | | |