1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 /* **** Includes **** */
22 #include <string.h>
23 #include "mxc_assert.h"
24 #include "mxc_sys.h"
25 #include "owm_reva.h"
26
27 /* **** Definitions **** */
28 #define MXC_OWM_CLK_FREQ 1000000 //1-Wire requires 1MHz clock
29
30 /* **** Globals **** */
31 static int LastDiscrepancy;
32 static int LastDeviceFlag;
33
34 /* **** Functions **** */
35 static uint8_t CalculateCRC8(uint8_t *data, int len);
36 static uint8_t update_crc8(uint8_t crc, uint8_t value);
37
38 /* ************************************************************************* */
MXC_OWM_RevA_Init(mxc_owm_reva_regs_t * owm,const mxc_owm_cfg_t * cfg)39 int MXC_OWM_RevA_Init(mxc_owm_reva_regs_t *owm, const mxc_owm_cfg_t *cfg)
40 {
41 uint32_t ext_pu_en = 0;
42
43 // Select the PU mode and polarity based on cfg input
44 switch (cfg->ext_pu_mode) {
45 case MXC_OWM_EXT_PU_ACT_HIGH:
46 ext_pu_en = 1; // EXT_PULLUP_MODE_USED;
47 break;
48
49 case MXC_OWM_EXT_PU_ACT_LOW:
50 ext_pu_en = 1; // EXT_PULLUP_MODE_USED;
51 break;
52
53 case MXC_OWM_EXT_PU_UNUSED:
54 ext_pu_en = 0; // EXT_PULLUP_MODE_UNUSED;
55 break;
56
57 default:
58 return E_BAD_PARAM;
59 }
60
61 // Set owm internal clock divider
62 MXC_OWM_SystemClockUpdated();
63
64 // Set configuration
65 owm->cfg = (((cfg->int_pu_en << MXC_F_OWM_REVA_CFG_INT_PULLUP_ENABLE_POS) &
66 MXC_F_OWM_REVA_CFG_INT_PULLUP_ENABLE) |
67 ((ext_pu_en << MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE_POS) &
68 MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE) |
69 ((cfg->long_line_mode << MXC_F_OWM_REVA_CFG_LONG_LINE_MODE_POS) &
70 MXC_F_OWM_REVA_CFG_LONG_LINE_MODE));
71
72 // If external pullup is enabled, set the mode
73 if (ext_pu_en) {
74 MXC_SETFIELD(owm->cfg, MXC_F_OWM_REVA_CFG_EXT_PULLUP_MODE,
75 cfg->ext_pu_mode << MXC_F_OWM_REVA_CFG_EXT_PULLUP_MODE_POS);
76 }
77
78 // Clear all interrupt flags
79 owm->intfl = owm->intfl;
80
81 return E_NO_ERROR;
82 }
83
84 /* ************************************************************************* */
MXC_OWM_RevA_Shutdown(mxc_owm_reva_regs_t * owm)85 void MXC_OWM_RevA_Shutdown(mxc_owm_reva_regs_t *owm)
86 {
87 // Disable and clear interrupts
88 owm->inten = 0;
89 owm->intfl = owm->intfl;
90 }
91
92 /* ************************************************************************* */
MXC_OWM_RevA_Reset(mxc_owm_reva_regs_t * owm)93 int MXC_OWM_RevA_Reset(mxc_owm_reva_regs_t *owm)
94 {
95 owm->intfl = MXC_F_OWM_REVA_INTFL_OW_RESET_DONE; // Clear the reset flag
96 owm->ctrl_stat |= MXC_F_OWM_REVA_CTRL_STAT_START_OW_RESET; // Generate a reset pulse
97
98 while ((owm->intfl & MXC_F_OWM_REVA_INTFL_OW_RESET_DONE) == 0) {}
99 // Wait for reset time slot to complete
100
101 return MXC_OWM_GetPresenceDetect(); // Return presence pulse detect status
102 }
103
104 /* ************************************************************************* */
MXC_OWM_RevA_TouchByte(mxc_owm_reva_regs_t * owm,uint8_t data)105 int MXC_OWM_RevA_TouchByte(mxc_owm_reva_regs_t *owm, uint8_t data)
106 {
107 owm->cfg &= ~MXC_F_OWM_REVA_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode
108 owm->intfl = (MXC_F_OWM_REVA_INTFL_TX_DATA_EMPTY | MXC_F_OWM_REVA_INTEN_LINE_SHORT |
109 MXC_F_OWM_REVA_INTFL_RX_DATA_READY); // Clear the flags
110 owm->data = (data << MXC_F_OWM_REVA_DATA_TX_RX_POS) & MXC_F_OWM_REVA_DATA_TX_RX; // Write data
111
112 while ((owm->intfl & MXC_F_OWM_REVA_INTFL_TX_DATA_EMPTY) == 0) {}
113 // Wait for data to be sent
114
115 while ((owm->intfl & MXC_F_OWM_REVA_INTFL_RX_DATA_READY) == 0) {}
116 // Wait for data to be read
117
118 // Check error flag
119 if (owm->intfl & MXC_F_OWM_REVA_INTEN_LINE_SHORT) {
120 return E_COMM_ERR; // Wire was low before transaction
121 }
122
123 return (owm->data >> MXC_F_OWM_REVA_DATA_TX_RX_POS) & 0xFF; // Return the data read
124 }
125
126 /* ************************************************************************* */
MXC_OWM_RevA_WriteByte(uint8_t data)127 int MXC_OWM_RevA_WriteByte(uint8_t data)
128 {
129 // Send one byte of data and verify the data sent = data parameter
130 return (MXC_OWM_TouchByte(data) == data) ? E_NO_ERROR : E_COMM_ERR;
131 }
132
133 /* ************************************************************************* */
MXC_OWM_RevA_ReadByte(void)134 int MXC_OWM_RevA_ReadByte(void)
135 {
136 // Read one byte of data
137 return MXC_OWM_TouchByte(0xFF);
138 }
139
140 /* ************************************************************************* */
MXC_OWM_RevA_TouchBit(mxc_owm_reva_regs_t * owm,uint8_t bit)141 int MXC_OWM_RevA_TouchBit(mxc_owm_reva_regs_t *owm, uint8_t bit)
142 {
143 owm->cfg |= MXC_F_OWM_REVA_CFG_SINGLE_BIT_MODE; // Set to 1 bit mode
144 owm->intfl = (MXC_F_OWM_REVA_INTFL_TX_DATA_EMPTY | MXC_F_OWM_REVA_INTEN_LINE_SHORT |
145 MXC_F_OWM_REVA_INTFL_RX_DATA_READY); // Clear the flags
146 owm->data = (bit << MXC_F_OWM_REVA_DATA_TX_RX_POS) & MXC_F_OWM_REVA_DATA_TX_RX; // Write data
147
148 while ((owm->intfl & MXC_F_OWM_REVA_INTFL_TX_DATA_EMPTY) == 0) {}
149 // Wait for data to be sent
150
151 while ((owm->intfl & MXC_F_OWM_REVA_INTFL_RX_DATA_READY) == 0) {}
152 // Wait for data to be read
153
154 // Check error flag
155 if (owm->intfl & MXC_F_OWM_REVA_INTEN_LINE_SHORT) {
156 return E_COMM_ERR; // Wire was low before transaction
157 }
158
159 return (owm->data >> MXC_F_OWM_REVA_DATA_TX_RX_POS) & 0x1; // Return the bit read
160 }
161
162 /* ************************************************************************* */
MXC_OWM_RevA_WriteBit(uint8_t bit)163 int MXC_OWM_RevA_WriteBit(uint8_t bit)
164 {
165 // Send a bit and verify the bit sent = bit parameter
166 return (MXC_OWM_TouchBit(bit) == bit) ? E_NO_ERROR : E_COMM_ERR;
167 }
168
169 /* ************************************************************************* */
MXC_OWM_RevA_ReadBit(void)170 int MXC_OWM_RevA_ReadBit(void)
171 {
172 // Read a bit
173 return MXC_OWM_TouchBit(1);
174 }
175
176 /* ************************************************************************* */
MXC_OWM_RevA_Write(mxc_owm_reva_regs_t * owm,uint8_t * data,int len)177 int MXC_OWM_RevA_Write(mxc_owm_reva_regs_t *owm, uint8_t *data, int len)
178 {
179 int num = 0;
180
181 owm->cfg &= ~MXC_F_OWM_REVA_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode
182
183 while (num < len) { // Loop for number of bytes to write
184 if (MXC_OWM_WriteByte(data[num]) != E_NO_ERROR) {
185 return E_COMM_ERR;
186 }
187
188 num++; // Keep track of how many bytes written
189 }
190
191 return num; // Return number of bytes written
192 }
193
194 /* ************************************************************************* */
MXC_OWM_RevA_Read(mxc_owm_reva_regs_t * owm,uint8_t * data,int len)195 int MXC_OWM_RevA_Read(mxc_owm_reva_regs_t *owm, uint8_t *data, int len)
196 {
197 int num = 0;
198
199 owm->cfg &= ~MXC_F_OWM_REVA_CFG_SINGLE_BIT_MODE; // Set to 8 bit mode
200
201 while (num < len) { // Loop for number of bytes to read
202 // Store read data into buffer
203 data[num] = MXC_OWM_ReadByte();
204
205 num++; // Keep track of how many bytes read
206 }
207
208 return num; // Return number of bytes read
209 }
210
211 /* ************************************************************************* */
MXC_OWM_RevA_ReadROM(uint8_t * ROMCode)212 int MXC_OWM_RevA_ReadROM(uint8_t *ROMCode)
213 {
214 int num_read;
215
216 // Send reset and wait for presence pulse
217 if (MXC_OWM_Reset()) {
218 // Send Read ROM command code
219 if (MXC_OWM_WriteByte(READ_ROM_COMMAND) == E_NO_ERROR) {
220 // Read 8 bytes and store in buffer
221 num_read = MXC_OWM_Read(ROMCode, 8);
222
223 // Check the number of bytes read
224 if (num_read != 8) {
225 return E_COMM_ERR;
226 }
227 } else {
228 // Write failed
229 return E_COMM_ERR;
230 }
231 } else {
232 // No presence pulse
233 return E_COMM_ERR;
234 }
235
236 return E_NO_ERROR;
237 }
238
239 /* ************************************************************************* */
MXC_OWM_RevA_MatchROM(uint8_t * ROMCode)240 int MXC_OWM_RevA_MatchROM(uint8_t *ROMCode)
241 {
242 int num_wrote;
243
244 // Send reset and wait for presence pulse
245 if (MXC_OWM_Reset()) {
246 // Send match ROM command code
247 if (MXC_OWM_WriteByte(MATCH_ROM_COMMAND) == E_NO_ERROR) {
248 // Write 8 bytes in ROMCode buffer
249 num_wrote = MXC_OWM_Write(ROMCode, 8);
250
251 // Check the number of bytes written
252 if (num_wrote != 8) {
253 return E_COMM_ERR;
254 }
255 } else {
256 // Write failed
257 return E_COMM_ERR;
258 }
259 } else {
260 // No presence pulse
261 return E_COMM_ERR;
262 }
263
264 return E_NO_ERROR;
265 }
266
267 /* ************************************************************************* */
MXC_OWM_RevA_ODMatchROM(mxc_owm_reva_regs_t * owm,uint8_t * ROMCode)268 int MXC_OWM_RevA_ODMatchROM(mxc_owm_reva_regs_t *owm, uint8_t *ROMCode)
269 {
270 int num_wrote;
271
272 // Set to standard speed
273 owm->cfg &= ~(MXC_F_OWM_REVA_CFG_OVERDRIVE);
274
275 // Send reset and wait for presence pulse
276 if (MXC_OWM_Reset()) {
277 // Send Overdrive match ROM command code
278 if (MXC_OWM_WriteByte(OD_MATCH_ROM_COMMAND) == E_NO_ERROR) {
279 // Set overdrive
280 owm->cfg |= MXC_F_OWM_REVA_CFG_OVERDRIVE;
281
282 // Write 8 bytes in ROMCode buffer
283 num_wrote = MXC_OWM_Write(ROMCode, 8);
284
285 // Check the number of bytes written
286 if (num_wrote != 8) {
287 return E_COMM_ERR;
288 }
289 } else {
290 // Write failed
291 return E_COMM_ERR;
292 }
293 } else {
294 // No presence pulse
295 return E_COMM_ERR;
296 }
297
298 return E_NO_ERROR;
299 }
300
301 /* ************************************************************************* */
MXC_OWM_RevA_SkipROM(void)302 int MXC_OWM_RevA_SkipROM(void)
303 {
304 // Send reset and wait for presence pulse
305 if (MXC_OWM_Reset()) {
306 // Send skip ROM command code
307 return MXC_OWM_WriteByte(SKIP_ROM_COMMAND);
308 } else {
309 // No presence pulse
310 return E_COMM_ERR;
311 }
312 }
313
314 /* ************************************************************************* */
MXC_OWM_RevA_ODSkipROM(mxc_owm_reva_regs_t * owm)315 int MXC_OWM_RevA_ODSkipROM(mxc_owm_reva_regs_t *owm)
316 {
317 // Set to standard speed
318 owm->cfg &= ~(MXC_F_OWM_REVA_CFG_OVERDRIVE);
319
320 // Send reset and wait for presence pulse
321 if (MXC_OWM_Reset()) {
322 // Send Overdrive skip ROM command code
323 if (MXC_OWM_WriteByte(OD_SKIP_ROM_COMMAND) == E_NO_ERROR) {
324 // Set overdrive speed
325 owm->cfg |= MXC_F_OWM_REVA_CFG_OVERDRIVE;
326
327 return E_NO_ERROR;
328 } else {
329 // Write failed
330 return E_COMM_ERR;
331 }
332 } else {
333 // No presence pulse
334 return E_COMM_ERR;
335 }
336 }
337
338 /* ************************************************************************* */
MXC_OWM_RevA_Resume(void)339 int MXC_OWM_RevA_Resume(void)
340 {
341 // Send reset and wait for presence pulse
342 if (MXC_OWM_Reset()) {
343 // Send resume command code
344 return MXC_OWM_WriteByte(RESUME_COMMAND);
345 } else {
346 // No presence pulse
347 return E_COMM_ERR;
348 }
349 }
350
351 /* ************************************************************************* */
MXC_OWM_RevA_SearchROM(mxc_owm_reva_regs_t * owm,int newSearch,uint8_t * ROMCode)352 int MXC_OWM_RevA_SearchROM(mxc_owm_reva_regs_t *owm, int newSearch, uint8_t *ROMCode)
353 {
354 int nibble_start_bit = 1;
355 int rom_byte_number = 0;
356 uint8_t rom_nibble_mask = 0x0F;
357 uint8_t search_direction;
358 int readValue;
359 int sentBits;
360 int discrepancy;
361 int bit_position;
362 int discrepancy_mask;
363 int last_zero = 0;
364 uint8_t crc8;
365 int search_result = 0;
366
367 // Clear ROM array
368 memset(ROMCode, 0x0, 8);
369
370 if (newSearch) {
371 // Reset all global variables to start search from beginning
372 LastDiscrepancy = 0;
373 LastDeviceFlag = 0;
374 }
375
376 // Check if the last call was the last device
377 if (LastDeviceFlag) {
378 // Reset the search
379 LastDiscrepancy = 0;
380 LastDeviceFlag = 0;
381 return search_result;
382 }
383
384 // Send reset and wait for presence pulse
385 if (MXC_OWM_Reset()) {
386 // Send the search command
387 MXC_OWM_WriteByte(SEARCH_ROM_COMMAND);
388
389 // Set search ROM accelerator bit
390 owm->ctrl_stat |= MXC_F_OWM_REVA_CTRL_STAT_SRA_MODE;
391
392 // Loop through all ROM bytes 0-7(this loops 2 times per byte)
393 while (rom_byte_number < 8) {
394 // Each loop finds the discrepancy bits and finds 4 bits(nibble) of the ROM
395
396 // Set the search direction the same as last time for the nibble masked
397 search_direction = ROMCode[rom_byte_number] & rom_nibble_mask;
398
399 // If the upper nibble is the mask then shift bits to lower nibble
400 if (rom_nibble_mask > 0x0F) {
401 search_direction = search_direction >> 4;
402 }
403
404 // Get the last discrepancy bit position relative to the nibble start bit
405 bit_position = LastDiscrepancy - nibble_start_bit;
406
407 // Check if last discrepancy is within this nibble
408 if ((bit_position >= 0) && (bit_position < 4)) {
409 // Last discrepancy is within this nibble
410 // Set the bit of the last discrepancy bit
411 search_direction |= (1 << (bit_position));
412 }
413
414 // Performs two read bits and a write bit for 4 bits of the ROM
415 readValue = MXC_OWM_TouchByte(search_direction);
416 // Get discrepancy flags
417 discrepancy = readValue & 0xF;
418 // Get the 4 bits sent to select the ROM
419 sentBits = (readValue >> 4) & 0xF;
420
421 // Store the bit location of the MSB discrepancy with sentbit = 0
422 if (discrepancy) {
423 // Initialize bit_position to MSB of nibble
424 bit_position = 3;
425
426 while (bit_position >= 0) {
427 // Get discrepancy flag of the current bit position
428 discrepancy_mask = discrepancy & (1 << bit_position);
429
430 // If there is a discrepancy and the sent bit is 0 save this bit position
431 if ((discrepancy_mask) && !(sentBits & discrepancy_mask)) {
432 last_zero = nibble_start_bit + bit_position;
433 break;
434 }
435
436 bit_position--;
437 }
438 }
439
440 // Clear the nibble
441 ROMCode[rom_byte_number] &= ~rom_nibble_mask;
442
443 // Store the sentBits in the ROMCode
444 if (rom_nibble_mask > 0x0F) {
445 ROMCode[rom_byte_number] |= (sentBits << 4);
446 } else {
447 ROMCode[rom_byte_number] |= sentBits;
448 }
449
450 // Increment the nibble start bit and shift mask
451 nibble_start_bit += 4;
452 rom_nibble_mask <<= 4;
453
454 // If the mask is 0 then go to new ROM byte rom_byte_number and reset mask
455 if (rom_nibble_mask == 0) {
456 rom_byte_number++;
457 rom_nibble_mask = 0x0F;
458 }
459 } // End while(rom_byte_number < 8)
460
461 // Clear search ROM accelerator
462 owm->ctrl_stat &= ~(MXC_F_OWM_REVA_CTRL_STAT_SRA_MODE);
463
464 // Calculate CRC to verify ROM code is correct
465 crc8 = CalculateCRC8(ROMCode, 7);
466
467 // If the search was successful then
468 if ((nibble_start_bit >= 65) && (crc8 == ROMCode[7])) {
469 // Search successful so set LastDiscrepancy,LastDeviceFlag,search_result
470 LastDiscrepancy = last_zero;
471
472 // Check for last device
473 if (LastDiscrepancy == 0) {
474 LastDeviceFlag = 1;
475 }
476
477 search_result = 1;
478 }
479 } // End if(MXC_OWM_Reset)
480
481 // If no device found then reset counters so next 'search' will be like a first
482 if (!search_result || !ROMCode[0]) {
483 LastDiscrepancy = 0;
484 LastDeviceFlag = 0;
485 search_result = 0;
486 }
487
488 return search_result;
489 }
490
491 /* ************************************************************************* */
MXC_OWM_RevA_ClearFlags(mxc_owm_reva_regs_t * owm,uint32_t mask)492 void MXC_OWM_RevA_ClearFlags(mxc_owm_reva_regs_t *owm, uint32_t mask)
493 {
494 owm->intfl = mask;
495 }
496
497 /* ************************************************************************* */
MXC_OWM_RevA_GetFlags(mxc_owm_reva_regs_t * owm)498 unsigned MXC_OWM_RevA_GetFlags(mxc_owm_reva_regs_t *owm)
499 {
500 return (owm->intfl);
501 }
502
503 /* ************************************************************************* */
MXC_OWM_RevA_SetExtPullup(mxc_owm_reva_regs_t * owm,int enable)504 void MXC_OWM_RevA_SetExtPullup(mxc_owm_reva_regs_t *owm, int enable)
505 {
506 if (enable) {
507 owm->cfg |= MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE;
508 } else {
509 owm->cfg &= ~(MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE);
510 }
511 }
512
513 /* ************************************************************************* */
MXC_OWM_RevA_SetOverdrive(mxc_owm_reva_regs_t * owm,int enable)514 void MXC_OWM_RevA_SetOverdrive(mxc_owm_reva_regs_t *owm, int enable)
515 {
516 if (enable) {
517 owm->cfg |= MXC_F_OWM_REVA_CFG_OVERDRIVE;
518 } else {
519 owm->cfg &= ~(MXC_F_OWM_REVA_CFG_OVERDRIVE);
520 }
521 }
522
523 /* ************************************************************************* */
MXC_OWM_RevA_EnableInt(mxc_owm_reva_regs_t * owm,int flags)524 void MXC_OWM_RevA_EnableInt(mxc_owm_reva_regs_t *owm, int flags)
525 {
526 owm->inten |= flags;
527 }
528
529 /* ************************************************************************* */
MXC_OWM_RevA_DisableInt(mxc_owm_reva_regs_t * owm,int flags)530 void MXC_OWM_RevA_DisableInt(mxc_owm_reva_regs_t *owm, int flags)
531 {
532 owm->inten &= ~flags;
533 }
534
535 /* ************************************************************************* */
MXC_OWM_RevA_SetForcePresenceDetect(mxc_owm_reva_regs_t * owm,int enable)536 int MXC_OWM_RevA_SetForcePresenceDetect(mxc_owm_reva_regs_t *owm, int enable)
537 {
538 MXC_SETFIELD(owm->cfg, MXC_F_OWM_REVA_CFG_FORCE_PRES_DET,
539 enable << MXC_F_OWM_REVA_CFG_FORCE_PRES_DET_POS);
540 return E_NO_ERROR;
541 }
542
543 /* ************************************************************************* */
MXC_OWM_RevA_SetInternalPullup(mxc_owm_reva_regs_t * owm,int enable)544 int MXC_OWM_RevA_SetInternalPullup(mxc_owm_reva_regs_t *owm, int enable)
545 {
546 MXC_SETFIELD(owm->cfg, MXC_F_OWM_REVA_CFG_INT_PULLUP_ENABLE,
547 enable << MXC_F_OWM_REVA_CFG_INT_PULLUP_ENABLE_POS);
548 return E_NO_ERROR;
549 }
550
551 /* ************************************************************************* */
MXC_OWM_RevA_SetExternalPullup(mxc_owm_reva_regs_t * owm,mxc_owm_ext_pu_t ext_pu_mode)552 int MXC_OWM_RevA_SetExternalPullup(mxc_owm_reva_regs_t *owm, mxc_owm_ext_pu_t ext_pu_mode)
553 {
554 switch (ext_pu_mode) {
555 case MXC_OWM_EXT_PU_ACT_HIGH:
556 owm->cfg |= MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE;
557 owm->cfg &= ~MXC_F_OWM_REVA_CFG_EXT_PULLUP_MODE;
558 break;
559
560 case MXC_OWM_EXT_PU_ACT_LOW:
561 owm->cfg &= ~MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE;
562 owm->cfg &= ~MXC_F_OWM_REVA_CFG_EXT_PULLUP_MODE;
563 break;
564
565 case MXC_OWM_EXT_PU_UNUSED:
566 owm->cfg &= ~MXC_F_OWM_REVA_CFG_EXT_PULLUP_ENABLE;
567 owm->cfg |= MXC_F_OWM_REVA_CFG_EXT_PULLUP_MODE;
568 break;
569 }
570
571 return E_NO_ERROR;
572 }
573
574 /* ************************************************************************* */
MXC_OWM_RevA_SystemClockUpdated(mxc_owm_reva_regs_t * owm)575 int MXC_OWM_RevA_SystemClockUpdated(mxc_owm_reva_regs_t *owm)
576 {
577 uint32_t mxc_owm_clk, clk_div = 0;
578
579 // Configure clk divisor to get 1MHz OWM clk
580 mxc_owm_clk = PeripheralClock;
581
582 if (mxc_owm_clk == 0) {
583 return E_UNINITIALIZED;
584 }
585
586 // Return error if clk doesn't divide evenly to 1MHz
587 if (mxc_owm_clk % MXC_OWM_CLK_FREQ) {
588 return E_NOT_SUPPORTED;
589 }
590
591 clk_div = (mxc_owm_clk / (MXC_OWM_CLK_FREQ));
592
593 // Can not support lower frequencies
594 if (clk_div == 0) {
595 return E_NOT_SUPPORTED;
596 }
597
598 // Set clk divisor
599 owm->clk_div_1us = (clk_div << MXC_F_OWM_REVA_CLK_DIV_1US_DIVISOR_POS) &
600 MXC_F_OWM_REVA_CLK_DIV_1US_DIVISOR;
601
602 return E_NO_ERROR;
603 }
604
605 /* ************************************************************************ */
MXC_OWM_RevA_SetSearchROMAccelerator(mxc_owm_reva_regs_t * owm,int enable)606 int MXC_OWM_RevA_SetSearchROMAccelerator(mxc_owm_reva_regs_t *owm, int enable)
607 {
608 MXC_SETFIELD(owm->ctrl_stat, MXC_F_OWM_REVA_CTRL_STAT_SRA_MODE,
609 enable << MXC_F_OWM_REVA_CTRL_STAT_SRA_MODE_POS);
610 return E_NO_ERROR;
611 }
612
613 /* ************************************************************************* */
MXC_OWM_RevA_BitBang_Init(mxc_owm_reva_regs_t * owm,int initialState)614 int MXC_OWM_RevA_BitBang_Init(mxc_owm_reva_regs_t *owm, int initialState)
615 {
616 owm->cfg |= MXC_F_OWM_REVA_CFG_BIT_BANG_EN;
617
618 MXC_SETFIELD(owm->ctrl_stat, MXC_F_OWM_REVA_CTRL_STAT_BIT_BANG_OE,
619 initialState << MXC_F_OWM_REVA_CTRL_STAT_BIT_BANG_OE_POS);
620
621 return E_NO_ERROR;
622 }
623
624 /* ************************************************************************* */
MXC_OWM_RevA_BitBang_Read(mxc_owm_reva_regs_t * owm)625 int MXC_OWM_RevA_BitBang_Read(mxc_owm_reva_regs_t *owm)
626 {
627 return !!(owm->ctrl_stat & MXC_F_OWM_REVA_CTRL_STAT_BIT_BANG_OE);
628 }
629
630 /* ************************************************************************* */
MXC_OWM_RevA_BitBang_Write(mxc_owm_reva_regs_t * owm,int state)631 int MXC_OWM_RevA_BitBang_Write(mxc_owm_reva_regs_t *owm, int state)
632 {
633 MXC_SETFIELD(owm->ctrl_stat, MXC_F_OWM_REVA_CTRL_STAT_BIT_BANG_OE,
634 state << MXC_F_OWM_REVA_CTRL_STAT_BIT_BANG_OE_POS);
635 return E_NO_ERROR;
636 }
637
638 /* ************************************************************************* */
MXC_OWM_RevA_BitBang_Disable(mxc_owm_reva_regs_t * owm)639 int MXC_OWM_RevA_BitBang_Disable(mxc_owm_reva_regs_t *owm)
640 {
641 owm->cfg &= ~MXC_F_OWM_REVA_CFG_BIT_BANG_EN;
642 return E_NO_ERROR;
643 }
644
645 /* ************************************************************************* */
CalculateCRC8(uint8_t * data,int len)646 static uint8_t CalculateCRC8(uint8_t *data, int len)
647 {
648 int i;
649 uint8_t crc = 0;
650
651 for (i = 0; i < len; i++) {
652 crc = update_crc8(crc, data[i]);
653 }
654
655 return crc;
656 }
657
658 /* ************************************************************************* */
update_crc8(uint8_t crc,uint8_t val)659 static uint8_t update_crc8(uint8_t crc, uint8_t val)
660 {
661 uint8_t inc, tmp;
662
663 for (inc = 0; inc < 8; inc++) {
664 tmp = (uint8_t)(crc << 7); // Save X7 bit value
665 crc >>= 1; // Shift crc
666
667 if (((tmp >> 7) ^ (val & 0x01)) == 1) { // If X7 xor X8(input data)
668 crc ^= 0x8c; // XOR crc with X4 and X5, X1 = X7^X8
669 crc |= 0x80; // Carry
670 }
671
672 val >>= 1;
673 }
674
675 return crc;
676 }
677