/************************************************************************ * LOCAL MAILBOX FUNCTIONS ***********************************************************************/ void IPC_resetMbxFlag(mbxId_t mbxNum) { // on cortex M4/M3 use primask // on cortex M0 disable interrupts globally IRQ_LOCK_KEY _lockInts(); mbxFlags[mbxNum] = NO_MSG; _unlockInts(); }
/************************************************************************ * LOCAL INTERRUPT FUNCTIONS ***********************************************************************/ void IPC_resetIntFlag(void) { /* on cortex M4/M3 use primask */ /* on cortex M0 disable interrupts globally */ IRQ_LOCK_KEY _lockInts(); intFlag = NO_MSG; _unlockInts(); }
/* change the local mailbox status */ void _setMbxStatus(mbxId_t mbxNum, mbxStat_t status) { // if cortex M4/M3 use primask, else disable interrupts globally IRQ_LOCK_KEY Mbx* lPtr = (Mbx*) (mbxLocalTablePtr); lPtr += mbxNum; _lockInts(); lPtr->mbxStatus = status; if((status == READY) || (status == ERROR_OCCURRED)) mbxFlags[mbxNum] = NO_MSG; __DSB(); /* sync the data */ _unlockInts(); }
/* after the command is retrieved, the queue contents are invalidated */ qStat IPC_masterPopMsg(maxMsg_t* item) { IRQ_LOCK_KEY msg_t msg; msgToken *rP, *wP, *eA, *sA; rP = msgBlockAddress->msgRdPtr; wP = msgBlockAddress->msgWrPtr; if(rP == wP) { _lockInts(); msgPending = NO_TOKEN; _unlockInts(); return(QEMPTY); }; msg = IPC_getMsgType(rP); eA = msgBlockAddress->msgQendAddress; sA = msgBlockAddress->msgQstartAddress; switch(msg) { case MSG_SRV: *((srvMsg*) item) = *((srvMsg*)rP); *rP = INVALID_SRV_MSG; /* invalidate the data */ if(++rP > eA) rP = sA; break; case MSG_RD: /* check for roll over */ if((rP+1) > eA) { ((msgToken*)item)->msgClass.rawMsgWord = rP->msgClass.rawMsgWord; *rP = INVALID_MSG_TOKEN; rP = sA; /* roll over the pointer */ /* read the parameter as uint_32 */ ((rdMsg*) item)->param = *((uint32_t*)rP); *rP = INVALID_MSG_TOKEN; if(++rP > eA) rP = sA; /* update again the read pointer and roll over if needed */ } else { /* can read the parameter as for the message type */ *((rdMsg*) item) = *((rdMsg*)rP); *((rdMsg*)rP) = INVALID_RD_MSG; if(++rP > eA) rP = sA; /* do it twice because of the size */ if(++rP > eA) rP = sA; } break; case MSG_RD_STS: *((rdStsMsg*) item) = *((rdStsMsg*)rP); *rP = INVALID_RD_STS_MSG; /* invalidate the data */ if(++rP > eA) rP = sA; break; case MSG_WR_STS: *((wrStsMsg*) item) = *((wrStsMsg*)rP); *rP = INVALID_WR_STS_MSG; /* invalidate the data */ if(++rP > eA) rP = sA; break; case INVALID_MSG: *rP = INVALID_MSG_TOKEN; /* just invalidate a single item to try to recover */ if(++rP > eA) rP = sA; /* update the read pointer by one and roll over if needed */ msgBlockAddress->msgRdPtr = rP; /* fall through by purpose, let application know there was an error */ default: return(QERROR); }; msgBlockAddress->msgRdPtr = rP; return(QVALID); }
/* after the command is retrieved, the queue contents are invalidated */ qStat IPC_slavePopCmd(maxCmd_t* item) { IRQ_LOCK_KEY cmd_t cmd; cmdToken *rP, *wP, *eA, *sA; rP = cmdBlockAddress->cmdRdPtr; wP = cmdBlockAddress->cmdWrPtr; if(rP == wP) { _lockInts(); cmdPending = NO_TOKEN; _unlockInts(); return(QEMPTY); }; cmd = IPC_getCmdType(rP); eA = cmdBlockAddress->cmdQendAddress; sA = cmdBlockAddress->cmdQstartAddress; switch(cmd) { case CMD_RD_ID: *((rdCmd*) item) = *((rdCmd*)rP); *rP = INVALID_RD_CMD; /* invalidate the data */ if(++rP > eA) rP = sA; break; case CMD_WR_ID: /* check for roll over */ if((rP+1) > eA) { ((cmdToken*)item)->cmdClass.rawCmdWord = rP->cmdClass.rawCmdWord; *rP = INVALID_CMD_TOKEN; rP = sA; /* roll over the pointer */ /* read the parameter as uint_32 */ ((wrCmd*) item)->param = *((uint32_t*) rP); *rP = INVALID_CMD_TOKEN; if(++rP > eA) rP = sA; /* update again the read pointer and roll over if needed */ } else { /* can read the parameter as for the message type */ *((wrCmd*) item) = *((wrCmd*)rP); *((wrCmd*)rP) = INVALID_WR_CMD; if(++rP > eA) rP = sA; /* do it twice because of the size */ if(++rP > eA) rP = sA; } break; case INVALID_CMD: *rP = INVALID_CMD_TOKEN; /* just invalidate a single item to try to recover */ if(++rP > eA) rP = sA; /* update the read pointer by one and roll over if needed */ cmdBlockAddress->cmdRdPtr = rP; /* fall through by purpose, let application know there was an error */ default: return(QERROR); }; cmdBlockAddress->cmdRdPtr = rP; return(QVALID); }