/************************************************************************* $Archive: /PACS/OnBoard/link1355.c $ $Revision: 1.11 $ $Date: 2009/04/23 13:51:12 $ $Author: amazy $ $Log: link1355.c,v $ Revision 1.11 2009/04/23 13:51:12 amazy 6.029 * * 29 3/14/06 4:32p Pacs Egse * Version 6.001 * Cleaned and commented *************************************************************************/ #ifdef SIMULATOR #include "virtuosoSim.h" #else // SIMULATOR #include "v_macro.h" #include "node1.h" #include "k_struct.h" #include "smcs\rawdef.h" #endif //SIMULATOR #ifndef LINK1355_H #include "link1355.h" #endif //LINK1355_H #include "links.h" #include "u_bits.h" //**************************************************************** // GLOBAL PARAMETERS //**************************************************************** // array of events used to signal 'end of transmission' on each of the 1355 link int gaEventsSmcsTransmitCompleted[6] = { EVENT_TX_CHANNEL_1, EVENT_TX_CHANNEL_2, EVENT_TX_CHANNEL_3, EVENT_TX_CHANNEL_4, EVENT_TX_CHANNEL_5, EVENT_TX_CHANNEL_6 }; // array of events used to signal 'end of reception' on each of the 1355 link int gaEventsSmcsReceiveCompleted[6] = { EVENT_RX_CHANNEL_1, EVENT_RX_CHANNEL_2, EVENT_RX_CHANNEL_3, EVENT_RX_CHANNEL_4, EVENT_RX_CHANNEL_5, EVENT_RX_CHANNEL_6 }; #ifndef SIMULATOR #include "l_hwmap.h" #include "m_smcsge.h" #include "m_smcsin.h" #include "m_smcsco.h" #include "m_smcsre.h" //**************************************************************** // GLOBAL PARAMETERS //**************************************************************** extern int gaLinkStatus[]; // array containing the status of each of the 1355 link extern int gaStartReading[6]; extern int gaStartLink[6]; extern int gaMasterSlave[6]; //**************************************************************** // FUNCTION DECLARATION //**************************************************************** void __StartLink(int device, int masterSlave); //**************************************************************** // FUNCTION IMPLEMENTATION //**************************************************************** /* FUNCTION : void ConfigureLinkToAutoReconnect(int device) ******************************************************** AUTHOR : AMazy USE : Configure a 1355 link to auto-reconnect after a disconnection PARAMS: device: the id of the link */ void ConfigureLinkToAutoReconnect(int device) { switch (device) { case K_SMCSCHANNEL_1 : DSMCS_WriteSMCSReg(K_DMADD_SMCS1_CH1_DSM_CMDR, 0x04); break; case K_SMCSCHANNEL_2 : DSMCS_WriteSMCSReg(K_DMADD_SMCS1_CH2_DSM_CMDR, 0x04); break; case K_SMCSCHANNEL_3 : DSMCS_WriteSMCSReg(K_DMADD_SMCS1_CH3_DSM_CMDR, 0x04); break; case K_SMCSCHANNEL_4 : DSMCS_WriteSMCSReg(K_DMADD_SMCS2_CH4_DSM_CMDR, 0x04); break; case K_SMCSCHANNEL_5 : DSMCS_WriteSMCSReg(K_DMADD_SMCS2_CH5_DSM_CMDR, 0x04); break; case K_SMCSCHANNEL_6 : DSMCS_WriteSMCSReg(K_DMADD_SMCS2_CH6_DSM_CMDR, 0x04); break; default : }; } /* FUNCTION : void StartReadingOnLink(int device) ********************************************** AUTHOR : AMazy USE : Initialize a read operation on a 1355 link PARAMS: device: the id of the link */ void StartReadingOnLink(int device) { T_UNSIGNED_32 packetStartAddressDPRAM; // offset from start of DPRAM T_UNSIGNED_32 absoluteStartAddress; packetStartAddressDPRAM = DPRAM_BUFFER_SIZE*(2*((device-K_SMCSCHANNEL_1)%3) + 1); // find start address if (device <= K_SMCSCHANNEL_3) { absoluteStartAddress = K_DMADDR_BASE_SMCS1DPRAM + packetStartAddressDPRAM; } else { absoluteStartAddress = K_DMADDR_BASE_SMCS2DPRAM + packetStartAddressDPRAM; } SET_BIT(gaLinkStatus[device-K_SMCSCHANNEL_1], READING); // start reception DSMCS_ReceiveBuffer(device, absoluteStartAddress, DPRAM_BUFFER_SIZE); }; /* FUNCTION : void Link1355Read(int device, int size, void* pDataBlock) ******************************************************************** AUTHOR : AMazy USE : Wait that a read operation is completed, copy the data in the buffer and initiate the next read operation PARAMS: device: the id of the link size: the size to be read p_dataBlock: the buffer where the data must be copied */ void Link1355Read(int device, int size, void* p_dataBlock) { T_UNSIGNED_32 packetStartAddressDPRAM; // offset from start of DPRAM T_UNSIGNED_32 absoluteStartAddress; packetStartAddressDPRAM = DPRAM_BUFFER_SIZE*(2*((device-K_SMCSCHANNEL_1)%3) + 1); // find start address // wait for event (raised by ISR when a packet has been received) KS_EventTestW(gaEventsSmcsReceiveCompleted[device-K_SMCSCHANNEL_1]); CLEAR_BIT(gaLinkStatus[device-K_SMCSCHANNEL_1], READING); // copy DPRAM into p_dataBlock if (device <= K_SMCSCHANNEL_3) { absoluteStartAddress = K_DMADDR_BASE_SMCS1DPRAM + packetStartAddressDPRAM; } else { absoluteStartAddress = K_DMADDR_BASE_SMCS2DPRAM + packetStartAddressDPRAM; } MEMCPY(p_dataBlock, (void*)(absoluteStartAddress), size); //restart reading (for next packet) StartReadingOnLink(device); SET_BITS(gaLinkStatus[device-K_SMCSCHANNEL_1], READ_FROM, READ_FROM_LINK1355_READ); } /* FUNCTION : void Link1355Read(int device, int size, void* pDataBlock) ******************************************************************** AUTHOR : AMazy USE : Wait that the previous write operation is completed, copy the data in the buffer and initiate the write operation PARAMS: device: the id of the link size: the size to be written p_dataBlock: the buffer to send */ void Link1355Write(int device, int size, void* p_dataBlock) { T_UNSIGNED_32 packetStartAddressDPRAM; // offset from start of DPRAM T_UNSIGNED_32 absoluteStartAddress; // wait for event (raised by ISR when previous transmission is finished) KS_EventTestW(gaEventsSmcsTransmitCompleted[device-K_SMCSCHANNEL_1]); // copy pDataBlock into DPRAM packetStartAddressDPRAM = DPRAM_BUFFER_SIZE*(2*((device-K_SMCSCHANNEL_1)%3)); // find start address if (device <= K_SMCSCHANNEL_3) { absoluteStartAddress = K_DMADDR_BASE_SMCS1DPRAM + packetStartAddressDPRAM; } else { absoluteStartAddress = K_DMADDR_BASE_SMCS2DPRAM + packetStartAddressDPRAM; } MEMCPY((void*)(absoluteStartAddress), p_dataBlock, size); // start transmission DSMCS_TransmitBuffer(device, K_EOP1, absoluteStartAddress, size); } /* FUNCTION : int Link1355Test(int device) *************************************** AUTHOR : AMazy USE : Check if a link 1355 is connected PARAMS: device: the id of the link */ int Link1355Test(int device) { T_UNSIGNED_32 status=0; // read status register DSMCS_GetChannelStatus(device, &status); /* Check if NULLs have been received */ if (status & (1 << K_BPOS_CHx_DSM_STAR_NULLRECEIVED)) { return RC_OK; } else { return RC_FAIL; } } /* FUNCTION : int GetSmcsChipForLink(int device) ********************************************* AUTHOR : AMazy USE : Get the SMCS id where the link is. PARAMS: device: the id of the link */ int GetSmcsChipForLink(int device) { if (device <= K_SMCSCHANNEL_3) { return K_SMCS_1; } else { return K_SMCS_2; } } /* FUNCTION : void MaskUnmaskInterruptsForLink(int device, int mask) ***************************************************************** USE : mask/unmask the smcs interrupts independently for each channel PARAMS : device : 1355 channel, from K_SMCSCHANNEL_1 to K_SMCSCHANNEL_6 mask : K_MASK to disable, K_UNMASK to enable SEE ALSO : used in EnableInterruptsForLink and DisableInterruptsForLink */ void MaskUnmaskInterruptsForLink(int device, int mask) { //enable TX/RX/ERR interrupts on the SMCS chips switch(device) { case K_SMCSCHANNEL_1 : DSMCS_MaskUnmaskSMCSSubInt(K_SMCS_1, K_BMASK_SMCSINT_CH1_PAR_DIS_ERR | K_BMASK_SMCSINT_CH1_DATA_TXED | K_BMASK_SMCSINT_CH1_DATA_RXED | K_BMASK_SMCSINT_CH1_EOP_RXED, mask); break; case K_SMCSCHANNEL_2 : DSMCS_MaskUnmaskSMCSSubInt(K_SMCS_1, K_BMASK_SMCSINT_CH2_PAR_DIS_ERR | K_BMASK_SMCSINT_CH2_DATA_TXED | K_BMASK_SMCSINT_CH2_DATA_RXED | K_BMASK_SMCSINT_CH2_EOP_RXED, mask); break; case K_SMCSCHANNEL_3 : DSMCS_MaskUnmaskSMCSSubInt(K_SMCS_1, K_BMASK_SMCSINT_CH3_PAR_DIS_ERR | K_BMASK_SMCSINT_CH3_DATA_TXED | K_BMASK_SMCSINT_CH3_DATA_RXED | K_BMASK_SMCSINT_CH3_EOP_RXED, mask); break; case K_SMCSCHANNEL_4 : DSMCS_MaskUnmaskSMCSSubInt(K_SMCS_2, K_BMASK_SMCSINT_CH4_PAR_DIS_ERR | K_BMASK_SMCSINT_CH4_DATA_TXED | K_BMASK_SMCSINT_CH4_DATA_RXED | K_BMASK_SMCSINT_CH4_EOP_RXED | K_BMASK_SMCSINT_CH4_RXFIFOFULL, mask); break; case K_SMCSCHANNEL_5 : DSMCS_MaskUnmaskSMCSSubInt(K_SMCS_2, K_BMASK_SMCSINT_CH5_PAR_DIS_ERR | K_BMASK_SMCSINT_CH5_DATA_TXED | K_BMASK_SMCSINT_CH5_DATA_RXED | K_BMASK_SMCSINT_CH5_EOP_RXED, mask); break; case K_SMCSCHANNEL_6 : DSMCS_MaskUnmaskSMCSSubInt(K_SMCS_2, K_BMASK_SMCSINT_CH6_PAR_DIS_ERR | K_BMASK_SMCSINT_CH6_DATA_TXED | K_BMASK_SMCSINT_CH6_DATA_RXED | K_BMASK_SMCSINT_CH6_EOP_RXED | K_BMASK_SMCSINT_CH6_RXFIFOFULL, mask); break; } } void EnableInterruptsForLink(int device) { MaskUnmaskInterruptsForLink(device, K_UNMASK); } void DisableInterruptsForLink(int device) { MaskUnmaskInterruptsForLink(device, K_MASK); } /* FUNCTION : void EnableReadingAndWritingOnLink(int device) ********************************************************* USE : Configure the link such that they are ready to read and write PARAMS : device : 1355 channel, from K_SMCSCHANNEL_1 to K_SMCSCHANNEL_6 */ void EnableReadingAndWritingOnLink(int device) { //enable reading and writing on this link //*************************************** // signal event to allow first write command to execute KS_EventSignal(gaEventsSmcsTransmitCompleted[device - K_SMCSCHANNEL_1]); // initiate the first read operation StartReadingOnLink(device); } /* FUNCTION : void StartLink(int device, int resetChip) **************************************************** USE : High level function to start a 1355 link (including an optional chip reset of the SMCS) PARAMS : device : 1355 channel, from K_SMCSCHANNEL_1 to K_SMCSCHANNEL_6 resetChip : RESET_SMCS or NO_SMCS_RESET */ void StartLink(int device, int resetChip) { // note that we request this link to be started gaStartLink[device-K_SMCSCHANNEL_1] = gaMasterSlave[device-K_SMCSCHANNEL_1] + resetChip; // wake up the SMCS DRV STATE task. It will start the link KS_SemaSignal(SEMA_SMCS_DRV_STATE); } /* FUNCTION : void _StartLink(int device, int masterSlave, int resetChip) ********************************************************************** USE : starts a 1355 link (including an optional chip reset of the SMCS). This function shall only be called by the SMCS_DRV_STATE task. PARAMS : device : 1355 channel, from K_SMCSCHANNEL_1 to K_SMCSCHANNEL_6 resetChip : RESET_SMCS or NO_SMCS_RESET */ void _StartLink(int device, int masterSlave, int resetChip) { if (resetChip == RESET_SMCS) { unsigned int smcsChip = GetSmcsChipForLink(device); int linkIterator = 0; int firstLinkOfSmcs = (smcsChip == K_SMCS_1 ? K_SMCSCHANNEL_1 : K_SMCSCHANNEL_4); int linkStatus[6]; //stops all the links that are already connected for (linkIterator = firstLinkOfSmcs; linkIterator < firstLinkOfSmcs+3; ++linkIterator) { linkStatus[linkIterator - K_SMCSCHANNEL_1] = gaLinkStatus[linkIterator - K_SMCSCHANNEL_1]; if ((gaLinkStatus[linkIterator - K_SMCSCHANNEL_1] & CONN_STATUS_MASK) != NOT_STARTED) { StopLink(linkIterator); } } //reset the chip DSMCS_ResetSMCSChip(smcsChip); DSMCS_ConfigureSMCSNominal(smcsChip); // and restart the links that were already started before the reset (except the link identified by 'device') for (linkIterator = firstLinkOfSmcs; linkIterator < firstLinkOfSmcs+3; ++linkIterator) { if (((linkStatus[linkIterator - K_SMCSCHANNEL_1] & CONN_STATUS_MASK) != NOT_STARTED) && (linkIterator != device)) { __StartLink(linkIterator, gaMasterSlave[linkIterator - K_SMCSCHANNEL_1]); } } } //start the link itself __StartLink(device, masterSlave); } /* FUNCTION : void __StartLink(int device, int masterSlave) ******************************************************** USE : Low level function to start a link. This function is only called from _StartLink PARAMS : device : 1355 channel, from K_SMCSCHANNEL_1 to K_SMCSCHANNEL_6 masterSlave : MASTER or SLAVE */ void __StartLink(int device, int masterSlave) { if (masterSlave == MASTER) { DSMCS_StartChannelAsMaster(device); SET_BITS(gaLinkStatus[device - K_SMCSCHANNEL_1], CONN_STATUS_MASK, WAITING_CONNECTION_MASTER); } else { //to start a slave, nothing has to be done ! SET_BITS(gaLinkStatus[device - K_SMCSCHANNEL_1], CONN_STATUS_MASK, WAITING_CONNECTION_SLAVE); } } /* FUNCTION : void StopLink(int device) ************************************ USE : High level function to stop a 1355 link PARAMS : device : 1355 channel, from K_SMCSCHANNEL_1 to K_SMCSCHANNEL_6 */ void StopLink(int device) { DisableInterruptsForLink(device); DSMCS_StopChannel(device); //record that the link has been stopped CLEAR_BIT(gaLinkStatus[device-K_SMCSCHANNEL_1], CONN_STATUS_MASK | READ_FROM | READING); } #endif //SIMULATOR