📄 pu_irom_sdhc_ip.c
字号:
/*! * execute a command and wait for the response */U32 interface_send_cmd_wait_resp(command_t *cmd){ /* Start the clock */ sdhc_start_clk(); /* Clear Interrupt status Register */ psdhc->sdhc_status = 0xFFFFFFFF; /* Enable interrupts */ psdhc->sdhc_int_cntr = SDHC_INTERRUPTS_MASK; /* Configure Command */ sdhc_cmd_config(cmd); /* Wait for interrupt end_command_resp */ sdhc_wait_end_cmd_resp_intr(); /* Mask all interrupts */ psdhc->sdhc_int_cntr = 0; /* Check if an error occured */ return sdhc_check_response();}/*! * Read the response returned by the card after a command */U32 interface_read_response(command_response_t * resp){ U32 status = SDHC_STATUS_FAILURE; U16 resp_h = 0; U16 resp_l = 0; if(resp != 0) { /* Stop MMC clock */ sdhc_stop_clk(); if(resp->format == RESPONSE_136) { /* response is read in MSB first order */ resp_h = psdhc->sdhc_res_fifo & 0xffff; resp_l = psdhc->sdhc_res_fifo & 0xffff; resp->cmd_rsp3 = (resp_h << 16) | resp_l; resp_h = psdhc->sdhc_res_fifo & 0xffff; resp_l = psdhc->sdhc_res_fifo & 0xffff; resp->cmd_rsp2 = (resp_h << 16) | resp_l; resp_h = psdhc->sdhc_res_fifo & 0xffff; resp_l = psdhc->sdhc_res_fifo & 0xffff; resp->cmd_rsp1 = (resp_h << 16) | resp_l; resp_h = psdhc->sdhc_res_fifo & 0xffff; resp_l = psdhc->sdhc_res_fifo & 0xffff; resp->cmd_rsp0 = (resp_h << 16) | resp_l; } else if((resp->format == RESPONSE_48) || (resp->format == RESPONSE_48_WITHOUT_CRC)) { /* Extract the bit 8-39 from the 48 bit response and return 32-bit significant response in cmd_rsp0 */ resp->cmd_rsp0 = ((UINT32)(psdhc->sdhc_res_fifo & 0x00ff) << 24) | ((UINT32)(psdhc->sdhc_res_fifo & 0xffff) << 8) | ((UINT32)(psdhc->sdhc_res_fifo & 0xff00) >> 8); } /* Clear w1c bits from STATUS register */ psdhc->sdhc_status = psdhc->sdhc_status | SDHC_STATUS_CLEAR; status = SDHC_STATUS_PASS; } return status;}/*! * Read data from cmd->arg address to cmd->arg + blk_len. */U32 interface_data_read(U32* dest_ptr, U32 blk_len) { U32 i,j=0; U32 status = SDHC_STATUS_FAILURE; /* Enable interrupts */ psdhc->sdhc_int_cntr = SDHC_INTERRUPTS_MASK; for(i = 0; i < blk_len/(FIFO_SIZE*FIFO_SIZE); i++) { /* Wait for BRR bit to be set */ sdhc_wait_buf_rdy_intr(SDHC_STATUS_BUF_READ_RDY_MSK); for(j=0;j<FIFO_SIZE;j++) { /* Read 32 bit data from buffer data port register */ *dest_ptr = psdhc->sdhc_buffer_access; /*increment destination pointer */ dest_ptr++; } } /* Wait for transfer complete operation interrupt */ sdhc_wait_op_done_intr(SDHC_STATUS_READ_OP_DONE_MSK); /* Check for status errors */ status = sdhc_check_data(SDHC_STATUS_READ_OP_DONE_MSK, SDHC_STATUS_TIME_OUT_READ, SDHC_STATUS_READ_CRC_ERR_MSK); return status; }U32 interface_data_write(U32* dest_ptr, U32 blk_len){ U32 i,j=0; U32 status = SDHC_STATUS_FAILURE; /* Enable interrupts */ psdhc->sdhc_int_cntr = SDHC_INTERRUPTS_MASK; for(i = 0; i < blk_len/(FIFO_SIZE*FIFO_SIZE); i++) { /* Wait for BRR bit to be set */ sdhc_wait_buf_rdy_intr(SDHC_STATUS_BUF_WRITE_RDY_MSK); for(j=0;j<FIFO_SIZE;j++) { /* Read 32 bit data from buffer data port register */ psdhc->sdhc_buffer_access =*dest_ptr;; /*increment destination pointer */ dest_ptr++; } } /* Wait for transfer complete operation interrupt */ sdhc_wait_op_done_intr(SDHC_STATUS_WRITE_OP_DONE_MSK); /* Check for status errors */ status = sdhc_check_data(SDHC_STATUS_WRITE_OP_DONE_MSK, SDHC_STATUS_WR_CRC_ERR_CODE_MSK, SDHC_STATUS_WRITE_CRC_ERR_MSK); return status; }/*! * Execute a software reset. */ void interface_reset(){ psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_RESET; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_RESET | SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP; psdhc->sdhc_str_stp_clk = SDHC_STR_STP_CLK_STOP;}/*! * This function configures the clock rate. */ void interface_configure_clock(sdhc_freq_t frequency){ /* Clear the clock rate register */ psdhc->sdhc_clk_rate = psdhc->sdhc_clk_rate & ~SDHC_CLK_RATE_PRESCALER_MASK; psdhc->sdhc_clk_rate = psdhc->sdhc_clk_rate & ~SDHC_CLK_RATE_DIVIDE_MASK; if ( ( (*(VP_U32)CCM_CCMR ) & CLOCK_SEL_MASK ) == CKIL_CLOCK_SEL) { /* IPG_PER_CLK is 49.15 MHz after reset */ if(frequency == IDENTIFICATION_FREQ) { /* Below 100 kHz ( ~96 kHz) */ psdhc->sdhc_clk_rate |= (PRE_CLK_DIV_64 << SDHC_CLK_RATE_PRESCALER_SHIFT) | CLK_DIV_3; /* Start SDHC clock */ sdhc_start_clk(); } else if(frequency == OPERATING_FREQ) { /* Below 20 MHz (~16.384 MHz) */ psdhc->sdhc_clk_rate |= (PRE_CLK_DIV << SDHC_CLK_RATE_PRESCALER_SHIFT) | CLK_DIV_3; } psdhc->sdhc_clk_rate |= (PRE_CLK_DIV << SDHC_CLK_RATE_PRESCALER_SHIFT) | CLK_DIV_3; } else { /* IPG_PER_CLK is 39 MHz after reset */ if(frequency == IDENTIFICATION_FREQ) { /* Below 100 kHz ( ~101.5 kHz) */ psdhc->sdhc_clk_rate |= (PRE_CLK_DIV_64 << SDHC_CLK_RATE_PRESCALER_SHIFT) | CLK_DIV_6; /* Start SDHC clock */ sdhc_start_clk(); } else if(frequency == OPERATING_FREQ) { /* Below 20 MHz (~19.5 MHz) */ psdhc->sdhc_clk_rate |= (PRE_CLK_DIV << SDHC_CLK_RATE_PRESCALER_SHIFT) | CLK_DIV_2; } }}/* *Initialize the interface. */ void interface_init(UINT32 base_address){ /* IOMUX programming */ VP_U32 iomux_sw_ctl_reg1 = (VP_U32)(0x43FAC000 + 0x18); VP_U32 iomux_sw_ctl_reg2 = (VP_U32)(0x43FAC000 + 0x1c); *iomux_sw_ctl_reg1 = *iomux_sw_ctl_reg1 & 0x000000FF; *iomux_sw_ctl_reg1 = *iomux_sw_ctl_reg1 | 0x12121200; *iomux_sw_ctl_reg2 = *iomux_sw_ctl_reg2 & 0xFF000000; *iomux_sw_ctl_reg2 = *iomux_sw_ctl_reg2 | 0x00121012; /* Initialize base address */ psdhc = (psdhc_t)base_address; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -