openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

merlin16_access.c (20264B)


      1 /***********************************************************************************
      2  ***********************************************************************************
      3  *  File Name     :  merlin16_access.c                                           *
      4  *  Created On    :  03 Nov 2015                                                   *
      5  *  Created By    :  Brent Roberts                                                 *
      6  *  Description   :  APIs for Serdes IPs                                           *
      7  *  Revision      :    *
      8  *                                                                                 *
      9  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
     10  * 
     11  * Copyright 2007-2019 Broadcom Inc. All rights reserved.                                                           *
     12  *  No portions of this material may be reproduced in any form without             *
     13  *  the written permission of:                                                     *
     14  *      Broadcom Corporation                                                       *
     15  *      5300 California Avenue                                                     *
     16  *      Irvine, CA  92617                                                          *
     17  *                                                                                 *
     18  *  All information contained in this document is Broadcom Corporation             *
     19  *  company private proprietary, and trade secret.                                 *
     20  */
     21 
     22 /** @file merlin16_access.c
     23  * Implementation of API uC access functions
     24  */
     25 
     26 #include "merlin16_access.h"
     27 #include "merlin16_common.h"
     28 #include "merlin16_functions.h"
     29 #include "merlin16_internal.h"
     30 #include "merlin16_internal_error.h"
     31 #include "merlin16_select_defns.h"
     32 
     33 
     34 /******************************************************/
     35 /*  Commands through Serdes FW DSC Command Interface  */
     36 /******************************************************/
     37 
     38 err_code_t merlin16_pmd_uc_cmd_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info) {
     39   err_code_t err_code;
     40   uint16_t   cmddata;
     41 
     42   err_code = merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */
     43   if (err_code) {
     44     EFUN_PRINTF(("ERROR : DSC ready for command timed out (before cmd) cmd = %d, supp_info = x%02x err=%d !\n", cmd, supp_info, err_code));
     45     return (err_code);
     46   }
     47   /*EFUN(wr_uc_dsc_supp_info(supp_info)); */                   /* Supplement info field */
     48   /*EFUN(wr_uc_dsc_error_found(0x0)    ); */                   /* Clear error found field */
     49   /*EFUN(wr_uc_dsc_gp_uc_req(cmd)      ); */                   /* Set command code */
     50   /*EFUN(wr_uc_dsc_ready_for_cmd(0x0)  ); */                   /* Issue command, by clearing "ready for command" field */
     51   cmddata = (((uint16_t)supp_info)<<8) | (uint16_t)cmd;        /* Combine writes to single write instead of 4 RMW */
     52 
     53   EFUN(reg_wr_DSC_A_DSC_UC_CTRL(cmddata));         
     54 
     55   return(ERR_CODE_NONE);
     56 }
     57 
     58 err_code_t merlin16_pmd_uc_cmd(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info, uint32_t timeout_ms) {
     59 
     60   EFUN(merlin16_pmd_uc_cmd_return_immediate(sa__, cmd, supp_info));    /* Invoke merlin16_uc_cmd and return control immediately */
     61 
     62   EFUN(merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */
     63   
     64   return(ERR_CODE_NONE);
     65 }
     66 
     67 
     68 err_code_t merlin16_pmd_uc_cmd_with_data_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info, uint16_t data) {
     69   uint16_t   cmddata;
     70   err_code_t err_code;
     71 
     72   err_code = merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */
     73   if (err_code) {
     74      EFUN_PRINTF(("ERROR : DSC ready for command timed out (before cmd) cmd = %d, supp_info = x%02x, data = x%04x err=%d !\n", cmd, supp_info, data,err_code));
     75     return (err_code);
     76   }
     77 
     78   EFUN(wr_uc_dsc_data(data));                                  /* Write value written to uc_dsc_data field */
     79   /*EFUN(wr_uc_dsc_supp_info(supp_info)); */                   /* Supplement info field */
     80   /*EFUN(wr_uc_dsc_error_found(0x0));     */                   /* Clear error found field */
     81   /*EFUN(wr_uc_dsc_gp_uc_req(cmd));       */                   /* Set command code */
     82   /*EFUN(wr_uc_dsc_ready_for_cmd(0x0));   */                   /* Issue command, by clearing "ready for command" field */
     83   cmddata = (((uint16_t)supp_info)<<8) | (uint16_t)cmd;        /* Combine writes to single write instead of 4 RMW */
     84 
     85   EFUN(reg_wr_DSC_A_DSC_UC_CTRL(cmddata));         
     86 
     87   return(ERR_CODE_NONE);
     88 }
     89 
     90 
     91 err_code_t merlin16_pmd_uc_cmd_with_data(srds_access_t *sa__, enum srds_pmd_uc_cmd_enum cmd, uint8_t supp_info, uint16_t data, uint32_t timeout_ms) {
     92 
     93     EFUN(merlin16_pmd_uc_cmd_with_data_return_immediate(sa__, cmd, supp_info, data)); /* Invoke merlin16_uc_cmd and return control immediately */
     94 
     95     EFUN(merlin16_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16 ready for command */
     96     return(ERR_CODE_NONE);
     97 }
     98 
     99 err_code_t merlin16_pmd_uc_control_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control) {
    100   return(merlin16_pmd_uc_cmd_return_immediate(sa__, CMD_UC_CTRL, (uint8_t) control));
    101 }
    102 
    103 err_code_t merlin16_pmd_uc_control(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control, uint32_t timeout_ms) {
    104   return(merlin16_pmd_uc_cmd(sa__, CMD_UC_CTRL, (uint8_t) control, timeout_ms));
    105 }
    106 
    107 err_code_t merlin16_pmd_uc_diag_cmd(srds_access_t *sa__, enum srds_pmd_uc_diag_cmd_enum control, uint32_t timeout_ms) {
    108   return(merlin16_pmd_uc_cmd(sa__, CMD_DIAG_EN, (uint8_t) control, timeout_ms));
    109 }
    110 
    111 /************************************************************/
    112 /*      Serdes IP RAM access - Lane RAM Variables           */
    113 /*----------------------------------------------------------*/
    114 /*   - through Micro Register Interface for PMD IPs         */
    115 /*   - through Serdes FW DSC Command Interface for Gallardo */
    116 /************************************************************/
    117 
    118 /* This function returns the absolute address of lane RAM variables given the offset address and lane */
    119 uint16_t merlin16_INTERNAL_get_lane_addr(uint16_t addr, uint8_t lane) {
    120     uint16_t lane_var_ram_base=0, lane_var_ram_size=0;
    121     uint16_t lane_addr_offset = 0;
    122 
    123     lane_var_ram_base = LANE_VAR_RAM_BASE;
    124     lane_var_ram_size = LANE_VAR_RAM_SIZE;
    125     lane_addr_offset = lane_var_ram_base+addr+(lane*lane_var_ram_size);
    126     return(lane_addr_offset);
    127 }
    128 
    129 /* Micro RAM Lane Byte Read */
    130 uint8_t merlin16_rdbl_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    131     uint8_t rddata;
    132     uint16_t lane_addr_offset = 0;
    133     uint8_t lane;
    134 
    135     if(!err_code_p) {
    136         return(0);
    137     }
    138 
    139     {
    140         lane = merlin16_get_physical_lane(sa__);
    141         lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane);
    142 
    143         EPSTM(rddata = merlin16_rdb_uc_ram(sa__, err_code_p, lane_addr_offset)); /* Use Micro register interface for reading RAM */
    144         return (rddata);
    145     }
    146 }
    147 
    148 /* Micro RAM Lane Byte Signed Read */
    149 int8_t merlin16_rdbls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    150   return ((int8_t) merlin16_rdbl_uc_var(sa__, err_code_p, addr));
    151 }
    152 
    153 /* Micro RAM Lane Word Read */
    154 uint16_t merlin16_rdwl_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    155     uint16_t rddata;
    156     uint16_t lane_addr_offset = 0;
    157     uint8_t lane;
    158 
    159     if(!err_code_p) {
    160         return(0);
    161     }
    162     if (addr%2 != 0) {                                                                /* Validate even address */
    163         *err_code_p = ERR_CODE_INVALID_RAM_ADDR;
    164         return (0);
    165     }
    166 
    167     {
    168         lane = merlin16_get_physical_lane(sa__);
    169         lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane);
    170 
    171         EPSTM(rddata = merlin16_rdw_uc_ram(sa__, err_code_p, lane_addr_offset)); /* Use Micro register interface for reading RAM */
    172         return (rddata);
    173     }
    174 }
    175 
    176 
    177 /* Micro RAM Lane Word Signed Read */
    178 int16_t merlin16_rdwls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    179   return ((int16_t) merlin16_rdwl_uc_var(sa__, err_code_p, addr));
    180 }
    181 
    182 /* Micro RAM Lane Byte Write */
    183 err_code_t merlin16_wrbl_uc_var(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) {
    184     uint16_t lane_addr_offset = 0;
    185     uint8_t lane;
    186 
    187 
    188     {
    189         lane = merlin16_get_physical_lane(sa__);
    190         lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane);
    191 
    192         return (merlin16_wrb_uc_ram(sa__, lane_addr_offset, wr_val));    /* Use Micro register interface for writing RAM */
    193     }
    194 }
    195 
    196 /* Micro RAM Lane Byte Signed Write */
    197 err_code_t merlin16_wrbls_uc_var(srds_access_t *sa__, uint16_t addr, int8_t wr_val) {
    198   return (merlin16_wrbl_uc_var(sa__, addr, wr_val));
    199 }
    200 
    201 /* Micro RAM Lane Word Write */
    202 err_code_t merlin16_wrwl_uc_var(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) {
    203     uint16_t lane_addr_offset = 0;
    204     uint8_t lane;
    205 
    206     if (addr%2 != 0) {                                                                /* Validate even address */
    207         return (_error(ERR_CODE_INVALID_RAM_ADDR));
    208     }
    209 
    210     {
    211         lane = merlin16_get_physical_lane(sa__);
    212         lane_addr_offset = merlin16_INTERNAL_get_lane_addr(addr,lane);
    213 
    214         return (merlin16_wrw_uc_ram(sa__, lane_addr_offset, wr_val));    /* Use Micro register interface for writing RAM */
    215     }
    216 
    217 }
    218 
    219 /* Micro RAM Lane Word Signed Write */
    220 err_code_t merlin16_wrwls_uc_var(srds_access_t *sa__, uint16_t addr, int16_t wr_val) {
    221   return (merlin16_wrwl_uc_var(sa__, addr,wr_val));
    222 }
    223 
    224 
    225 
    226 
    227 /************************************************************/
    228 /*      Serdes IP RAM access - Core RAM Variables           */
    229 /*----------------------------------------------------------*/
    230 /*   - through Micro Register Interface for PMD IPs         */
    231 /*   - through Serdes FW DSC Command Interface for Gallardo */
    232 /************************************************************/
    233 
    234 /* This function returns the absolute address of core RAM variables given the offset address and lane */
    235 uint16_t merlin16_INTERNAL_get_core_address(uint16_t addr, uint8_t lane) {
    236     uint16_t core_var_ram_base=0;
    237     uint16_t core_addr_offset = 0;
    238 
    239     core_var_ram_base = CORE_VAR_RAM_BASE;
    240     core_addr_offset = core_var_ram_base + addr;
    241 
    242     return(core_addr_offset);
    243 }
    244 
    245 /* Micro RAM Core Byte Read */
    246 uint8_t merlin16_rdbc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    247 
    248     uint8_t  rddata;
    249     uint8_t  lane;
    250     uint16_t core_addr_offset;
    251     if(!err_code_p) {
    252         return(0);
    253     }
    254 
    255     {
    256         lane = merlin16_get_physical_lane(sa__);
    257         core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane);
    258         EPSTM(rddata = merlin16_rdb_uc_ram(sa__, err_code_p, core_addr_offset));    /* Use Micro register interface for reading RAM */
    259         return (rddata);
    260     }
    261 }
    262 
    263 /* Micro RAM Core Byte Signed Read */
    264 int8_t merlin16_rdbcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    265   return ((int8_t) merlin16_rdbc_uc_var(sa__, err_code_p, addr));
    266 }
    267 
    268 /* Micro RAM Core Word Read */
    269 uint16_t merlin16_rdwc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    270     uint16_t rddata;
    271     uint8_t  lane;
    272     uint16_t core_addr_offset;
    273 
    274     if(!err_code_p) {
    275         return(0);
    276     }
    277     if (addr%2 != 0) {                                                                /* Validate even address */
    278         *err_code_p = ERR_CODE_INVALID_RAM_ADDR;
    279         return (0);
    280     }
    281 
    282     {
    283         lane = merlin16_get_physical_lane(sa__);
    284         core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane);
    285 
    286         EPSTM(rddata = merlin16_rdw_uc_ram(sa__, err_code_p, core_addr_offset));    /* Use Micro register interface for reading RAM */
    287         return (rddata);
    288     }
    289 }
    290 
    291 /* Micro RAM Core Word Signed Read */
    292 int16_t merlin16_rdwcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    293   return ((int16_t) merlin16_rdwc_uc_var(sa__, err_code_p, addr));
    294 }
    295 
    296 /* Micro RAM Core Byte Write  */
    297 err_code_t merlin16_wrbc_uc_var(srds_access_t *sa__, uint8_t addr, uint8_t wr_val) {
    298     uint8_t  lane;
    299     uint16_t core_addr_offset;
    300 
    301     {
    302         lane = merlin16_get_physical_lane(sa__);
    303         core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane);
    304 
    305         return (merlin16_wrb_uc_ram(sa__, core_addr_offset, wr_val));               /* Use Micro register interface for writing RAM */
    306     }
    307 
    308 }
    309 
    310 
    311 /* Micro RAM Core Byte Signed Write */
    312 err_code_t merlin16_wrbcs_uc_var(srds_access_t *sa__, uint8_t addr, int8_t wr_val) {
    313   return (merlin16_wrbc_uc_var(sa__, addr, wr_val));
    314 }
    315 
    316 /* Micro RAM Core Word Write  */
    317 err_code_t merlin16_wrwc_uc_var(srds_access_t *sa__, uint8_t addr, uint16_t wr_val) {
    318     uint8_t  lane;
    319     uint16_t core_addr_offset;
    320 
    321     {
    322         if (addr%2 != 0) {                                                              /* Validate even address */
    323             return (_error(ERR_CODE_INVALID_RAM_ADDR));
    324         }
    325 
    326         lane = merlin16_get_physical_lane(sa__);
    327         core_addr_offset = merlin16_INTERNAL_get_core_address(addr,lane);
    328         return (merlin16_wrw_uc_ram(sa__, core_addr_offset, wr_val));             /* Use Micro register interface for writing RAM */
    329     }
    330 }
    331 
    332 /* Micro RAM Core Word Signed Write */
    333 err_code_t merlin16_wrwcs_uc_var(srds_access_t *sa__, uint8_t addr, int16_t wr_val) {
    334   return(merlin16_wrwc_uc_var(sa__, addr,wr_val));
    335 }
    336 
    337 /*********************************************************/
    338 /*  Program RAM access through Micro Register Interface  */
    339 /*********************************************************/
    340 
    341 /* Micro Program Ram Long Read */
    342 uint32_t merlin16_rd_long_uc_prog_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    343    uint32_t rddata;
    344    if(!err_code_p) {
    345         return(0);
    346    }
    347    *err_code_p = ERR_CODE_NONE;
    348    EPFUN(wrc_micro_autoinc_rdaddr_en(1));
    349    EPFUN(wrc_micro_ra_rddatasize(0x1));                 /* Select 16bit read datasize */
    350    EPFUN(wrc_micro_ra_rdaddr_msw(0));                   /* Upper 16bits of ROM address to be read */
    351    EPFUN(wrc_micro_ra_rdaddr_lsw(addr));                /* Lower 16bits of ROM address to be read */
    352    EPSTM(rddata = rdc_micro_ra_rddata_lsw());           /* 16bit read data */
    353    EPSTM(rddata |= (rdc_micro_ra_rddata_lsw() << 16));  /* 16bit read data */
    354    return (rddata);
    355 }
    356 
    357 /* Micro Program RAM Block Read */
    358 err_code_t merlin16_rdblk_uc_prog_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) {
    359     merlin16_INTERNAL_rdblk_callback_arg_t arg;
    360 
    361     if(!mem) {
    362         return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    363     }
    364 
    365     arg.mem_ptr = mem;
    366     return merlin16_INTERNAL_rdblk_uc_generic_ram(sa__, addr, cnt, 0, cnt, &arg, merlin16_INTERNAL_rdblk_callback);
    367 }
    368 
    369 /*************************************************/
    370 /*  RAM access through Micro Register Interface  */
    371 /*************************************************/
    372 
    373 /* Micro RAM Long Write */
    374 err_code_t merlin16_wr_long_uc_ram(srds_access_t *sa__, uint16_t offset, uint32_t value) {
    375     EFUN(merlin16_wrw_uc_ram(sa__, offset+2, value >> 16));
    376     EFUN(merlin16_wrw_uc_ram(sa__, offset, value & 0xFFFF));
    377     return (ERR_CODE_NONE);
    378 }
    379 /* Micro RAM Word Write */
    380 err_code_t merlin16_wrw_uc_ram(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) {
    381 
    382     EFUN(wrc_micro_autoinc_wraddr_en(0));
    383     EFUN(wrc_micro_ra_wrdatasize(0x1));                 /* Select 16bit write datasize */
    384     EFUN(wrc_micro_ra_wraddr_msw(0x2000));              /* Upper 16bits of RAM address to be written to */
    385     EFUN(wrc_micro_ra_wraddr_lsw(addr));                /* Lower 16bits of RAM address to be written to */
    386     EFUN(wrc_micro_ra_wrdata_lsw(wr_val));              /* uC RAM lower 16bits write data */
    387     return (ERR_CODE_NONE);
    388 }
    389 
    390 /* Micro RAM Byte Write */
    391 err_code_t merlin16_wrb_uc_ram(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) {
    392     EFUN(wrc_micro_autoinc_wraddr_en(0));
    393     EFUN(wrc_micro_ra_wrdatasize(0x0));                 /* Select 8bit write datasize */
    394     EFUN(wrc_micro_ra_wraddr_msw(0x2000));              /* Upper 16bits of RAM address to be written to */
    395     EFUN(wrc_micro_ra_wraddr_lsw(addr));                /* Lower 16bits of RAM address to be written to */
    396     EFUN(wrc_micro_ra_wrdata_lsw(wr_val));              /* uC RAM lower 16bits write data */
    397     return (ERR_CODE_NONE);
    398 }
    399 
    400 /* Micro RAM Long Read */
    401 uint32_t merlin16_rd_long_uc_ram(srds_access_t *sa__, err_code_t *err, uint16_t offset) {
    402     uint32_t result;
    403     ESTM(result = merlin16_rdw_uc_ram(sa__, err, offset+2) << 16);
    404     ESTM(result |= merlin16_rdw_uc_ram(sa__, err, offset) & 0xFFFF);
    405     return result;
    406 }
    407 /* Micro RAM Word Read */
    408 uint16_t merlin16_rdw_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    409    uint16_t rddata;
    410    if(!err_code_p) {
    411         return(0);
    412    }
    413    *err_code_p = ERR_CODE_NONE;
    414    EPFUN(wrc_micro_autoinc_rdaddr_en(0));
    415    EPFUN(wrc_micro_ra_rddatasize(0x1));                 /* Select 16bit read datasize */
    416    EPFUN(wrc_micro_ra_rdaddr_msw(0x2000));              /* Upper 16bits of RAM address to be read */
    417    EPFUN(wrc_micro_ra_rdaddr_lsw(addr));                /* Lower 16bits of RAM address to be read */
    418    EPSTM(rddata = rdc_micro_ra_rddata_lsw());           /* 16bit read data */
    419    return (rddata);
    420 }
    421 
    422 /* Micro RAM Byte Read */
    423 uint8_t merlin16_rdb_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    424     uint8_t rddata;
    425     if(!err_code_p) {
    426         return(0);
    427     }
    428     *err_code_p = ERR_CODE_NONE;
    429     EPFUN(wrc_micro_autoinc_rdaddr_en(0));
    430     EPFUN(wrc_micro_ra_rddatasize(0x0));                 /* Select 8bit read datasize */
    431     EPFUN(wrc_micro_ra_rdaddr_msw(0x2000));              /* Upper 16bits of RAM address to be read */
    432     EPFUN(wrc_micro_ra_rdaddr_lsw(addr));                /* Lower 16bits of RAM address to be read */
    433     EPSTM(rddata = (uint8_t) rdc_micro_ra_rddata_lsw()); /* 16bit read data */
    434     return (rddata);
    435 }
    436 
    437 /* Micro RAM Word Signed Write */
    438 err_code_t merlin16_wrws_uc_ram(srds_access_t *sa__, uint16_t addr, int16_t wr_val) {
    439     return (merlin16_wrw_uc_ram(sa__, addr, wr_val));
    440 }
    441 
    442 /* Micro RAM Byte Signed Write */
    443 err_code_t merlin16_wrbs_uc_ram(srds_access_t *sa__, uint16_t addr, int8_t wr_val) {
    444     return (merlin16_wrb_uc_ram(sa__, addr, wr_val));
    445 }
    446 
    447 /* Micro RAM Word Signed Read */
    448 int16_t merlin16_rdws_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    449     return ((int16_t)merlin16_rdw_uc_ram(sa__, err_code_p, addr));
    450 }
    451 
    452 /* Micro RAM Byte Signed Read */
    453 int8_t merlin16_rdbs_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    454     return ((int8_t)merlin16_rdb_uc_ram(sa__, err_code_p, addr));
    455 }
    456 
    457 /* Micro RAM Block Read */
    458 err_code_t merlin16_rdblk_uc_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) {
    459     merlin16_INTERNAL_rdblk_callback_arg_t arg;
    460 
    461     if(!mem) {
    462         return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    463     }
    464 
    465     arg.mem_ptr = mem;
    466     return merlin16_INTERNAL_rdblk_uc_generic_ram(sa__, (uint32_t)addr | 0x20000000, cnt, 0, cnt, &arg, merlin16_INTERNAL_rdblk_callback);
    467 }
    468 
    469 /**************************/
    470 /*  Temperature reading   */
    471 /**************************/
    472 
    473 err_code_t merlin16_read_die_temperature (srds_access_t *sa__, int16_t *die_temp) {
    474 
    475     uint16_t die_temp_sensor_reading;
    476 
    477     ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi());
    478     *die_temp = _bin_to_degC(die_temp_sensor_reading);
    479 
    480     return(ERR_CODE_NONE);
    481 }
    482 
    483 
    484 err_code_t merlin16_read_die_temperature_double (srds_access_t *sa__, USR_DOUBLE *die_temp) {
    485 #ifdef SERDES_API_FLOATING_POINT
    486     uint16_t die_temp_sensor_reading;
    487 
    488     ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi());
    489 
    490     *die_temp = _bin_to_degC_double(die_temp_sensor_reading);
    491 
    492     return(ERR_CODE_NONE);
    493 #else
    494     *die_temp = 0;
    495     EFUN_PRINTF((" Function 'merlin16_read_die_temperature_double' needs SERDES_API_FLOATING_POINT defined to operate \n"));
    496     return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    497 #endif
    498 }
    499