SDHI_driver patch (mbedOS 5.11.5)
mbed-os-program/mbed-os/components/storage/blockdevice/COMPONENT_RZ_SDHI/driver/sdhi_low.c
- Committer:
- tvendov
- Date:
- 2019-03-29
- Revision:
- 2:7c75ab32d7c9
File content as of revision 2:7c75ab32d7c9:
/******************************************************************************* * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only * intended for use with Renesas products. No other uses are authorized. This * software is owned by Renesas Electronics Corporation and is protected under * all applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software * and to discontinue the availability of this software. By using this software, * you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * * Copyright (C) 2013 Renesas Electronics Corporation. All rights reserved. *******************************************************************************/ /******************************************************************************* * File Name : sd_dev_low.c * $Rev: $ * $Date:: $ * Device(s) : RZ/A1H * Tool-Chain : DS-5 Ver 5.8 * : ARM Complier * OS : * H/W Platform : RZ/A1H CPU Board * Description : RZ/A1H SD Driver Sample Program * Operation : * Limitations : *******************************************************************************/ /****************************************************************************** Includes <System Includes> , "Project Includes" ******************************************************************************/ #include <stdio.h> #include <string.h> #include "r_typedefs.h" #include "iodefine.h" #include "rza_io_regrw.h" /*#include "devdrv_intc.h"*/ #include "sdif.h" #include "sd_cfg.h" /*#include "sd_dev_dmacdrv.h"*/ #include "us_ticker_api.h" #include "cmsis_os2.h" #include "mbed_assert.h" #include "pinmap.h" /****************************************************************************** Typedef definitions ******************************************************************************/ /****************************************************************************** Macro definitions ******************************************************************************/ //#define MTU_TIMER_CNT 32 /* P-phy = 32MHz */ #define INT_LEVEL_SDHI 10 /* SDHI interrupt level */ #define SDHI_PINS_COMMON 2 #define SDHI_PINS_SERIAL 3 #define SDHI_PINS_PARALLEL 6 #if defined(SDCFG_SDMODE_1BIT) # define SDHI_PORT_MODE SD_PORT_SERIAL #else # define SDHI_PORT_MODE SD_PORT_PARALLEL #endif /****************************************************************************** Imported global variables and functions (from other files) ******************************************************************************/ /****************************************************************************** Exported global variables and functions (to be accessed by other files) ******************************************************************************/ /****************************************************************************** Private global variables and functions ******************************************************************************/ #if 0 static uint8_t g_sdhi_priority_backup; #endif static const PinName SDHIpin_Common[SDHI_COUNT][SDHI_PINS_COMMON] = { /* WP & CD */ #if defined(TARGET_VK_RZ_A1H) {P4_8, P4_9}, {P3_8, P3_9} #elif defined(TARGET_VK_RZ_A1LU) {P3_6, P3_7}, {P7_1, P7_0} #else #error RZ_SDHI driver does not support this TARGET #endif }; static const PinName SDHIpin_serial[SDHI_COUNT][SDHI_PINS_SERIAL] = { /* CLK CMD D0 */ #if defined(TARGET_VK_RZ_A1H) {P4_11, P4_12, P4_13}, {P3_11, P3_12, P3_13} #elif defined(TARGET_VK_RZ_A1LU) {P3_3, P3_2, P3_4}, {P7_4, P7_5, P7_3} #else #error RZ_SDHI driver does not support this TARGET #endif }; static const PinName SDHIpin_parallel[SDHI_COUNT][SDHI_PINS_PARALLEL] = { /* CLK CMD D0-D3 */ #if defined(TARGET_VK_RZ_A1H) {P4_10, P4_11, P4_12, P4_13, P4_14, P4_15}, {P3_10, P3_11, P3_12, P3_13, P3_14, P3_15} #elif defined(TARGET_VK_RZ_A1LU) {P3_3, P3_2, P3_4, P3_5, P3_0, P3_1}, {P7_4, P7_5, P7_3, P7_2, P7_7, P7_6} #else #error RZ_SDHI driver does not support this TARGET #endif }; static const PinMap PinMap_SDHI_PIN[] = { /* pin | periph| func */ #if defined(TARGET_VK_RZ_A1H) {P4_8 , SDHI_0, 3}, /* SD_CD_0 */ {P4_9 , SDHI_0, 3}, /* SD_WP_0 */ {P4_10 , SDHI_0, 3}, /* SD_D1_0 */ {P4_11 , SDHI_0, 3}, /* SD_D0_0 */ {P4_12 , SDHI_0, 3}, /* SD_CLK_0 */ {P4_13 , SDHI_0, 3}, /* SD_CMD_0 */ {P4_14 , SDHI_0, 3}, /* SD_D3_0 */ {P4_15 , SDHI_0, 3}, /* SD_D2_0 */ /*----------------*/ {P3_8 , SDHI_1, 7}, /* SD_CD_1 */ {P3_9 , SDHI_1, 7}, /* SD_WP_1 */ {P3_10 , SDHI_1, 7}, /* SD_D1_1 */ {P3_11 , SDHI_1, 7}, /* SD_D0_1 */ {P3_12 , SDHI_1, 7}, /* SD_CLK_1 */ {P3_13 , SDHI_1, 7}, /* SD_CMD_1 */ {P3_14 , SDHI_1, 7}, /* SD_D3_1 */ {P3_15 , SDHI_1, 7}, /* SD_D2_1 */ {NC , NC , 0} #elif defined(TARGET_VK_RZ_A1LU) //{P3_7 , SDHI_0, 2}, /* SD_CD_0 can be used if SDRAM is not soldered */ //{P3_6 , SDHI_0, 2}, /* SD_WP_0 can be used if SDRAM is not soldered */ //{P3_5 , SDHI_0, 2}, /* SD_D1_0 can be used if SDRAM is not soldered */ //{P3_4 , SDHI_0, 2}, /* SD_D0_0 can be used if SDRAM is not soldered */ //{P3_3 , SDHI_0, 2}, /* SD_CLK_0 can be used if SDRAM is not soldered */ //{P3_2 , SDHI_0, 2}, /* SD_CMD_0 can be used if SDRAM is not soldered */ //{P3_1 , SDHI_0, 2}, /* SD_D3_0 can be used if SDRAM is not soldered */ //{P3_0 , SDHI_0, 2}, /* SD_D2_0 can be used if SDRAM is not soldered */ /*----------------*/ {P7_0 , SDHI_1, 3}, /* SD_CD_1 */ {P7_1 , SDHI_1, 3}, /* SD_WP_1 */ {P7_2 , SDHI_1, 3}, /* SD_D1_1 */ {P7_3 , SDHI_1, 3}, /* SD_D0_1 */ {P7_4 , SDHI_1, 3}, /* SD_CLK_1 */ {P7_5 , SDHI_1, 3}, /* SD_CMD_1 */ {P7_6 , SDHI_1, 3}, /* SD_D3_1 */ {P7_7 , SDHI_1, 3}, /* SD_D2_1 */ {NC , NC , 0} #else #error RZ_SDHI driver does not support this TARGET #endif }; static unsigned long _ulStart = 0; static unsigned long _ulDelta = 0; static const ticker_data_t *_ticker; //static int sddev_init_0(void); //static int sddev_init_1(void); //static int sddev_set_port_0(int mode); //static int sddev_set_port_1(int mode); static int sddev_init_dma_0(unsigned long buff,unsigned long reg,long cnt,int dir); static int sddev_init_dma_1(unsigned long buff,unsigned long reg,long cnt,int dir); static int sddev_wait_dma_end_0(long cnt); static int sddev_wait_dma_end_1(long cnt); static int sddev_disable_dma_0(void); static int sddev_disable_dma_1(void); static void sddev_sd_int_handler_0(uint32_t int_sense); static void sddev_sd_int_handler_1(uint32_t int_sense); static void sddev_sdio_int_handler_0(uint32_t int_sense); static void sddev_sdio_int_handler_1(uint32_t int_sense); static void sddev_start_timer(int msec); static void sddev_end_timer(void); static int sddev_check_timer(void); /****************************************************************************** * Function Name: int sddev_cmd0_sdio_mount(int sd_port); * Description : Select to issue CMD0 before SDIO Mount * Arguments : none * Return Value : SD_OK : issue CMD0 * : SD_ERR : not issue CMD0 ******************************************************************************/ int sddev_cmd0_sdio_mount(int sd_port) { #ifdef SDCFG_IO return SD_ERR; #else return SD_ERR; #endif } /****************************************************************************** * Function Name: int sddev_cmd8_sdio_mount(int sd_port); * Description : Select to issue CMD8 before SDIO Mount * Arguments : none * Return Value : SD_OK : issue CMD8 * : SD_ERR : not issue CMD8 ******************************************************************************/ int sddev_cmd8_sdio_mount(int sd_port) { #ifdef SDCFG_IO return SD_OK; #else return SD_ERR; #endif } /****************************************************************************** * Function Name: int sddev_init(void); * Description : Initialize H/W to use SDHI * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_init(int sd_port) { if ( sd_port >= SDHI_COUNT ) return SD_ERR; volatile uint8_t dummy_buf; CPG.STBCR12 = 0xF0u; /* [1], [1], [1], [1], SDHI00, SDHI01, SDHI10, SDHI11 */ dummy_buf = CPG.STBCR12; /* (Dummy read) */ for( uint32_t no=0; no < SDHI_PINS_COMMON; no++ ) { if ( pinmap_peripheral(SDHIpin_Common[sd_port][no], PinMap_SDHI_PIN ) != sd_port) { return SD_ERR; } pinmap_pinout(SDHIpin_Common[sd_port][no], PinMap_SDHI_PIN); } sddev_set_port(sd_port, SDHI_PORT_MODE); #ifdef SDCFG_HWINT if ( sd_port == (uint32_t)SDHI_0 ) { InterruptHandlerRegister(SDHI0_0_IRQn, sddev_sd_int_handler_0); GIC_SetPriority(SDHI0_0_IRQn, INT_LEVEL_SDHI); GIC_EnableIRQ(SDHI0_0_IRQn); InterruptHandlerRegister(SDHI0_3_IRQn, sddev_sd_int_handler_0); GIC_SetPriority(SDHI0_3_IRQn, INT_LEVEL_SDHI); GIC_EnableIRQ(SDHI0_3_IRQn); InterruptHandlerRegister(SDHI0_1_IRQn, sddev_sdio_int_handler_0); GIC_SetPriority(SDHI0_1_IRQn, INT_LEVEL_SDHI); GIC_EnableIRQ(SDHI0_1_IRQn); } else if ( sd_port == (uint32_t)SDHI_1 ) { InterruptHandlerRegister(SDHI1_0_IRQn, sddev_sd_int_handler_1); GIC_SetPriority(SDHI1_0_IRQn, INT_LEVEL_SDHI); GIC_EnableIRQ(SDHI1_0_IRQn); InterruptHandlerRegister(SDHI1_3_IRQn, sddev_sd_int_handler_1); GIC_SetPriority(SDHI1_3_IRQn, INT_LEVEL_SDHI); GIC_EnableIRQ(SDHI1_3_IRQn); InterruptHandlerRegister(SDHI1_1_IRQn, sddev_sdio_int_handler_1); GIC_SetPriority(SDHI1_1_IRQn, INT_LEVEL_SDHI); GIC_EnableIRQ(SDHI1_1_IRQn); } #endif /* ---- wait card detect ---- */ osDelay(100); /* wait 100ms */ return SD_OK; } /****************************************************************************** * Function Name: int sddev_power_on(int sd_port); * Description : Power-on H/W to use SDHI * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_power_on(int sd_port) { /* ---Power On SD ---- */ /* ---- Wait for SD Wake up ---- */ osDelay(100); /* wait 100ms */ return SD_OK; } /****************************************************************************** * Function Name: int sddev_power_off(int sd_port); * Description : Power-off H/W to use SDHI * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_power_off(int sd_port) { return SD_OK; } /****************************************************************************** * Function Name: int sddev_read_data(int sd_port, unsigned char *buff,unsigned long reg_addr,long num); * Description : read from SDHI buffer FIFO * Arguments : unsigned char *buff : buffer addrees to store reading datas * : unsigned long reg_addr : SDIP FIFO address * : long num : counts to read(unit:byte) * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ #ifdef __CC_ARM #pragma push #pragma Ospace #elif defined(__ICCARM__) #pragma optimize=size #elif (defined( __GNUC__ ) && !defined( __CC_ARM )) #pragma GCC push_options #pragma GCC optimize ("Os") #endif int sddev_read_data(int sd_port, unsigned char *buff,unsigned long reg_addr,long num) { long i; long cnt; unsigned long *reg; unsigned long *ptr_l; unsigned char *ptr_c; unsigned long tmp; reg = (unsigned long *)(reg_addr); cnt = (num / 4); if(((unsigned long)buff & 0x3) != 0) { ptr_c = (unsigned char *)buff; for(i = cnt; i > 0 ; i--) { tmp = *reg; *ptr_c++ = (unsigned char)(tmp); *ptr_c++ = (unsigned char)(tmp >> 8); *ptr_c++ = (unsigned char)(tmp >> 16); *ptr_c++ = (unsigned char)(tmp >> 24); } cnt = (num % 4); if( cnt != 0 ) { tmp = *reg; for(i = cnt; i > 0 ; i--) { *ptr_c++ = (unsigned char)(tmp); tmp >>= 8; } } } else { ptr_l = (unsigned long *)buff; for(i = cnt; i > 0 ; i--) { *ptr_l++ = *reg; } cnt = (num % 4); if( cnt != 0 ) { ptr_c = (unsigned char *)ptr_l; tmp = *reg; for(i = cnt; i > 0 ; i--) { *ptr_c++ = (unsigned char)(tmp); tmp >>= 8; } } } return SD_OK; } #ifdef __CC_ARM #pragma pop #elif (defined( __GNUC__ ) && !defined( __CC_ARM )) #pragma GCC pop_options #endif /****************************************************************************** * Function Name: int sddev_write_data(int sd_port, unsigned char *buff,unsigned long reg_addr,long num); * Description : write to SDHI buffer FIFO * Arguments : unsigned char *buff : buffer addrees to store writting datas * : unsigned long reg_addr : SDIP FIFO address * : long num : counts to write(unit:byte) * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_write_data(int sd_port, unsigned char *buff,unsigned long reg_addr,long num) { long i; unsigned long *reg = (unsigned long *)(reg_addr); unsigned long *ptr = (unsigned long *)buff; unsigned long tmp; /* dont care non 4byte allignment data */ num += 3; num /= 4; if(((unsigned long)buff & 0x3) != 0) { for(i = num; i > 0 ; i--) { tmp = *buff++ ; tmp |= *buff++ << 8; tmp |= *buff++ << 16; tmp |= *buff++ << 24; *reg = tmp; } } else { for(i = num; i > 0 ; i--) { *reg = *ptr++; } } return SD_OK; } /****************************************************************************** * Function Name: unsigned int sddev_get_clockdiv(int sd_port, int clock); * Description : write to SDHI buffer FIFO * Arguments : int clock : request clock frequency * : SD_CLK_50MHz * : SD_CLK_25MHz * : SD_CLK_20MHz * : SD_CLK_10MHz * : SD_CLK_5MHz * : SD_CLK_1MHz * : SD_CLK_400kHz * Return Value : clock div value * : SD_DIV_2 : 1/2 clock * : SD_DIV_2 : 1/4 clock * : SD_DIV_2 : 1/8 clock * : SD_DIV_2 : 1/16 clock * : SD_DIV_2 : 1/128 clock * : SD_DIV_2 : 1/256 clock ******************************************************************************/ unsigned int sddev_get_clockdiv(int sd_port, int clock) { unsigned int div; switch(clock) { case SD_CLK_50MHz: div = SD_DIV_2; /* 64MHz/2 = 32MHz */ break; case SD_CLK_25MHz: div = SD_DIV_4; /* 64MHz/4 = 16MHz */ break; case SD_CLK_20MHz: div = SD_DIV_4; /* 64MHz/4 = 16MHz */ break; case SD_CLK_10MHz: div = SD_DIV_8; /* 64MHz/8 = 8MHz */ break; case SD_CLK_5MHz: div = SD_DIV_16; /* 64MHz/16 = 4MHz */ break; case SD_CLK_1MHz: div = SD_DIV_128; /* 64MHz/128 = 512kHz */ break; case SD_CLK_400kHz: div = SD_DIV_256; /* 64MHz/256 = 256kHz */ break; default: div = SD_DIV_256; break; } return div; } /****************************************************************************** * Function Name: int sddev_set_port(int sd_port, int mode); * Description : setting ports to use MMCHI * Arguments : int mode : SD_PORT_PARALLEL : 4bit mode * : SD_PORT_SERIAL : 1bit mode * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_set_port(int sd_port, int mode) { if ( sd_port >= SDHI_COUNT) return SD_ERR; if(mode == SD_PORT_SERIAL) { for( uint32_t no=0; no < SDHI_PINS_SERIAL; no++ ) { if ( pinmap_peripheral(SDHIpin_serial[sd_port][no], PinMap_SDHI_PIN ) != sd_port) { return SD_ERR; } pinmap_pinout(SDHIpin_serial[sd_port][no], PinMap_SDHI_PIN); } } else if( mode == SD_PORT_PARALLEL ) { for( uint32_t no=0; no < SDHI_PINS_PARALLEL; no++ ) { if ( pinmap_peripheral(SDHIpin_parallel[sd_port][no], PinMap_SDHI_PIN ) != sd_port) { return SD_ERR; } pinmap_pinout(SDHIpin_parallel[sd_port][no], PinMap_SDHI_PIN); } } else { return SD_ERR; } return SD_OK; } /****************************************************************************** * Function Name: int sddev_int_wait(int sd_port, int time); * Description : Waitting for SDHI Interrupt * Arguments : int time : time out value to wait interrupt * Return Value : get interrupt : SD_OK * : time out : SD_ERR ******************************************************************************/ int sddev_int_wait(int sd_port, int time) { sddev_start_timer(time); while( sddev_check_timer() == SD_OK ) { /* interrupt generated? */ if(sd_check_int(sd_port) == SD_OK) { sddev_end_timer(); return SD_OK; } } sddev_end_timer(); return SD_ERR; } /****************************************************************************** * Function Name: int sddev_init_dma(unsigned long buff,unsigned long reg,long cnt,int dir); * Description : Initialize DMAC to transfer data from SDHI FIFO * Arguments : unsigned long buff : buffer addrees to transfer datas * : unsigned long reg : SDIP FIFO address * : long cnt : counts to transfer(unit:byte) * : int dir : direction to transfer * : : 0 : FIFO -> buffer * : : 1 : buffer -> FIFO * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_init_dma(int sd_port, unsigned long buff,unsigned long reg,long cnt,int dir) { int ret; if( sd_port == 0 ) { ret = sddev_init_dma_0(buff, reg, cnt, dir); } else if( sd_port == 1 ) { ret = sddev_init_dma_1(buff, reg, cnt, dir); } return ret; } /****************************************************************************** * Function Name: static int sddev_init_dma_0(unsigned long buff,unsigned long reg,long cnt,int dir); * Description : Initialize DMAC to transfer data from SDHI FIFO * Arguments : unsigned long buff : buffer addrees to transfer datas * : unsigned long reg : SDIP FIFO address * : long cnt : counts to transfer(unit:byte) * : int dir : direction to transfer * : : 0 : FIFO -> buffer * : : 1 : buffer -> FIFO * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ static int sddev_init_dma_0(unsigned long buff,unsigned long reg,long cnt,int dir) { #ifdef SDCFG_TRNS_DMA dmac_transinfo_t trans_info; uint32_t request_factor; int32_t ret; trans_info.count = (uint32_t)cnt; #ifdef SDCFG_TRANS_DMA_64 if( (cnt % 64) != 0 ) { trans_info.src_size = DMAC_TRANS_SIZE_32; trans_info.dst_size = DMAC_TRANS_SIZE_32; if( reg & 0x0000003f ) { trans_info.src_size = DMAC_TRANS_SIZE_32; trans_info.dst_size = DMAC_TRANS_SIZE_32; } } else { trans_info.src_size = DMAC_TRANS_SIZE_512; trans_info.dst_size = DMAC_TRANS_SIZE_512; } #else trans_info.src_size = DMAC_TRANS_SIZE_32; trans_info.dst_size = DMAC_TRANS_SIZE_32; #endif if( dir == 0 ) { request_factor = DMAC_REQ_SDHI_0_RX; trans_info.src_addr = (uint32_t)reg; trans_info.dst_addr = (uint32_t)buff; trans_info.saddr_dir = DMAC_TRANS_ADR_NO_INC; trans_info.daddr_dir = DMAC_TRANS_ADR_INC; } else if( dir == 1 ) { request_factor = DMAC_REQ_SDHI_0_TX; trans_info.src_addr = (uint32_t)buff; trans_info.dst_addr = (uint32_t)reg; trans_info.saddr_dir = DMAC_TRANS_ADR_INC; trans_info.daddr_dir = DMAC_TRANS_ADR_NO_INC; } sd_DMAC1_PeriReqInit( (const dmac_transinfo_t *)&trans_info, DMAC_MODE_REGISTER, DMAC_SAMPLE_SINGLE, request_factor, 0 ); /* Dont care DMAC_REQ_REQD is setting in usb0_host_DMAC1_PeriReqInit() */ ret = sd_DMAC1_Open(DMAC_REQ_MODE_PERI); if( ret != 0 ) { printf("DMAC1 Open error!!\n"); return SD_ERR; } #endif return SD_OK; } /****************************************************************************** * Function Name: static int sddev_init_dma_1(unsigned long buff,unsigned long reg,long cnt,int dir); * Description : Initialize DMAC to transfer data from SDHI FIFO * Arguments : unsigned long buff : buffer address to transfer datas * : unsigned long reg : SDIP FIFO address * : long cnt : counts to transfer(unit:byte) * : int dir : direction to transfer * : : 0 : FIFO -> buffer * : : 1 : buffer -> FIFO * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ static int sddev_init_dma_1(unsigned long buff,unsigned long reg,long cnt,int dir) { #ifdef SDCFG_TRNS_DMA dmac_transinfo_t trans_info; uint32_t request_factor; int32_t ret; trans_info.count = (uint32_t)cnt; #ifdef SDCFG_TRANS_DMA_64 if( (cnt % 64) != 0 ) { trans_info.src_size = DMAC_TRANS_SIZE_32; trans_info.dst_size = DMAC_TRANS_SIZE_32; if( reg & 0x0000003f ) { trans_info.src_size = DMAC_TRANS_SIZE_32; trans_info.dst_size = DMAC_TRANS_SIZE_32; } } else { trans_info.src_size = DMAC_TRANS_SIZE_512; trans_info.dst_size = DMAC_TRANS_SIZE_512; } #else trans_info.src_size = DMAC_TRANS_SIZE_32; trans_info.dst_size = DMAC_TRANS_SIZE_32; #endif if( dir == 0 ) { request_factor = DMAC_REQ_SDHI_1_RX; trans_info.src_addr = (uint32_t)reg; trans_info.dst_addr = (uint32_t)buff; trans_info.saddr_dir = DMAC_TRANS_ADR_NO_INC; trans_info.daddr_dir = DMAC_TRANS_ADR_INC; } else if( dir == 1 ) { request_factor = DMAC_REQ_SDHI_1_TX; trans_info.src_addr = (uint32_t)buff; trans_info.dst_addr = (uint32_t)reg; trans_info.saddr_dir = DMAC_TRANS_ADR_INC; trans_info.daddr_dir = DMAC_TRANS_ADR_NO_INC; } sd_DMAC2_PeriReqInit( (const dmac_transinfo_t *)&trans_info, DMAC_MODE_REGISTER, DMAC_SAMPLE_SINGLE, request_factor, 0 ); /* Dont care DMAC_REQ_REQD is setting in usb0_host_DMAC1_PeriReqInit() */ ret = sd_DMAC2_Open(DMAC_REQ_MODE_PERI); if( ret != 0 ) { printf("DMAC1 Open error!!\n"); return SD_ERR; } #endif return SD_OK; } /****************************************************************************** * Function Name: int sddev_wait_dma_end(int sd_port, long cnt); * Description : Wait to complete DMAC transfer * Arguments : long cnt : counts to transfer(unit:byte) * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_wait_dma_end(int sd_port, long cnt) { int ret; if( sd_port == 0 ) { ret = sddev_wait_dma_end_0(cnt); } else if( sd_port == 1 ) { ret = sddev_wait_dma_end_1(cnt); } return ret; } /****************************************************************************** * Function Name: static int sddev_wait_dma_end_0(long cnt); * Description : Wait to complete DMAC transfer * Arguments : long cnt : counts to transfer(unit:byte) * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ static int sddev_wait_dma_end_0(long cnt) { #ifdef SDCFG_TRNS_DMA int loop; int time; time = (cnt / 512); time = ((time * 1000) / 1024); if(time < 1000) { time = 1000; } if(time > (0x0000ffff / MTU_TIMER_CNT)) { /* @1000ms */ loop = (time / 1000); if( (time % 1000) != 0 ) { loop++; } time = 1000; } else { loop = 1; } do{ sddev_start_timer(time); while(1) { /* get end flag? */ if( sd_DMAC1_Get_Endflag() == 1 ) { sddev_end_timer(); return SD_OK; } /* detect timeout? */ if(sddev_check_timer() == SD_ERR) { break; } } loop--; if( loop <= 0 ) { break; } } while(1); sddev_end_timer(); return SD_ERR; #else return SD_OK; #endif } /****************************************************************************** * Function Name: static int sddev_wait_dma_end_1(long cnt); * Description : Wait to complete DMAC transfer * Arguments : long cnt : counts to transfer(unit:byte) * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ static int sddev_wait_dma_end_1(long cnt) { #ifdef SDCFG_TRNS_DMA int loop; int time; time = (cnt / 512); time = ((time * 1000) / 1024); if(time < 1000) { time = 1000; } if(time > (0x0000ffff / MTU_TIMER_CNT)) { /* @1000ms */ loop = (time / 1000); if( (time % 1000) != 0 ) { loop++; } time = 1000; } else { loop = 1; } do{ sddev_start_timer(time); while(1) { /* get end flag? */ if( sd_DMAC2_Get_Endflag() == 1 ) { sddev_end_timer(); return SD_OK; } /* detect timeout? */ if(sddev_check_timer() == SD_ERR) { break; } } loop--; if( loop <= 0 ) { break; } } while(1); sddev_end_timer(); return SD_ERR; #else return SD_OK; #endif } /****************************************************************************** * Function Name: int sddev_disable_dma(int sd_port); * Description : Disable DMAC transfer * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_disable_dma(int sd_port) { int ret; if( sd_port == 0 ) { ret = sddev_disable_dma_0(); } else { ret = sddev_disable_dma_1(); } return ret; } /****************************************************************************** * Function Name: static int sddev_disable_dma_0(void); * Description : Disable DMAC transfer * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ static int sddev_disable_dma_0(void) { #ifdef SDCFG_TRNS_DMA uint32_t remain; sd_DMAC1_Close(&remain); #endif return SD_OK; } /****************************************************************************** * Function Name: staticint sddev_disable_dma_1(void); * Description : Disable DMAC transfer * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ static int sddev_disable_dma_1(void) { #ifdef SDCFG_TRNS_DMA uint32_t remain; sd_DMAC2_Close(&remain); #endif return SD_OK; } /****************************************************************************** * Function Name: int sddev_loc_cpu(int sd_port); * Description : lock cpu to disable interrupt * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_loc_cpu(int sd_port) { #if 0 R_INTC_GetMaskLevel(&g_sdhi_priority_backup); R_INTC_SetMaskLevel(0); core_util_critical_section_enter(); #endif return SD_OK; } /****************************************************************************** * Function Name: int sddev_unl_cpu(int sd_port); * Description : unlock cpu to enable interrupt * Arguments : none * Return Value : success : SD_OK * : fail : SD_ERR ******************************************************************************/ int sddev_unl_cpu(int sd_port) { #if 0 R_INTC_SetMaskLevel(g_sdhi_priority_backup); core_util_critical_section_exit(); #endif return SD_OK; } /****************************************************************************** * Function Name: int sddev_finalize(int sd_port); * Description : finalize SDHI * Arguments : none * Return Value : none ******************************************************************************/ int sddev_finalize(int sd_port) { return SD_OK; } /****************************************************************************** * Function Name: static void sddev_sd_int_handler_0(uint32_t int_sense); * Description : Setting Interrupt function for SDHI(INTC_ID_SDHI0_0,INTC_ID_SDHI0_3) * Arguments : Interrupt mode * Return Value : none ******************************************************************************/ static void sddev_sd_int_handler_0(uint32_t int_sense) { sd_int_handler(0); } /****************************************************************************** * Function Name: static void sddev_sd_int_handler_1(uint32_t int_sense); * Description : Setting Interrupt function for SDHI(INTC_ID_SDHI0_0,INTC_ID_SDHI0_3) * Arguments : Interrupt mode * Return Value : none ******************************************************************************/ static void sddev_sd_int_handler_1(uint32_t int_sense) { sd_int_handler(1); } /****************************************************************************** * Function Name: static void sddev_sdio_int_handler_0(uint32_t int_sense); * Description : Setting Interrupt function for SDHI(INTC_ID_SDHI0_1) * Arguments : Interrupt mode * Return Value : none ******************************************************************************/ static void sddev_sdio_int_handler_0(uint32_t int_sense) { sdio_int_handler(0); } /****************************************************************************** * Function Name: static void sddev_sdio_int_handler_1(uint32_t int_sense); * Description : Setting Interrupt function for SDHI(INTC_ID_SDHI1_1) * Arguments : Interrupt mode * Return Value : none ******************************************************************************/ static void sddev_sdio_int_handler_1(uint32_t int_sense) { sdio_int_handler(1); } /****************************************************************************** * Function Name: static void sddev_start_timer(int msec); * Description : start timer * Arguments : * Return Value : none ******************************************************************************/ static void sddev_start_timer(int msec) { _ticker = get_us_ticker_data(); _ulStart = ticker_read(_ticker); _ulDelta = msec*1000ul; } /****************************************************************************** * Function Name: static void sddev_end_timer(void); * Description : end timer * Arguments : * Return Value : none ******************************************************************************/ static void sddev_end_timer(void) { _ulStart = 0ul; _ulDelta = 0ul; } /****************************************************************************** * Function Name: static int sddev_check_timer(void); * Description : check * Arguments : * Return Value : t ******************************************************************************/ static int sddev_check_timer(void) { if ( _ulStart && _ulDelta ) { return ((ticker_read(_ticker)-_ulStart) < _ulDelta) ? SD_OK : SD_ERR; } else { return SD_ERR; } } /* End of File */