| /****************************************************************************** |
| * drivers/wireless/spirit/lib/spirit_pktbasic.c |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| * SPDX-FileCopyrightText: Copyright(c) 2015 STMicroelectronics |
| * SPDX-FileContributor: Author: VMA division - AMS |
| * Version 3.2.2 08-July-2015 |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of STMicroelectronics nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| ******************************************************************************/ |
| |
| /****************************************************************************** |
| * Included Files |
| ******************************************************************************/ |
| |
| #include <sys/types.h> |
| #include <assert.h> |
| #include <errno.h> |
| |
| #include "spirit_pktbasic.h" |
| #include "spirit_spi.h" |
| |
| /****************************************************************************** |
| * Public Functions |
| ******************************************************************************/ |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_initialize |
| * |
| * Description: |
| * Initializes the Spirit Basic packet according to the specified parameters |
| * in the struct spirit_pktbasic_init_s. Notice that this function sets the |
| * autofiltering option on CRC if it is set to any value different from |
| * BASIC_NO_CRC. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * pktpasic - Basic packet init structure. |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_initialize(FAR struct spirit_library_s *spirit, |
| FAR const struct spirit_pktbasic_init_s *pktpasic) |
| { |
| uint8_t regval[4]; |
| uint8_t pktlenwidth; |
| uint8_t i; |
| int ret; |
| |
| /* Check the parameters */ |
| |
| DEBUGASSERT(IS_PKT_PREAMBLE_LENGTH(pktpasic->preamblen)); |
| DEBUGASSERT(IS_PKT_SYNC_LENGTH(pktpasic->synclen)); |
| DEBUGASSERT(IS_PKT_CRC_MODE(pktpasic->crcmode)); |
| DEBUGASSERT(IS_PKT_LENGTH_WIDTH_BITS(pktpasic->pktlenwidth)); |
| DEBUGASSERT(IS_PKT_FIX_VAR_LENGTH(pktpasic->fixvarlen)); |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(pktpasic->txdestaddr)); |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(pktpasic->fec)); |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(pktpasic->datawhite)); |
| DEBUGASSERT(IS_PKT_CONTROL_LENGTH(pktpasic->ctrllen)); |
| |
| /* Reads the PROTOCOL1 register */ |
| |
| ret = spirit_reg_read(spirit, PROTOCOL1_BASE, ®val[0], 1); |
| |
| /* Mask a reserved bit */ |
| |
| regval[0] &= ~0x20; |
| |
| /* Always set the automatic packet filtering */ |
| |
| regval[0] |= PROTOCOL1_AUTO_PCKT_FLT_MASK; |
| |
| /* Writes the value on register */ |
| |
| ret = spirit_reg_write(spirit, PROTOCOL1_BASE, ®val[0], 1); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| /* Reads the PCKT_FLT_OPTIONS register */ |
| |
| ret = spirit_reg_read(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| /* Always reset the control and source filtering (also if it is not present |
| * in basic). |
| */ |
| |
| regval[0] &= ~(PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK | |
| PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK); |
| |
| /* Writes the value on register */ |
| |
| ret = spirit_reg_write(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| if (pktpasic->txdestaddr == S_ENABLE) |
| { |
| regval[0] = 0x08; |
| } |
| else |
| { |
| regval[0] = 0x00; |
| } |
| |
| /* Address and control length setting */ |
| |
| regval[0] |= (uint8_t)pktpasic->ctrllen; |
| |
| /* Packet format and width length setting */ |
| |
| pktlenwidth = pktpasic->pktlenwidth; |
| if (pktlenwidth == 0) |
| { |
| pktlenwidth = 1; |
| } |
| |
| regval[1] = (uint8_t)PCKTCTRL3_PCKT_FRMT_BASIC | (uint8_t)(pktlenwidth - 1); |
| |
| /* Preamble, sync and fixed or variable length setting */ |
| |
| regval[2] = (uint8_t)pktpasic->preamblen | (uint8_t)pktpasic->synclen | |
| (uint8_t)pktpasic->fixvarlen; |
| |
| /* CRC length, whitening and FEC setting */ |
| |
| regval[3] = (uint8_t)pktpasic->crcmode; |
| |
| if (pktpasic->datawhite == S_ENABLE) |
| { |
| regval[3] |= PCKTCTRL1_WHIT_MASK; |
| } |
| |
| if (pktpasic->fec == S_ENABLE) |
| { |
| regval[3] |= PCKTCTRL1_FEC_MASK; |
| } |
| |
| /* Writes registers */ |
| |
| ret = spirit_reg_write(spirit, PCKTCTRL4_BASE, regval, 4); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| /* Sync words setting */ |
| |
| for (i = 0; i < 4; i++) |
| { |
| if (i < 3 - (pktpasic->synclen >> 1)) |
| { |
| regval[i] = 0; |
| } |
| else |
| { |
| regval[i] = (uint8_t)(pktpasic->syncwords >> (8 * i)); |
| } |
| } |
| |
| /* Sets CRC check bit */ |
| |
| if (pktpasic->crcmode == PKT_NO_CRC) |
| { |
| ret = spirit_pktcommon_enable_crcfilter(spirit, S_DISABLE); |
| } |
| else |
| { |
| ret = spirit_pktcommon_enable_crcfilter(spirit, S_ENABLE); |
| } |
| |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| return spirit_reg_write(spirit, SYNC4_BASE, regval, 4); |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_get_setup |
| * |
| * Description: |
| * Returns the SPIRIT Basic packet structure according to the specified |
| * parameters in the registers. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * pktbasic - Basic packet init structure. |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_get_setup(FAR struct spirit_library_s *spirit, |
| FAR struct spirit_pktbasic_init_s *pktbasic) |
| { |
| uint8_t regval[10]; |
| int ret; |
| int i; |
| |
| /* Reads registers */ |
| |
| ret = spirit_reg_read(spirit, PCKTCTRL4_BASE, regval, 10); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| /* Length width */ |
| |
| pktbasic->pktlenwidth = (regval[1] & 0x0f) + 1; |
| |
| /* Address field */ |
| |
| pktbasic->txdestaddr = |
| (enum spirit_functional_state_e)((regval[0] >> 3) & 0x01); |
| |
| /* Control length */ |
| |
| pktbasic->ctrllen = (enum pkt_ctrllen_e)(regval[0] & 0x07); |
| |
| /* CRC mode */ |
| |
| pktbasic->crcmode = (enum pkt_crcmode_e)(regval[3] & 0xe0); |
| |
| /* Whitening */ |
| |
| pktbasic->datawhite = |
| (enum spirit_functional_state_e) ((regval[3] >> 4) & 0x01); |
| |
| /* FEC */ |
| |
| pktbasic->fec = (enum spirit_functional_state_e)(regval[3] & 0x01); |
| |
| /* FIX or VAR bit */ |
| |
| pktbasic->fixvarlen = (enum pkt_fixvar_len_e)(regval[2] & 0x01); |
| |
| /* Preamble length */ |
| |
| pktbasic->preamblen = (enum pkt_preamblen_e)(regval[2] & 0xf8); |
| |
| /* Sync length */ |
| |
| pktbasic->synclen = (enum pkt_synlen_e)(regval[2] & 0x06); |
| |
| /* Sync Words */ |
| |
| pktbasic->syncwords = 0; |
| for (i = 0; i < 4; i++) |
| { |
| if (i > 2 - (((uint8_t)pktbasic->synclen) >> 1)) |
| { |
| pktbasic->syncwords |= (uint32_t) (regval[i + 6]) << (8 * i); |
| } |
| } |
| |
| return OK; |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_addr_initialize |
| * |
| * Description: |
| * Initializes the SPIRIT Basic packet addresses according to the specified |
| * parameters in the struct struct spirit_pktbasic_init_s struct. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * basicaddr - Basic packet addresses init structure. |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_addr_initialize(FAR struct spirit_library_s *spirit, |
| FAR struct spirit_pktbasic_addr_s *basicaddr) |
| { |
| uint8_t regval[3]; |
| int ret; |
| |
| /* Check the parameters */ |
| |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(basicaddr->destfilter)); |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(basicaddr->mcastfilter)); |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(basicaddr->bcastfilter)); |
| |
| /* Reads the PCKT_FLT_OPTIONS ragister */ |
| |
| ret = spirit_reg_read(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); |
| if (ret < 0) |
| { |
| return ret; |
| } |
| |
| /* Enables or disables filtering on my address */ |
| |
| if (basicaddr->destfilter == S_ENABLE) |
| { |
| regval[0] |= PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK; |
| } |
| else |
| { |
| regval[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK; |
| } |
| |
| /* Enables or disables filtering on multicast address */ |
| |
| if (basicaddr->mcastfilter == S_ENABLE) |
| { |
| regval[0] |= PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK; |
| } |
| else |
| { |
| regval[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK; |
| } |
| |
| /* Enables or disables filtering on broadcast address */ |
| |
| if (basicaddr->bcastfilter == S_ENABLE) |
| { |
| regval[0] |= PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK; |
| } |
| else |
| { |
| regval[0] &= ~PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK; |
| } |
| |
| /* Writes the new value on the PCKT_FLT_OPTIONS register */ |
| |
| ret = spirit_reg_write(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); |
| |
| /* Fills the array with the addresses passed in the structure */ |
| |
| regval[0] = basicaddr->bcastaddr; |
| regval[1] = basicaddr->mcastaddr; |
| regval[2] = basicaddr->srcaddr; |
| |
| /* Writes values on the PCKT_FLT_GOALS registers */ |
| |
| return spirit_reg_write(spirit, PCKT_FLT_GOALS_BROADCAST_BASE, regval, 3); |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_get_addrsetup |
| * |
| * Description: |
| * Returns the SPIRIT Basic packet addresses structure according to the |
| * specified parameters in the registers. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * basicaddr - Basic packet addresses init structure. |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_get_addrsetup(FAR struct spirit_library_s *spirit, |
| FAR struct spirit_pktbasic_addr_s *basicaddr) |
| { |
| uint8_t regval[3]; |
| int ret; |
| |
| /* Reads values on the PCKT_FLT_GOALS registers */ |
| |
| ret = spirit_reg_read(spirit, PCKT_FLT_GOALS_BROADCAST_BASE, regval, 3); |
| if (ret >= 0) |
| { |
| /* Fit the structure with the read addresses */ |
| |
| basicaddr->bcastaddr = regval[0]; |
| basicaddr->mcastaddr = regval[1]; |
| basicaddr->srcaddr = regval[2]; |
| |
| ret = spirit_reg_read(spirit, PCKT_FLT_OPTIONS_BASE, ®val[0], 1); |
| if (ret >= 0) |
| { |
| /* Fit the structure with the read filtering bits */ |
| |
| basicaddr->bcastfilter = |
| (enum spirit_functional_state_e)((regval[0] >> 1) & 0x01); |
| basicaddr->mcastfilter = |
| (enum spirit_functional_state_e)((regval[0] >> 2) & 0x01); |
| basicaddr->destfilter = |
| (enum spirit_functional_state_e)((regval[0] >> 3) & 0x01); |
| } |
| } |
| |
| return ret; |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_set_format |
| * |
| * Description: |
| * Configures the Basic packet format as packet used by SPIRIT. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_set_format(FAR struct spirit_library_s *spirit) |
| { |
| uint8_t regval; |
| int ret; |
| |
| /* Reads the register value */ |
| |
| ret = spirit_reg_read(spirit, PCKTCTRL3_BASE, ®val, 1); |
| if (ret >= 0) |
| { |
| /* Build the new value. Also set to 0 the direct RX mode bits */ |
| |
| regval &= 0x0f; |
| regval |= (uint8_t) PCKTCTRL3_PCKT_FRMT_BASIC; |
| |
| /* Write the value to the PCKTCTRL3 register */ |
| |
| ret = spirit_reg_write(spirit, PCKTCTRL3_BASE, ®val, 1); |
| } |
| |
| if (ret >= 0) |
| { |
| /* Reads the PCKTCTRL1_BASE register */ |
| |
| ret = spirit_reg_read(spirit, PCKTCTRL1_BASE, ®val, 1); |
| if (ret >= 0) |
| { |
| /* Build the new value. Set to 0 the direct TX mode bits */ |
| |
| regval &= 0xf3; |
| |
| /* Write the value to the PCKTCTRL1 register */ |
| |
| ret = spirit_reg_write(spirit, PCKTCTRL1_BASE, ®val, 1); |
| } |
| } |
| |
| if (ret >= 0) |
| { |
| /* Reads the PROTOCOL1 register */ |
| |
| ret = spirit_reg_read(spirit, PROTOCOL1_BASE, ®val, 1); |
| if (ret >= 0) |
| { |
| /* Mask a reserved bit */ |
| |
| regval &= ~0x20; |
| |
| /* Write the value to the register */ |
| |
| ret = spirit_reg_write(spirit, PROTOCOL1_BASE, ®val, 1); |
| } |
| } |
| |
| return ret; |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pkbasic_enable_addrlen |
| * |
| * Description: |
| * Sets the address length for SPIRIT Basic packets. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * txdestaddr - Enable/disable address field |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value on failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pkbasic_enable_addrlen(FAR struct spirit_library_s *spirit, |
| enum spirit_functional_state_e txdestaddr) |
| { |
| uint8_t regval; |
| int ret; |
| |
| /* Check the parameters */ |
| |
| DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(txdestaddr)); |
| |
| /* Reads the PCKTCTRL4 register value */ |
| |
| ret = spirit_reg_read(spirit, PCKTCTRL4_BASE, ®val, 1); |
| if (ret >= 0) |
| { |
| /* Build the address length for the register */ |
| |
| if (txdestaddr == S_ENABLE) |
| { |
| regval |= 0x08; |
| } |
| else |
| { |
| regval &= 0x07; |
| } |
| |
| /* Writes the new value on the PCKTCTRL4 register */ |
| |
| ret = spirit_reg_write(spirit, PCKTCTRL4_BASE, ®val, 1); |
| } |
| |
| return ret; |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pkbasic_isenabled_addrlen |
| * |
| * Description: |
| * Specifies if the Address field for SPIRIT Basic packets is enabled or |
| * disabled. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * |
| * Returned Value: |
| * Notifies if the address field is enabled or disabled. |
| * |
| ******************************************************************************/ |
| |
| enum spirit_functional_state_e |
| spirit_pkbasic_isenabled_addrlen(FAR struct spirit_library_s *spirit) |
| { |
| uint8_t regval; |
| |
| /* Reads the PCKTCTRL4 register value */ |
| |
| spirit_reg_read(spirit, PCKTCTRL4_BASE, ®val, 1); |
| |
| /* Returns the address field value */ |
| |
| if ((regval & PCKTCTRL4_ADDRESS_LEN_MASK) != 0) |
| { |
| return S_ENABLE; |
| } |
| else |
| { |
| return S_DISABLE; |
| } |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_set_payloadlen |
| * |
| * Description: |
| * Sets the payload length for SPIRIT Basic packets. Since the packet length |
| * depends from the address and the control field size, this function reads |
| * the correspondent registers in order to determine the correct packet |
| * length to be written. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * payloadlen - Payload length in bytes. |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value is returned on any failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_set_payloadlen(FAR struct spirit_library_s *spirit, |
| uint16_t payloadlen) |
| { |
| uint8_t regval[2]; |
| uint16_t oversize = 0; |
| |
| /* Computes the oversize (address + control) size */ |
| |
| if (spirit_pkbasic_isenabled_addrlen(spirit)) |
| { |
| oversize = 1; |
| } |
| |
| oversize += (uint16_t)spirit_pktcommon_get_controllen(spirit); |
| |
| /* Computes PCKTLEN0 value from payloadlen */ |
| |
| regval[1] = BUILD_PCKTLEN0(payloadlen + oversize); |
| |
| /* Computes PCKTLEN1 value from payloadlen */ |
| |
| regval[0] = BUILD_PCKTLEN1(payloadlen + oversize); |
| |
| /* Writes data on the PCKTLEN1/0 register */ |
| |
| return spirit_reg_write(spirit, PCKTLEN1_BASE, regval, 2); |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbase_get_payloadlen |
| * |
| * Description: |
| * Returns the payload length for SPIRIT Basic packets. Since the packet |
| * length depends from the address and the control field size, this function |
| * reads the correspondent registers in order to determine the correct |
| * payload length to be returned. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * |
| * Returned Value: |
| * Payload length in bytes. |
| * |
| ******************************************************************************/ |
| |
| uint16_t spirit_pktbase_get_payloadlen(FAR struct spirit_library_s *spirit) |
| { |
| uint8_t regval[2]; |
| uint16_t oversize = 0; |
| |
| /* Computes the oversize (address + control) size */ |
| |
| if (spirit_pkbasic_isenabled_addrlen(spirit)) |
| { |
| oversize = 1; |
| } |
| |
| oversize += (uint16_t)spirit_pktcommon_get_controllen(spirit); |
| |
| /* Reads the packet length registers */ |
| |
| spirit_reg_read(spirit, PCKTLEN1_BASE, regval, 2); |
| |
| /* Returns the packet length */ |
| |
| return ((((uint16_t) regval[0]) << 8) + (uint16_t) regval[1]) - oversize; |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_get_rxpktlen |
| * |
| * Description: |
| * Returns the packet length field of the received packet. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * |
| * Returned Value: |
| * Rx Packet length. |
| * |
| ******************************************************************************/ |
| |
| uint16_t spirit_pktbasic_get_rxpktlen(FAR struct spirit_library_s *spirit) |
| { |
| uint8_t regval[2]; |
| uint16_t oversize = 0; |
| |
| /* Computes the oversize (address + control) size */ |
| |
| if (spirit_pkbasic_isenabled_addrlen(spirit)) |
| { |
| oversize = 1; |
| } |
| |
| oversize += (uint16_t)spirit_pktcommon_get_controllen(spirit); |
| |
| /* Reads the RX_PCKT_LENx registers value */ |
| |
| spirit_reg_read(spirit, RX_PCKT_LEN1_BASE, regval, 2); |
| |
| /* Rebuild and return the length field */ |
| |
| return (((((uint16_t) regval[0]) << 8) + (uint16_t)regval[1]) - oversize); |
| } |
| |
| /****************************************************************************** |
| * Name: spirit_pktbasic_set_varlen |
| * |
| * Description: |
| * Computes and sets the variable payload length for SPIRIT Basic packets. |
| * |
| * Input Parameters: |
| * spirit - Reference to a Spirit library state structure instance |
| * payloadlen - Payload length in bytes. |
| * txdestaddr - Enable or disable address field. |
| * ctrllen - Control length in bytes. |
| * |
| * Returned Value: |
| * Zero (OK) on success; a negated errno value is returned on any failure. |
| * |
| ******************************************************************************/ |
| |
| int spirit_pktbasic_set_varlen(FAR struct spirit_library_s *spirit, |
| uint16_t payloadlen, |
| enum spirit_functional_state_e txdestaddr, |
| enum pkt_ctrllen_e ctrllen) |
| { |
| uint32_t pktlen; |
| uint8_t regval; |
| uint8_t addrlen; |
| int ret; |
| int i; |
| |
| /* Sets the address length according to txdestaddr */ |
| |
| if (txdestaddr == S_ENABLE) |
| { |
| addrlen = 1; |
| } |
| else |
| { |
| addrlen = 0; |
| } |
| |
| /* packet length = payload length + address length + control length */ |
| |
| pktlen = payloadlen + addrlen + ctrllen; |
| |
| /* Computes the number of bits */ |
| |
| for (i = 0; i < 16; i++) |
| { |
| if (pktlen == 0) |
| { |
| break; |
| } |
| |
| pktlen >>= 1; |
| } |
| |
| if (i == 0) |
| { |
| i = 1; |
| } |
| |
| /* Reads the PCKTCTRL3 register value */ |
| |
| ret = spirit_reg_read(spirit, PCKTCTRL3_BASE, ®val, 1); |
| if (ret >= 0) |
| { |
| /* Build value for the length width */ |
| |
| regval &= ~PCKTCTRL3_LEN_WID_MASK; |
| regval |= (uint8_t)(i - 1); |
| |
| /* Write to the PCKTCTRL3 register value */ |
| |
| ret = spirit_reg_write(spirit, PCKTCTRL3_BASE, ®val, 1); |
| } |
| |
| return ret; |
| } |