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_pcieg3_access.c (20878B)


      1 /***********************************************************************************
      2  ***********************************************************************************
      3  *  File Name     :  merlin16_pcieg3_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_pcieg3_access.c
     23  * Implementation of API uC access functions
     24  */
     25 
     26 #include "merlin16_pcieg3_access.h"
     27 #include "merlin16_pcieg3_common.h"
     28 #include "merlin16_pcieg3_functions.h"
     29 #include "merlin16_pcieg3_internal.h"
     30 #include "merlin16_pcieg3_internal_error.h"
     31 #include "merlin16_pcieg3_select_defns.h"
     32 
     33 
     34 /******************************************************/
     35 /*  Commands through Serdes FW DSC Command Interface  */
     36 /******************************************************/
     37 
     38 err_code_t merlin16_pcieg3_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_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 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_pcieg3_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_pcieg3_pmd_uc_cmd_return_immediate(sa__, cmd, supp_info));    /* Invoke merlin16_pcieg3_uc_cmd and return control immediately */
     61 
     62   EFUN(merlin16_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 ready for command */
     63   
     64   return(ERR_CODE_NONE);
     65 }
     66 
     67 
     68 err_code_t merlin16_pcieg3_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_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, 1, cmd); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 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_pcieg3_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_pcieg3_pmd_uc_cmd_with_data_return_immediate(sa__, cmd, supp_info, data)); /* Invoke merlin16_pcieg3_uc_cmd and return control immediately */
     94 
     95     EFUN(merlin16_pcieg3_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(sa__, timeout_ms, cmd)); /* Poll for uc_dsc_ready_for_cmd = 1 to indicate merlin16_pcieg3 ready for command */
     96     return(ERR_CODE_NONE);
     97 }
     98 
     99 err_code_t merlin16_pcieg3_pmd_uc_control_return_immediate(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control) {
    100   return(merlin16_pcieg3_pmd_uc_cmd_return_immediate(sa__, CMD_UC_CTRL, (uint8_t) control));
    101 }
    102 
    103 err_code_t merlin16_pcieg3_pmd_uc_control(srds_access_t *sa__, enum srds_pmd_uc_ctrl_cmd_enum control, uint32_t timeout_ms) {
    104   return(merlin16_pcieg3_pmd_uc_cmd(sa__, CMD_UC_CTRL, (uint8_t) control, timeout_ms));
    105 }
    106 
    107 err_code_t merlin16_pcieg3_pmd_uc_diag_cmd(srds_access_t *sa__, enum srds_pmd_uc_diag_cmd_enum control, uint32_t timeout_ms) {
    108   return(merlin16_pcieg3_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_pcieg3_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_pcieg3_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_pcieg3_get_lane(sa__);
    141         lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane);
    142 
    143         EPSTM(rddata = merlin16_pcieg3_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_pcieg3_rdbls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    150   return ((int8_t) merlin16_pcieg3_rdbl_uc_var(sa__, err_code_p, addr));
    151 }
    152 
    153 /* Micro RAM Lane Word Read */
    154 uint16_t merlin16_pcieg3_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_pcieg3_get_lane(sa__);
    169         lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane);
    170 
    171         EPSTM(rddata = merlin16_pcieg3_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_pcieg3_rdwls_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    179   return ((int16_t) merlin16_pcieg3_rdwl_uc_var(sa__, err_code_p, addr));
    180 }
    181 
    182 /* Micro RAM Lane Byte Write */
    183 err_code_t merlin16_pcieg3_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_pcieg3_get_lane(sa__);
    190         lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane);
    191 
    192         return (merlin16_pcieg3_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_pcieg3_wrbls_uc_var(srds_access_t *sa__, uint16_t addr, int8_t wr_val) {
    198   return (merlin16_pcieg3_wrbl_uc_var(sa__, addr, wr_val));
    199 }
    200 
    201 /* Micro RAM Lane Word Write */
    202 err_code_t merlin16_pcieg3_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         lane = merlin16_pcieg3_get_lane(sa__);
    211         lane_addr_offset = merlin16_pcieg3_INTERNAL_get_lane_addr(addr,lane);
    212 
    213         return (merlin16_pcieg3_wrw_uc_ram(sa__, lane_addr_offset, wr_val));    /* Use Micro register interface for writing RAM */
    214 
    215 
    216 }
    217 
    218 /* Micro RAM Lane Word Signed Write */
    219 err_code_t merlin16_pcieg3_wrwls_uc_var(srds_access_t *sa__, uint16_t addr, int16_t wr_val) {
    220   return (merlin16_pcieg3_wrwl_uc_var(sa__, addr,wr_val));
    221 }
    222 
    223 
    224 
    225 
    226 /************************************************************/
    227 /*      Serdes IP RAM access - Core RAM Variables           */
    228 /*----------------------------------------------------------*/
    229 /*   - through Micro Register Interface for PMD IPs         */
    230 /*   - through Serdes FW DSC Command Interface for Gallardo */
    231 /************************************************************/
    232 
    233 /* This function returns the absolute address of core RAM variables given the offset address and lane */
    234 uint16_t merlin16_pcieg3_INTERNAL_get_core_address(uint16_t addr, uint8_t lane) {
    235     uint16_t core_var_ram_base=0;
    236     uint16_t core_addr_offset = 0;
    237 
    238     core_var_ram_base = CORE_VAR_RAM_BASE;
    239     core_addr_offset = core_var_ram_base + addr;
    240 
    241     return(core_addr_offset);
    242 }
    243 
    244 /* Micro RAM Core Byte Read */
    245 uint8_t merlin16_pcieg3_rdbc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    246 
    247     uint8_t  rddata;
    248     uint8_t  lane;
    249     uint16_t core_addr_offset;
    250     if(!err_code_p) {
    251         return(0);
    252     }
    253 
    254         lane = merlin16_pcieg3_get_lane(sa__);
    255         core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane);
    256         EPSTM(rddata = merlin16_pcieg3_rdb_uc_ram(sa__, err_code_p, core_addr_offset));    /* Use Micro register interface for reading RAM */
    257         return (rddata);
    258 
    259 }
    260 
    261 /* Micro RAM Core Byte Signed Read */
    262 int8_t merlin16_pcieg3_rdbcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    263   return ((int8_t) merlin16_pcieg3_rdbc_uc_var(sa__, err_code_p, addr));
    264 }
    265 
    266 /* Micro RAM Core Word Read */
    267 uint16_t merlin16_pcieg3_rdwc_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    268     uint16_t rddata;
    269     uint8_t  lane;
    270     uint16_t core_addr_offset;
    271 
    272     if(!err_code_p) {
    273         return(0);
    274     }
    275     if (addr%2 != 0) {                                                                /* Validate even address */
    276         *err_code_p = ERR_CODE_INVALID_RAM_ADDR;
    277         return (0);
    278     }
    279 
    280         lane = merlin16_pcieg3_get_lane(sa__);
    281         core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane);
    282 
    283         EPSTM(rddata = merlin16_pcieg3_rdw_uc_ram(sa__, err_code_p, core_addr_offset));    /* Use Micro register interface for reading RAM */
    284         return (rddata);
    285 
    286 }
    287 
    288 /* Micro RAM Core Word Signed Read */
    289 int16_t merlin16_pcieg3_rdwcs_uc_var(srds_access_t *sa__, err_code_t *err_code_p, uint8_t addr) {
    290   return ((int16_t) merlin16_pcieg3_rdwc_uc_var(sa__, err_code_p, addr));
    291 }
    292 
    293 /* Micro RAM Core Byte Write  */
    294 err_code_t merlin16_pcieg3_wrbc_uc_var(srds_access_t *sa__, uint8_t addr, uint8_t wr_val) {
    295     uint8_t  lane;
    296     uint16_t core_addr_offset;
    297 
    298         lane = merlin16_pcieg3_get_lane(sa__);
    299         core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane);
    300 
    301         return (merlin16_pcieg3_wrb_uc_ram(sa__, core_addr_offset, wr_val));               /* Use Micro register interface for writing RAM */
    302 
    303 
    304 }
    305 
    306 
    307 /* Micro RAM Core Byte Signed Write */
    308 err_code_t merlin16_pcieg3_wrbcs_uc_var(srds_access_t *sa__, uint8_t addr, int8_t wr_val) {
    309   return (merlin16_pcieg3_wrbc_uc_var(sa__, addr, wr_val));
    310 }
    311 
    312 /* Micro RAM Core Word Write  */
    313 err_code_t merlin16_pcieg3_wrwc_uc_var(srds_access_t *sa__, uint8_t addr, uint16_t wr_val) {
    314     uint8_t  lane;
    315     uint16_t core_addr_offset;
    316 
    317 
    318         if (addr%2 != 0) {                                                              /* Validate even address */
    319             return (_error(ERR_CODE_INVALID_RAM_ADDR));
    320         }
    321 
    322         lane = merlin16_pcieg3_get_lane(sa__);
    323         core_addr_offset = merlin16_pcieg3_INTERNAL_get_core_address(addr,lane);
    324         return (merlin16_pcieg3_wrw_uc_ram(sa__, core_addr_offset, wr_val));             /* Use Micro register interface for writing RAM */
    325 
    326 }
    327 
    328 /* Micro RAM Core Word Signed Write */
    329 err_code_t merlin16_pcieg3_wrwcs_uc_var(srds_access_t *sa__, uint8_t addr, int16_t wr_val) {
    330   return(merlin16_pcieg3_wrwc_uc_var(sa__, addr,wr_val));
    331 }
    332 
    333 /*********************************************************/
    334 /*  Program RAM access through Micro Register Interface  */
    335 /*********************************************************/
    336 
    337 /* Micro Program Ram Long Read */
    338 uint32_t merlin16_pcieg3_rd_long_uc_prog_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    339    uint32_t rddata;
    340    if(!err_code_p) {
    341         return(0);
    342    }
    343    *err_code_p = ERR_CODE_NONE;
    344    EPFUN(wrc_micro_autoinc_rdaddr_en(1));
    345    EPFUN(wrc_micro_ra_rddatasize(0x1));                 /* Select 16bit read datasize */
    346    EPFUN(wrc_micro_ra_rdaddr_msw(0));                   /* Upper 16bits of ROM address to be read */
    347    EPFUN(wrc_micro_ra_rdaddr_lsw(addr));                /* Lower 16bits of ROM address to be read */
    348    EPSTM(rddata = rdc_micro_ra_rddata_lsw());           /* 16bit read data */
    349    EPSTM(rddata |= (rdc_micro_ra_rddata_lsw() << 16));  /* 16bit read data */
    350    return (rddata);
    351 }
    352 
    353 /* Micro Program RAM Block Read */
    354 err_code_t merlin16_pcieg3_rdblk_uc_prog_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) {
    355     merlin16_pcieg3_INTERNAL_rdblk_callback_arg_t arg;
    356 
    357     if(!mem) {
    358         return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    359     }
    360 
    361     arg.mem_ptr = mem;
    362     return merlin16_pcieg3_INTERNAL_rdblk_uc_generic_ram(sa__, addr, cnt, 0, cnt, &arg, merlin16_pcieg3_INTERNAL_rdblk_callback);
    363 }
    364 
    365 /*************************************************/
    366 /*  RAM access through Micro Register Interface  */
    367 /*************************************************/
    368 
    369 /* Micro RAM Long Write */
    370 err_code_t merlin16_pcieg3_wr_long_uc_ram(srds_access_t *sa__, uint16_t offset, uint32_t value) {
    371     EFUN(merlin16_pcieg3_wrw_uc_ram(sa__, offset+2, value >> 16));
    372     EFUN(merlin16_pcieg3_wrw_uc_ram(sa__, offset, value & 0xFFFF));
    373     return (ERR_CODE_NONE);
    374 }
    375 /* Micro RAM Word Write */
    376 err_code_t merlin16_pcieg3_wrw_uc_ram(srds_access_t *sa__, uint16_t addr, uint16_t wr_val) {
    377 
    378     EFUN(wrc_micro_autoinc_wraddr_en(0));
    379     EFUN(wrc_micro_ra_wrdatasize(0x1));                 /* Select 16bit write datasize */
    380     EFUN(wrc_micro_ra_wraddr_msw(0x2000));              /* Upper 16bits of RAM address to be written to */
    381     EFUN(wrc_micro_ra_wraddr_lsw(addr));                /* Lower 16bits of RAM address to be written to */
    382     EFUN(wrc_micro_ra_wrdata_lsw(wr_val));              /* uC RAM lower 16bits write data */
    383     return (ERR_CODE_NONE);
    384 }
    385 
    386 /* Micro RAM Byte Write */
    387 err_code_t merlin16_pcieg3_wrb_uc_ram(srds_access_t *sa__, uint16_t addr, uint8_t wr_val) {
    388     EFUN(wrc_micro_autoinc_wraddr_en(0));
    389     EFUN(wrc_micro_ra_wrdatasize(0x0));                 /* Select 8bit write datasize */
    390     EFUN(wrc_micro_ra_wraddr_msw(0x2000));              /* Upper 16bits of RAM address to be written to */
    391     EFUN(wrc_micro_ra_wraddr_lsw(addr));                /* Lower 16bits of RAM address to be written to */
    392     EFUN(wrc_micro_ra_wrdata_lsw(wr_val));              /* uC RAM lower 16bits write data */
    393     return (ERR_CODE_NONE);
    394 }
    395 
    396 /* Micro RAM Long Read */
    397 uint32_t merlin16_pcieg3_rd_long_uc_ram(srds_access_t *sa__, err_code_t *err, uint16_t offset) {
    398     uint32_t result;
    399     ESTM(result = merlin16_pcieg3_rdw_uc_ram(sa__, err, offset+2) << 16);
    400     ESTM(result |= merlin16_pcieg3_rdw_uc_ram(sa__, err, offset) & 0xFFFF);
    401     return result;
    402 }
    403 /* Micro RAM Word Read */
    404 uint16_t merlin16_pcieg3_rdw_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    405    uint16_t rddata;
    406    if(!err_code_p) {
    407         return(0);
    408    }
    409    *err_code_p = ERR_CODE_NONE;
    410    EPFUN(wrc_micro_autoinc_rdaddr_en(0));
    411    EPFUN(wrc_micro_ra_rddatasize(0x1));                 /* Select 16bit read datasize */
    412    EPFUN(wrc_micro_ra_rdaddr_msw(0x2000));              /* Upper 16bits of RAM address to be read */
    413    EPFUN(wrc_micro_ra_rdaddr_lsw(addr));                /* Lower 16bits of RAM address to be read */
    414    EPSTM(rddata = rdc_micro_ra_rddata_lsw());           /* 16bit read data */
    415    return (rddata);
    416 }
    417 
    418 /* Micro RAM Byte Read */
    419 uint8_t merlin16_pcieg3_rdb_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    420     uint8_t rddata;
    421     if(!err_code_p) {
    422         return(0);
    423     }
    424     *err_code_p = ERR_CODE_NONE;
    425     EPFUN(wrc_micro_autoinc_rdaddr_en(0));
    426     EPFUN(wrc_micro_ra_rddatasize(0x0));                 /* Select 8bit read datasize */
    427     EPFUN(wrc_micro_ra_rdaddr_msw(0x2000));              /* Upper 16bits of RAM address to be read */
    428     EPFUN(wrc_micro_ra_rdaddr_lsw(addr));                /* Lower 16bits of RAM address to be read */
    429     EPSTM(rddata = (uint8_t) rdc_micro_ra_rddata_lsw()); /* 16bit read data */
    430     return (rddata);
    431 }
    432 
    433 /* Micro RAM Word Signed Write */
    434 err_code_t merlin16_pcieg3_wrws_uc_ram(srds_access_t *sa__, uint16_t addr, int16_t wr_val) {
    435     return (merlin16_pcieg3_wrw_uc_ram(sa__, addr, wr_val));
    436 }
    437 
    438 /* Micro RAM Byte Signed Write */
    439 err_code_t merlin16_pcieg3_wrbs_uc_ram(srds_access_t *sa__, uint16_t addr, int8_t wr_val) {
    440     return (merlin16_pcieg3_wrb_uc_ram(sa__, addr, wr_val));
    441 }
    442 
    443 /* Micro RAM Word Signed Read */
    444 int16_t merlin16_pcieg3_rdws_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    445     return ((int16_t)merlin16_pcieg3_rdw_uc_ram(sa__, err_code_p, addr));
    446 }
    447 
    448 /* Micro RAM Byte Signed Read */
    449 int8_t merlin16_pcieg3_rdbs_uc_ram(srds_access_t *sa__, err_code_t *err_code_p, uint16_t addr) {
    450     return ((int8_t)merlin16_pcieg3_rdb_uc_ram(sa__, err_code_p, addr));
    451 }
    452 
    453 /* Micro RAM Block Read */
    454 err_code_t merlin16_pcieg3_rdblk_uc_ram(srds_access_t *sa__, uint8_t *mem, uint16_t addr, uint16_t cnt) {
    455     merlin16_pcieg3_INTERNAL_rdblk_callback_arg_t arg;
    456 
    457     if(!mem) {
    458         return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    459     }
    460 
    461     arg.mem_ptr = mem;
    462     return merlin16_pcieg3_INTERNAL_rdblk_uc_generic_ram(sa__, (uint32_t)addr | 0x20000000, cnt, 0, cnt, &arg, merlin16_pcieg3_INTERNAL_rdblk_callback);
    463 }
    464 
    465 /**************************/
    466 /*  Temperature reading   */
    467 /**************************/
    468 
    469 err_code_t merlin16_pcieg3_read_die_temperature (srds_access_t *sa__, int16_t *die_temp) {
    470 
    471     uint16_t die_temp_sensor_reading;
    472 
    473     ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi());
    474     *die_temp = _bin_to_degC(die_temp_sensor_reading);
    475 
    476     return(ERR_CODE_NONE);
    477 }
    478 
    479 
    480 err_code_t merlin16_pcieg3_read_die_temperature_double (srds_access_t *sa__, USR_DOUBLE *die_temp) {
    481 #ifdef SERDES_API_FLOATING_POINT
    482     uint16_t die_temp_sensor_reading;
    483 
    484     ESTM(die_temp_sensor_reading=rdc_micro_pvt_tempdata_rmi());
    485 
    486     *die_temp = _bin_to_degC_double(die_temp_sensor_reading);
    487 
    488     return(ERR_CODE_NONE);
    489 #else
    490     *die_temp = 0;
    491     EFUN_PRINTF((" Function 'merlin16_pcieg3_read_die_temperature_double' needs SERDES_API_FLOATING_POINT defined to operate \n"));
    492     return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT));
    493 #endif
    494 }
    495