t

Fork of mbed-dev by mbed official

Committer:
amithy
Date:
Thu Nov 09 22:14:37 2017 +0000
Revision:
178:c26431f84b0d
Parent:
150:02e0a0aed4ec
test export

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 150:02e0a0aed4ec 1 /**
<> 150:02e0a0aed4ec 2 * @file owm.c
<> 150:02e0a0aed4ec 3 * @brief 1-Wire Master (OWM) API Function Implementations.
<> 150:02e0a0aed4ec 4 */
<> 150:02e0a0aed4ec 5 /* *****************************************************************************
<> 150:02e0a0aed4ec 6 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
<> 150:02e0a0aed4ec 7 *
<> 150:02e0a0aed4ec 8 * Permission is hereby granted, free of charge, to any person obtaining a
<> 150:02e0a0aed4ec 9 * copy of this software and associated documentation files (the "Software"),
<> 150:02e0a0aed4ec 10 * to deal in the Software without restriction, including without limitation
<> 150:02e0a0aed4ec 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
<> 150:02e0a0aed4ec 12 * and/or sell copies of the Software, and to permit persons to whom the
<> 150:02e0a0aed4ec 13 * Software is furnished to do so, subject to the following conditions:
<> 150:02e0a0aed4ec 14 *
<> 150:02e0a0aed4ec 15 * The above copyright notice and this permission notice shall be included
<> 150:02e0a0aed4ec 16 * in all copies or substantial portions of the Software.
<> 150:02e0a0aed4ec 17 *
<> 150:02e0a0aed4ec 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
<> 150:02e0a0aed4ec 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
<> 150:02e0a0aed4ec 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
<> 150:02e0a0aed4ec 21 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
<> 150:02e0a0aed4ec 22 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
<> 150:02e0a0aed4ec 23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
<> 150:02e0a0aed4ec 24 * OTHER DEALINGS IN THE SOFTWARE.
<> 150:02e0a0aed4ec 25 *
<> 150:02e0a0aed4ec 26 * Except as contained in this notice, the name of Maxim Integrated
<> 150:02e0a0aed4ec 27 * Products, Inc. shall not be used except as stated in the Maxim Integrated
<> 150:02e0a0aed4ec 28 * Products, Inc. Branding Policy.
<> 150:02e0a0aed4ec 29 *
<> 150:02e0a0aed4ec 30 * The mere transfer of this software does not imply any licenses
<> 150:02e0a0aed4ec 31 * of trade secrets, proprietary technology, copyrights, patents,
<> 150:02e0a0aed4ec 32 * trademarks, maskwork rights, or any other form of intellectual
<> 150:02e0a0aed4ec 33 * property whatsoever. Maxim Integrated Products, Inc. retains all
<> 150:02e0a0aed4ec 34 * ownership rights.
<> 150:02e0a0aed4ec 35 *
<> 150:02e0a0aed4ec 36 * $Date: 2016-03-14 10:08:53 -0500 (Mon, 14 Mar 2016) $
<> 150:02e0a0aed4ec 37 * $Revision: 21855 $
<> 150:02e0a0aed4ec 38 *
<> 150:02e0a0aed4ec 39 **************************************************************************** */
<> 150:02e0a0aed4ec 40
<> 150:02e0a0aed4ec 41 /* **** Includes **** */
<> 150:02e0a0aed4ec 42 #include <string.h>
<> 150:02e0a0aed4ec 43 #include "mxc_assert.h"
<> 150:02e0a0aed4ec 44 #include "mxc_sys.h"
<> 150:02e0a0aed4ec 45 #include "owm.h"
<> 150:02e0a0aed4ec 46
<> 150:02e0a0aed4ec 47 /**
<> 150:02e0a0aed4ec 48 * @ingroup owm
<> 150:02e0a0aed4ec 49 * @{
<> 150:02e0a0aed4ec 50 */
<> 150:02e0a0aed4ec 51 ///@cond
<> 150:02e0a0aed4ec 52 /* **** Definitions **** */
<> 150:02e0a0aed4ec 53 #define OWM_CLK_FREQ 1000000 //1-Wire requires 1MHz clock
<> 150:02e0a0aed4ec 54
<> 150:02e0a0aed4ec 55 /* **** Globals **** */
<> 150:02e0a0aed4ec 56 int LastDiscrepancy;
<> 150:02e0a0aed4ec 57 int LastDeviceFlag;
<> 150:02e0a0aed4ec 58
<> 150:02e0a0aed4ec 59 /* **** Functions **** */
<> 150:02e0a0aed4ec 60 static uint8_t CalculateCRC8(uint8_t* data, int len);
<> 150:02e0a0aed4ec 61 static uint8_t update_crc8(uint8_t crc, uint8_t value);
<> 150:02e0a0aed4ec 62 ///@endcond
<> 150:02e0a0aed4ec 63
<> 150:02e0a0aed4ec 64
<> 150:02e0a0aed4ec 65 /* ************************************************************************* */
<> 150:02e0a0aed4ec 66 int OWM_Init(mxc_owm_regs_t *owm, const owm_cfg_t *cfg, const sys_cfg_owm_t *sys_cfg)
<> 150:02e0a0aed4ec 67 {
<> 150:02e0a0aed4ec 68 int err = 0;
<> 150:02e0a0aed4ec 69 uint32_t owm_clk, clk_div = 0;
<> 150:02e0a0aed4ec 70 uint32_t ext_pu_mode = 0;
<> 150:02e0a0aed4ec 71 uint32_t ext_pu_polarity = 0;
<> 150:02e0a0aed4ec 72
<> 150:02e0a0aed4ec 73 // Check the OWM register pointer is valid
<> 150:02e0a0aed4ec 74 MXC_ASSERT(MXC_OWM_GET_IDX(owm) >= 0);
<> 150:02e0a0aed4ec 75
<> 150:02e0a0aed4ec 76 if(cfg == NULL) {
<> 150:02e0a0aed4ec 77 return E_NULL_PTR;
<> 150:02e0a0aed4ec 78 }
<> 150:02e0a0aed4ec 79
<> 150:02e0a0aed4ec 80 // Set system level configurations
<> 150:02e0a0aed4ec 81 if ((err = SYS_OWM_Init(owm, sys_cfg)) != E_NO_ERROR) {
<> 150:02e0a0aed4ec 82 return err;
<> 150:02e0a0aed4ec 83 }
<> 150:02e0a0aed4ec 84
<> 150:02e0a0aed4ec 85 // Configure clk divisor to get 1MHz OWM clk
<> 150:02e0a0aed4ec 86 owm_clk = SYS_OWM_GetFreq(owm);
<> 150:02e0a0aed4ec 87
<> 150:02e0a0aed4ec 88 if(owm_clk == 0) {
<> 150:02e0a0aed4ec 89 return E_UNINITIALIZED;
<> 150:02e0a0aed4ec 90 }
<> 150:02e0a0aed4ec 91
<> 150:02e0a0aed4ec 92 // Return error if clk doesn't divide evenly to 1MHz
<> 150:02e0a0aed4ec 93 if(owm_clk % OWM_CLK_FREQ) {
<> 150:02e0a0aed4ec 94 return E_NOT_SUPPORTED;
<> 150:02e0a0aed4ec 95 }
<> 150:02e0a0aed4ec 96
<> 150:02e0a0aed4ec 97 clk_div = (owm_clk / (OWM_CLK_FREQ));
<> 150:02e0a0aed4ec 98
<> 150:02e0a0aed4ec 99 // Can not support lower frequencies
<> 150:02e0a0aed4ec 100 if(clk_div == 0) {
<> 150:02e0a0aed4ec 101 return E_NOT_SUPPORTED;
<> 150:02e0a0aed4ec 102 }
<> 150:02e0a0aed4ec 103
<> 150:02e0a0aed4ec 104 // Select the PU mode and polarity based on cfg input
<> 150:02e0a0aed4ec 105 switch(cfg->ext_pu_mode) {
<> 150:02e0a0aed4ec 106 case OWM_EXT_PU_ACT_HIGH:
<> 150:02e0a0aed4ec 107 ext_pu_mode = MXC_V_OWM_CFG_EXT_PULLUP_MODE_USED;
<> 150:02e0a0aed4ec 108 ext_pu_polarity = MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_HIGH;
<> 150:02e0a0aed4ec 109 break;
<> 150:02e0a0aed4ec 110 case OWM_EXT_PU_ACT_LOW:
<> 150:02e0a0aed4ec 111 ext_pu_mode = MXC_V_OWM_CFG_EXT_PULLUP_MODE_USED;
<> 150:02e0a0aed4ec 112 ext_pu_polarity = MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_LOW;
<> 150:02e0a0aed4ec 113 break;
<> 150:02e0a0aed4ec 114 case OWM_EXT_PU_UNUSED:
<> 150:02e0a0aed4ec 115 ext_pu_mode = MXC_V_OWM_CFG_EXT_PULLUP_MODE_UNUSED;
<> 150:02e0a0aed4ec 116 ext_pu_polarity = MXC_V_OWM_CTRL_STAT_EXT_PULLUP_POL_ACT_HIGH;
<> 150:02e0a0aed4ec 117 break;
<> 150:02e0a0aed4ec 118 default:
<> 150:02e0a0aed4ec 119 return E_BAD_PARAM;
<> 150:02e0a0aed4ec 120 }
<> 150:02e0a0aed4ec 121
<> 150:02e0a0aed4ec 122 // Set clk divisor
<> 150:02e0a0aed4ec 123 owm->clk_div_1us = (clk_div << MXC_F_OWM_CLK_DIV_1US_DIVISOR_POS) & MXC_F_OWM_CLK_DIV_1US_DIVISOR;
<> 150:02e0a0aed4ec 124
<> 150:02e0a0aed4ec 125 // Set configuration
<> 150:02e0a0aed4ec 126 owm->cfg = (((cfg->int_pu_en << MXC_F_OWM_CFG_INT_PULLUP_ENABLE_POS) & MXC_F_OWM_CFG_INT_PULLUP_ENABLE) |
<> 150:02e0a0aed4ec 127 ((ext_pu_mode << MXC_F_OWM_CFG_EXT_PULLUP_MODE_POS) & MXC_F_OWM_CFG_EXT_PULLUP_MODE) |
<> 150:02e0a0aed4ec 128 ((cfg->long_line_mode << MXC_F_OWM_CFG_LONG_LINE_MODE) & MXC_F_OWM_CFG_LONG_LINE_MODE_POS));
<> 150:02e0a0aed4ec 129
<> 150:02e0a0aed4ec 130 owm->ctrl_stat = (((ext_pu_polarity << MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL_POS) & MXC_F_OWM_CTRL_STAT_EXT_PULLUP_POL) |
<> 150:02e0a0aed4ec 131 ((cfg->overdrive_spec << MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE_POS) & MXC_F_OWM_CTRL_STAT_OD_SPEC_MODE));
<> 150:02e0a0aed4ec 132
<> 150:02e0a0aed4ec 133 // Clear all interrupt flags
<> 150:02e0a0aed4ec 134 owm->intfl = owm->intfl;
<> 150:02e0a0aed4ec 135
<> 150:02e0a0aed4ec 136 return E_NO_ERROR;
<> 150:02e0a0aed4ec 137 }
<> 150:02e0a0aed4ec 138
<> 150:02e0a0aed4ec 139 /* ************************************************************************* */
<> 150:02e0a0aed4ec 140 int OWM_Shutdown(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 141 {
<> 150:02e0a0aed4ec 142 int err;
<> 150:02e0a0aed4ec 143
<> 150:02e0a0aed4ec 144 // Disable and clear interrupts
<> 150:02e0a0aed4ec 145 owm->inten = 0;
<> 150:02e0a0aed4ec 146 owm->intfl = owm->intfl;
<> 150:02e0a0aed4ec 147
<> 150:02e0a0aed4ec 148 // Release IO pins and disable clk
<> 150:02e0a0aed4ec 149 if ((err = SYS_OWM_Shutdown(owm)) != E_NO_ERROR) {
<> 150:02e0a0aed4ec 150 return err;
<> 150:02e0a0aed4ec 151 }
<> 150:02e0a0aed4ec 152
<> 150:02e0a0aed4ec 153 return E_NO_ERROR;
<> 150:02e0a0aed4ec 154 }
<> 150:02e0a0aed4ec 155
<> 150:02e0a0aed4ec 156 /* ************************************************************************* */
<> 150:02e0a0aed4ec 157 int OWM_Reset(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 158 {
<> 150:02e0a0aed4ec 159 owm->intfl = MXC_F_OWM_INTFL_OW_RESET_DONE; // Clear the reset flag
<> 150:02e0a0aed4ec 160 owm->ctrl_stat |= MXC_F_OWM_CTRL_STAT_START_OW_RESET; // Generate a reset pulse
<> 150:02e0a0aed4ec 161 while((owm->intfl & MXC_F_OWM_INTFL_OW_RESET_DONE) == 0); // Wait for reset time slot to complete
<> 150:02e0a0aed4ec 162
<> 150:02e0a0aed4ec 163 return (!!(owm->ctrl_stat & MXC_F_OWM_CTRL_STAT_PRESENCE_DETECT)); // Return presence pulse detect status
<> 150:02e0a0aed4ec 164 }
<> 150:02e0a0aed4ec 165
<> 150:02e0a0aed4ec 166 /* ************************************************************************* */
<> 150:02e0a0aed4ec 167 int OWM_TouchByte(mxc_owm_regs_t *owm, uint8_t data)
<> 150:02e0a0aed4ec 168 {
<> 150:02e0a0aed4ec 169 owm->cfg &= ~MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode
<> 150:02e0a0aed4ec 170 owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY); // Clear the flags
<> 150:02e0a0aed4ec 171 owm->data = (data << MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; // Write data
<> 150:02e0a0aed4ec 172 while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent
<> 150:02e0a0aed4ec 173 while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read
<> 150:02e0a0aed4ec 174
<> 150:02e0a0aed4ec 175 return (owm->data >> MXC_F_OWM_DATA_TX_RX_POS) & 0xFF; // Return the data read
<> 150:02e0a0aed4ec 176 }
<> 150:02e0a0aed4ec 177
<> 150:02e0a0aed4ec 178 /* ************************************************************************* */
<> 150:02e0a0aed4ec 179 int OWM_WriteByte(mxc_owm_regs_t *owm, uint8_t data)
<> 150:02e0a0aed4ec 180 {
<> 150:02e0a0aed4ec 181 // Send one byte of data and verify the data sent = data parameter
<> 150:02e0a0aed4ec 182 return (OWM_TouchByte(owm, data) == data) ? E_NO_ERROR : E_COMM_ERR;
<> 150:02e0a0aed4ec 183 }
<> 150:02e0a0aed4ec 184
<> 150:02e0a0aed4ec 185 /* ************************************************************************* */
<> 150:02e0a0aed4ec 186 int OWM_ReadByte(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 187 {
<> 150:02e0a0aed4ec 188 // Read one byte of data
<> 150:02e0a0aed4ec 189 return OWM_TouchByte(owm, 0xFF);
<> 150:02e0a0aed4ec 190 }
<> 150:02e0a0aed4ec 191
<> 150:02e0a0aed4ec 192 /* ************************************************************************* */
<> 150:02e0a0aed4ec 193 int OWM_TouchBit(mxc_owm_regs_t *owm, uint8_t bit)
<> 150:02e0a0aed4ec 194 {
<> 150:02e0a0aed4ec 195 MXC_OWM->cfg |= MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 1 bit mode
<> 150:02e0a0aed4ec 196 owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY); // Clear the flags
<> 150:02e0a0aed4ec 197 owm->data = (bit << MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; // Write data
<> 150:02e0a0aed4ec 198 while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent
<> 150:02e0a0aed4ec 199 while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read
<> 150:02e0a0aed4ec 200
<> 150:02e0a0aed4ec 201 return (owm->data >> MXC_F_OWM_DATA_TX_RX_POS) & 0x1; // Return the bit read
<> 150:02e0a0aed4ec 202 }
<> 150:02e0a0aed4ec 203
<> 150:02e0a0aed4ec 204 /* ************************************************************************* */
<> 150:02e0a0aed4ec 205 int OWM_WriteBit(mxc_owm_regs_t *owm, uint8_t bit)
<> 150:02e0a0aed4ec 206 {
<> 150:02e0a0aed4ec 207 // Send a bit and verify the bit sent = bit parameter
<> 150:02e0a0aed4ec 208 return (OWM_TouchBit(owm, bit) == bit) ? E_NO_ERROR : E_COMM_ERR;
<> 150:02e0a0aed4ec 209 }
<> 150:02e0a0aed4ec 210
<> 150:02e0a0aed4ec 211 /* ************************************************************************* */
<> 150:02e0a0aed4ec 212 int OWM_ReadBit(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 213 {
<> 150:02e0a0aed4ec 214 // Read a bit
<> 150:02e0a0aed4ec 215 return OWM_TouchBit(owm, 1);
<> 150:02e0a0aed4ec 216 }
<> 150:02e0a0aed4ec 217
<> 150:02e0a0aed4ec 218 /* ************************************************************************* */
<> 150:02e0a0aed4ec 219 int OWM_Write(mxc_owm_regs_t *owm, uint8_t* data, int len)
<> 150:02e0a0aed4ec 220 {
<> 150:02e0a0aed4ec 221 int num = 0;
<> 150:02e0a0aed4ec 222
<> 150:02e0a0aed4ec 223 owm->cfg &= ~MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode
<> 150:02e0a0aed4ec 224
<> 150:02e0a0aed4ec 225 while(num < len) { // Loop for number of bytes to write
<> 150:02e0a0aed4ec 226 owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY | MXC_F_OWM_INTEN_LINE_SHORT); // Clear the flags
<> 150:02e0a0aed4ec 227 owm->data = (data[num] << MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX; // Write data
<> 150:02e0a0aed4ec 228 while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent
<> 150:02e0a0aed4ec 229 while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read
<> 150:02e0a0aed4ec 230
<> 150:02e0a0aed4ec 231 // Verify data sent is correct
<> 150:02e0a0aed4ec 232 if(owm->data != data[num]) {
<> 150:02e0a0aed4ec 233 return E_COMM_ERR;
<> 150:02e0a0aed4ec 234 }
<> 150:02e0a0aed4ec 235
<> 150:02e0a0aed4ec 236 // Check error flag
<> 150:02e0a0aed4ec 237 if(owm->intfl & MXC_F_OWM_INTEN_LINE_SHORT) {
<> 150:02e0a0aed4ec 238 return E_COMM_ERR; // Wire was low before transaction
<> 150:02e0a0aed4ec 239 }
<> 150:02e0a0aed4ec 240
<> 150:02e0a0aed4ec 241 num++; // Keep track of how many bytes written
<> 150:02e0a0aed4ec 242 }
<> 150:02e0a0aed4ec 243
<> 150:02e0a0aed4ec 244 return num; // Return number of bytes written
<> 150:02e0a0aed4ec 245 }
<> 150:02e0a0aed4ec 246
<> 150:02e0a0aed4ec 247 /* ************************************************************************* */
<> 150:02e0a0aed4ec 248 int OWM_Read(mxc_owm_regs_t *owm, uint8_t* data, int len)
<> 150:02e0a0aed4ec 249 {
<> 150:02e0a0aed4ec 250 int num = 0;
<> 150:02e0a0aed4ec 251
<> 150:02e0a0aed4ec 252 owm->cfg &= ~MXC_F_OWM_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode
<> 150:02e0a0aed4ec 253
<> 150:02e0a0aed4ec 254 while(num < len) { // Loop for number of bytes to read
<> 150:02e0a0aed4ec 255 owm->intfl = (MXC_F_OWM_INTFL_TX_DATA_EMPTY | MXC_F_OWM_INTFL_RX_DATA_READY | MXC_F_OWM_INTEN_LINE_SHORT); // Clear the flags
<> 150:02e0a0aed4ec 256 owm->data = 0xFF; // Write 0xFF for a read
<> 150:02e0a0aed4ec 257 while((owm->intfl & MXC_F_OWM_INTFL_TX_DATA_EMPTY) == 0); // Wait for data to be sent
<> 150:02e0a0aed4ec 258 while((owm->intfl & MXC_F_OWM_INTFL_RX_DATA_READY) == 0); // Wait for data to be read
<> 150:02e0a0aed4ec 259
<> 150:02e0a0aed4ec 260 // Check error flag
<> 150:02e0a0aed4ec 261 if(owm->intfl & MXC_F_OWM_INTEN_LINE_SHORT) {
<> 150:02e0a0aed4ec 262 return E_COMM_ERR; // Wire was low before transaction
<> 150:02e0a0aed4ec 263 }
<> 150:02e0a0aed4ec 264
<> 150:02e0a0aed4ec 265 // Store read data into buffer
<> 150:02e0a0aed4ec 266 data[num] = (owm->data >> MXC_F_OWM_DATA_TX_RX_POS) & MXC_F_OWM_DATA_TX_RX;
<> 150:02e0a0aed4ec 267
<> 150:02e0a0aed4ec 268 num++; // Keep track of how many bytes read
<> 150:02e0a0aed4ec 269 }
<> 150:02e0a0aed4ec 270
<> 150:02e0a0aed4ec 271 return num; // Return number of bytes read
<> 150:02e0a0aed4ec 272 }
<> 150:02e0a0aed4ec 273
<> 150:02e0a0aed4ec 274 /* ************************************************************************* */
<> 150:02e0a0aed4ec 275 int OWM_ReadROM(mxc_owm_regs_t *owm, uint8_t* ROMCode)
<> 150:02e0a0aed4ec 276 {
<> 150:02e0a0aed4ec 277 int num_read = 0;
<> 150:02e0a0aed4ec 278
<> 150:02e0a0aed4ec 279 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 280 if(OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 281 // Send Read ROM command code
<> 150:02e0a0aed4ec 282 if(OWM_WriteByte(owm, READ_ROM_COMMAND) == E_NO_ERROR) {
<> 150:02e0a0aed4ec 283 // Read 8 bytes and store in buffer
<> 150:02e0a0aed4ec 284 num_read = OWM_Read(owm, ROMCode, 8);
<> 150:02e0a0aed4ec 285
<> 150:02e0a0aed4ec 286 // Check the number of bytes read
<> 150:02e0a0aed4ec 287 if(num_read != 8) {
<> 150:02e0a0aed4ec 288 return E_COMM_ERR;
<> 150:02e0a0aed4ec 289 }
<> 150:02e0a0aed4ec 290 } else {
<> 150:02e0a0aed4ec 291 // Write failed
<> 150:02e0a0aed4ec 292 return E_COMM_ERR;
<> 150:02e0a0aed4ec 293 }
<> 150:02e0a0aed4ec 294 } else {
<> 150:02e0a0aed4ec 295 // No presence pulse
<> 150:02e0a0aed4ec 296 return E_COMM_ERR;
<> 150:02e0a0aed4ec 297 }
<> 150:02e0a0aed4ec 298
<> 150:02e0a0aed4ec 299 return E_NO_ERROR;
<> 150:02e0a0aed4ec 300 }
<> 150:02e0a0aed4ec 301
<> 150:02e0a0aed4ec 302 /* ************************************************************************* */
<> 150:02e0a0aed4ec 303 int OWM_MatchROM(mxc_owm_regs_t *owm, uint8_t* ROMCode)
<> 150:02e0a0aed4ec 304 {
<> 150:02e0a0aed4ec 305 int num_wrote = 0;
<> 150:02e0a0aed4ec 306
<> 150:02e0a0aed4ec 307 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 308 if(OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 309 // Send match ROM command code
<> 150:02e0a0aed4ec 310 if(OWM_WriteByte(owm, MATCH_ROM_COMMAND) == E_NO_ERROR) {
<> 150:02e0a0aed4ec 311 // Write 8 bytes in ROMCode buffer
<> 150:02e0a0aed4ec 312 num_wrote = OWM_Write(owm, ROMCode, 8);
<> 150:02e0a0aed4ec 313
<> 150:02e0a0aed4ec 314 // Check the number of bytes written
<> 150:02e0a0aed4ec 315 if(num_wrote != 8) {
<> 150:02e0a0aed4ec 316 return E_COMM_ERR;
<> 150:02e0a0aed4ec 317 }
<> 150:02e0a0aed4ec 318 } else {
<> 150:02e0a0aed4ec 319 // Write failed
<> 150:02e0a0aed4ec 320 return E_COMM_ERR;
<> 150:02e0a0aed4ec 321 }
<> 150:02e0a0aed4ec 322 } else {
<> 150:02e0a0aed4ec 323 // No presence pulse
<> 150:02e0a0aed4ec 324 return E_COMM_ERR;
<> 150:02e0a0aed4ec 325 }
<> 150:02e0a0aed4ec 326
<> 150:02e0a0aed4ec 327 return E_NO_ERROR;
<> 150:02e0a0aed4ec 328 }
<> 150:02e0a0aed4ec 329
<> 150:02e0a0aed4ec 330 /* ************************************************************************* */
<> 150:02e0a0aed4ec 331 int OWM_ODMatchROM(mxc_owm_regs_t *owm, uint8_t* ROMCode)
<> 150:02e0a0aed4ec 332 {
<> 150:02e0a0aed4ec 333 int num_wrote = 0;
<> 150:02e0a0aed4ec 334
<> 150:02e0a0aed4ec 335 // Set to standard speed
<> 150:02e0a0aed4ec 336 owm->cfg &= ~(MXC_F_OWM_CFG_OVERDRIVE);
<> 150:02e0a0aed4ec 337
<> 150:02e0a0aed4ec 338 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 339 if(OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 340 // Send Overdrive match ROM command code
<> 150:02e0a0aed4ec 341 if(OWM_WriteByte(owm, OD_MATCH_ROM_COMMAND) == E_NO_ERROR) {
<> 150:02e0a0aed4ec 342 // Set overdrive
<> 150:02e0a0aed4ec 343 owm->cfg |= MXC_F_OWM_CFG_OVERDRIVE;
<> 150:02e0a0aed4ec 344
<> 150:02e0a0aed4ec 345 // Write 8 bytes in ROMCode buffer
<> 150:02e0a0aed4ec 346 num_wrote = OWM_Write(owm, ROMCode, 8);
<> 150:02e0a0aed4ec 347
<> 150:02e0a0aed4ec 348 // Check the number of bytes written
<> 150:02e0a0aed4ec 349 if(num_wrote != 8) {
<> 150:02e0a0aed4ec 350 return E_COMM_ERR;
<> 150:02e0a0aed4ec 351 }
<> 150:02e0a0aed4ec 352 } else {
<> 150:02e0a0aed4ec 353 // Write failed
<> 150:02e0a0aed4ec 354 return E_COMM_ERR;
<> 150:02e0a0aed4ec 355 }
<> 150:02e0a0aed4ec 356 } else {
<> 150:02e0a0aed4ec 357 // No presence pulse
<> 150:02e0a0aed4ec 358 return E_COMM_ERR;
<> 150:02e0a0aed4ec 359 }
<> 150:02e0a0aed4ec 360
<> 150:02e0a0aed4ec 361 return E_NO_ERROR;
<> 150:02e0a0aed4ec 362 }
<> 150:02e0a0aed4ec 363
<> 150:02e0a0aed4ec 364 /* ************************************************************************* */
<> 150:02e0a0aed4ec 365 int OWM_SkipROM(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 366 {
<> 150:02e0a0aed4ec 367 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 368 if(OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 369 // Send skip ROM command code
<> 150:02e0a0aed4ec 370 return OWM_WriteByte(owm, SKIP_ROM_COMMAND);
<> 150:02e0a0aed4ec 371 } else {
<> 150:02e0a0aed4ec 372 // No presence pulse
<> 150:02e0a0aed4ec 373 return E_COMM_ERR;
<> 150:02e0a0aed4ec 374 }
<> 150:02e0a0aed4ec 375 }
<> 150:02e0a0aed4ec 376
<> 150:02e0a0aed4ec 377 /* ************************************************************************* */
<> 150:02e0a0aed4ec 378 int OWM_ODSkipROM(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 379 {
<> 150:02e0a0aed4ec 380 // Set to standard speed
<> 150:02e0a0aed4ec 381 owm->cfg &= ~(MXC_F_OWM_CFG_OVERDRIVE);
<> 150:02e0a0aed4ec 382
<> 150:02e0a0aed4ec 383 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 384 if(OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 385 // Send Overdrive skip ROM command code
<> 150:02e0a0aed4ec 386 if(OWM_WriteByte(owm, OD_SKIP_ROM_COMMAND) == E_NO_ERROR) {
<> 150:02e0a0aed4ec 387 // Set overdrive speed
<> 150:02e0a0aed4ec 388 owm->cfg |= MXC_F_OWM_CFG_OVERDRIVE;
<> 150:02e0a0aed4ec 389
<> 150:02e0a0aed4ec 390 return E_NO_ERROR;
<> 150:02e0a0aed4ec 391 } else {
<> 150:02e0a0aed4ec 392 // Write failed
<> 150:02e0a0aed4ec 393 return E_COMM_ERR;
<> 150:02e0a0aed4ec 394 }
<> 150:02e0a0aed4ec 395 } else {
<> 150:02e0a0aed4ec 396 // No presence pulse
<> 150:02e0a0aed4ec 397 return E_COMM_ERR;
<> 150:02e0a0aed4ec 398 }
<> 150:02e0a0aed4ec 399 }
<> 150:02e0a0aed4ec 400
<> 150:02e0a0aed4ec 401 /* ************************************************************************* */
<> 150:02e0a0aed4ec 402 int OWM_Resume(mxc_owm_regs_t *owm)
<> 150:02e0a0aed4ec 403 {
<> 150:02e0a0aed4ec 404 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 405 if(OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 406 // Send resume command code
<> 150:02e0a0aed4ec 407 return OWM_WriteByte(owm, RESUME_COMMAND);
<> 150:02e0a0aed4ec 408 } else {
<> 150:02e0a0aed4ec 409 // No presence pulse
<> 150:02e0a0aed4ec 410 return E_COMM_ERR;
<> 150:02e0a0aed4ec 411 }
<> 150:02e0a0aed4ec 412 }
<> 150:02e0a0aed4ec 413
<> 150:02e0a0aed4ec 414 /* ************************************************************************* */
<> 150:02e0a0aed4ec 415 int OWM_SearchROM(mxc_owm_regs_t *owm, int newSearch, uint8_t* ROMCode)
<> 150:02e0a0aed4ec 416 {
<> 150:02e0a0aed4ec 417 int nibble_start_bit = 1;
<> 150:02e0a0aed4ec 418 int rom_byte_number = 0;
<> 150:02e0a0aed4ec 419 uint8_t rom_nibble_mask = 0x0F;
<> 150:02e0a0aed4ec 420 uint8_t search_direction = 0;
<> 150:02e0a0aed4ec 421 int readValue = 0;
<> 150:02e0a0aed4ec 422 int sentBits = 0;
<> 150:02e0a0aed4ec 423 int discrepancy = 0;
<> 150:02e0a0aed4ec 424 int bit_position = 0;
<> 150:02e0a0aed4ec 425 int discrepancy_mask = 0;
<> 150:02e0a0aed4ec 426 int last_zero = 0;
<> 150:02e0a0aed4ec 427 uint8_t crc8 = 0;
<> 150:02e0a0aed4ec 428 int search_result = 0;
<> 150:02e0a0aed4ec 429
<> 150:02e0a0aed4ec 430 // Clear ROM array
<> 150:02e0a0aed4ec 431 memset(ROMCode, 0x0, 8);
<> 150:02e0a0aed4ec 432
<> 150:02e0a0aed4ec 433 if(newSearch) {
<> 150:02e0a0aed4ec 434 // Reset all global variables to start search from begining
<> 150:02e0a0aed4ec 435 LastDiscrepancy = 0;
<> 150:02e0a0aed4ec 436 LastDeviceFlag = 0;
<> 150:02e0a0aed4ec 437 }
<> 150:02e0a0aed4ec 438
<> 150:02e0a0aed4ec 439 // Check if the last call was the last device
<> 150:02e0a0aed4ec 440 if(LastDeviceFlag) {
<> 150:02e0a0aed4ec 441 // Reset the search
<> 150:02e0a0aed4ec 442 LastDiscrepancy = 0;
<> 150:02e0a0aed4ec 443 LastDeviceFlag = 0;
<> 150:02e0a0aed4ec 444 return 0;
<> 150:02e0a0aed4ec 445 }
<> 150:02e0a0aed4ec 446
<> 150:02e0a0aed4ec 447 // Send reset and wait for presence pulse
<> 150:02e0a0aed4ec 448 if (OWM_Reset(owm)) {
<> 150:02e0a0aed4ec 449 // Send the search command
<> 150:02e0a0aed4ec 450 OWM_WriteByte(owm, SEARCH_ROM_COMMAND);
<> 150:02e0a0aed4ec 451
<> 150:02e0a0aed4ec 452 // Set search ROM accelerator bit
<> 150:02e0a0aed4ec 453 owm->ctrl_stat |= MXC_F_OWM_CTRL_STAT_SRA_MODE;
<> 150:02e0a0aed4ec 454
<> 150:02e0a0aed4ec 455 // Loop until through all ROM bytes 0-7 (this loops 2 times per byte)
<> 150:02e0a0aed4ec 456 while(rom_byte_number < 8) {
<> 150:02e0a0aed4ec 457 // Each loop finds the discrepancy bits and finds 4 bits (nibble) of the ROM
<> 150:02e0a0aed4ec 458
<> 150:02e0a0aed4ec 459 // Set the search direction the same as last time for the nibble masked
<> 150:02e0a0aed4ec 460 search_direction = ROMCode[rom_byte_number] & rom_nibble_mask;
<> 150:02e0a0aed4ec 461
<> 150:02e0a0aed4ec 462 // If the upper nibble is the mask then shift bits to lower nibble
<> 150:02e0a0aed4ec 463 if(rom_nibble_mask > 0x0F) {
<> 150:02e0a0aed4ec 464 search_direction = search_direction >> 4;
<> 150:02e0a0aed4ec 465 }
<> 150:02e0a0aed4ec 466
<> 150:02e0a0aed4ec 467 // Get the last discrepancy bit position relative to the nibble start bit
<> 150:02e0a0aed4ec 468 bit_position = LastDiscrepancy - nibble_start_bit;
<> 150:02e0a0aed4ec 469
<> 150:02e0a0aed4ec 470 // Check if last discrepancy is witin this nibble
<> 150:02e0a0aed4ec 471 if( (bit_position >= 0) && (bit_position < 4) ) {
<> 150:02e0a0aed4ec 472 // Last discrepancy is within this nibble
<> 150:02e0a0aed4ec 473 // Set the bit of the last discrepancy bit
<> 150:02e0a0aed4ec 474 search_direction |= (1 << (bit_position));
<> 150:02e0a0aed4ec 475 }
<> 150:02e0a0aed4ec 476
<> 150:02e0a0aed4ec 477 // Performs two read bits and a write bit for 4 bits of the ROM
<> 150:02e0a0aed4ec 478 readValue = OWM_TouchByte(owm, search_direction);
<> 150:02e0a0aed4ec 479 // Get discrepancy flags
<> 150:02e0a0aed4ec 480 discrepancy = readValue & 0xF;
<> 150:02e0a0aed4ec 481 // Get the 4 bits sent to select the ROM
<> 150:02e0a0aed4ec 482 sentBits = (readValue >> 4) & 0xF;
<> 150:02e0a0aed4ec 483
<> 150:02e0a0aed4ec 484 // Store the bit location of the MSB discrepancy with sentbit = 0
<> 150:02e0a0aed4ec 485 if(discrepancy) {
<> 150:02e0a0aed4ec 486 // Initialize bit_position to MSB of nibble
<> 150:02e0a0aed4ec 487 bit_position = 3;
<> 150:02e0a0aed4ec 488
<> 150:02e0a0aed4ec 489 while(bit_position >= 0) {
<> 150:02e0a0aed4ec 490 // Get discrepancy flag of the current bit position
<> 150:02e0a0aed4ec 491 discrepancy_mask = discrepancy & (1 << bit_position);
<> 150:02e0a0aed4ec 492
<> 150:02e0a0aed4ec 493 // If there is a discrepancy and the sent bit is 0 save this bit position
<> 150:02e0a0aed4ec 494 if( (discrepancy_mask) && !(sentBits & discrepancy_mask)) {
<> 150:02e0a0aed4ec 495 last_zero = nibble_start_bit + bit_position;
<> 150:02e0a0aed4ec 496 break;
<> 150:02e0a0aed4ec 497 }
<> 150:02e0a0aed4ec 498
<> 150:02e0a0aed4ec 499 bit_position--;
<> 150:02e0a0aed4ec 500 }
<> 150:02e0a0aed4ec 501 }
<> 150:02e0a0aed4ec 502
<> 150:02e0a0aed4ec 503 // Clear the nibble
<> 150:02e0a0aed4ec 504 ROMCode[rom_byte_number] &= ~rom_nibble_mask;
<> 150:02e0a0aed4ec 505
<> 150:02e0a0aed4ec 506 // Store the sentBits in the ROMCode
<> 150:02e0a0aed4ec 507 if(rom_nibble_mask > 0x0F) {
<> 150:02e0a0aed4ec 508 ROMCode[rom_byte_number] |= (sentBits << 4);
<> 150:02e0a0aed4ec 509 } else {
<> 150:02e0a0aed4ec 510 ROMCode[rom_byte_number] |= sentBits;
<> 150:02e0a0aed4ec 511 }
<> 150:02e0a0aed4ec 512
<> 150:02e0a0aed4ec 513 // Increment the nibble start bit and shift mask
<> 150:02e0a0aed4ec 514 nibble_start_bit += 4;
<> 150:02e0a0aed4ec 515 rom_nibble_mask <<= 4;
<> 150:02e0a0aed4ec 516
<> 150:02e0a0aed4ec 517 // If the mask is 0 then go to new ROM byte rom_byte_number and reset mask
<> 150:02e0a0aed4ec 518 if (rom_nibble_mask == 0) {
<> 150:02e0a0aed4ec 519 rom_byte_number++;
<> 150:02e0a0aed4ec 520 rom_nibble_mask = 0x0F;
<> 150:02e0a0aed4ec 521 }
<> 150:02e0a0aed4ec 522
<> 150:02e0a0aed4ec 523 } // End while(rom_byte_number < 8)
<> 150:02e0a0aed4ec 524
<> 150:02e0a0aed4ec 525 // Clear search ROM accelerator
<> 150:02e0a0aed4ec 526 owm->ctrl_stat &= ~(MXC_F_OWM_CTRL_STAT_SRA_MODE);
<> 150:02e0a0aed4ec 527
<> 150:02e0a0aed4ec 528 // Calculate CRC to verify ROM code is correct
<> 150:02e0a0aed4ec 529 crc8 = CalculateCRC8(ROMCode, 7);
<> 150:02e0a0aed4ec 530
<> 150:02e0a0aed4ec 531 // If the search was successful then
<> 150:02e0a0aed4ec 532 if ((nibble_start_bit >= 65) && (crc8 == ROMCode[7])) {
<> 150:02e0a0aed4ec 533 // Search successful so set LastDiscrepancy,LastDeviceFlag,search_result
<> 150:02e0a0aed4ec 534 LastDiscrepancy = last_zero;
<> 150:02e0a0aed4ec 535
<> 150:02e0a0aed4ec 536 // Check for last device
<> 150:02e0a0aed4ec 537 if (LastDiscrepancy == 0) {
<> 150:02e0a0aed4ec 538 LastDeviceFlag = 1;
<> 150:02e0a0aed4ec 539 }
<> 150:02e0a0aed4ec 540
<> 150:02e0a0aed4ec 541 search_result = 1;
<> 150:02e0a0aed4ec 542 }
<> 150:02e0a0aed4ec 543 } // End if (OWM_Reset)
<> 150:02e0a0aed4ec 544
<> 150:02e0a0aed4ec 545 // If no device found then reset counters so next 'search' will be like a first
<> 150:02e0a0aed4ec 546 if (!search_result || !ROMCode[0]) {
<> 150:02e0a0aed4ec 547 LastDiscrepancy = 0;
<> 150:02e0a0aed4ec 548 LastDeviceFlag = 0;
<> 150:02e0a0aed4ec 549 search_result = 0;
<> 150:02e0a0aed4ec 550 }
<> 150:02e0a0aed4ec 551
<> 150:02e0a0aed4ec 552 return search_result;
<> 150:02e0a0aed4ec 553 }
<> 150:02e0a0aed4ec 554
<> 150:02e0a0aed4ec 555 /*
<> 150:02e0a0aed4ec 556 * Calcualate CRC8 of the buffer of data provided
<> 150:02e0a0aed4ec 557 */
<> 150:02e0a0aed4ec 558 uint8_t CalculateCRC8(uint8_t* data, int len)
<> 150:02e0a0aed4ec 559 {
<> 150:02e0a0aed4ec 560 int i;
<> 150:02e0a0aed4ec 561 uint8_t crc = 0;
<> 150:02e0a0aed4ec 562
<> 150:02e0a0aed4ec 563 for(i = 0; i < len; i++) {
<> 150:02e0a0aed4ec 564 crc = update_crc8(crc, data[i]);
<> 150:02e0a0aed4ec 565 }
<> 150:02e0a0aed4ec 566
<> 150:02e0a0aed4ec 567 return crc;
<> 150:02e0a0aed4ec 568 }
<> 150:02e0a0aed4ec 569
<> 150:02e0a0aed4ec 570 /*
<> 150:02e0a0aed4ec 571 * Calculate the CRC8 of the byte value provided with the current crc value
<> 150:02e0a0aed4ec 572 * provided Returns updated crc value
<> 150:02e0a0aed4ec 573 */
<> 150:02e0a0aed4ec 574 uint8_t update_crc8(uint8_t crc, uint8_t val)
<> 150:02e0a0aed4ec 575 {
<> 150:02e0a0aed4ec 576 uint8_t inc, tmp;
<> 150:02e0a0aed4ec 577
<> 150:02e0a0aed4ec 578 for (inc = 0; inc < 8; inc++) {
<> 150:02e0a0aed4ec 579 tmp = (uint8_t)(crc << 7); // Save X7 bit value
<> 150:02e0a0aed4ec 580 crc >>= 1; // Shift crc
<> 150:02e0a0aed4ec 581 if (((tmp >> 7) ^ (val & 0x01)) == 1) { // If X7 xor X8 (input data)
<> 150:02e0a0aed4ec 582 crc ^= 0x8c; // XOR crc with X4 and X5, X1 = X7^X8
<> 150:02e0a0aed4ec 583 crc |= 0x80; // Carry
<> 150:02e0a0aed4ec 584 }
<> 150:02e0a0aed4ec 585 val >>= 1;
<> 150:02e0a0aed4ec 586 }
<> 150:02e0a0aed4ec 587
<> 150:02e0a0aed4ec 588 return crc;
<> 150:02e0a0aed4ec 589 }
<> 150:02e0a0aed4ec 590
<> 150:02e0a0aed4ec 591 /**@} end of group owm */