#include #include #include "em_device.h" #include "em_cmu.h" #include "em_assert.h" #include "em_bitband.h" #include "em_emu.h" #include "em_usart.h" #include "em_gpio.h" #include "wiznet.h" #include "wiznet_tcp.h" #include "globaldefs.h" #include "./WMP/GlobExt.h" #include "./WMP/ExternalFuncs.h" #include "helper_functions.h" /* *********************************************************************************** Private Variables *********************************************************************************** */ static uint8_t I_STATUS[MAX_SOCK_NUM]; /* Interrupt status */ static uint16_t SMASK[MAX_SOCK_NUM]; /* Variable for Tx buffer MASK in each channel */ static uint16_t RMASK[MAX_SOCK_NUM]; /* Variable for Rx buffer MASK in each channel */ static uint16_t SSIZE[MAX_SOCK_NUM]; /* Max Tx buffer size of each channel */ static uint16_t RSIZE[MAX_SOCK_NUM]; /* Max Rx buffer size of each channel */ static uint16_t SBUFBASEADDRESS[MAX_SOCK_NUM]; /* Tx buffer base address of each channel */ static uint16_t RBUFBASEADDRESS[MAX_SOCK_NUM]; /* Rx buffer base address of each channel */ uint8_t temp; USART_TypeDef *usart_to_wiznet = USART0; USART_InitSync_TypeDef usart_to_wiznet_init = USART_INITSYNC_DEFAULT; #define WIZNET_CS_LOW() (GPIO_PinOutClear (gpioPortC, 8)) #define WIZNET_CS_HIGH() (GPIO_PinOutSet (gpioPortC, 8)) #define ASSERT_WIZNET_RESET() (GPIO_PinOutClear (gpioPortE, 12)) #define DEASSERT_WIZNET_RESET() (GPIO_PinOutSet (gpioPortE, 12)) void init_usart0_for_wiznet(void) { /* Configure USART for basic sync operation */ usart_to_wiznet_init.enable = usartEnable; usart_to_wiznet_init.refFreq = 0; usart_to_wiznet_init.databits = usartDatabits8; usart_to_wiznet_init.baudrate = 100000; usart_to_wiznet_init.clockMode = usartClockMode0; usart_to_wiznet_init.msbf = true; USART_InitSync (usart_to_wiznet, &usart_to_wiznet_init); /* Enable pins at location 2*/ //We will control the CS pin ourselves. usart_to_wiznet->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | /*USART_ROUTE_CSPEN |*/ USART_ROUTE_CLKPEN | USART_ROUTE_LOCATION_LOC2; /* Clear previous RX interrupts */ // USART_IntClear ( (USART_TypeDef *) cmuClock_USART2, USART_IF_RXDATAV); // NVIC_ClearPendingIRQ ( USART2_RX_IRQn); /* Finally enable it */ USART_Enable (usart_to_wiznet, usartEnable); } /********************************************************************************** Function Name: sysinit Purpose: This function set the transmit & receive buffer size as per the channels. Note for TMSR and RMSR bits are as follows bit 1-0 : memory size of channel #0 bit 3-2 : memory size of channel #1 bit 5-4 : memory size of channel #2 bit 7-6 : memory size of channel #3 (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte) Maximum memory size for Tx, Rx in the W5100 is 8K Bytes, In the range of 8KBytes, the memory size could be allocated dynamically by each channel. Sum of memory sizes shouldn't exceed 8Kbytes (Tx + Rx) Data transmission and receiption from non-allocated channel may cause some problems. If the 8KBytes memory is already assigned to certain channel, other 3 channels can't be used, for there's no available memory. If two 4KBytes memory are assigned to two channels, other 2 channels can't be used, for there's no available memory. Input: Tx Memory size for each channel Rx Memory size for each channel Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ void SysInit(uint8_t ucharTx_Size, uint8_t ucharRx_Size ) { uint16_t i; uint16_t TxMemorySize = 0; uint16_t RxMemorySize = 0; //setMR(MR_RST); setTMSR(ucharTx_Size); /* Set Tx memory size for each channel */ setRMSR(ucharRx_Size); /* Set Rx memory size for each channel */ SBUFBASEADDRESS[0] = (uint16_t)(W5100_TXBUF_START_ADDRESS); /* Set base address of Tx memory for channel #0 */ RBUFBASEADDRESS[0] = (uint16_t)(W5100_RXBUF_START_ADDRESS); /* Set base address of Rx memory for channel #0 */ for (i = 0; i < MAX_SOCK_NUM; i++) /* Set the size, masking and base address of Tx & Rx memory by each channel */ { SSIZE[i] = (uint16_t)(0); RSIZE[i] = (uint16_t)(0); if (TxMemorySize < 8192) { switch((ucharTx_Size >> i*2) & 0x03) /* Set Tx memory size */ { case 0: /* 1KB */ SSIZE[i] = (uint16_t)(1024); SMASK[i] = (uint16_t)(0x03FF); break; case 1: /* 2KB */ SSIZE[i] = (uint16_t)(2048); SMASK[i] = (uint16_t)(0x07FF); break; case 2: /* 4KB */ SSIZE[i] = (uint16_t)(4096); SMASK[i] = (uint16_t)(0x0FFF); break; case 3: /* 8KB */ SSIZE[i] = (uint16_t)(8192); SMASK[i] = (uint16_t)(0x1FFF); break; } } if (RxMemorySize < 8192) { switch((ucharRx_Size >> i*2) & 0x03) /* Set Rx memory size */ { case 0: /* 1KB */ RSIZE[i] = (uint16_t)(1024); RMASK[i] = (uint16_t)(0x03FF); break; case 1: /* 2KB */ RSIZE[i] = (uint16_t)(2048); RMASK[i] = (uint16_t)(0x07FF); break; case 2: /* 4KB */ RSIZE[i] = (uint16_t)(4096); RMASK[i] = (uint16_t)(0x0FFF); break; case 3: /* 8KB */ RSIZE[i] = (uint16_t)(8192); RMASK[i] = (uint16_t)(0x1FFF); break; } } TxMemorySize += SSIZE[i]; RxMemorySize += RSIZE[i]; if (i != 0) // Sets base address of Tx and Rx memory for channel #1,#2,#3 { SBUFBASEADDRESS[i] = SBUFBASEADDRESS[i-1] + SSIZE[i-1]; RBUFBASEADDRESS[i] = RBUFBASEADDRESS[i-1] + RSIZE[i-1]; } } } /********************************************************************************** Function Name: wiz_read_buf Purpose: Reads W5100 memory(Buffer) Input: WIznet W5100 memory address from where to read. Where to read. Number of bytes to read. Return value: Number of bytes read. Change History: Author Date Remarks Omer Miranda 17-01-2014 Created ***********************************************************************************/ uint16_t wiz_read_buf(uint16_t ushAddr, uint8_t* ucharBuf,uint16_t ushLen) { uint16_t ushLocation = 0; /* This might be needed to be replace by eqvivalent code * IINCHIP_ISR_DISABLE(); */ //IINCHIP_SpiInit(); This is not needed. I guess... for (ushLocation = 0; ushLocation < ushLen; ushLocation++) { //IINCHIP_CSoff(); // CS=0, SPI start ucharBuf[ushLocation] = read_wiznet_reg(ushAddr + ushLocation); //IINCHIP_SpiSendData(0x0F); //IINCHIP_SpiSendData(((addr+idx) & 0xFF00) >> 8); //IINCHIP_SpiSendData((addr+idx) & 0x00FF); //IINCHIP_SpiSendData(0); //buf[idx] = IINCHIP_SpiRecvData(); //IINCHIP_CSon(); // CS=0, SPI end } /* This might be needed to be replace by eqvivalent code * IINCHIP_ISR_ENABLE(); */ return ushLen; } /********************************************************************************** Function Name: wiz_write_buf Purpose: Writes to W5100 memory(Buffer) Input: WIznet W5100 memory address where to write. From where to write. Number of bytes to write. Return value: Number of bytes wrote. Change History: Author Date Remarks Omer Miranda 17-01-2014 Created ***********************************************************************************/ uint16_t wiz_write_buf(uint16_t ushAddr,uint8_t* ucharBuf,uint16_t ushLen) { uint16_t ushLocation = 0; /* This might be needed to be replace by eqvivalent code * IINCHIP_ISR_DISABLE(); */ //IINCHIP_SpiInit(); This is not needed. I guess... for(ushLocation = 0; ushLocation < ushLen; ushLocation++) { write_wiznet_reg((ushAddr + ushLocation), ucharBuf[ushLocation]); } /* This might be needed to be replace by eqvivalent code * IINCHIP_ISR_ENABLE(); */ return ushLen; } uint8_t read_wiznet_reg(uint16_t addr) { uint8_t data=0x00; uint8_t junk=0x00; junk = junk; WIZNET_CS_LOW() ; USART_Tx(usart_to_wiznet,W5100_READ_OPCODE); junk = USART_Rx(usart_to_wiznet); USART_Tx(usart_to_wiznet,((addr&0xFF00)>>8)); junk = USART_Rx(usart_to_wiznet); USART_Tx(usart_to_wiznet,(addr&0x00FF)); junk = USART_Rx(usart_to_wiznet); USART_Tx(usart_to_wiznet,0); //Must send a dummy byte to get data data = USART_Rx(usart_to_wiznet); WIZNET_CS_HIGH() ; return data; } uint8_t write_wiznet_reg(uint16_t addr, uint8_t data) { uint8_t junk = 0x00; WIZNET_CS_LOW() ; Delay_ms(1); USART_Tx(usart_to_wiznet,W5100_WRITE_OPCODE); junk = USART_Rx(usart_to_wiznet); USART_Tx(usart_to_wiznet,((addr&0xFF00)>>8)); junk = USART_Rx(usart_to_wiznet); USART_Tx(usart_to_wiznet,(addr&0x00FF)); junk = USART_Rx(usart_to_wiznet); USART_Tx(usart_to_wiznet,data); junk = USART_Rx(usart_to_wiznet); Delay_ms(1); WIZNET_CS_HIGH() ; return junk; } /********************************************************************************** Function Name: initWiznet Purpose: This function inits the USART0 used for wiznet. It also configures the network and the wiznet chip for TCP communication Input: None Return value: None. Change History: Author Date Remarks Omer Miranda 24-01-2014 Created ***********************************************************************************/ uint32_t initWiznet(void) { //unsigned char MAC_ADDR[6]; uint8_t status = 0x01; /* Power the wiznet chip */ GPIO_PinOutSet (gpioPortC, 1); Delay_ms(1); /* Reset the wiznet chip */ ASSERT_WIZNET_RESET(); Delay_ms(1); init_usart0_for_wiznet(); DEASSERT_WIZNET_RESET(); setRTR(6000); /* Retry time = 600 ms*/ Delay_ms(1); setRCR(3); /* Retry count = 3 */ Delay_ms(1); //setIMR(0x00); /* Interrupt mask */ setGAR(); /* Gateway IP address */ Delay_ms(1); setSUBR(); /* Subnet mask */ Delay_ms(1); setSHAR(); /* MAC address */ Delay_ms(1); setSIPR(); /* Source IP address */ Delay_ms(1); SysInit(0x55, 0x55); /* TX = 8kB, RX = 8 kB */ Delay_ms(1); setIMR(IR_SOCK(0)); /* Enable the socket 0 interrupt */ Delay_ms(1); /* Configure the EFM32 for external interrupt from Wiznet chip */ NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); NVIC_EnableIRQ(GPIO_ODD_IRQn); /* Configure PE13 as input */ GPIO_PinModeSet(gpioPortE, 13, gpioModeInput, 1); /* Set falling edge interrupt */ GPIO_IntConfig(gpioPortE, 13, false, true, true); write_wiznet_reg(Sn_IR(0), 0xff); /* Open the socket for server mode */ temp = 1; /* The below code is for testing purpose only * It checks if :listen command is properly set. * Else it loops forever. */ while( temp) { socket(0, Sn_MR_TCP, 502, 0x00); temp = getSn_SR(0); temp = listen(0); } return status; } /********************************************************************************** Function Name: send_data_processing Purpose: This function is called by send() and sendto(). This function reads the Tx write pointer register, copies the data in Tx buffer and then updates the Tx write pointer register. User should read upper byte first and lower byte later to get proper value. Input: Socket number. Local Buffer from where to write. Number of bytes to write. Return value: None. Change History: Author Date Remarks Omer Miranda 17-01-2014 Created ***********************************************************************************/ void send_data_processing(SOCKET s, uint8_t *ucharDataBuf, uint16_t ushLen) { uint16_t TxBufAddress; /* Get the Wiznet Tx Buffer address */ TxBufAddress = read_wiznet_reg(Sn_TX_WR0(s)); TxBufAddress = ((TxBufAddress & 0x00ff) << 8) + read_wiznet_reg(Sn_TX_WR0(s) + 1); write_data(s, ucharDataBuf, TxBufAddress, ushLen); TxBufAddress += ushLen; /* Update the Wiznet Tx Buffer address */ write_wiznet_reg(Sn_TX_WR0(s),(uint8_t)((TxBufAddress & 0xff00) >> 8)); write_wiznet_reg((Sn_TX_WR0(s) + 1),(uint8_t)(TxBufAddress & 0x00ff)); } /********************************************************************************** Function Name: write_data Purpose: Copies the data form application buffer to Tx buffer of the Wiznet chip. It calculates the actual physical address where one has to write the data in transmite buffer. Also takes care of the condition where it exceeds the Tx memory uper-bound of socket. Input: Socket number. Local Buffer from where to write. Wiznet Tx address where to write. Number of bytes to write. Return value: None. Change History: Author Date Remarks Omer Miranda 17-01-2014 Created ***********************************************************************************/ void write_data(SOCKET s, volatile uint8_t* p_ucharSrc, volatile uint16_t ushTxBufAddr, uint16_t ushLen) { uint16_t ushSize; uint16_t ushDstAddrMask; uint16_t ushDstAddr; ushDstAddrMask = ushTxBufAddr & getW5100_TxMASK(s); ushDstAddr = getW5100_TxBASE(s) + ushDstAddrMask; if (ushDstAddrMask + ushLen > getW5100_TxMAX(s)) { ushSize = getW5100_TxMAX(s) - ushDstAddrMask; wiz_write_buf(ushDstAddr, (uint8_t*)p_ucharSrc, ushSize); p_ucharSrc += ushSize; ushSize = ushLen - ushSize; ushDstAddr = (getW5100_TxBASE(s)); wiz_write_buf((uint16_t)ushDstAddr, (uint8_t*)p_ucharSrc, ushSize); } else { wiz_write_buf((uint16_t)ushDstAddr, (uint8_t*)p_ucharSrc, ushLen); } } /********************************************************************************** Function Name: recv_data_processing Purpose: This function is called by recv(). This function reads the Rx read pointer register, copies the data from receive buffer and updates the Rx write pointer register. User should read upper byte first and lower byte later to get proper value. Input: Socket number. Local Buffer where to read. Number of bytes to read. Return value: None. Change History: Author Date Remarks Omer Miranda 17-01-2014 Created ***********************************************************************************/ void recv_data_processing(SOCKET s, uint8_t* ucharDataBuf, uint16_t ushLen) { uint16_t RxBufAddress; /* Get the Wiznet Rx Buffer address */ RxBufAddress = read_wiznet_reg(Sn_RX_RD0(s)); RxBufAddress = ((RxBufAddress & 0x00ff) << 8) + read_wiznet_reg(Sn_RX_RD0(s) + 1); read_data(s, RxBufAddress, ucharDataBuf, ushLen); // read data RxBufAddress += ushLen; /* Update the Wiznet Rx Buffer address */ write_wiznet_reg(Sn_RX_RD0(s),(uint8_t)((RxBufAddress & 0xff00) >> 8)); write_wiznet_reg((Sn_RX_RD0(s) + 1),(uint8_t)(RxBufAddress & 0x00ff)); } /********************************************************************************** Function Name: read_data Purpose: This function is called by recv(). This function reads the Rx read pointer register, copies the data from receive buffer and updates the Rx write pointer register. User should read upper byte first and lower byte later to get proper value. Input: Socket number. Wiznet Rx address from where to Read. Local Buffer where to read. Number of bytes to read. Return value: None. Change History: Author Date Remarks Omer Miranda 17-01-2014 Created ***********************************************************************************/ void read_data(SOCKET s, volatile uint16_t ushRxBufAddr, volatile uint8_t* p_ucharDst, uint16_t ushLen) { uint16_t ushSize; uint16_t ushSrcAddrMask; uint16_t ushSrcAddr; ushSrcAddrMask = ushRxBufAddr & getW5100_RxMASK(s); ushSrcAddr = getW5100_RxBASE(s) + ushSrcAddrMask; if( (ushSrcAddrMask + ushLen) > getW5100_RxMAX(s) ) { ushSize = getW5100_RxMAX(s) - ushSrcAddrMask; wiz_read_buf(ushSrcAddr, (uint8_t*)p_ucharDst, ushSize); p_ucharDst += ushSize; ushSize = ushLen - ushSize; ushSrcAddr = getW5100_RxBASE(s); wiz_read_buf(ushSrcAddr, (uint8_t*)p_ucharDst, ushSize); } else { wiz_read_buf(ushSrcAddr, (uint8_t*)p_ucharDst, ushLen); } } /********************************************************************************** Function Name: setMR Purpose: Set the Mode register Input: MR Value. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setMR(uint8_t ucharVal) { write_wiznet_reg(W5100_MR, ucharVal); } /********************************************************************************** Function Name: setRTR Purpose: Set the Retry Time register If there is no response from the peer or delay in response then retransmission will be there as per RTR (Retry Time-value Register)setting Input: RTR Value. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setRTR(uint16_t ushTimeout) { write_wiznet_reg(W5100_RTR,(uint8_t)((ushTimeout & 0xff00) >> 8)); write_wiznet_reg((W5100_RTR + 1), (uint8_t)(ushTimeout & 0x00ff)); } /********************************************************************************** Function Name: setRCR Purpose: Set the Retry Count register If there is no response from the peer or delay in response then recorded time as per RTR & RCR register seeting then time out will occur. Input: RCR Value. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setRCR(uint8_t ucharRetry) { write_wiznet_reg(W5100_RCR, ucharRetry); } /********************************************************************************** Function Name: setIMR Purpose: Set the interrupt mask Enable/Disable appropriate Interrupt. ('1' : interrupt enable) If any bit in IMR is set as '0' then there is no interrupt signal, even though the bit is set in IR register. Input: IMR Value. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setIMR(uint8_t ucharMask) { write_wiznet_reg(W5100_IMR, ucharMask); } /********************************************************************************** Function Name: getIR Purpose: Gets Interrupt register in common register. Input: None. Return value: IR Value. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ uint8_t getIR( void ) { return read_wiznet_reg(W5100_IR); } /********************************************************************************** Function Name: setGAR Purpose: Sets the gateway IP as configued via the modbus. Input: None. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setGAR(void) { write_wiznet_reg((W5100_GAR + 0), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushGAR[0]); write_wiznet_reg((W5100_GAR + 1), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushGAR[1]); write_wiznet_reg((W5100_GAR + 2), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushGAR[2]); write_wiznet_reg((W5100_GAR + 3), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushGAR[3]); } /********************************************************************************** Function Name: getGAR Purpose: Gets gateway IP address. Input: Pointer to a 4 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void getGAR(uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(W5100_GAR); p_ucharAddr[1] = read_wiznet_reg(W5100_GAR + 1); p_ucharAddr[2] = read_wiznet_reg(W5100_GAR + 2); p_ucharAddr[3] = read_wiznet_reg(W5100_GAR + 3); } /********************************************************************************** Function Name: setSUBR Purpose: Sets the subnet mask IP as configued via the modbus. Input: None. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setSUBR(void) { write_wiznet_reg((W5100_SUBR + 0), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSubnet[0]); write_wiznet_reg((W5100_SUBR + 1), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSubnet[1]); write_wiznet_reg((W5100_SUBR + 2), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSubnet[2]); write_wiznet_reg((W5100_SUBR + 3), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSubnet[3]); } /********************************************************************************** Function Name: getSUBR Purpose: Gets Subnet Mask IP address. Input: Pointer to a 4 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void getSUBR(uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(W5100_SUBR); p_ucharAddr[1] = read_wiznet_reg(W5100_SUBR + 1); p_ucharAddr[2] = read_wiznet_reg(W5100_SUBR + 2); p_ucharAddr[3] = read_wiznet_reg(W5100_SUBR + 3); } /********************************************************************************** Function Name: clearSUBR Purpose: Clears the subnet mask register. Input: None. Return value: None. Change History: Author Date Remarks Omer Miranda 20-01-2014 Created ***********************************************************************************/ void clearSUBR(void) { write_wiznet_reg((W5100_SUBR + 0), 0); write_wiznet_reg((W5100_SUBR + 1), 0); write_wiznet_reg((W5100_SUBR + 2), 0); write_wiznet_reg((W5100_SUBR + 3), 0); } /********************************************************************************** Function Name: setSHAR Purpose: Sets the source MAC addres as configued via the modbus. Input: None. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setSHAR(void) { write_wiznet_reg((W5100_SHAR + 0), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSHAR[0]); write_wiznet_reg((W5100_SHAR + 1), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSHAR[1]); write_wiznet_reg((W5100_SHAR + 2), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSHAR[2]); write_wiznet_reg((W5100_SHAR + 3), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSHAR[3]); write_wiznet_reg((W5100_SHAR + 4), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSHAR[4]); write_wiznet_reg((W5100_SHAR + 5), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSHAR[5]); } /********************************************************************************** Function Name: getSHAR Purpose: Gets MAC address. Input: Pointer to a 6 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void getSHAR(uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(W5100_SHAR); p_ucharAddr[1] = read_wiznet_reg(W5100_SHAR + 1); p_ucharAddr[2] = read_wiznet_reg(W5100_SHAR + 2); p_ucharAddr[3] = read_wiznet_reg(W5100_SHAR + 3); p_ucharAddr[4] = read_wiznet_reg(W5100_SHAR + 2); p_ucharAddr[5] = read_wiznet_reg(W5100_SHAR + 3); } /********************************************************************************** Function Name: setSIPR Purpose: Sets the Source IP address as configued via the modbus. Input: None. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setSIPR(void) { write_wiznet_reg((W5100_SIPR + 0), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSIPR[0]); write_wiznet_reg((W5100_SIPR + 1), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSIPR[1]); write_wiznet_reg((W5100_SIPR + 2), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSIPR[2]); write_wiznet_reg((W5100_SIPR + 3), g_strctpFlash->m_strctHolding.m_strctNetConfig.a_ushSIPR[3]); } /********************************************************************************** Function Name: getSIPR Purpose: Gets Source IP address. Input: Pointer to a 4 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void getSIPR(uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(W5100_SIPR); p_ucharAddr[1] = read_wiznet_reg(W5100_SIPR + 1); p_ucharAddr[2] = read_wiznet_reg(W5100_SIPR + 2); p_ucharAddr[3] = read_wiznet_reg(W5100_SIPR + 3); } /********************************************************************************** Function Name: setTMSR Purpose: Sets the Tx memory size register. 00 = 1 kb, 01 = 2 kb, 01 = 4 kb and 11 = 8bk Input: Tx size for each channel. Total 8 kb is available for 4 channels. So if ch1 = 8kb then TxSize = 0x03 and other three channels are not used. If ch1 = 4 kb and ch2 = 4 kb, then TxSize = 00001010b = 0x0A and other 2 are not used and so forth... Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setTMSR(uint8_t TxSize) { write_wiznet_reg(W5100_TMSR, TxSize); } /********************************************************************************** Function Name: setRMSR Purpose: Sets the Rx memory size register. 00 = 1 kb, 01 = 2 kb, 01 = 4 kb and 11 = 8bk Input: Rx size for each channel. Total 8 kb is available for 4 channels. So if ch1 = 8kb then RxSize = 0x03 and other three channels are not used. If ch1 = 4 kb and ch2 = 4 kb, then RxSize = 00001010b = 0x0A and other 2 are not used and so forth... Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setRMSR(uint8_t RxSize) { write_wiznet_reg(W5100_RMSR, RxSize); } /********************************************************************************** Function Name: setSn_MSS Purpose: Sets the maximum segment size of TCP in Active Mode), while in Passive Mode this is set by peer Input: Socket number Size Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setSn_MSS(SOCKET s, uint16_t ushSn_MSSR0) { write_wiznet_reg(Sn_MSSR0(s), (uint8_t)((ushSn_MSSR0 & 0xff00) >> 8)); write_wiznet_reg((Sn_MSSR0(s) + 1), (uint8_t)(ushSn_MSSR0 & 0x00ff)); } /********************************************************************************** Function Name: getSn_IR Purpose: Get socket interrupt status Input: Socket number Return value: Sn_IR register value . Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ uint8_t getSn_IR(SOCKET s) { return read_wiznet_reg(Sn_IR(s)); } /********************************************************************************** Function Name: getSn_SR Purpose: Get socket status Input: Socket number Return value: Sn_SR register value . Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ uint8_t getSn_SR(SOCKET s) { return read_wiznet_reg(Sn_SR(s)); } /********************************************************************************** Function Name: getSn_TX_FSR Purpose: Get socket TX free buf size. This gives free buffer size of transmit buffer. This is the data size that user can transmit. User should check this value first and control the size of transmitting data Input: Socket number Return value: Sn_TX_FSR register value . Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ uint16_t getSn_TX_FSR(SOCKET s) { uint16_t ushVal=0; uint16_t ushVal1=0; do { ushVal1 = read_wiznet_reg(Sn_TX_FSR0(s)); ushVal1 = (ushVal1 << 8) + read_wiznet_reg(Sn_TX_FSR0(s) + 1); if (ushVal1 != 0) { ushVal = read_wiznet_reg(Sn_TX_FSR0(s)); ushVal = (ushVal << 8) + read_wiznet_reg(Sn_TX_FSR0(s) + 1); } } while (ushVal != ushVal1); return ushVal; } /********************************************************************************** Function Name: getSn_RX_RSR Purpose: Get socket RX recv buf size. This gives free buffer size of receive buffer. Input: Socket number Return value: Sn_RX_RSR register value . Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ uint16_t getSn_RX_RSR(SOCKET s) { uint16_t ushVal=0; uint16_t ushVal1=0; do { ushVal1 = read_wiznet_reg(Sn_RX_RSR0(s)); ushVal1 = (ushVal1 << 8) + read_wiznet_reg(Sn_RX_RSR0(s) + 1); if(ushVal1 != 0) { ushVal = read_wiznet_reg(Sn_RX_RSR0(s)); ushVal = (ushVal << 8) + read_wiznet_reg(Sn_RX_RSR0(s) + 1); } } while (ushVal != ushVal1); return ushVal; } /********************************************************************************** Function Name: setSn_DHAR Purpose: Sets Destination Hardware Address (MAC Address). Input: Socket number Pointer to a 6 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setSn_DHAR(SOCKET s, uint8_t* p_ucharAddr) { write_wiznet_reg((Sn_DHAR0(s) + 0), p_ucharAddr[0]); write_wiznet_reg((Sn_DHAR0(s) + 1), p_ucharAddr[1]); write_wiznet_reg((Sn_DHAR0(s) + 2), p_ucharAddr[2]); write_wiznet_reg((Sn_DHAR0(s) + 3), p_ucharAddr[3]); write_wiznet_reg((Sn_DHAR0(s) + 4), p_ucharAddr[4]); write_wiznet_reg((Sn_DHAR0(s) + 5), p_ucharAddr[5]); } /********************************************************************************** Function Name: getSn_DHAR Purpose: Gets Destination Hardware Address (MAC Address). Input: Socket number Pointer to a 6 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void getSn_DHAR(SOCKET s, uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(Sn_DHAR0(s)); p_ucharAddr[1] = read_wiznet_reg(Sn_DHAR0(s)+1); p_ucharAddr[2] = read_wiznet_reg(Sn_DHAR0(s)+2); p_ucharAddr[3] = read_wiznet_reg(Sn_DHAR0(s)+3); p_ucharAddr[4] = read_wiznet_reg(Sn_DHAR0(s)+4); p_ucharAddr[5] = read_wiznet_reg(Sn_DHAR0(s)+5); } /********************************************************************************** Function Name: setSn_DIPR Purpose: Sets Destination IP Address. Input: Socket number Pointer to a 4 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void setSn_DIPR(SOCKET s, uint8_t* p_ucharAddr) { write_wiznet_reg((Sn_DIPR0(s) + 0), p_ucharAddr[0]); write_wiznet_reg((Sn_DIPR0(s) + 1), p_ucharAddr[1]); write_wiznet_reg((Sn_DIPR0(s) + 2), p_ucharAddr[2]); write_wiznet_reg((Sn_DIPR0(s) + 3), p_ucharAddr[3]); } /********************************************************************************** Function Name: getSn_DIPR Purpose: Gets Destination IP Address. Input: Socket number Pointer to a 4 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 15-01-2014 Created ***********************************************************************************/ void getSn_DIPR(SOCKET s, uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(Sn_DIPR0(s)); p_ucharAddr[1] = read_wiznet_reg(Sn_DIPR0(s)+1); p_ucharAddr[2] = read_wiznet_reg(Sn_DIPR0(s)+2); p_ucharAddr[3] = read_wiznet_reg(Sn_DIPR0(s)+3); } /********************************************************************************** Function Name: setSn_DPORT Purpose: Sets Destination Port. Input: Socket number Pointer to a 2 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ void setSn_DPORT(SOCKET s, uint8_t* p_ucharAddr) { write_wiznet_reg((Sn_DPORT0(s) + 0), p_ucharAddr[0]); write_wiznet_reg((Sn_DPORT0(s) + 1), p_ucharAddr[1]); } /********************************************************************************** Function Name: getSn_DPORT Purpose: Gets Destination Port. Input: Socket number Pointer to a 2 -byte array. Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ void getSn_DPORT(SOCKET s, uint8_t* p_ucharAddr) { p_ucharAddr[0] = read_wiznet_reg(Sn_DPORT0(s)); p_ucharAddr[1] = read_wiznet_reg(Sn_DPORT0(s)+1); } /********************************************************************************** Function Name: setSn_TTL Purpose: Sets Time to live register. Input: Socket number TTL value. Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ void setSn_TTL(SOCKET s, uint8_t ucharTTL) { write_wiznet_reg(Sn_TTL(s), ucharTTL); } /********************************************************************************** Function Name: getISR Purpose: Gets Interrupt status of socket s locally. Input: Socket number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint8_t getISR(uint8_t s) { return I_STATUS[s]; } /********************************************************************************** Function Name: putISR Purpose: Saves the Interrupt status of socket s locally. Input: Socket number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ void putISR(uint8_t s, uint8_t ucharVal) { I_STATUS[s] = ucharVal; } /********************************************************************************** Function Name: getW5100_RxMAX Purpose: Get the Rx memory size for channel s. Input: Socket(channel) number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint16_t getW5100_RxMAX(uint8_t s) { return RSIZE[s]; } /********************************************************************************** Function Name: getW5100_TxMAX Purpose: Get the Tx memory size for channel s. Input: Socket(channel) number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint16_t getW5100_TxMAX(uint8_t s) { return SSIZE[s]; } /********************************************************************************** Function Name: getW5100_RxMASK Purpose: Get the Rx memory Mask for channel s. Input: Socket(channel) number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint16_t getW5100_RxMASK(uint8_t s) { return RMASK[s]; } /********************************************************************************** Function Name: getW5100_TxMASK Purpose: Get the Tx memory Mask for channel s. Input: Socket(channel) number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint16_t getW5100_TxMASK(uint8_t s) { return SMASK[s]; } /********************************************************************************** Function Name: getW5100_RxBASE Purpose: Get the Rx memory base address for channel s. Input: Socket(channel) number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint16_t getW5100_RxBASE(uint8_t s) { return RBUFBASEADDRESS[s]; } /********************************************************************************** Function Name: getW5100_TxBASE Purpose: Get the Tx memory base address for channel s. Input: Socket(channel) number Return value: None. Change History: Author Date Remarks Omer Miranda 16-01-2014 Created ***********************************************************************************/ uint16_t getW5100_TxBASE(uint8_t s) { return SBUFBASEADDRESS[s]; } /** This function process the wiznet interrupt. It will be called whenever there is an interrupt from the wiznet chip. This function will be called from the EFM32 ISR for external interrupt. */ void processWiznetISR(void) { //#ifdef __DEF_IINCHIP_INT__ uint8_t ucharIRvalue; /* Disable the external interrupt of EFM32*/ //IINCHIP_ISR_DISABLE(); ucharIRvalue = read_wiznet_reg(W5100_IR); /* process all interrupts */ do { if (ucharIRvalue & IR_CONFLICT) { /*IP conflict */ write_wiznet_reg(W5100_IR, 0xf0); /* clear interrupt */ } if (ucharIRvalue & IR_UNREACH) { /*INT Port Unreachable */ write_wiznet_reg(W5100_IR, 0xf0); /* clear interrupt */ } /* clear interrupt */ write_wiznet_reg(W5100_IR, 0xf0); if (ucharIRvalue & IR_SOCK(0)) { /* save interrupt value*/ I_STATUS[0] |= read_wiznet_reg(Sn_IR(0)); // can be come to over two times. write_wiznet_reg(Sn_IR(0), I_STATUS[0]); } if (ucharIRvalue & IR_SOCK(1)) { /* save interrupt value*/ I_STATUS[1] |= read_wiznet_reg(Sn_IR(1)); write_wiznet_reg(Sn_IR(1), I_STATUS[1]); } if (ucharIRvalue & IR_SOCK(2)) { /* save interrupt value*/ I_STATUS[2] |= read_wiznet_reg(Sn_IR(2)); write_wiznet_reg(Sn_IR(2), I_STATUS[2]); } if (ucharIRvalue & IR_SOCK(3)) { /* save interrupt value*/ I_STATUS[3] |= read_wiznet_reg(Sn_IR(3)); write_wiznet_reg(Sn_IR(3), I_STATUS[3]); } /* re-read interrupt value*/ ucharIRvalue = read_wiznet_reg(W5100_IR); } while (ucharIRvalue != 0x00); /* if exist, contiue to process */ /* Enable the external interrupt of EFM32*/ //IINCHIP_ISR_ENABLE(); //#endif }