//----等待芯片内部慢速操作完成------------------------------------------------- //功能: 对芯片执行写操作后,要调用本函数等待操作完成才能进一步操作。由于一连串的 // 同步操作将浪费很多时间,对于一些很快就绪的操作,宜使用__wait_ready_nand // 函数。 //参数: wait_time,估计等待时间,微秒数 //返回: true = 正确完成操作,false = 发生错误 //注:此处应改为用定时器 //----------------------------------------------------------------------------- bool_t __wait_ready_nand_slow(u16 wait_time) { // Timer_SetCounter(1,wait_time); //计数值设为wait_time // Timer_Reload(1); //重载定时值 // Timer_Start(1); //启动定时器 // Int_AsynSignalSync(cn_int_line_timer1); // Timer_Stop(1); // while((pg_nand_reg->NFSTAT & 1) ==0 ); // return true; u32 timestart,timeend; timestart = (u32)DjyGetTime( ); timeend = timestart; while ( (timeend - timestart) < wait_time) { if(GPIO_ReadInputDataBit(GPIOD, NandFlash_RB_GPIOD6)) { break; } timeend = (u32)DjyGetTime( ); } if( (timeend - timestart) >= wait_time) { return false; } else { return true; } }
//----等待芯片内部完成操作---------------------------------------------------- //功能: 对芯片执行写操作后,要效用本函数等待操作完成才能进一步操作。 //参数: 无 //返回: true = 正确完成操作,false = 发生错误 //----------------------------------------------------------------------------- bool_t __wait_ready_nand(void) { u32 timestart,timeend; timestart = (u32)DjyGetTime( ); timeend = timestart; while ( (timeend - timestart) < 100) { if(GPIO_ReadInputDataBit(GPIOD, NandFlash_RB_GPIOD6)) { break; } timeend = (u32)DjyGetTime( ); } if( (timeend - timestart) >= 100) { return false; } else { return true; } }
// ============================================================================= // 函数功能:复位看门狗 // 输入参数:wdt,待操作的看门狗 // 输出参数: // 返回值 :true success while false failed // 说明 : // ============================================================================= bool_t Wdt_Clean(tagWdt *wdt) { bool_t result; tagWdtMsg wdtmsg; atom_low_t atom; s64 ostime; result = false; if(NULL != wdt) { atom = Int_LowAtomStart(); if(ptWdtHead != wdt) { //可以直接修改wdtqueue ostime = DjyGetTime(); __Wdt_RemovefQueue(wdt); wdt->deadtime = wdt->cycle + ostime; __Wdt_Add2Queque(wdt); Int_LowAtomEnd(atom); } else { //snd msg to the monitor task Int_LowAtomEnd(atom); wdtmsg.pwdt = wdt; wdtmsg.opcode = EN_WDTCMD_CLEAN; wdtmsg.para = 0; result = MsgQ_Send(ptWdtMsgBox,(u8 *)&wdtmsg,sizeof(tagWdtMsg),\ CN_TIMEOUT_FOREVER,CN_MSGQ_PRIO_NORMAL); } } return result; }
// ============================================================================= // 函数功能:看门狗监视任务 // 输入参数: // 输出参数: // 返回值 : // 说明 : // ============================================================================= static ptu32_t Wdt_Service(void) { s64 timenow; tagWdt *wdt; u32 waittime; tagWdtMsg wdtmsg; //将硬件狗从裸狗中接管过来 WdtHal_BootEnd(); // deal all the msg cached in the msgbox timenow = DjyGetTime(); while(MsgQ_Receive(ptWdtMsgBox,(u8 *)&wdtmsg,sizeof(tagWdtMsg),0)) { __Wdt_DealMsg(&wdtmsg); //all the wdt will be queued in the wdt queue } //now we come into the never get out loop, deal all the msg and timeout wdt while(1) { //preapara the wait time wdt = ptWdtHead; if((NULL == wdt)||(wdt->deadtime == CN_WDT_YIP_NEVER)) { waittime = CN_TIMEOUT_FOREVER; } else { timenow = DjyGetTime(); waittime = (u32)(wdt->deadtime - timenow); } //ok, now we wait the msg box during the expect time if(MsgQ_Receive(ptWdtMsgBox,(u8 *)&wdtmsg,sizeof(tagWdtMsg),waittime)) { //must look out that:there maybe more than one msgs in the msgbox //some app has send some msg to the __Wdt_DealMsg(&wdtmsg); //all the wdt will be queued in the wdt queue // deal all the msg cached in the msgbox while(MsgQ_Receive(ptWdtMsgBox,(u8 *)&wdtmsg,sizeof(tagWdtMsg),0)) { __Wdt_DealMsg(&wdtmsg); //all the wdt will be queued in the wdt queue } } //scan the queue to deal the timeout wdt __Wdt_ScanWdtQueque(); } return 1; //if no exp, this could not be reached }
// ============================================================================= // 函数功能:扫描整个看门狗队列并处理超时的看门狗 // 输入参数: // 输出参数: // 返回值 : // 说明 : // ============================================================================= static void __Wdt_ScanWdtQueque(void) { s64 timenow; u32 result; tagWdt *wdt; wdt = ptWdtHead; while(NULL != wdt)//处理所有在叫的狗 { timenow = DjyGetTime();//实时更新时间 if((timenow + CN_WDT_YIP_PRECISION)>= wdt->deadtime) // the wdt has been timeout { __Wdt_AnalyzeYipReason(wdt); if(NULL != wdt->fnhook) { result = wdt->fnhook(wdt);//尽情的叫吧,少年 if(result == EN_EXP_DEAL_DEFAULT) { result = wdt->action; } } else { result = wdt->action; } if(wdt->shyiptimes >= wdt->sheduletimeslevel) { result = result; } else//在忍耐限度以内 { result = EN_EXP_DEAL_RECORD; } //this wdt should be relocate in the queue __Wdt_DealWdtYipResult(result,wdt); __Wdt_RemovefQueue(wdt); wdt->deadtime = wdt->cycle + timenow; __Wdt_Add2Queque(wdt); //ok, do another wdt wdt = ptWdtHead; } else { //the head is not timeout, so we believe that all others are all not //time out wdt = NULL; } } }
// ============================================================================= // 函数功能:Rtc_SetTime // 设置日历时间,单位微秒 // 输入参数:rtctime,设置RTC时间,微秒数 // 输出参数: // 返回值 :获取的RTC时间,秒数 // 说明:距离1970年的时间;先设置RTC模块的日历时间;如果有RTC设备,同样记得设置RTC设备时间 // ============================================================================= bool_t __Rtc_SetTime(s64 rtctime) { bool_t result = true; atom_low_t atom; s64 systime; systime = DjyGetTime(); if(NULL == fnRtcSetTime) { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; Int_LowAtomEnd(atom); #else sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; #endif } else { if(fnRtcSetTime(rtctime)) { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; Int_LowAtomEnd(atom); #else sgRtcTimeSet = rtctime; sgRtcUpdateTime2SysTime = systime; #endif } else { //rtc set failed, so don't update the rtc module time,otherwise will //make the rtc dev and rtc module time not sync result = false; } } return result; }
bool_t tcptstserver(void) { int sockfd; int clientfd; int multiid; int addrlen; int i =0; struct sockaddr_in serveraddr; struct sockaddr_in clientaddr; char *sndbuf; char *rcvbuf; int sndlen; s64 sndtotal; unsigned int sndprint =0; int sndopt; s64 sndtimestart; s64 sndtimetest; int sndspeed; int sndkbytes; int rcvlen; int rcvtotal; int rcvtimes; s64 rcvtimestart; s64 rcvtimeend; u32 nrcvtime; u32 activebits; struct tagMultiplexSetsCB *writesets; u32 badmultiwrite =0; struct tagMultiplexSetsCB *acceptsets; //创建发送集合 activebits = CN_SOCKET_OR | CN_SOCKET_WRITEALBE; writesets = Multiplex_Creat(activebits); if(NULL==writesets) { printk("Create WriteSets failed!\n\r"); } else { printk("Create WriteSets success!\n\r"); } //创建接收客户端集合 activebits = CN_SOCKET_OR | CN_SOCKET_ACCEPT; acceptsets = Multiplex_Creat(activebits); if(NULL==acceptsets) { printk("Create acceptsets failed!\n\r"); } else { printk("Create acceptsets success!\n\r"); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == sockfd) { printk("socket failed!\n\r"); return true; } else { printk("socket success!\n\r"); } serveraddr.sin_port = htons(CN_TCP_SERVERPORT); serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); if(-1==bind(sockfd, &serveraddr, sizeof(serveraddr))) { printk("bind failed!\n\r"); return true; } else { printk("bind success!\n\r"); } if(-1 == listen(sockfd, 100)) { printk("listen failed!\n\r"); return true; } else { printk("listen success!\n\r"); } //测试MULTIIO,不断的监视服务器端 //设置为非阻塞 // sndopt = 1; // if(0 == setsockopt(sockfd,SOL_SOCKET ,SO_NOBLOCK,&sndopt,4)) // { // printk("Server:Set server noblock success!\n\r"); // } // else // { // printk("Sever:Set server noblock failed!\n\r"); // } if(Socket_MultiplexAdd(acceptsets,sockfd,CN_SOCKET_ACCEPT)) { printk("add server to acceptsets success!\n\r"); } else { printk("add server to acceptsets failed!\n\r"); } while(1) { if(sockfd != Multiplex_Wait(acceptsets,NULL, CN_TIMEOUT_FOREVER)) { printk("MultiIo activated err!\n\r"); } else { printk("MultiIo activated success!\n\r"); } clientfd = accept(sockfd, &clientaddr, &addrlen); if(clientfd != -1) { printk("Got an client:ip = %08x port = %04x\n\r",\ ntohl(clientaddr.sin_addr.s_addr),ntohs(clientaddr.sin_port)); //关闭NAGLE sndopt = 1; if(0 == setsockopt(clientfd, IPPROTO_TCP,TCP_NODELAY,&sndopt,4)) { printk("Client:close nagle success!\n\r"); } else { printk("Client:close nagle failed!\n\r"); } //设置接收缓冲区 sndopt = CN_RCVBUF_LEN; if(0 == setsockopt(clientfd,SOL_SOCKET ,SO_RCVBUF,&sndopt,4)) { printk("Client:set client sndbuf success!\n\r"); } else { printk("Client:set client sndbuf failed!\n\r"); } //TEST RCV // rcvtotal = 0; // rcvbuf = M_Malloc(CN_RCVBUF_LEN,CN_TIMEOUT_FOREVER); // rcvtimestart = DjyGetTime(); // while(1) // { // rcvlen = recv(clientfd,rcvbuf,CN_RCVBUF_LEN,0); // if(rcvlen>0) // { // rcvtotal+=rcvlen; // rcvtimes++; // } // else // { // printk("Rcv Failed!\n\r"); // } // if(0==rcvtimes%1000) // { // rcvtimeend = DjyGetTime(); // nrcvtime = (u32)(rcvtimeend - rcvtimestart); // printk("Rcv: Len =0x%08x MBytes,Time = 0x%08x us\n\r",\ // rcvtotal/1024/1024,nrcvtime); // } // } //TEST SND //设置发送缓冲区 sndopt = CN_SNDBUF_LEN; if(0 == setsockopt(clientfd,SOL_SOCKET ,SO_SNDBUF,&sndopt,4)) { printk("Client:set client sndbuf success!\n\r"); } else { printk("Client:set client sndbuf failed!\n\r"); } sndbuf = M_Malloc(CN_SNDBUF_LEN,CN_TIMEOUT_FOREVER); for(i = 0; i <CN_SNDBUF_LEN; i++) { sndbuf[i] = 'a'+i%27; } while(1) { sndlen = send(clientfd,sndbuf,CN_SNDBUF_LEN,0); sgSndTimes++; Djy_EventDelay(1000*mS); } //设置接收缓冲区16KB sndopt = 0x4000; if(0 == setsockopt(clientfd,SOL_SOCKET ,SO_RCVBUF,&sndopt,4)) { printk("Client:set client rcvbuf success!\n\r"); } else { printk("Client:set client rcvbuf failed!\n\r"); } //设置发送低水位,发送低水平为28K sndopt = 0x7000; if(0 == setsockopt(clientfd,SOL_SOCKET ,SO_SNDLOWAT,&sndopt,4)) { printk("Client:set client sndbuf trig level success!\n\r"); } else { printk("Client:set client sndbuf trig level failed!\n\r"); } //设置接收水位,4KB sndopt = 0x1000; if(0 == setsockopt(clientfd,SOL_SOCKET ,SO_RCVLOWAT,&sndopt,4)) { printk("Client:set client rcvbuf trig level success!\n\r"); printk("Client:Begin Data Snd Test!\n\r"); } else { printk("Client:set client rcvbuf trig level failed!\n\r"); } //设置为非阻塞 sndopt = 1; if(0 == setsockopt(clientfd,SOL_SOCKET ,SO_NOBLOCK,&sndopt,4)) { printk("Client:Set noblock success!\n\r"); } else { printk("Client:set noblock failed!\n\r"); } // if(Socket_MultiplexAdd(writesets,clientfd,CN_SOCKET_WRITEALBE)) { printk("add client to writesets success!\n\r"); } else { printk("add client to writesets failed!\n\r"); } sndtotal = 0; sndtimestart = DjyGetTime(); while(1) { multiid = Multiplex_Wait(writesets,NULL, CN_TIMEOUT_FOREVER); if(clientfd == multiid) { sndlen = send(clientfd,sndbuf,CN_SNDBUF_LEN,0); sndprint++; if(sndlen >0) { sndtotal += sndlen; if(0 == sndprint%10000) { sndkbytes = sndtotal /1024; sndtimetest = DjyGetTime(); sndtimetest -= sndtimestart; sndspeed = (sndtotal*1000)/sndtimetest; printk("Send Msg:%d kbytes--speed = %d KB/S\n\r",\ sndkbytes,sndspeed); } // Djy_EventDelay(1000*mS); } else { // printk("Client SndSet trigged but could not write!\n\r"); } } else { badmultiwrite++; } } } else { printk("Bad Accept!\n\r"); } } closesocket(sockfd); return true; }
// ============================================================================= // 函数功能:Rtc_TimeUs // 获取日历时间,单位微秒 // 输入参数: // 输出参数:rtctime,存储获取的RTC时间,秒数 // 返回值 :获取的RTC时间,秒数 // 说明:距离1970年的时间;如果有RTC设备,则直接读取RTC设备的US,如果没有RTC时间,则自己用系统运行时间计算 // ============================================================================= s64 __Rtc_TimeUs(s64 *rtctime) { s64 result; s64 systime; atom_low_t atom; systime = DjyGetTime(); //we'd better to get the RTC time now if(NULL == fnRtcGetTime) { //no rtc dev yet,we could cal the rtc time use the sysrunning time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { if(false == fnRtcGetTime(&result)) { //failed to get the rtc dev time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } } result = result; if(NULL != rtctime) { *rtctime = result; } return result; }
// ============================================================================= // 函数功能:Rtc_Time // 获取日历时间,单位秒 // 输入参数: // 输出参数:rtctime,存储获取的RTC时间,秒数 // 返回值 :获取的RTC时间,秒数 // 说明:距离1970年的时间;当连续的多次获取RTC时间时,可能获取的值相同,因为我们 // 近似的认为在一秒内的值差不多,所以用同一个无可厚非,因为本身都是用的秒, // 精度自然在秒级 // ============================================================================= s64 __Rtc_Time(s64 *rtctime) { s64 result; s64 systime; atom_low_t atom; systime = DjyGetTime(); if((sgRtcUpdateTime2SysTime/CN_RTC_UNIT_SECOND) ==(systime/CN_RTC_UNIT_SECOND)) { //which means that we get the RTC time at the same second //we could return the same time as last time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet; #endif } else { //we'd better to get the RTC time now if(NULL == fnRtcGetTime) { //no rtc dev yet,we could cal the rtc time use the sysrunning time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { if(false == fnRtcGetTime(&result)) { //failed to get the rtc dev time #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else result = sgRtcTimeSet + systime - sgRtcUpdateTime2SysTime; sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } else { #if (64 > CN_CPU_BITS) atom = Int_LowAtomStart(); sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; Int_LowAtomEnd(atom); #else sgRtcUpdateTime2SysTime = systime; sgRtcTimeSet = result; #endif } } } result = result/CN_RTC_UNIT_SECOND; if(NULL != rtctime) { *rtctime = result; } return result; }
// ============================================================================= // 函数功能:处理传递给监视任务的消息指示 // 输入参数:msg, 待处理参数,ostime,当前系统时间 // 输出参数: // 返回值 : // 说明 : // ============================================================================= static void __Wdt_DealMsg(tagWdtMsg *msg) { u32 opcode; u32 oppara; tagWdt *wdt; struct tagEventInfo eventinfo; s64 ostime; wdt = msg->pwdt; opcode = msg->opcode; oppara = msg->para; if(NULL != wdt) { //更新WDT线程拥有者最后一次操作WDT时间 if(CN_EVENT_ID_INVALID != wdt->taskownerid) { if(Djy_GetEventInfo(wdt->taskownerid, &eventinfo)) { wdt->runtime = eventinfo.consumed_time; } } //清空连续狗叫成员 wdt->shyiptimes = 0; wdt->timeoutreason = EN_WDT_NOYIP; ostime = DjyGetTime(); switch (opcode) { case EN_WDTCMD_ADD: { //add an new wdt to the queue wdt->deadtime = wdt->cycle + ostime; __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_DEL: { __Wdt_RemovefQueue(wdt); break; } case EN_WDTCMD_PAUSE: { __Wdt_RemovefQueue(wdt); wdt->deadtime = CN_WDT_YIP_NEVER; __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_RESUME: { __Wdt_RemovefQueue(wdt); wdt->deadtime = wdt->cycle + ostime; __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_CLEAN: { __Wdt_RemovefQueue(wdt); wdt->deadtime = wdt->cycle + ostime; __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_SETTASKID: { __Wdt_RemovefQueue(wdt); wdt->taskownerid = oppara; if(wdt->deadtime != CN_WDT_YIP_NEVER) { wdt->deadtime = wdt->cycle + ostime; } __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_SETCYCLE: { __Wdt_RemovefQueue(wdt); wdt->cycle = oppara; if(wdt->deadtime != CN_WDT_YIP_NEVER) { wdt->deadtime = wdt->cycle + ostime; } __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_SETYIPACTION: { __Wdt_RemovefQueue(wdt); wdt->action = oppara; if(wdt->deadtime != CN_WDT_YIP_NEVER) { wdt->deadtime = wdt->cycle + ostime; } __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_SETYIPHOOK: { __Wdt_RemovefQueue(wdt); wdt->fnhook = (fnYipHook)oppara; if(wdt->deadtime != CN_WDT_YIP_NEVER) { wdt->deadtime = wdt->cycle + ostime; } __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_SETCONSUMEDTIMELEVEL: { __Wdt_RemovefQueue(wdt); wdt->runtimelevel = oppara; if(wdt->deadtime != CN_WDT_YIP_NEVER) { wdt->deadtime = wdt->cycle + ostime; } __Wdt_Add2Queque(wdt); break; } case EN_WDTCMD_SETSCHLEVEL: { __Wdt_RemovefQueue(wdt); wdt->sheduletimeslevel = oppara; if(wdt->deadtime != CN_WDT_YIP_NEVER) { wdt->deadtime = wdt->cycle + ostime; } __Wdt_Add2Queque(wdt); break; } default: { break; } } } return; }
// ============================================================================= // 功能:数据传送函数,完成数据的发送和接收。该函数完成的功能如下: // 1.若器件驱动为了避免组包的麻烦,可先发命令再发送数据,分多次调用,多次调用前 // 后被CSActive和CsInactive函数包裹; // 2.根据Dev查找所属SPI总线; // 3.若缓冲区大于发送字节数,则直接将数据填入缓冲区; // 4.若为阻塞发送,则等待总线信号量,若为非阻塞,则等待buf信号量; // 5.发生超时或错误时,拉高CS并释放信号量 // 参数:Dev,器件指针 // spidata,SPI数据结构体 // block_option,阻塞选项,为true时,表明最后一次传输为阻塞方式,否则为非阻塞 // timeout,超时参数,us // 返回:返回发送状态,超时或错误或无错误 // ============================================================================= s32 SPI_Transfer(struct tagSPI_Device *Dev,struct tagSPI_DataFrame *spidata, u8 block_option,u32 timeout) { struct tagSPI_CB *SPI; // struct semaphore_LCB *spi_semp; s32 result ; u32 written=0; u32 base_time = 0,rel_timeout = timeout; if(NULL == Dev) return CN_SPI_EXIT_PARAM_ERR; SPI = (struct tagSPI_CB *)Rsc_GetParent(&Dev->DevNode);//查找该器件属于哪条总线 if(NULL == SPI) return CN_SPI_EXIT_PARAM_ERR; base_time = (u32)DjyGetTime(); //若配置需自动片选,则本函数内部需拉低片选 if(Dev->AutoCs == true) { if(false == Lock_SempPend(SPI->SPI_BusSemp,timeout)) //需要等待总线空闲 { result = CN_SPI_EXIT_TIMEOUT; goto exit_from_bus_timeout; } __SPI_AutoCsActive(SPI,Dev); } Lock_SempPend(SPI->SPI_BlockSemp,0); //相当于重置信号量 //禁止调试或未登记pTransferTxRx,使用轮询方式通信 if((Djy_QuerySch() == false) || (SPI->pTransferTxRx == NULL) || (SPI->Flag & CN_SPI_FLAG_POLL)) { if(SPI->pTransferPoll != NULL) { SPI->pTransferPoll(SPI->SpecificFlag,spidata->SendBuf,spidata->SendLen, spidata->RecvBuf,spidata->RecvLen,spidata->RecvOff); if(Dev->AutoCs == true) __SPI_AutoCsInactive(SPI,Dev->Cs); result = CN_SPI_EXIT_NOERR; } goto exit_from_no_err; } if(spidata->RecvLen) block_option = true; //接收数据自动转为阻塞 SPI->SPI_Buf.Offset = 0; //发送前先清空缓冲区 SPI->Frame = *spidata; SPI->BlockOption = block_option; //如果非阻塞方式,且缓冲区够大,则直接写入缓冲区 //若不是,则先发送调用者提供的缓冲区,直到剩余字节数能够填充到缓冲区 if((!block_option) && (spidata->SendLen <= SPI->SPI_Buf.MaxLen)) { memcpy(SPI->SPI_Buf.pBuf,spidata->SendBuf,spidata->SendLen); written = spidata->SendLen; } //调用启动时序的回调函数 if(true == SPI->pTransferTxRx(SPI->SpecificFlag, spidata->SendLen, spidata->RecvLen, spidata->RecvOff )) { rel_timeout = (u32)DjyGetTime(); if(rel_timeout - base_time < timeout) rel_timeout = timeout - (rel_timeout - base_time); else { result = CN_SPI_EXIT_TIMEOUT; goto exit_from_timeout; } //需要等待的情况:1.阻塞发送;2.数据未全部填到缓冲区 if((true == block_option) || (written < spidata->SendLen)) { //等待中断函数释放信号量 if(!Lock_SempPend(SPI->SPI_BlockSemp,rel_timeout)) { result = CN_SPI_EXIT_TIMEOUT; goto exit_from_timeout; } } result = CN_SPI_EXIT_NOERR; goto exit_from_no_err; }else { result = CN_SPI_EXIT_UNKNOW_ERR; goto exit_from_timeout; } exit_from_timeout: if(Dev->AutoCs == true) //自动片选时,返回前需拉低片选 { __SPI_AutoCsInactive(SPI,Dev->Cs); } exit_from_bus_timeout: exit_from_no_err: return result; }