/* * Copyright (C) 2021-23 Texas Instruments Incorporated * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Texas Instruments Incorporated 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 * OWNER 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. */ #ifndef ENDAT_DRV_H_ #define ENDAT_DRV_H_ #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #define ENDAT_MODE_SINGLE_CHANNEL_SINGLE_PRU (0U) #define ENDAT_MODE_MULTI_CHANNEL_SINGLE_PRU (1U) #define ENDAT_MODE_MULTI_CHANNEL_MULTI_PRU (2U) #define HWREG(x) \ (*((volatile uint32_t *)(x))) #define HWREGB(x) \ (*((volatile uint8_t *)(x))) #define HWREGH(x) \ (*((volatile uint16_t *)(x))) /*12 words */ #define MRS_CODE_PARAM_ENCODER_MANUFACTURER_PAGE0 0xA1 /*16 words */ #define MRS_CODE_PARAM_ENCODER_MANUFACTURER_PAGE1 0xA3 /*16 words*/ #define MRS_CODE_PARAM_ENCODER_MANUFACTURER_PAGE2 0xA5 /* Adjust 1-bit as we transmit early */ #define ENDAT_TX_30BITS (30 + 1) /*Adjust 1-bit as we transmit early */ #define ENDAT_TX_6BITS (6 + 1) #define ENDAT_RX_29BITS 29 /* For EnDat 2.1: encoder to send test values */ #define ENDAT_RX_46BITS 46 #define APP_ENDAT_WORD_0 0 #define APP_ENDAT_WORD_1 1 #define APP_ENDAT_WORD_2 2 #define APP_ENDAT_WORD_3 3 #define APP_ENDAT_WORD_4 4 #define APP_ENDAT_WORD_5 5 #define APP_ENDAT_WORD_6 6 #define APP_ENDAT_WORD_7 7 #define APP_ENDAT_WORD_8 8 #define APP_ENDAT_WORD_9 9 #define APP_ENDAT_WORD_10 10 #define APP_ENDAT_WORD_11 11 #define APP_ENDAT_WORD_12 12 #define APP_ENDAT_WORD_13 13 #define APP_ENDAT_WORD_14 14 #define APP_ENDAT_WORD_15 15 #define APP_ENDAT_WORD_16 16 #define APP_ENDAT_WORD_17 17 #define APP_ENDAT_WORD_18 18 #define APP_ENDAT_WORD_19 19 #define ENDAT_NUM_BITS_POSITION_CRC 5 #define ENDAT_NUM_BITS_F1 1 #define ENDAT_NUM_BITS_F2 1 #define ENDAT_NUM_BITS_PARAMETER 16 #define ENDAT_NUM_BITS_ADDRESS 8 #define EINVAL 1 struct endat_clk_cfg { uint16_t rx_div; uint16_t tx_div; uint16_t rx_en_cnt; uint16_t rx_div_attr; }; struct flags { uint32_t info1 : 1; uint32_t info2 : 1; }; struct id { uint32_t ascii; uint32_t binary; }; struct sn { uint32_t ascii_msb; uint32_t binary; uint32_t ascii_lsb; }; enum { linear, rotary }; struct endat_priv { int32_t pruicss_slicex; int32_t load_share; int32_t pos_res; int32_t single_turn_res; int32_t multi_turn_res; int32_t step; uint32_t pos_rx_bits_21_RTUPRU; uint32_t pos_rx_bits_21_PRU; uint32_t pos_rx_bits_21_TXPRU; uint32_t pos_rx_bits_22_RTUPRU; uint32_t pos_rx_bits_22_PRU; uint32_t pos_rx_bits_22_TXPRU; struct flags flags; struct id id; struct sn sn; uint32_t cmd_set_2_2; int32_t type; int32_t raw_data; int32_t channel; uint16_t rx_en_cnt; struct endat_pruss_xchg *pruss_xchg; int32_t has_safety; void *pruss_cfg; void *pruss_iep; uint64_t cmp3; uint64_t cmp5; uint64_t cmp6; }; struct cmd_supplement { /* * uint8_t is ideal for address, but as scanf(%x) is done, * there could be side effects as other fields may get corrupted, * though it is not much of an issue as address is ensured to be * less than 0xff. But to be on safer side keep it unsigned, * same applies to block also */ uint32_t address; uint32_t data; uint32_t block; uint8_t has_block_address; uint32_t frequency; uint64_t cmp3; uint64_t cmp5; uint64_t cmp6; }; struct endat_data { /* position */ uint64_t recvd1; /* addinfo 1/2 */ uint32_t recvd2; /* addinfo 1 */ uint32_t recvd3; }; struct endat_position { uint64_t position; uint64_t revolution; uint8_t f1; uint8_t f2; uint8_t crc; }; struct endat_addinfo { uint32_t addinfo; uint8_t crc; }; struct endat_position_addinfo { struct endat_position position; struct endat_addinfo addinfo1, addinfo2; }; struct endat_addr_params { uint8_t address; uint16_t params; uint8_t crc; }; struct endat_test_values { uint64_t value; uint8_t f1; uint8_t crc; }; union endat_format_data { struct endat_position_addinfo position_addinfo; struct endat_addr_params addr_params; struct endat_test_values test; }; #define VALID_2_1_CMD(x) (((x) == 1) || ((x) == 2) || ((x) == 3) || ((x) == 4) || ((x) == 5) || ((x) == 6) || ((x) == 7) ) #define VALID_2_2_CMD(x) (((x) == 8) || ((x) == 9) || ((x) == 10) || ((x) == 11) || ((x) == 12) || ((x) == 13) || ((x) == 14)) #define ENDAT_NUM_ADDITIONAL_INFO_DUMMY_BIT 1 #define ENDAT_NUM_BYTES_ADDITIONAL_INFO 3 #define ENDAT_STATUS_WARN_SHIFT 7 #define ENDAT_STATUS_RM_SHIFT 6 #define ENDAT_STATUS_BUSY_SHIFT 5 #define ENDAT_STATUS_WARN_MASK (1 << ENDAT_STATUS_WARN_SHIFT) #define ENDAT_STATUS_RM_MASK (1 << ENDAT_STATUS_RM_SHIFT) #define ENDAT_STATUS_BUSY_MASK (1 << ENDAT_STATUS_BUSY_SHIFT) #define ENDAT_INFORMATION_MASK 0x1f #define ENDAT_21_F1_SHIFT 31 #define ENDAT_21_F1_MASK (1 << ENDAT_21_F1_SHIFT) #define ENDAT_22_F1_SHIFT ENDAT_21_F1_SHIFT #define ENDAT_22_F1_MASK (1 << ENDAT_22_F1_SHIFT) #define ENDAT_F2_SHIFT 30 #define ENDAT_F2_MASK (1 << ENDAT_F2_SHIFT) #define ENDAT_ADDITIONAL_INFO_RX_BITS 30 #define ENDAT_SECTION2_MEMORY 0xBF #define ENDAT_NUM_BITS_VALID_PAGE0_WORD13 6 #define ENDAT_NUM_BITS_VALID_PAGE1_WORD1 16 #define ENDAT_MRS_SHIFT_C7_C4 (4) #define ENDAT_MRS_VAL_C7_C4_SELECT_ADDITIONAL_INFO1 (0x4) #define ENDAT_MRS_VAL_C7_C4_SELECT_ADDITIONAL_INFO2 (0x5) #define ENDAT_MRS_MASK_SELECT_ADDITIONAL_INFO (0xF << ENDAT_MRS_SHIFT_C7_C4) #define ENDAT_MRS_VAL_STOP_ADDITIONAL_INFO (0xF) #define ENDAT_MRS_MASK_STOP_ADDITIONAL_INFO (ENDAT_MRS_VAL_STOP_ADDITIONAL_INFO) #define ENDAT_GET_POS_MULTI_TURN(pos, priv) (((pos) & (((unsigned long long) 1 << (priv)->pos_res) - 1)) >> (priv)->single_turn_res) #define ENDAT_GET_POS_SINGLE_TURN(pos, priv) ((pos) & (((unsigned long long) 1 << (priv)->single_turn_res) - 1)) #include "endat_api.h" #ifdef __cplusplus } #endif #endif