mbed library sources. Supersedes mbed-src. Fixed broken STM32F1xx RTC on rtc_api.c

Dependents:   Nucleo_F103RB_RTC_battery_bkup_pwr_off_okay

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Thu Feb 02 17:01:33 2017 +0000
Revision:
157:ff67d9f36b67
This updates the lib to the mbed lib v135

Who changed what in which revision?

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