Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Max4146x.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2019 Maxim Integrated Products, Inc., All rights Reserved. 00003 * 00004 * This software is protected by copyright laws of the United States and 00005 * of foreign countries. This material may also be protected by patent laws 00006 * and technology transfer regulations of the United States and of foreign 00007 * countries. This software is furnished under a license agreement and/or a 00008 * nondisclosure agreement and may only be used or reproduced in accordance 00009 * with the terms of those agreements. Dissemination of this information to 00010 * any party or parties not specified in the license agreement and/or 00011 * nondisclosure agreement is expressly prohibited. 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00017 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00019 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00020 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00021 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00022 * OTHER DEALINGS IN THE SOFTWARE. 00023 * 00024 * Except as contained in this notice, the name of Maxim Integrated 00025 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00026 * Products, Inc. Branding Policy. 00027 * 00028 * The mere transfer of this software does not imply any licenses 00029 * of trade secrets, proprietary technology, copyrights, patents, 00030 * trademarks, maskwork rights, or any other form of intellectual 00031 * property whatsoever. Maxim Integrated Products, Inc. retains all 00032 * ownership rights. 00033 ******************************************************************************* 00034 */ 00035 00036 #include "Max4146x.h" 00037 #include <iostream> 00038 00039 using namespace std; 00040 00041 const uint8_t default_register_value_0[17] = {0x90, 0x81, 0x03, 0x00, 0x00, 0x04, 0x80, 0x80, 0x60, 0x00, 00042 0x00, 0xC4, 0xDE, 0x98, 0x28, 0x04, 0x02}; 00043 const uint8_t default_register_value_1[20] = {0x90, 0x81, 0x03, 0x00, 0x00, 0x04, 0x80, 0x80, 0x60, 0x00, 00044 0x00, 0xC4, 0xDE, 0x98, 0x28, 0x04, 0x04, 0x00, 0xFF, 0x00}; 00045 00046 template <class REG> 00047 MAX4146X<REG>::MAX4146X(REG *reg, SPI *spi, DigitalOut *cs) 00048 { 00049 operation_mode = UNINITIALIZED; 00050 00051 if (reg == NULL) { 00052 return; 00053 } 00054 00055 if (cs == NULL) { 00056 return; 00057 } 00058 00059 this->reg = reg; 00060 ssel = cs; 00061 00062 if (spi == NULL) { 00063 return; 00064 } 00065 00066 spi_handler = spi; 00067 i2c_handler = NULL; 00068 preset_mode = 0; 00069 00070 if (initial_programming() < 0) { 00071 return; 00072 } 00073 00074 this->crystal_frequency = 16.0; 00075 this->center_frequency = 315.0; 00076 this->baud_rate = 5000.0; //5 kHz 00077 00078 operation_mode = INITIALIZED; 00079 } 00080 00081 template <class REG> 00082 MAX4146X<REG>::MAX4146X(REG *reg, SPI *spi) 00083 { 00084 operation_mode = UNINITIALIZED; 00085 00086 if (reg == NULL) { 00087 return; 00088 } 00089 00090 this->reg = reg; 00091 00092 if (spi == NULL) { 00093 return; 00094 } 00095 00096 spi_handler = spi; 00097 i2c_handler = NULL; 00098 ssel = NULL; 00099 preset_mode = 0; 00100 00101 if (initial_programming() < 0) { 00102 return; 00103 } 00104 00105 this->crystal_frequency = 16.0; 00106 this->center_frequency = 315.0; 00107 this->baud_rate = 5000.0; //5 kHz 00108 00109 operation_mode = INITIALIZED; 00110 } 00111 00112 template <class REG> 00113 MAX4146X<REG>::MAX4146X(REG *reg, I2C *i2c) 00114 { 00115 operation_mode = UNINITIALIZED; 00116 00117 if (reg == NULL) { 00118 return; 00119 } 00120 00121 this->reg = reg; 00122 00123 if (i2c == NULL) { 00124 return; 00125 } 00126 00127 i2c_handler = i2c; 00128 spi_handler = NULL; 00129 ssel = NULL; 00130 preset_mode = 0; 00131 00132 if (initial_programming() < 0) { 00133 return; 00134 } 00135 00136 this->crystal_frequency = 16.0; 00137 this->center_frequency = 315.0; 00138 this->baud_rate = 5000.0; //5 kHz 00139 00140 operation_mode = INITIALIZED; 00141 } 00142 00143 template <class REG> 00144 MAX4146X<REG>::MAX4146X(DigitalOut *cs) 00145 { 00146 operation_mode = UNINITIALIZED; 00147 00148 if (cs == NULL) { 00149 return; 00150 } 00151 00152 data_sent = cs; 00153 00154 data_rate = 5; 00155 00156 this->reg = NULL; 00157 this->ssel = NULL; 00158 spi_handler = NULL; 00159 i2c_handler = NULL; 00160 preset_mode = 1; 00161 00162 operation_mode = INITIALIZED; 00163 } 00164 00165 template <> 00166 int MAX4146X<max41460_reg_map_t>::read_register(uint8_t reg, uint8_t *value, uint8_t len) 00167 { 00168 int rtn_val = -1; 00169 00170 if (value == NULL) { 00171 return -1; 00172 } 00173 00174 if (this->reg == NULL) { 00175 return -1; 00176 } 00177 00178 if (ssel != NULL) { 00179 *ssel = 0; 00180 } 00181 spi_handler->write((uint8_t)0x80 | reg); 00182 for (uint8_t i = 0; i < len; i++) { 00183 *(value++) = spi_handler->write(0x00); // read back data bytes 00184 } 00185 if (ssel != NULL) { 00186 *ssel = 1; 00187 } 00188 return 0; 00189 } 00190 00191 template <class REG> 00192 int MAX4146X<REG>::read_register(uint8_t reg, uint8_t *value, uint8_t len) 00193 { 00194 int rtn_val = -1; 00195 00196 if (value == NULL) { 00197 return -1; 00198 } 00199 00200 if (this->reg == NULL) { 00201 return -1; 00202 } 00203 00204 rtn_val = i2c_handler->write(I2C_ADDRESS, (const char *)®, 1, true); 00205 if (rtn_val != 0) { 00206 return -1; 00207 } 00208 00209 rtn_val = i2c_handler->read(I2C_ADDRESS, (char *) value, len, false); 00210 if (rtn_val < 0) { 00211 return rtn_val; 00212 } 00213 00214 return 0; 00215 } 00216 00217 template <> 00218 int MAX4146X<max41460_reg_map_t>::write_register(uint8_t reg, const uint8_t *value, uint8_t len) 00219 { 00220 int rtn_val = -1; 00221 uint8_t local_data[1 + len]; 00222 00223 if (value == NULL) { 00224 return -1; 00225 } 00226 00227 memcpy(&local_data[0], value, len); 00228 00229 rtn_val = spi_handler->write(0x7F & reg); // write mode and adress send 00230 for (int i = 0; i < len; i++) { 00231 rtn_val = spi_handler->write(local_data[i]); // write adress 00232 } 00233 if (rtn_val != 0) { 00234 return rtn_val; 00235 } 00236 00237 return 0; 00238 } 00239 00240 template <class REG> 00241 int MAX4146X<REG>::write_register(uint8_t reg, const uint8_t *value, uint8_t len) 00242 { 00243 int rtn_val = -1; 00244 uint8_t local_data[1 + len]; 00245 00246 if (value == NULL) { 00247 return -1; 00248 } 00249 00250 local_data[0] = reg; 00251 00252 memcpy(&local_data[1], value, len); 00253 00254 rtn_val = i2c_handler->write(I2C_ADDRESS, (const char *)local_data, 00255 sizeof(local_data)); 00256 if (rtn_val != 0) { 00257 return -1; 00258 } 00259 00260 return 0; 00261 } 00262 00263 #define SET_BIT_FIELD(address, reg_name, bit_field_name, value) \ 00264 int ret; \ 00265 ret = read_register(address, (uint8_t *)&(reg_name), 1); \ 00266 if (ret) { \ 00267 return ret; \ 00268 } \ 00269 bit_field_name = value; \ 00270 ret = write_register(address, (uint8_t *)&(reg_name), 1); \ 00271 if (ret) { \ 00272 return ret; \ 00273 } 00274 00275 template <class REG> 00276 int MAX4146X<REG>::set_crystal_frequency(float freq) 00277 { 00278 if (freq < 250 || freq > 950) { 00279 return -1; 00280 } 00281 this->crystal_frequency = freq; 00282 00283 return 0; 00284 } 00285 00286 template <class REG> 00287 float MAX4146X<REG>::get_crystal_frequency() 00288 { 00289 return this->crystal_frequency; 00290 } 00291 00292 template <class REG> 00293 int MAX4146X<REG>::set_center_frequency(float freq) 00294 { 00295 if (freq < 250 || freq > 950) { 00296 return -1; 00297 } 00298 00299 this->center_frequency = freq; 00300 00301 uint32_t value = (uint32_t)((65536 * freq) / this->crystal_frequency); //65536 is constant defined in the datasheet 00302 00303 return this->set_frequency(value); 00304 } 00305 00306 template <class REG> 00307 float MAX4146X<REG>::get_center_frequency() 00308 { 00309 return this->center_frequency; 00310 } 00311 00312 template <class REG> 00313 int MAX4146X<REG>::adjust_baudrate(float rate) 00314 { 00315 if (rate < 195.3 || rate > 200000.0) { 00316 return -1; 00317 } 00318 00319 if (this->preset_mode == 1) { 00320 this->baud_rate = rate; 00321 } 00322 00323 int error = 0; 00324 uint8_t prediv = 3; 00325 00326 if (rate < 12500.0) { 00327 error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_5); 00328 prediv = (uint8_t)((50000.0 / rate) - 1); 00329 } else if (rate < 25000.0) { 00330 error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_4); 00331 prediv = (uint8_t)((100000.0 / rate) - 1); 00332 } else if (rate < 50000.0) { 00333 error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_3); 00334 prediv = (uint8_t)((200000.0 / rate) - 1); 00335 } else if (rate < 100000.0) { 00336 error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_2); 00337 prediv = (uint8_t)((400000.0 / rate) - 1); 00338 } else { 00339 error = this->set_bclk_postdiv(this->BCLK_POSTDIV_BY_1); 00340 prediv = (uint8_t)((800000.0 / rate) - 1); 00341 } 00342 00343 if (error < 0) { 00344 return -1; 00345 } 00346 00347 return this->set_bclk_prediv(prediv); 00348 } 00349 00350 template <class REG> 00351 float MAX4146X<REG>::get_baudrate() 00352 { 00353 return this->baud_rate; 00354 } 00355 00356 template <class REG> 00357 int MAX4146X<REG>::adjust_frequency_deviation(float deviation) 00358 { 00359 uint8_t dev = 0; 00360 00361 if (this->read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1) < 0) { 00362 return -1; 00363 } 00364 00365 if (this->reg->reg_cfg1.bits.fskshape == 0) { 00366 dev = (uint8_t)(deviation * 8.192 / crystal_frequency); 00367 if (dev < 127) { 00368 return this->set_deltaf(dev); 00369 } 00370 } else { 00371 dev = (uint8_t)(deviation * 81.92 / crystal_frequency); // crystal_frequency in MHz form 00372 if (dev < 15) { 00373 return this->set_deltaf_shape(dev); 00374 } 00375 } 00376 00377 return -1; 00378 } 00379 00380 template <class REG> 00381 int MAX4146X<REG>::adjust_manchester_bitrate(char rate) 00382 { 00383 this->data_rate = rate; 00384 00385 return 0; 00386 } 00387 00388 template <class REG> 00389 char MAX4146X<REG>::get_manchester_bitrate() 00390 { 00391 return this->data_rate; 00392 } 00393 00394 template <> 00395 int MAX4146X<max41460_reg_map_t>::send_data(uint8_t *data, uint32_t length) 00396 { 00397 if (this->preset_mode == 0) { 00398 00399 if (ssel != NULL) { 00400 *ssel = 0; 00401 } 00402 00403 spi_handler->write(0x7F & 0x0A); /*write mode and adress send*/ 00404 00405 spi_handler->write(0x01); /*write data SPI_EN1 clear*/ 00406 00407 00408 if (ssel != NULL) { 00409 *ssel = 1; 00410 } 00411 00412 wait_us(300); /* for waiting another SPI operation*/ 00413 00414 if (ssel != NULL) { 00415 *ssel = 0; 00416 } 00417 00418 spi_handler->write(0x7F & 0x10); /*write mode and adress send*/ 00419 00420 spi_handler->write(0x03); /*write data SPI_EN2 set*/ 00421 00422 if (ssel != NULL) { 00423 *ssel = 0; 00424 } 00425 00426 wait_us(300); /* for waiting another SPI operation*/ 00427 00428 } 00429 00430 return this->io_write(data, length); 00431 } 00432 00433 template <class REG> 00434 int MAX4146X<REG>::send_data(uint8_t *data, uint32_t length) 00435 { 00436 if (this->preset_mode == 0) { 00437 if (length > 32767) { 00438 return -100; 00439 } 00440 00441 this->adjust_baudrate(this->baud_rate); 00442 00443 // this->set_i2c_txen1(I2C_TXEN1_DISABLE); 00444 00445 char * value = (char *)malloc(17 * sizeof(char)); 00446 00447 if (value == NULL) { 00448 return -99; 00449 } 00450 00451 int rtn_val = i2c_handler->write(I2C_ADDRESS, (char *) 0x00, 1, true); 00452 rtn_val = i2c_handler->read(I2C_ADDRESS, value, length, true); 00453 if (rtn_val != 0) { 00454 return rtn_val; 00455 } 00456 00457 free(value); 00458 00459 uint8_t local_data[4+length]; 00460 00461 local_data[0] = CFG7_ADDR; 00462 local_data[1] = 0x04; 00463 local_data[2] = (uint8_t)((length >> 8) | 0x80); 00464 local_data[3] = (uint8_t)((length) & 0x0FF); 00465 00466 memcpy(&local_data[4], data, length); 00467 00468 i2c_handler->write(I2C_ADDRESS, (const char *)local_data, sizeof(local_data), false); 00469 00470 } else { 00471 this->io_write(data, length); 00472 } 00473 00474 return 0; 00475 } 00476 00477 template <class REG> 00478 int MAX4146X<REG>::io_write(uint8_t *data, uint32_t length) 00479 { 00480 //manchester array 00481 manchester_bit_array = new unsigned char[length * 2 * 8]; 00482 00483 //bit array 00484 bits_array = new unsigned char[length * 8]; 00485 00486 //byte to bit conversion 00487 for (int i = 0; i < length; i++) { 00488 for (int j = 0; j < 8; j++) { 00489 // Mask each bit in the byte and store it 00490 if (data[i] & (mask << j)) { 00491 bits_array[i * 8 + j] = 1; 00492 } else { 00493 bits_array[i * 8 + j] = 0; 00494 } 00495 } 00496 } 00497 00498 //manchester encode 00499 for (int i = 0; i < length * 8; i++) { 00500 if (bits_array[i] == 0) { 00501 //falling edge 00502 manchester_bit_array[2 * i] = 1; 00503 manchester_bit_array[2 * i + 1] = 0; 00504 } else { 00505 //rising edge 00506 manchester_bit_array[2 * i] = 0; 00507 manchester_bit_array[2 * i + 1] = 1; 00508 } 00509 } 00510 00511 delete[] bits_array; //delete bit array anymore not used 00512 00513 float result = (500.0 / data_rate); 00514 00515 bool rxFinished = false; 00516 Timer t; 00517 core_util_critical_section_enter(); 00518 *this->data_sent = 0; 00519 wait_us(100); 00520 *this->data_sent = 1; 00521 wait_us(350); 00522 *this->data_sent = 0; 00523 wait_us(10); 00524 t.start(); 00525 int manch_bit_counter = 0; 00526 do { 00527 if (t.read_us() >= (result * manch_bit_counter)) { 00528 if (manchester_bit_array[manch_bit_counter] == 0) { 00529 *this->data_sent = 0; 00530 } else { 00531 *this->data_sent = 1; 00532 } 00533 00534 manch_bit_counter++; 00535 00536 if (manch_bit_counter >= (length * 2 * 8)) { 00537 rxFinished = true; 00538 t.stop(); 00539 if (this->ssel != NULL) { 00540 *this->ssel = 1; 00541 } 00542 } 00543 00544 } 00545 } while (!rxFinished); 00546 *this->data_sent = 0; 00547 core_util_critical_section_exit(); 00548 00549 delete[] manchester_bit_array; //manchester array clean 00550 00551 return 0; 00552 } 00553 00554 template <class REG> 00555 int MAX4146X<REG>::set_softreset(softreset_t softreset) 00556 { 00557 SET_BIT_FIELD(CFG8_ADDR, this->reg->reg_cfg8, this->reg->reg_cfg8.bits.softreset, softreset); 00558 00559 return 0; 00560 } 00561 00562 template <class REG> 00563 int MAX4146X<REG>::set_xoclkdelay(xoclkdelay_t delay) 00564 { 00565 SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdelay, delay); 00566 00567 return 0; 00568 } 00569 00570 template <class REG> 00571 int MAX4146X<REG>::get_xoclkdelay(xoclkdelay_t *delay) 00572 { 00573 int ret; 00574 00575 ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); 00576 if (ret < 0) { 00577 return ret; 00578 } 00579 00580 *delay = (xoclkdelay_t)this->reg->reg_cfg1.bits.xoclkdelay; 00581 00582 return 0; 00583 } 00584 00585 template <class REG> 00586 int MAX4146X<REG>::get_fifo_flags(uint8_t *fifo_flags) 00587 { 00588 return read_register(I2C6_ADDR, fifo_flags, 1); 00589 } 00590 00591 template <class REG> 00592 int MAX4146X<REG>::get_pktcomplete(uint8_t *pktcomplete) 00593 { 00594 int ret; 00595 00596 ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 1); 00597 if (ret < 0) { 00598 return ret; 00599 } 00600 00601 *pktcomplete = (uint8_t)this->reg->reg_i2c4.bits.pktcomplete; 00602 00603 return 0; 00604 } 00605 00606 template <class REG> 00607 int MAX4146X<REG>::get_tx_pktlen(uint16_t *pktlen) 00608 { 00609 int ret; 00610 00611 ret = read_register(I2C4_ADDR, (uint8_t *) & (this->reg->reg_i2c4), 2); 00612 if (ret < 0) { 00613 return ret; 00614 } 00615 00616 *pktlen = (uint16_t)(((this->reg->reg_i2c4.bits.tx_pktlen_14_to_8) << 8) + (this->reg->reg_i2c5.raw)) ; 00617 00618 return 0; 00619 } 00620 00621 template <class REG> 00622 int MAX4146X<REG>::set_xoclkdiv(xoclkdiv_t div) 00623 { 00624 SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.xoclkdiv, div); 00625 00626 return 0; 00627 } 00628 00629 template <class REG> 00630 int MAX4146X<REG>::get_xoclkdiv(xoclkdiv_t* div) 00631 { 00632 int ret; 00633 00634 ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); 00635 if (ret < 0) { 00636 return ret; 00637 } 00638 00639 *div = (xoclkdiv_t)this->reg->reg_cfg1.bits.xoclkdiv; 00640 00641 return 0; 00642 } 00643 00644 template <class REG> 00645 int MAX4146X<REG>::set_fskshape(fskshape_t shape) 00646 { 00647 SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.fskshape, shape); 00648 00649 return 0; 00650 } 00651 00652 template <class REG> 00653 int MAX4146X<REG>::get_fskshape(fskshape_t* shape) 00654 { 00655 int ret; 00656 00657 ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); 00658 if (ret < 0) { 00659 return ret; 00660 } 00661 00662 *shape = (fskshape_t)this->reg->reg_cfg1.bits.fskshape; 00663 00664 return 0; 00665 } 00666 00667 template <class REG> 00668 int MAX4146X<REG>::set_sync(sync_t state) 00669 { 00670 SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.sync, state); 00671 00672 return 0; 00673 } 00674 00675 template <class REG> 00676 int MAX4146X<REG>::get_sync(sync_t* state) 00677 { 00678 int ret; 00679 00680 ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); 00681 if (ret < 0) { 00682 return ret; 00683 } 00684 00685 *state = (sync_t)this->reg->reg_cfg1.bits.sync; 00686 00687 return 0; 00688 } 00689 00690 template <class REG> 00691 int MAX4146X<REG>::set_modmode(modmode_t mode) 00692 { 00693 SET_BIT_FIELD(CFG1_ADDR, this->reg->reg_cfg1, this->reg->reg_cfg1.bits.modmode, mode); 00694 00695 return 0; 00696 } 00697 00698 template <class REG> 00699 int MAX4146X<REG>::get_modmode(modmode_t* mode) 00700 { 00701 int ret; 00702 00703 ret = read_register(CFG1_ADDR, (uint8_t *) & (this->reg->reg_cfg1), 1); 00704 if (ret < 0) { 00705 return ret; 00706 } 00707 00708 *mode = (modmode_t)this->reg->reg_cfg1.bits.modmode; 00709 00710 return 0; 00711 } 00712 00713 template <class REG> 00714 int MAX4146X<REG>::set_clkout_delay(clkout_delay_t delay) 00715 { 00716 SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.clkout_delay, delay); 00717 00718 return 0; 00719 } 00720 00721 template <class REG> 00722 int MAX4146X<REG>::get_clkout_delay(clkout_delay_t* delay) 00723 { 00724 int ret; 00725 00726 ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1); 00727 if (ret < 0) { 00728 return ret; 00729 } 00730 00731 *delay = (clkout_delay_t)this->reg->reg_cfg2.bits.clkout_delay; 00732 00733 return 0; 00734 } 00735 00736 template <class REG> 00737 int MAX4146X<REG>::set_bclk_postdiv(bclk_postdiv_t div) 00738 { 00739 SET_BIT_FIELD(CFG2_ADDR, this->reg->reg_cfg2, this->reg->reg_cfg2.bits.bclk_postdiv, div); 00740 00741 return 0; 00742 } 00743 00744 template <class REG> 00745 int MAX4146X<REG>::get_bclk_postdiv(bclk_postdiv_t* div) 00746 { 00747 int ret; 00748 00749 ret = read_register(CFG2_ADDR, (uint8_t *) & (this->reg->reg_cfg2), 1); 00750 if (ret < 0) { 00751 return ret; 00752 } 00753 00754 *div = (bclk_postdiv_t)this->reg->reg_cfg2.bits.bclk_postdiv; 00755 00756 return 0; 00757 } 00758 00759 template <class REG> 00760 int MAX4146X<REG>::set_bclk_prediv(uint8_t prediv) 00761 { 00762 if (prediv < 3) { 00763 return -1; 00764 } 00765 00766 SET_BIT_FIELD(CFG3_ADDR, this->reg->reg_cfg3, this->reg->reg_cfg3.bits.bclk_prediv, prediv); 00767 00768 return 0; 00769 } 00770 00771 template <class REG> 00772 int MAX4146X<REG>::get_bclk_prediv(uint8_t* prediv) 00773 { 00774 int ret; 00775 00776 ret = read_register(CFG3_ADDR, (uint8_t *) & (this->reg->reg_cfg3), 1); 00777 if (ret < 0) { 00778 return ret; 00779 } 00780 00781 *prediv = (uint8_t)this->reg->reg_cfg3.bits.bclk_prediv; 00782 00783 return 0; 00784 } 00785 00786 template <class REG> 00787 int MAX4146X<REG>::set_pwdn_mode(pwdn_mode_t pwdn_mode) 00788 { 00789 SET_BIT_FIELD(CFG4_ADDR, this->reg->reg_cfg4, this->reg->reg_cfg4.bits.pwdn_mode, pwdn_mode); 00790 00791 return 0; 00792 } 00793 00794 template <class REG> 00795 int MAX4146X<REG>::get_pwdn_mode(pwdn_mode_t* pwdn_mode) 00796 { 00797 int ret; 00798 00799 ret = read_register(CFG4_ADDR, (uint8_t *) & (this->reg->reg_cfg4), 1); 00800 if (ret < 0) { 00801 return ret; 00802 } 00803 00804 *pwdn_mode = (pwdn_mode_t)this->reg->reg_cfg4.bits.pwdn_mode; 00805 00806 return 0; 00807 } 00808 00809 template <class REG> 00810 int MAX4146X<REG>::set_tstep(uint8_t tstep) 00811 { 00812 SET_BIT_FIELD(CFG5_ADDR, this->reg->reg_cfg5, this->reg->reg_cfg5.bits.tstep, tstep); 00813 00814 return 0; 00815 } 00816 00817 template <class REG> 00818 int MAX4146X<REG>::get_tstep(uint8_t* tstep) 00819 { 00820 int ret; 00821 00822 ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_cfg5), 1); 00823 if (ret < 0) { 00824 return ret; 00825 } 00826 00827 *tstep = (uint8_t)this->reg->reg_cfg5.bits.tstep; 00828 00829 return 0; 00830 } 00831 /*sdivarci*/ 00832 template <class REG> 00833 int MAX4146X<REG>::set_i2c_txen1(i2c_txen1_t setting) 00834 { 00835 SET_BIT_FIELD(CFG6_ADDR, this->reg->reg_cfg6, this->reg->reg_cfg6.bits.i2c_txen1, setting); 00836 00837 return 0; 00838 } 00839 00840 template <class REG> 00841 int MAX4146X<REG>::set_i2c_txen2(i2c_txen2_t setting) 00842 { 00843 SET_BIT_FIELD(CFG7_ADDR, this->reg->reg_cfg7, this->reg->reg_cfg7.bits.i2c_txen2, setting); 00844 00845 return 0; 00846 } 00847 00848 template <class REG> 00849 int MAX4146X<REG>::set_i2c_data(uint8_t setting) 00850 { 00851 return write_register(I2C3_ADDR, (uint8_t *)&setting, 1); 00852 } 00853 00854 00855 00856 00857 template <class REG> 00858 int MAX4146X<REG>::set_pa_boost(pa_boost_t pa_boost) 00859 { 00860 SET_BIT_FIELD(SHDN_ADDR, this->reg->reg_shdn, this->reg->reg_shdn.bits.pa_boost, pa_boost); 00861 00862 return 0; 00863 } 00864 00865 template <class REG> 00866 int MAX4146X<REG>::get_pa_boost(pa_boost_t* pa_boost) 00867 { 00868 int ret; 00869 00870 ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_shdn), 1); 00871 if (ret < 0) { 00872 return ret; 00873 } 00874 00875 *pa_boost = (pa_boost_t)this->reg->reg_shdn.bits.pa_boost; 00876 00877 return 0; 00878 } 00879 00880 template <class REG> 00881 int MAX4146X<REG>::set_papwr(papwr_t papwr) 00882 { 00883 SET_BIT_FIELD(PA1_ADDR, this->reg->reg_pa1, this->reg->reg_pa1.bits.papwr, papwr); 00884 00885 return 0; 00886 } 00887 00888 template <class REG> 00889 int MAX4146X<REG>::get_papwr(papwr_t* papwr) 00890 { 00891 int ret; 00892 00893 ret = read_register(PA1_ADDR, (uint8_t *) & (this->reg->reg_pa1), 1); 00894 if (ret < 0) { 00895 return ret; 00896 } 00897 00898 *papwr = (papwr_t)this->reg->reg_pa1.bits.papwr; 00899 00900 return 0; 00901 } 00902 00903 template <class REG> 00904 int MAX4146X<REG>::set_pacap(pacap_t pacap) 00905 { 00906 SET_BIT_FIELD(PA2_ADDR, this->reg->reg_pa2, this->reg->reg_pa2.bits.pacap, pacap); 00907 00908 return 0; 00909 } 00910 00911 template <class REG> 00912 int MAX4146X<REG>::get_pacap(pacap_t* pacap) 00913 { 00914 int ret; 00915 00916 ret = read_register(CFG5_ADDR, (uint8_t *) & (this->reg->reg_pa2), 1); 00917 if (ret < 0) { 00918 return ret; 00919 } 00920 00921 *pacap = (pacap_t)this->reg->reg_pa2.bits.pacap; 00922 00923 return 0; 00924 } 00925 00926 template <class REG> 00927 int MAX4146X<REG>::set_cplin(cplin_t cplin) 00928 { 00929 SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.cplin, cplin); 00930 00931 return 0; 00932 } 00933 00934 template <class REG> 00935 int MAX4146X<REG>::get_cplin(cplin_t* cplin) 00936 { 00937 int ret; 00938 00939 ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); 00940 if (ret < 0) { 00941 return ret; 00942 } 00943 00944 *cplin = (cplin_t)this->reg->reg_pll1.bits.cplin; 00945 00946 return 0; 00947 } 00948 00949 template <class REG> 00950 int MAX4146X<REG>::set_fracmode(fracmode_t fracmode) 00951 { 00952 SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.fracmode, fracmode); 00953 00954 return 0; 00955 } 00956 00957 template <class REG> 00958 int MAX4146X<REG>::get_fracmode(fracmode_t* fracmode) 00959 { 00960 int ret; 00961 00962 ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); 00963 if (ret < 0) { 00964 return ret; 00965 } 00966 00967 *fracmode = (fracmode_t)this->reg->reg_pll1.bits.fracmode; 00968 00969 return 0; 00970 } 00971 00972 template <class REG> 00973 int MAX4146X<REG>::set_lodiv(lodiv_t lodiv) 00974 { 00975 SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lodiv, lodiv); 00976 00977 return 0; 00978 } 00979 00980 template <class REG> 00981 int MAX4146X<REG>::get_lodiv(lodiv_t * lodiv) 00982 { 00983 int ret; 00984 00985 ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); 00986 if (ret < 0) { 00987 return ret; 00988 } 00989 00990 *lodiv = (lodiv_t )this->reg->reg_pll1.bits.lodiv; 00991 00992 return 0; 00993 } 00994 00995 template <class REG> 00996 int MAX4146X<REG>::set_lomode(lomode_t lomode) 00997 { 00998 SET_BIT_FIELD(PLL1_ADDR, this->reg->reg_pll1, this->reg->reg_pll1.bits.lomode, lomode); 00999 01000 return 0; 01001 } 01002 01003 template <class REG> 01004 int MAX4146X<REG>::get_lomode(lomode_t* lomode) 01005 { 01006 int ret; 01007 01008 ret = read_register(PLL1_ADDR, (uint8_t *) & (this->reg->reg_pll1), 1); 01009 if (ret < 0) { 01010 return ret; 01011 } 01012 01013 *lomode = (lomode_t)this->reg->reg_pll1.bits.lomode; 01014 01015 return 0; 01016 } 01017 01018 template <class REG> 01019 int MAX4146X<REG>::set_cpval(cpval_t cpval) 01020 { 01021 01022 SET_BIT_FIELD(PLL2_ADDR, this->reg->reg_pll2, this->reg->reg_pll2.bits.cpval, cpval); 01023 01024 return 0; 01025 } 01026 01027 template <class REG> 01028 int MAX4146X<REG>::get_cpval(cpval_t* cpval) 01029 { 01030 int ret; 01031 01032 ret = read_register(PLL2_ADDR, (uint8_t *) & (this->reg->reg_pll2), 1); 01033 if (ret < 0) { 01034 return ret; 01035 } 01036 01037 *cpval = (cpval_t)this->reg->reg_pll2.bits.cpval; 01038 01039 return 0; 01040 } 01041 01042 template <class REG> 01043 int MAX4146X<REG>::set_frequency(uint32_t freq) 01044 { 01045 uint8_t value[3] = {(uint8_t)(freq >> 16), (uint8_t)(freq >> 8), (uint8_t)freq}; 01046 01047 return write_register(PLL3_ADDR, (uint8_t *)&value, 3); 01048 01049 } 01050 01051 template <class REG> 01052 int MAX4146X<REG>::get_frequency(uint32_t* freq) 01053 { 01054 int ret; 01055 01056 uint8_t value[3]; 01057 01058 ret = read_register(PLL3_ADDR, (uint8_t *)&value, 3); 01059 if (ret < 0) { 01060 return ret; 01061 } 01062 01063 *freq = (uint32_t)((value[0] << 16) + (value[1] << 8) + value[2]); 01064 01065 return 0; 01066 } 01067 01068 template <class REG> 01069 int MAX4146X<REG>::set_deltaf(uint8_t deltaf) 01070 { 01071 if (deltaf > 127) { 01072 return -1; 01073 } 01074 01075 SET_BIT_FIELD(PLL6_ADDR, this->reg->reg_pll6, this->reg->reg_pll6.bits.deltaf, deltaf); 01076 01077 return 0; 01078 } 01079 01080 template <class REG> 01081 int MAX4146X<REG>::get_deltaf(uint8_t* deltaf) 01082 { 01083 int ret; 01084 01085 ret = read_register(PLL6_ADDR, (uint8_t *) & (this->reg->reg_pll6), 1); 01086 if (ret < 0) { 01087 return ret; 01088 } 01089 01090 *deltaf = (uint8_t)this->reg->reg_pll6.bits.deltaf; 01091 01092 return 0; 01093 } 01094 01095 template <class REG> 01096 int MAX4146X<REG>::set_deltaf_shape(uint8_t deltaf_shape) 01097 { 01098 if (deltaf_shape > 15) { 01099 return -1; 01100 } 01101 01102 SET_BIT_FIELD(PLL7_ADDR, this->reg->reg_pll7, this->reg->reg_pll7.bits.deltaf_shape, deltaf_shape); 01103 01104 return 0; 01105 } 01106 01107 template <class REG> 01108 int MAX4146X<REG>::get_deltaf_shape(uint8_t* deltaf_shape) 01109 { 01110 int ret; 01111 01112 ret = read_register(PLL7_ADDR, (uint8_t *) & (this->reg->reg_pll7), 1); 01113 if (ret < 0) { 01114 return ret; 01115 } 01116 01117 *deltaf_shape = (uint8_t)this->reg->reg_pll7.bits.deltaf_shape; 01118 01119 return 0; 01120 } 01121 01122 template <class REG> 01123 int MAX4146X<REG>::set_pktlen_mode(pktlen_mode_t pktlen_mode) 01124 { 01125 SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_mode, pktlen_mode); 01126 01127 return 0; 01128 } 01129 01130 template <class REG> 01131 int MAX4146X<REG>::get_pktlen_mode(pktlen_mode_t* pktlen_mode) 01132 { 01133 int ret; 01134 01135 ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1); 01136 if (ret < 0) { 01137 return ret; 01138 } 01139 01140 *pktlen_mode = (pktlen_mode_t)this->reg->reg_i2c1.bits.pktlen_mode; 01141 01142 return 0; 01143 } 01144 01145 01146 template <class REG> 01147 int MAX4146X<REG>::set_i2c_pktlen(uint16_t pktlen) 01148 { 01149 if (pktlen > 0x7FF) { 01150 return -1; 01151 } 01152 01153 SET_BIT_FIELD(I2C1_ADDR, this->reg->reg_i2c1, this->reg->reg_i2c1.bits.pktlen_14_to_8, (uint8_t)((pktlen >> 8) & 0x07)); 01154 01155 uint8_t value = (uint8_t)(pktlen & 0xFF); 01156 01157 return write_register(I2C2_ADDR, (uint8_t *)&value, 1); 01158 } 01159 01160 template <class REG> 01161 int MAX4146X<REG>::get_i2c_pktlen(uint16_t* pktlen) 01162 { 01163 int ret; 01164 01165 ret = read_register(I2C1_ADDR, (uint8_t *) & (this->reg->reg_i2c1), 1); 01166 if (ret < 0) { 01167 return ret; 01168 } 01169 01170 ret = read_register(I2C2_ADDR, (uint8_t *) & (this->reg->reg_i2c2), 1); 01171 if (ret < 0) { 01172 return ret; 01173 } 01174 01175 *pktlen = (uint16_t)(((this->reg->reg_i2c1.raw & 0x7F)<<8) + (this->reg->reg_i2c2.raw &0x7F)); 01176 01177 return 0; 01178 } 01179 01180 template <class REG> 01181 int MAX4146X<REG>::initial_programming(void) 01182 { 01183 uint8_t value = 0x80; 01184 write_register(ADDL2_ADDR, (uint8_t *)&value, 1); 01185 01186 return write_register(CFG1_ADDR, default_register_value_1, 20); 01187 } 01188 01189 template <> 01190 int MAX4146X<max41460_reg_map_t>::initial_programming(void) 01191 { 01192 if (this->ssel != NULL){ 01193 *this->ssel = 0; 01194 wait_us(100); 01195 } 01196 01197 int rtn = write_register(CFG1_ADDR, default_register_value_0, 17); 01198 01199 if (this->ssel != NULL){ 01200 wait_us(90); 01201 *this->ssel = 1; 01202 } 01203 01204 return rtn; 01205 } 01206 01207 01208 template class MAX4146X<max41460_reg_map_t> ; 01209 template class MAX4146X<max41461_2_reg_map_t> ; 01210 template class MAX4146X<max41463_4_reg_map_t> ; 01211 01212
Generated on Tue Jul 12 2022 16:06:46 by
1.7.2