예제 #1
0
/*---------------------------------------------------------------------------*
 * Routine:  SPI_Transfer
 *---------------------------------------------------------------------------*
 * Description:
 *      Attempt to transfer an array of bytes over the SPI channel given.
 *      When complete, the given callback routine is called.
 * Inputs:
 *      uint8_t channel -- Channel for the RDK peripheral
 *      uint32_t numBytes -- Number of bytes to transfer
 *      const uint8_t *send_buffer -- Pointer to bytes to send
 *      uint8_t *receive_buffer -- Pointer to buffer to receive SPI bytes.
 *          Can be the same location as the send_buffer.
 *      void (*callback)(void) -- Callback function to call when complete.
 * Outputs:
 *      bool -- true if successfully started, else false (busy).
 *---------------------------------------------------------------------------*/
bool SPI_Transfer(
        uint8_t channel,
        uint32_t numBytes,
        const uint8_t *send_buffer,
        uint8_t *receive_buffer,
        void(*callback)(void))
{
    if (G_SPI_IsBusy)
        return false;
    
    G_SPI_IsBusy = true;

    G_SPI_SendBuffer = send_buffer;
    G_SPI_ReceiveBuffer = receive_buffer;
    G_SPI_Callback = callback;
    G_SPI_SendIndex = 0;
    G_SPI_ReceiveIndex = 0;
    G_SPI_SendLength = numBytes;
    G_SPI_Channel = channel;
    
    SPI_DisableInterrupts();
    
    SPI_CS_Assert(G_SPI_Channel);
    
    /* started by writing data to SDR[7:0] */
    SIO10 = G_SPI_SendBuffer[G_SPI_SendIndex++];
    G_SPI_SendLength--;
    
    SPI_EnableInterrupts();
    
    return true;
}
예제 #2
0
파일: sdcmd.c 프로젝트: TemcoChelsea/CM5
/********************************************************************************************************************
** 函数名称: U8_T SD_SendCmd()						Name:	  U8_T SD_SendCmd()
** 功能描述: 向卡发送命令,并取得响应				Function: send command to the card,and get a response
** 输   入: U8_T cmd	    : 命令字				Input:	  U8_T cmd	    : command byte	
			 U8_T *param	: 命令参数,长度为4字节			  U8_T *param	: command parameter,length is 4 bytes  
			 U8_T resptype : 响应类型						  U8_T resptype: response type
			 U8_T *resp	: 响应,长度为1-5字节			  U8_T *resp	: response,length is 1-5 bytes
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
********************************************************************************************************************/
U8_T SD_SendCmd(U8_T cmd, U8_T *param, U8_T resptype, U8_T *resp)
{
	S8_T i;
	U8_T tmp,rlen;
    
	SPI_CS_Assert();
   
    SPI_SendByte((cmd & 0x3F) | 0x40);				 /* 发送命令头和命令字 send command header and word */
    
    for (i = 3; i >= 0; i--)
        SPI_SendByte(param[i]);						 /* 发送参数 send parameters */
    
	if(cmd == CMD8)
		SPI_SendByte(CMD8_CRC);
	else if(cmd == CMD0)
		SPI_SendByte(0x95);							 /* CRC校验码,只用于第1个命令 CRC,only used for the first command */
	else
		SPI_SendByte(0x00);
    
    rlen = 0;
    switch (resptype)								 /* 根据不同的命令,得到不同的响应长度 */
    {												 /* according various command,get the various response length */
  		case R1:
   	 	case R1B: rlen = 1;  break;
       		 
    	case R2:  rlen = 2;	 break;
       		 
   		case R3:
		case R7:  rlen = 5;	 break;
       		 
    	default:  SPI_SendByte(0xFF);	
      		      SPI_CS_Deassert();						 
        	      return SD_ERR_CMD_RESPTYPE;		 /* 返回命令响应类型错误 return error of command response type */
    		      break;
    }
    
    i = 0;				
    do 												 /* 等待响应,响应的开始位为0 */
    {												 /* Wait for a response,a response is a start bit(zero) */ 
        tmp = SPI_RecByte();
        i++;
    }while (((tmp & 0x80) != 0) && (i < SD_CMD_TIMEOUT));
    
    if (i >= SD_CMD_TIMEOUT)
    {				
        SPI_CS_Deassert();
        return SD_ERR_CMD_TIMEOUT;					 /* 返回命令超时 return response timeout of command */
    }
    
    for (i = rlen - 1; i >= 0; i--)
    {
        resp[i] = tmp;
        tmp = SPI_RecByte();					 	 /* 循环的最后发送8clock  at the last recycle,clock out 8 clock */
    }

	SPI_CS_Deassert();

    return SD_NO_ERR;								 /* 返回执行成功 return perform sucessfully */
}
예제 #3
0
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;

   if (pdrv)
    {   
        return RES_PARERR;  
    }
    //FATFS目前版本仅需处理CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ三个命令
    switch(cmd)
    {
    case CTRL_SYNC:
        SPI_CS_Assert();

        if(SD_ResetSD() == SD_NO_ERR)
        {
            res = RES_OK;
        }
        else
        {
            res = RES_ERROR;
        }
        SPI_CS_Deassert();
        break;
         
    case GET_BLOCK_SIZE:
        *(WORD*)buff = 512;
        res = RES_OK;
        break;
 
    case GET_SECTOR_COUNT:
        *(DWORD*)buff = SD_GetCardInfo();
        res = RES_OK;
        break;
    default:
        res = RES_PARERR;
        break;
    }
 
    return res;

}
예제 #4
0
__interrupt static void SPI_ISRHandler(void)
{
    uint8_t err_type;

    err_type = (uint8_t)(SSR13 & _SAU_OVERRUN_ERROR);
    SIR13 = (uint16_t)err_type;

    SPI_CS_Clear(G_SPI_Channel);
    
    if (1U == err_type) {
        /* overrun error occurs */
        G_SPI_OverrunErrorCount++;
    }
    else {
      
        /* Receive a character */
        G_SPI_ReceiveBuffer[G_SPI_ReceiveIndex++] = SIO31;
    
        /* Is there more data to send? */
        if (G_SPI_SendLength > 0) {
           
            /* Send the next character */
            SPI_CS_Assert(G_SPI_Channel);
            SIO31 = G_SPI_SendBuffer[G_SPI_SendIndex++];
            G_SPI_SendLength--;
        }
        else {
            /* Data transfer complete */
            SPI_CS_Clear(G_SPI_Channel);
            
            if (G_SPI_Callback)
                G_SPI_Callback();
            
            G_SPI_IsBusy = false;
        }
    }
}