Add [07_m1284p_WIZNET_telnets_basic] prj
							parent
							
								
									2c2de7b85a
								
							
						
					
					
						commit
						5710a9e18c
					
				| @ -0,0 +1,80 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> | ||||
| 	<storageModule moduleId="org.eclipse.cdt.core.settings"> | ||||
| 		<cconfiguration id="de.innot.avreclipse.configuration.app.release.1296246863"> | ||||
| 			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="de.innot.avreclipse.configuration.app.release.1296246863" moduleId="org.eclipse.cdt.core.settings" name="Release"> | ||||
| 				<externalSettings/> | ||||
| 				<extensions> | ||||
| 					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||||
| 				</extensions> | ||||
| 			</storageModule> | ||||
| 			<storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||||
| 				<configuration artifactName="${ProjName}" buildArtefactType="de.innot.avreclipse.buildArtefactType.app" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=de.innot.avreclipse.buildArtefactType.app,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" description="" id="de.innot.avreclipse.configuration.app.release.1296246863" name="Release" parent="de.innot.avreclipse.configuration.app.release"> | ||||
| 					<folderInfo id="de.innot.avreclipse.configuration.app.release.1296246863." name="/" resourcePath=""> | ||||
| 						<toolChain id="de.innot.avreclipse.toolchain.winavr.app.release.1035343131" name="AVR-GCC Toolchain" superClass="de.innot.avreclipse.toolchain.winavr.app.release"> | ||||
| 							<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release.1677804441" name="Generate HEX file for Flash memory" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.flash.app.release"/> | ||||
| 							<option id="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release.1592051743" name="Generate HEX file for EEPROM" superClass="de.innot.avreclipse.toolchain.options.toolchain.objcopy.eeprom.app.release"/> | ||||
| 							<option id="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release.1122611394" name="Generate Extended Listing (Source + generated Assembler)" superClass="de.innot.avreclipse.toolchain.options.toolchain.objdump.app.release"/> | ||||
| 							<option id="de.innot.avreclipse.toolchain.options.toolchain.size.app.release.1318978007" name="Print Size" superClass="de.innot.avreclipse.toolchain.options.toolchain.size.app.release"/> | ||||
| 							<option id="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release.330957466" name="AVRDude" superClass="de.innot.avreclipse.toolchain.options.toolchain.avrdude.app.release"/> | ||||
| 							<targetPlatform id="de.innot.avreclipse.targetplatform.winavr.app.release.1911832209" name="AVR Cross-Target" superClass="de.innot.avreclipse.targetplatform.winavr.app.release"/> | ||||
| 							<builder buildPath="${workspace_loc:/m1284p_blink}/Release" id="de.innot.avreclipse.target.builder.winavr.app.release.197425084" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="AVR GNU Make Builder" superClass="de.innot.avreclipse.target.builder.winavr.app.release"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.assembler.winavr.app.release.1044776614" name="AVR Assembler" superClass="de.innot.avreclipse.tool.assembler.winavr.app.release"> | ||||
| 								<option id="de.innot.avreclipse.assembler.option.debug.level.1934306003" name="Generate Debugging Info" superClass="de.innot.avreclipse.assembler.option.debug.level" value="de.innot.avreclipse.assembler.option.debug.level.none" valueType="enumerated"/> | ||||
| 								<inputType id="de.innot.avreclipse.tool.assembler.input.1445613337" superClass="de.innot.avreclipse.tool.assembler.input"/> | ||||
| 							</tool> | ||||
| 							<tool id="de.innot.avreclipse.tool.compiler.winavr.app.release.322918746" name="AVR Compiler" superClass="de.innot.avreclipse.tool.compiler.winavr.app.release"> | ||||
| 								<option id="de.innot.avreclipse.compiler.option.debug.level.1395543931" name="Generate Debugging Info" superClass="de.innot.avreclipse.compiler.option.debug.level" value="de.innot.avreclipse.compiler.option.debug.level.none" valueType="enumerated"/> | ||||
| 								<option id="de.innot.avreclipse.compiler.option.optimize.553992918" name="Optimization Level" superClass="de.innot.avreclipse.compiler.option.optimize" value="de.innot.avreclipse.compiler.optimize.size" valueType="enumerated"/> | ||||
| 								<option id="de.innot.avreclipse.compiler.option.incpath.478254702" name="Include Paths (-I)" superClass="de.innot.avreclipse.compiler.option.incpath" valueType="includePath"> | ||||
| 									<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Ethernet}""/> | ||||
| 									<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Ethernet/W5500}""/> | ||||
| 									<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Application/loopback}""/> | ||||
| 									<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Application/telnet}""/> | ||||
| 								</option> | ||||
| 								<inputType id="de.innot.avreclipse.compiler.winavr.input.167604838" name="C Source Files" superClass="de.innot.avreclipse.compiler.winavr.input"/> | ||||
| 							</tool> | ||||
| 							<tool id="de.innot.avreclipse.tool.cppcompiler.app.release.1282845851" name="AVR C++ Compiler" superClass="de.innot.avreclipse.tool.cppcompiler.app.release"> | ||||
| 								<option id="de.innot.avreclipse.cppcompiler.option.debug.level.590178482" name="Generate Debugging Info" superClass="de.innot.avreclipse.cppcompiler.option.debug.level" value="de.innot.avreclipse.cppcompiler.option.debug.level.none" valueType="enumerated"/> | ||||
| 								<option id="de.innot.avreclipse.cppcompiler.option.optimize.1730181360" name="Optimization Level" superClass="de.innot.avreclipse.cppcompiler.option.optimize" value="de.innot.avreclipse.cppcompiler.optimize.size" valueType="enumerated"/> | ||||
| 								<inputType id="de.innot.avreclipse.cppcompiler.input.1110129299" superClass="de.innot.avreclipse.cppcompiler.input"/> | ||||
| 							</tool> | ||||
| 							<tool id="de.innot.avreclipse.tool.linker.winavr.app.release.910552277" name="AVR C Linker" superClass="de.innot.avreclipse.tool.linker.winavr.app.release"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.cpplinker.app.release.704198725" name="AVR C++ Linker" superClass="de.innot.avreclipse.tool.cpplinker.app.release"> | ||||
| 								<inputType id="de.innot.avreclipse.tool.cpplinker.input.1469628063" name="OBJ Files" superClass="de.innot.avreclipse.tool.cpplinker.input"> | ||||
| 									<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> | ||||
| 									<additionalInput kind="additionalinput" paths="$(LIBS)"/> | ||||
| 								</inputType> | ||||
| 							</tool> | ||||
| 							<tool id="de.innot.avreclipse.tool.archiver.winavr.base.249251196" name="AVR Archiver" superClass="de.innot.avreclipse.tool.archiver.winavr.base"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.objdump.winavr.app.release.701513686" name="AVR Create Extended Listing" superClass="de.innot.avreclipse.tool.objdump.winavr.app.release"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release.1874041246" name="AVR Create Flash image" superClass="de.innot.avreclipse.tool.objcopy.flash.winavr.app.release"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release.1162490773" name="AVR Create EEPROM image" superClass="de.innot.avreclipse.tool.objcopy.eeprom.winavr.app.release"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.size.winavr.app.release.1789876684" name="Print Size" superClass="de.innot.avreclipse.tool.size.winavr.app.release"/> | ||||
| 							<tool id="de.innot.avreclipse.tool.avrdude.app.release.602378631" name="AVRDude" superClass="de.innot.avreclipse.tool.avrdude.app.release"/> | ||||
| 						</toolChain> | ||||
| 					</folderInfo> | ||||
| 				</configuration> | ||||
| 			</storageModule> | ||||
| 			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> | ||||
| 		</cconfiguration> | ||||
| 	</storageModule> | ||||
| 	<storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||||
| 		<project id="m1284p_blink.de.innot.avreclipse.project.winavr.elf_2.1.0.95248786" name="AVR Cross Target Application" projectType="de.innot.avreclipse.project.winavr.elf_2.1.0"/> | ||||
| 	</storageModule> | ||||
| 	<storageModule moduleId="scannerConfiguration"> | ||||
| 		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||||
| 		<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.1296246863;de.innot.avreclipse.configuration.app.release.1296246863.;de.innot.avreclipse.tool.cppcompiler.app.release.1282845851;de.innot.avreclipse.cppcompiler.input.1110129299"> | ||||
| 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileCPP"/> | ||||
| 		</scannerConfigBuildInfo> | ||||
| 		<scannerConfigBuildInfo instanceId="de.innot.avreclipse.configuration.app.release.1296246863;de.innot.avreclipse.configuration.app.release.1296246863.;de.innot.avreclipse.tool.compiler.winavr.app.release.322918746;de.innot.avreclipse.compiler.winavr.input.167604838"> | ||||
| 			<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="de.innot.avreclipse.core.AVRGCCManagedMakePerProjectProfileC"/> | ||||
| 		</scannerConfigBuildInfo> | ||||
| 	</storageModule> | ||||
| 	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> | ||||
| 	<storageModule moduleId="refreshScope"/> | ||||
| </cproject> | ||||
| @ -0,0 +1,28 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>07_m1284p_WIZNET_telnets_basic</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> | ||||
| 			<triggers>clean,full,incremental,</triggers> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> | ||||
| 			<triggers>full,incremental,</triggers> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.cdt.core.cnature</nature> | ||||
| 		<nature>org.eclipse.cdt.core.ccnature</nature> | ||||
| 		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> | ||||
| 		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> | ||||
| 		<nature>de.innot.avreclipse.core.avrnature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
| @ -0,0 +1,225 @@ | ||||
| #include <stdio.h> | ||||
| #include "loopback.h" | ||||
| #include "socket.h" | ||||
| #include "wizchip_conf.h" | ||||
| 
 | ||||
| #if LOOPBACK_MODE == LOOPBACK_MAIN_NOBLCOK | ||||
| 
 | ||||
| int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port) | ||||
| { | ||||
|    int32_t ret; | ||||
|    uint16_t size = 0, sentsize=0; | ||||
| 
 | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|    uint8_t destip[4]; | ||||
|    uint16_t destport; | ||||
| #endif | ||||
| 
 | ||||
|    switch(getSn_SR(sn)) | ||||
|    { | ||||
|       case SOCK_ESTABLISHED : | ||||
|          if(getSn_IR(sn) & Sn_IR_CON) | ||||
|          { | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
| 			getSn_DIPR(sn, destip); | ||||
| 			destport = getSn_DPORT(sn); | ||||
| 
 | ||||
| 			printf("%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); | ||||
| #endif | ||||
| 			setSn_IR(sn,Sn_IR_CON); | ||||
|          } | ||||
| 		 if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
 | ||||
|          { | ||||
| 			if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; | ||||
| 			ret = recv(sn, buf, size); | ||||
| 
 | ||||
| 			if(ret <= 0) return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
 | ||||
| 			size = (uint16_t) ret; | ||||
| 			sentsize = 0; | ||||
| 
 | ||||
| 			while(size != sentsize) | ||||
| 			{ | ||||
| 				ret = send(sn, buf+sentsize, size-sentsize); | ||||
| 				if(ret < 0) | ||||
| 				{ | ||||
| 					close(sn); | ||||
| 					return ret; | ||||
| 				} | ||||
| 				sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
 | ||||
| 			} | ||||
|          } | ||||
|          break; | ||||
|       case SOCK_CLOSE_WAIT : | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          //printf("%d:CloseWait\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret = disconnect(sn)) != SOCK_OK) return ret; | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          printf("%d:Socket Closed\r\n", sn); | ||||
| #endif | ||||
|          break; | ||||
|       case SOCK_INIT : | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|     	 printf("%d:Listen, TCP server loopback, port [%d]\r\n", sn, port); | ||||
| #endif | ||||
|          if( (ret = listen(sn)) != SOCK_OK) return ret; | ||||
|          break; | ||||
|       case SOCK_CLOSED: | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          //printf("%d:TCP server loopback start\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          //printf("%d:Socket opened\r\n",sn);
 | ||||
| #endif | ||||
|          break; | ||||
|       default: | ||||
|          break; | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport) | ||||
| { | ||||
|    int32_t ret; // return value for SOCK_ERRORs
 | ||||
|    uint16_t size = 0, sentsize=0; | ||||
| 
 | ||||
|    // Destination (TCP Server) IP info (will be connected)
 | ||||
|    // >> loopback_tcpc() function parameter
 | ||||
|    // >> Ex)
 | ||||
|    //	uint8_t destip[4] = 	{192, 168, 0, 214};
 | ||||
|    //	uint16_t destport = 	5000;
 | ||||
| 
 | ||||
|    // Port number for TCP client (will be increased)
 | ||||
|    static uint16_t any_port = 	50000; | ||||
| 
 | ||||
|    // Socket Status Transitions
 | ||||
|    // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
 | ||||
|    switch(getSn_SR(sn)) | ||||
|    { | ||||
|       case SOCK_ESTABLISHED : | ||||
|          if(getSn_IR(sn) & Sn_IR_CON)	// Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
 | ||||
|          { | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
| 			printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); | ||||
| #endif | ||||
| 			setSn_IR(sn, Sn_IR_CON);  // this interrupt should be write the bit cleared to '1'
 | ||||
|          } | ||||
| 
 | ||||
|          //////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|          // Data Transaction Parts; Handle the [data receive and send] process
 | ||||
|          //////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
| 		 if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
 | ||||
|          { | ||||
| 			if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
 | ||||
| 			ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
 | ||||
| 
 | ||||
| 			if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
 | ||||
| 			size = (uint16_t) ret; | ||||
| 			sentsize = 0; | ||||
| 
 | ||||
| 			// Data sentsize control
 | ||||
| 			while(size != sentsize) | ||||
| 			{ | ||||
| 				ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
 | ||||
| 				if(ret < 0) // Send Error occurred (sent data length < 0)
 | ||||
| 				{ | ||||
| 					close(sn); // socket close
 | ||||
| 					return ret; | ||||
| 				} | ||||
| 				sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
 | ||||
| 			} | ||||
|          } | ||||
| 		 //////////////////////////////////////////////////////////////////////////////////////////////
 | ||||
|          break; | ||||
| 
 | ||||
|       case SOCK_CLOSE_WAIT : | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          //printf("%d:CloseWait\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret=disconnect(sn)) != SOCK_OK) return ret; | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          printf("%d:Socket Closed\r\n", sn); | ||||
| #endif | ||||
|          break; | ||||
| 
 | ||||
|       case SOCK_INIT : | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|     	 printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport); | ||||
| #endif | ||||
|     	 if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret;	//	Try to TCP connect to the TCP server (destination)
 | ||||
|          break; | ||||
| 
 | ||||
|       case SOCK_CLOSED: | ||||
|     	  close(sn); | ||||
|     	  if((ret=socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn){ | ||||
|          if(any_port == 0xffff) any_port = 50000; | ||||
|          return ret; // TCP socket open with 'any_port' port number
 | ||||
|         }  | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|     	 //printf("%d:TCP client loopback start\r\n",sn);
 | ||||
|          //printf("%d:Socket opened\r\n",sn);
 | ||||
| #endif | ||||
|          break; | ||||
|       default: | ||||
|          break; | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port) | ||||
| { | ||||
|    int32_t  ret; | ||||
|    uint16_t size, sentsize; | ||||
|    uint8_t  destip[4]; | ||||
|    uint16_t destport; | ||||
| 
 | ||||
|    switch(getSn_SR(sn)) | ||||
|    { | ||||
|       case SOCK_UDP : | ||||
|          if((size = getSn_RX_RSR(sn)) > 0) | ||||
|          { | ||||
|             if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; | ||||
|             ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport); | ||||
|             if(ret <= 0) | ||||
|             { | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|                printf("%d: recvfrom error. %ld\r\n",sn,ret); | ||||
| #endif | ||||
|                return ret; | ||||
|             } | ||||
|             size = (uint16_t) ret; | ||||
|             sentsize = 0; | ||||
|             while(sentsize != size) | ||||
|             { | ||||
|                ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport); | ||||
|                if(ret < 0) | ||||
|                { | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|                   printf("%d: sendto error. %ld\r\n",sn,ret); | ||||
| #endif | ||||
|                   return ret; | ||||
|                } | ||||
|                sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
 | ||||
|             } | ||||
|          } | ||||
|          break; | ||||
|       case SOCK_CLOSED: | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          //printf("%d:UDP loopback start\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn) | ||||
|             return ret; | ||||
| #ifdef _LOOPBACK_DEBUG_ | ||||
|          printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port); | ||||
| #endif | ||||
|          break; | ||||
|       default : | ||||
|          break; | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,38 @@ | ||||
| #ifndef _LOOPBACK_H_ | ||||
| #define _LOOPBACK_H_ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| /* Loopback test debug message printout enable */ | ||||
| #define	_LOOPBACK_DEBUG_ | ||||
| 
 | ||||
| /* DATA_BUF_SIZE define for Loopback example */ | ||||
| #ifndef DATA_BUF_SIZE | ||||
| 	#define DATA_BUF_SIZE			2048 | ||||
| #endif | ||||
| 
 | ||||
| /************************/ | ||||
| /* Select LOOPBACK_MODE */ | ||||
| /************************/ | ||||
| #define LOOPBACK_MAIN_NOBLOCK    0 | ||||
| #define LOOPBACK_MODE   LOOPBACK_MAIN_NOBLOCK | ||||
| 
 | ||||
| 
 | ||||
| /* TCP server Loopback test example */ | ||||
| int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port); | ||||
| 
 | ||||
| /* TCP client Loopback test example */ | ||||
| int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport); | ||||
| 
 | ||||
| /* UDP Loopback test example */ | ||||
| int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,380 @@ | ||||
| /*
 | ||||
|  * telnet.c | ||||
|  * | ||||
|  *  Created on: 30 íîÿá. 2018 ã. | ||||
|  *      Author: maxx | ||||
|  */ | ||||
| #include <stdio.h> | ||||
| #include "telnet.h" | ||||
| #include "socket.h" | ||||
| #include "wizchip_conf.h" | ||||
| 
 | ||||
| #define GREETING_MSG 		 "Well done guys! Welcome to the IoT world.\r\nType <Help> or <Q> to exit.\r\n" | ||||
| #define PASS_MSG 		 	 "\r\n> pass: " | ||||
| #define BYE_MSG				 "\r\nBye-bye!\r\n" | ||||
| 
 | ||||
| #define _passcode				 "1234" //Pass for authorization telnet session
 | ||||
| 
 | ||||
| //Command processor exec command from telnet server
 | ||||
| void processCommand(char *command, char *answer) | ||||
| { | ||||
|     //Loopback mode
 | ||||
| 	//sprintf_P(answer,PSTR("\r\n> %s\r\n"), command);
 | ||||
| 
 | ||||
| 	if((strcasestr_P(command, PSTR("HELP")) != 0) ||\ | ||||
| 		(strncmp_P(command, PSTR("?"), 1) == 0)	) | ||||
| 	{ | ||||
| 		sprintf_P(answer,PSTR("\r\nAvailable commands:\r\n"\ | ||||
| 				"Help/Echo xyz/FreeRAM/Uptime/LED_(ON/OFF/TGL)\r\n")); | ||||
| 
 | ||||
| 	} | ||||
| 	else if(strcasestr_P(command, PSTR("ECHO ")) != 0) | ||||
| 	{ | ||||
| 		sprintf_P(answer,PSTR("\r\n> %s\r\n"), (char *)(command+5)); | ||||
| 	} | ||||
| 	else if(strcasestr_P(command, PSTR("Uptime")) != 0) | ||||
| 	{ | ||||
| 		sprintf_P(answer,PSTR("\r\nServer uptime: %lu sec\r\n"), millis()/1000); | ||||
| 	} | ||||
| 	else if(strcasestr_P(command, PSTR("FreeRAM")) != 0) | ||||
| 	{ | ||||
| 		sprintf_P(answer,PSTR("\r\nRAM free: %u bytes\r\n"), freeRam()); | ||||
| 	} | ||||
| 	else if(strcasestr_P(command, PSTR("LED_ON")) != 0) | ||||
| 	{ | ||||
| 		led1_high(); | ||||
| 		sprintf_P(answer,PSTR("\r\n> LED: %s\r\n"), (led1_read()? "ON": "OFF")); | ||||
| 	} | ||||
| 	else if(strcasestr_P(command, PSTR("LED_OFF")) != 0) | ||||
| 	{ | ||||
| 		led1_low(); | ||||
| 		sprintf_P(answer,PSTR("\r\n> LED: %s\r\n"), (led1_read()? "ON": "OFF")); | ||||
| 	} | ||||
| 	else if(strcasestr_P(command, PSTR("LED_TGL")) != 0) | ||||
| 	{ | ||||
| 		led1_tgl(); | ||||
| 		sprintf_P(answer,PSTR("\r\n> LED: %s\r\n"), (led1_read()? "ON": "OFF")); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		sprintf_P(answer,PSTR("\r\n??Unknown command: <%s>\r\nTry <Help>\r\n"), command); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int32_t telnet_srv(uint8_t sn, uint8_t* buf, uint16_t port) | ||||
| { | ||||
|    int32_t ret; | ||||
|    uint16_t size = 0; | ||||
| 
 | ||||
|     static char cmd_buffer[TELNET_BUF_SIZE] = "\0"; | ||||
| 	static uint8_t cmd_buffer_len; | ||||
| 	static char msg_answer[128] = "\0"; | ||||
| 
 | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|    uint8_t destip[4]; | ||||
|    uint16_t destport; | ||||
| #endif | ||||
| 
 | ||||
|    switch(getSn_SR(sn)) | ||||
|    { | ||||
|       case SOCK_ESTABLISHED : | ||||
|          if(getSn_IR(sn) & Sn_IR_CON) | ||||
|          { | ||||
|         	//Open connection
 | ||||
| #ifdef _TELNET_DEBUG_ | ||||
| 			getSn_DIPR(sn, destip); | ||||
| 			destport = getSn_DPORT(sn); | ||||
| 
 | ||||
| 			printf("%d telnet:Connected - %d.%d.%d.%d : %u\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); | ||||
| #endif | ||||
| 			setSn_IR(sn,Sn_IR_CON); | ||||
| 			cmd_buffer_len = 0; | ||||
| 			//Send welcome message to client
 | ||||
| 			ret = send(sn, GREETING_MSG, strlen(GREETING_MSG)); | ||||
| 			if(ret < 0) | ||||
| 			{ | ||||
| 				close(sn); | ||||
| 				return ret; | ||||
| 			} | ||||
|          } | ||||
| 		 if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
 | ||||
|          { | ||||
| 			//Here when receive message from client
 | ||||
| 			if(size > TELNET_BUF_SIZE) size = TELNET_BUF_SIZE; | ||||
| 			ret = recv(sn, buf, size); //receive message
 | ||||
| 
 | ||||
| 			if(ret <= 0) return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
 | ||||
| 			size = (uint16_t) ret; | ||||
| 
 | ||||
| 			//Parse <Q> to quit session
 | ||||
| 			if(buf[0] == 'Q') | ||||
| 			{ | ||||
| 				//Send welcome message to client
 | ||||
| 				ret = send(sn, BYE_MSG, strlen(BYE_MSG)); | ||||
| 				//Disconnect
 | ||||
| 				disconnect(sn); | ||||
| 				close(sn); | ||||
| 				return ret; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				//Loop-back received back, just for test!!!
 | ||||
| 				/*
 | ||||
| 				ret = send(sn, buf, size); | ||||
| 				if(ret < 0) | ||||
| 				{ | ||||
| 					close(sn); | ||||
| 					return ret; | ||||
| 				} | ||||
| 				*/ | ||||
| 
 | ||||
| 				//Parse received message from telnet client
 | ||||
| 				buf[size] = 0x0; //Insert null-terminate symbol (for string parse)
 | ||||
| 
 | ||||
| 				//Print out command from telnet client
 | ||||
| 				//PRINTF(">> %s\r\n", msg_receive);
 | ||||
| 
 | ||||
| 				//Fill cmd_buffer until '\n' (NEW LINE) received
 | ||||
| 				//some bulletproof for overflow protection
 | ||||
| 				if(size > TELNET_BUF_SIZE) size = TELNET_BUF_SIZE; | ||||
| 				for(int32_t i = 0; i < size; i++) | ||||
| 				{ | ||||
| 					if(buf[i] == '\n') //PARSE '\n'(0x0A NEW LINE)
 | ||||
| 					{ | ||||
| 						cmd_buffer[cmd_buffer_len++] = 0x0; //Received EOL,so process command
 | ||||
| 						//Clear commnad buffe
 | ||||
| 						cmd_buffer_len = 0; | ||||
| 						//Exec process command
 | ||||
| 						processCommand(cmd_buffer, msg_answer); | ||||
| 						//Send answer to telnet client
 | ||||
| 						send(sn, msg_answer, strlen(msg_answer)); | ||||
| 
 | ||||
| 					} | ||||
| 					else if(buf[i] == '\r') //PARSE '\r'(0x0D RETURN LINE)
 | ||||
| 					{ | ||||
| 						//Suppress CR symbol
 | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						// Any other symbol, fill input buffer
 | ||||
| 						cmd_buffer[cmd_buffer_len++] = buf[i]; | ||||
| 					} | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
|          } | ||||
|          break; | ||||
|       case SOCK_CLOSE_WAIT : | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          //printf("%d:CloseWait\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret = disconnect(sn)) != SOCK_OK) return ret; | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          printf("%d telnet:Socket Closed\r\n", sn); | ||||
| #endif | ||||
|          break; | ||||
|       case SOCK_INIT : | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|     	 printf("%d telnet:Listen, TELNET server, port [%u]\r\n", sn, port); | ||||
| #endif | ||||
|          if( (ret = listen(sn)) != SOCK_OK) return ret; | ||||
|          break; | ||||
|       case SOCK_CLOSED: | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          //printf("%d:TCP server loopback start\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          //printf("%d:Socket opened\r\n",sn);
 | ||||
| #endif | ||||
|          break; | ||||
|       default: | ||||
|          break; | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| //Command processor authorization
 | ||||
| uint8_t processAuth(char * pass) | ||||
| { | ||||
| 	if(strstr_P(pass, PSTR(_passcode)) != 0) | ||||
| 	{ | ||||
| 		//PASS OK
 | ||||
| 		return 1; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		//PASS ERROR
 | ||||
| 		return 0; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #define TELNET_STATE_BEGIN 0 | ||||
| #define TELNET_STATE_AUTH 1 | ||||
| #define TELNET_STATE_PROCESS 2 | ||||
| 
 | ||||
| int32_t telnet_auth_srv(uint8_t sn, uint8_t* buf, uint16_t port) | ||||
| { | ||||
|    int32_t ret; | ||||
|    uint16_t size = 0; | ||||
|     static uint8_t tel_st = TELNET_STATE_BEGIN; | ||||
| 	static char cmd_buffer[TELNET_BUF_SIZE] = "\0"; | ||||
| 	static uint8_t cmd_buffer_len; | ||||
| 	static char msg_answer[128] = "\0"; | ||||
| 
 | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|    uint8_t destip[4]; | ||||
|    uint16_t destport; | ||||
| #endif | ||||
| 
 | ||||
|    switch(getSn_SR(sn)) | ||||
|    { | ||||
|       case SOCK_ESTABLISHED : | ||||
|          if(getSn_IR(sn) & Sn_IR_CON) | ||||
|          { | ||||
|         	//Open connection
 | ||||
| #ifdef _TELNET_DEBUG_ | ||||
| 			getSn_DIPR(sn, destip); | ||||
| 			destport = getSn_DPORT(sn); | ||||
| 
 | ||||
| 			printf("%d telnet_auth:Connected - %d.%d.%d.%d : %u\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport); | ||||
| #endif | ||||
| 			setSn_IR(sn,Sn_IR_CON); | ||||
| 			cmd_buffer_len = 0; | ||||
| 			//Send pass message to client
 | ||||
| 			ret = send(sn, PASS_MSG, strlen(PASS_MSG)); | ||||
| 			if(ret < 0) | ||||
| 			{ | ||||
| 				close(sn); | ||||
| 				return ret; | ||||
| 			} | ||||
| 			tel_st = TELNET_STATE_AUTH; | ||||
|          } | ||||
| 		 if((size = getSn_RX_RSR(sn)) > 0) // Don't need to check SOCKERR_BUSY because it doesn't not occur.
 | ||||
|          { | ||||
| 			//Here when receive message from client
 | ||||
| 			if(size > TELNET_BUF_SIZE) size = TELNET_BUF_SIZE; | ||||
| 			ret = recv(sn, buf, size); //receive message
 | ||||
| 
 | ||||
| 			if(ret <= 0) return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.
 | ||||
| 			size = (uint16_t) ret; | ||||
| 
 | ||||
| 			//Parse <Q> to quit session
 | ||||
| 			if(buf[0] == 'Q') | ||||
| 			{ | ||||
| 				//Send welcome message to client
 | ||||
| 				ret = send(sn, BYE_MSG, strlen(BYE_MSG)); | ||||
| 				//Disconnect
 | ||||
| 				disconnect(sn); | ||||
| 				close(sn); | ||||
| 				return ret; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				//Loop-back received back, just for test
 | ||||
| 				/*
 | ||||
| 				ret = send(sn, buf, size); | ||||
| 				if(ret < 0) | ||||
| 				{ | ||||
| 					close(sn); | ||||
| 					return ret; | ||||
| 				} | ||||
| 				*/ | ||||
| 
 | ||||
| 				//Parse received message from telnet client
 | ||||
| 				buf[size] = 0x0; //Insert null-terminate symbol (for string parse)
 | ||||
| 
 | ||||
| 				//Print out command from telnet client
 | ||||
| 				//PRINTF(">> %s\r\n", msg_receive);
 | ||||
| 
 | ||||
| 				//Fill cmd_buffer until '\n' (NEW LINE) received
 | ||||
| 				//some bulletproof for overflow protection
 | ||||
| 				if(size > TELNET_BUF_SIZE) size = TELNET_BUF_SIZE; | ||||
| 				for(int32_t i = 0; i < size; i++) | ||||
| 				{ | ||||
| 					if(buf[i] == '\n') //PARSE '\n'(0x0A NEW LINE)
 | ||||
| 					{ | ||||
| 						cmd_buffer[cmd_buffer_len++] = 0x0; //Received EOL,so process command
 | ||||
| 						//Clear commnad buffe
 | ||||
| 						cmd_buffer_len = 0; | ||||
| 						//String to command done
 | ||||
| 						//Check state session (authorization done or not)
 | ||||
| 						if(tel_st == TELNET_STATE_AUTH) | ||||
| 						{ | ||||
| 							//Authorization required
 | ||||
| 							if (processAuth(cmd_buffer)) | ||||
| 							{ | ||||
| 								//Authorization OK
 | ||||
| 								tel_st = TELNET_STATE_PROCESS; | ||||
| 								//Send greetings message to client
 | ||||
| 								ret = send(sn, GREETING_MSG, strlen(GREETING_MSG)); | ||||
| 							} | ||||
| 							else | ||||
| 							{ | ||||
| 								//Authorization ERROR
 | ||||
| 								tel_st = TELNET_STATE_BEGIN; | ||||
| 								//Send bye message to client
 | ||||
| 								ret = send(sn, BYE_MSG, strlen(BYE_MSG)); | ||||
| 								//Disconnect
 | ||||
| 								disconnect(sn); | ||||
| 								close(sn); | ||||
| 								return ret; | ||||
| 							} | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							//Authorization done
 | ||||
| 							//Exec process command
 | ||||
| 							processCommand(cmd_buffer, msg_answer); | ||||
| 							//Send answer to telnet client
 | ||||
| 							send(sn, msg_answer, strlen(msg_answer)); | ||||
| 						} | ||||
| 					} | ||||
| 					else if(buf[i] == '\r') //PARSE '\r'(0x0D RETURN LINE)
 | ||||
| 					{ | ||||
| 						//Suppress CR symbol
 | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						// Any other symbol, fill input buffer
 | ||||
| 						cmd_buffer[cmd_buffer_len++] = buf[i]; | ||||
| 					} | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
|          } | ||||
|          break; | ||||
|       case SOCK_CLOSE_WAIT : | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          //printf("%d:CloseWait\r\n",sn);
 | ||||
| #endif | ||||
|          tel_st = TELNET_STATE_BEGIN; | ||||
|          if((ret = disconnect(sn)) != SOCK_OK) return ret; | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          printf("%d telnet_auth:Socket Closed\r\n", sn); | ||||
| #endif | ||||
|          break; | ||||
|       case SOCK_INIT : | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|     	 printf("%d telnet_auth:Listen, TELNET_AUTH server, port [%u]\r\n", sn, port); | ||||
| #endif | ||||
|          tel_st = TELNET_STATE_BEGIN; | ||||
|     	 if( (ret = listen(sn)) != SOCK_OK) return ret; | ||||
|          break; | ||||
|       case SOCK_CLOSED: | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          //printf("%d:TCP server loopback start\r\n",sn);
 | ||||
| #endif | ||||
|          if((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; | ||||
| #ifdef _TELNET_DEBUG_ | ||||
|          //printf("%d:Socket opened\r\n",sn);
 | ||||
| #endif | ||||
|          tel_st = TELNET_STATE_BEGIN; | ||||
|          break; | ||||
|       default: | ||||
|          break; | ||||
|    } | ||||
|    return 1; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,29 @@ | ||||
| /*
 | ||||
|  * telnet.h | ||||
|  * | ||||
|  *  Created on: 30 íîÿá. 2018 ã. | ||||
|  *      Author: maxx | ||||
|  */ | ||||
| 
 | ||||
| #ifndef TELNET_H_ | ||||
| #define TELNET_H_ | ||||
| 
 | ||||
| #include "stdint.h" | ||||
| #include "../../globals.h" | ||||
| 
 | ||||
| #define TELNET_PORT	23 | ||||
| #define TELNET_AUTH_PORT 24 | ||||
| 
 | ||||
| int32_t telnet_srv(uint8_t sn, uint8_t* buf, uint16_t port); | ||||
| 
 | ||||
| int32_t telnet_auth_srv(uint8_t sn, uint8_t* buf, uint16_t port); | ||||
| 
 | ||||
| /*Telnet test debug message printout enable */ | ||||
| #define	_TELNET_DEBUG_ | ||||
| 
 | ||||
| /* TELNET_BUF_SIZE define for TELNET example */ | ||||
| #ifndef TELNET_BUF_SIZE | ||||
| 	#define TELNET_BUF_SIZE			64 | ||||
| #endif | ||||
| 
 | ||||
| #endif /* TELNET_H_ */ | ||||
| @ -0,0 +1,267 @@ | ||||
| //*****************************************************************************
 | ||||
| //
 | ||||
| //! \file w5500.c
 | ||||
| //! \brief W5500 HAL Interface.
 | ||||
| //! \version 1.0.2
 | ||||
| //! \date 2013/10/21
 | ||||
| //! \par  Revision history
 | ||||
| //!       <2015/02/05> Notice
 | ||||
| //!        The version history is not updated after this point.
 | ||||
| //!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
 | ||||
| //!        >> https://github.com/Wiznet/ioLibrary_Driver
 | ||||
| //!       <2014/05/01> V1.0.2
 | ||||
| //!         1. Implicit type casting -> Explicit type casting. Refer to M20140501
 | ||||
| //!            Fixed the problem on porting into under 32bit MCU
 | ||||
| //!            Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh
 | ||||
| //!            Thank for your interesting and serious advices.
 | ||||
| //!       <2013/12/20> V1.0.1
 | ||||
| //!         1. Remove warning
 | ||||
| //!         2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case _WIZCHIP_IO_MODE_SPI_FDM_
 | ||||
| //!            for loop optimized(removed). refer to M20131220
 | ||||
| //!       <2013/10/21> 1st Release
 | ||||
| //! \author MidnightCow
 | ||||
| //! \copyright
 | ||||
| //!
 | ||||
| //! Copyright (c)  2013, WIZnet Co., LTD.
 | ||||
| //! All rights reserved.
 | ||||
| //! 
 | ||||
| //! Redistribution and use in source and binary forms, with or without 
 | ||||
| //! modification, are permitted provided that the following conditions 
 | ||||
| //! are met: 
 | ||||
| //! 
 | ||||
| //!     * Redistributions of source code must retain the above copyright 
 | ||||
| //! notice, this list of conditions and the following disclaimer. 
 | ||||
| //!     * Redistributions in binary form must reproduce the above copyright
 | ||||
| //! notice, this list of conditions and the following disclaimer in the
 | ||||
| //! documentation and/or other materials provided with the distribution. 
 | ||||
| //!     * Neither the name of the <ORGANIZATION> nor the names of its 
 | ||||
| //! contributors may be used to endorse or promote products derived 
 | ||||
| //! from this software without specific prior written permission. 
 | ||||
| //! 
 | ||||
| //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | ||||
| //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | ||||
| //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | ||||
| //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 | ||||
| //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 | ||||
| //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 | ||||
| //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | ||||
| //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 | ||||
| //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 | ||||
| //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 | ||||
| //! THE POSSIBILITY OF SUCH DAMAGE.
 | ||||
| //
 | ||||
| //*****************************************************************************
 | ||||
| //#include <stdio.h>
 | ||||
| #include "w5500.h" | ||||
| 
 | ||||
| #define _W5500_SPI_VDM_OP_          0x00 | ||||
| #define _W5500_SPI_FDM_OP_LEN1_     0x01 | ||||
| #define _W5500_SPI_FDM_OP_LEN2_     0x02 | ||||
| #define _W5500_SPI_FDM_OP_LEN4_     0x03 | ||||
| 
 | ||||
| #if   (_WIZCHIP_ == 5500) | ||||
| ////////////////////////////////////////////////////
 | ||||
| 
 | ||||
| uint8_t  WIZCHIP_READ(uint32_t AddrSel) | ||||
| { | ||||
|    uint8_t ret; | ||||
|    uint8_t spi_data[3]; | ||||
| 
 | ||||
|    WIZCHIP_CRITICAL_ENTER(); | ||||
|    WIZCHIP.CS._select(); | ||||
| 
 | ||||
|    AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); | ||||
| 
 | ||||
|    if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// byte operation
 | ||||
|    { | ||||
| 	   WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >>  8); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >>  0); | ||||
|    } | ||||
|    else																// burst operation
 | ||||
|    { | ||||
| 		spi_data[0] = (AddrSel & 0x00FF0000) >> 16; | ||||
| 		spi_data[1] = (AddrSel & 0x0000FF00) >> 8; | ||||
| 		spi_data[2] = (AddrSel & 0x000000FF) >> 0; | ||||
| 		WIZCHIP.IF.SPI._write_burst(spi_data, 3); | ||||
|    } | ||||
|    ret = WIZCHIP.IF.SPI._read_byte(); | ||||
| 
 | ||||
|    WIZCHIP.CS._deselect(); | ||||
|    WIZCHIP_CRITICAL_EXIT(); | ||||
|    return ret; | ||||
| } | ||||
| 
 | ||||
| void     WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb ) | ||||
| { | ||||
|    uint8_t spi_data[4]; | ||||
| 
 | ||||
|    WIZCHIP_CRITICAL_ENTER(); | ||||
|    WIZCHIP.CS._select(); | ||||
| 
 | ||||
|    AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); | ||||
| 
 | ||||
|    //if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// byte operation
 | ||||
|    if(!WIZCHIP.IF.SPI._write_burst) 	// byte operation
 | ||||
|    { | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >>  8); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >>  0); | ||||
| 		WIZCHIP.IF.SPI._write_byte(wb); | ||||
|    } | ||||
|    else									// burst operation
 | ||||
|    { | ||||
| 		spi_data[0] = (AddrSel & 0x00FF0000) >> 16; | ||||
| 		spi_data[1] = (AddrSel & 0x0000FF00) >> 8; | ||||
| 		spi_data[2] = (AddrSel & 0x000000FF) >> 0; | ||||
| 		spi_data[3] = wb; | ||||
| 		WIZCHIP.IF.SPI._write_burst(spi_data, 4); | ||||
|    } | ||||
| 
 | ||||
|    WIZCHIP.CS._deselect(); | ||||
|    WIZCHIP_CRITICAL_EXIT(); | ||||
| } | ||||
|           | ||||
| void     WIZCHIP_READ_BUF (uint32_t AddrSel, uint8_t* pBuf, uint16_t len) | ||||
| { | ||||
|    uint8_t spi_data[3]; | ||||
|    uint16_t i; | ||||
| 
 | ||||
|    WIZCHIP_CRITICAL_ENTER(); | ||||
|    WIZCHIP.CS._select(); | ||||
| 
 | ||||
|    AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); | ||||
| 
 | ||||
|    if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) 	// byte operation
 | ||||
|    { | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >>  8); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >>  0); | ||||
| 		for(i = 0; i < len; i++) | ||||
| 		   pBuf[i] = WIZCHIP.IF.SPI._read_byte(); | ||||
|    } | ||||
|    else																// burst operation
 | ||||
|    { | ||||
| 		spi_data[0] = (AddrSel & 0x00FF0000) >> 16; | ||||
| 		spi_data[1] = (AddrSel & 0x0000FF00) >> 8; | ||||
| 		spi_data[2] = (AddrSel & 0x000000FF) >> 0; | ||||
| 		WIZCHIP.IF.SPI._write_burst(spi_data, 3); | ||||
| 		WIZCHIP.IF.SPI._read_burst(pBuf, len); | ||||
|    } | ||||
| 
 | ||||
|    WIZCHIP.CS._deselect(); | ||||
|    WIZCHIP_CRITICAL_EXIT(); | ||||
| } | ||||
| 
 | ||||
| void     WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t* pBuf, uint16_t len) | ||||
| { | ||||
|    uint8_t spi_data[3]; | ||||
|    uint16_t i; | ||||
| 
 | ||||
|    WIZCHIP_CRITICAL_ENTER(); | ||||
|    WIZCHIP.CS._select(); | ||||
| 
 | ||||
|    AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); | ||||
| 
 | ||||
|    if(!WIZCHIP.IF.SPI._write_burst) 	// byte operation
 | ||||
|    { | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >>  8); | ||||
| 		WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >>  0); | ||||
| 		for(i = 0; i < len; i++) | ||||
| 			WIZCHIP.IF.SPI._write_byte(pBuf[i]); | ||||
|    } | ||||
|    else									// burst operation
 | ||||
|    { | ||||
| 		spi_data[0] = (AddrSel & 0x00FF0000) >> 16; | ||||
| 		spi_data[1] = (AddrSel & 0x0000FF00) >> 8; | ||||
| 		spi_data[2] = (AddrSel & 0x000000FF) >> 0; | ||||
| 		WIZCHIP.IF.SPI._write_burst(spi_data, 3); | ||||
| 		WIZCHIP.IF.SPI._write_burst(pBuf, len); | ||||
|    } | ||||
| 
 | ||||
|    WIZCHIP.CS._deselect(); | ||||
|    WIZCHIP_CRITICAL_EXIT(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| uint16_t getSn_TX_FSR(uint8_t sn) | ||||
| { | ||||
|    uint16_t val=0,val1=0; | ||||
| 
 | ||||
|    do | ||||
|    { | ||||
|       val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); | ||||
|       val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); | ||||
|       if (val1 != 0) | ||||
|       { | ||||
|         val = WIZCHIP_READ(Sn_TX_FSR(sn)); | ||||
|         val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn),1)); | ||||
|       } | ||||
|    }while (val != val1); | ||||
|    return val; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| uint16_t getSn_RX_RSR(uint8_t sn) | ||||
| { | ||||
|    uint16_t val=0,val1=0; | ||||
| 
 | ||||
|    do | ||||
|    { | ||||
|       val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); | ||||
|       val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); | ||||
|       if (val1 != 0) | ||||
|       { | ||||
|         val = WIZCHIP_READ(Sn_RX_RSR(sn)); | ||||
|         val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn),1)); | ||||
|       } | ||||
|    }while (val != val1); | ||||
|    return val; | ||||
| } | ||||
| 
 | ||||
| void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) | ||||
| { | ||||
|    uint16_t ptr = 0; | ||||
|    uint32_t addrsel = 0; | ||||
| 
 | ||||
|    if(len == 0)  return; | ||||
|    ptr = getSn_TX_WR(sn); | ||||
|    //M20140501 : implict type casting -> explict type casting
 | ||||
|    //addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3);
 | ||||
|    addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); | ||||
|    //
 | ||||
|    WIZCHIP_WRITE_BUF(addrsel,wizdata, len); | ||||
|     | ||||
|    ptr += len; | ||||
|    setSn_TX_WR(sn,ptr); | ||||
| } | ||||
| 
 | ||||
| void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) | ||||
| { | ||||
|    uint16_t ptr = 0; | ||||
|    uint32_t addrsel = 0; | ||||
|     | ||||
|    if(len == 0) return; | ||||
|    ptr = getSn_RX_RD(sn); | ||||
|    //M20140501 : implict type casting -> explict type casting
 | ||||
|    //addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3);
 | ||||
|    addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); | ||||
|    //
 | ||||
|    WIZCHIP_READ_BUF(addrsel, wizdata, len); | ||||
|    ptr += len; | ||||
|     | ||||
|    setSn_RX_RD(sn,ptr); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void wiz_recv_ignore(uint8_t sn, uint16_t len) | ||||
| { | ||||
|    uint16_t ptr = 0; | ||||
| 
 | ||||
|    ptr = getSn_RX_RD(sn); | ||||
|    ptr += len; | ||||
|    setSn_RX_RD(sn,ptr); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								| @ -0,0 +1,930 @@ | ||||
| //*****************************************************************************
 | ||||
| //
 | ||||
| //! \file socket.c
 | ||||
| //! \brief SOCKET APIs Implements file.
 | ||||
| //! \details SOCKET APIs like as Berkeley Socket APIs. 
 | ||||
| //! \version 1.0.3
 | ||||
| //! \date 2013/10/21
 | ||||
| //! \par  Revision history
 | ||||
| //!       <2015/02/05> Notice
 | ||||
| //!        The version history is not updated after this point.
 | ||||
| //!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
 | ||||
| //!        >> https://github.com/Wiznet/ioLibrary_Driver
 | ||||
| //!       <2014/05/01> V1.0.3. Refer to M20140501
 | ||||
| //!         1. Implicit type casting -> Explicit type casting.
 | ||||
| //!         2. replace 0x01 with PACK_REMAINED in recvfrom()
 | ||||
| //!         3. Validation a destination ip in connect() & sendto(): 
 | ||||
| //!            It occurs a fatal error on converting unint32 address if uint8* addr parameter is not aligned by 4byte address.
 | ||||
| //!            Copy 4 byte addr value into temporary uint32 variable and then compares it.
 | ||||
| //!       <2013/12/20> V1.0.2 Refer to M20131220
 | ||||
| //!                    Remove Warning.
 | ||||
| //!       <2013/11/04> V1.0.1 2nd Release. Refer to "20131104".
 | ||||
| //!                    In sendto(), Add to clear timeout interrupt status (Sn_IR_TIMEOUT)
 | ||||
| //!       <2013/10/21> 1st Release
 | ||||
| //! \author MidnightCow
 | ||||
| //! \copyright
 | ||||
| //!
 | ||||
| //! Copyright (c)  2013, WIZnet Co., LTD.
 | ||||
| //! All rights reserved.
 | ||||
| //! 
 | ||||
| //! Redistribution and use in source and binary forms, with or without 
 | ||||
| //! modification, are permitted provided that the following conditions 
 | ||||
| //! are met: 
 | ||||
| //! 
 | ||||
| //!     * Redistributions of source code must retain the above copyright 
 | ||||
| //! notice, this list of conditions and the following disclaimer. 
 | ||||
| //!     * Redistributions in binary form must reproduce the above copyright
 | ||||
| //! notice, this list of conditions and the following disclaimer in the
 | ||||
| //! documentation and/or other materials provided with the distribution. 
 | ||||
| //!     * Neither the name of the <ORGANIZATION> nor the names of its 
 | ||||
| //! contributors may be used to endorse or promote products derived 
 | ||||
| //! from this software without specific prior written permission. 
 | ||||
| //! 
 | ||||
| //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | ||||
| //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | ||||
| //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | ||||
| //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 | ||||
| //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 | ||||
| //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 | ||||
| //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | ||||
| //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 | ||||
| //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 | ||||
| //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 | ||||
| //! THE POSSIBILITY OF SUCH DAMAGE.
 | ||||
| //
 | ||||
| //*****************************************************************************
 | ||||
| #include "socket.h" | ||||
| 
 | ||||
| //M20150401 : Typing Error
 | ||||
| //#define SOCK_ANY_PORT_NUM  0xC000;
 | ||||
| #define SOCK_ANY_PORT_NUM  0xC000 | ||||
| 
 | ||||
| static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; | ||||
| static uint16_t sock_io_mode = 0; | ||||
| static uint16_t sock_is_sending = 0; | ||||
| 
 | ||||
| static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = {0,0,}; | ||||
| 
 | ||||
| //M20150601 : For extern decleation
 | ||||
| //static uint8_t  sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,};
 | ||||
| uint8_t  sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; | ||||
| //
 | ||||
| 
 | ||||
| #if _WIZCHIP_ == 5200 | ||||
|    static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] ={0,}; | ||||
| #endif | ||||
| 
 | ||||
| //A20150601 : For integrating with W5300
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = {0,}; // set by wiz_recv_data()
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #define CHECK_SOCKNUM()   \ | ||||
|    do{                    \ | ||||
|       if(sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM;   \ | ||||
|    }while(0);             \ | ||||
| 
 | ||||
| #define CHECK_SOCKMODE(mode)  \ | ||||
|    do{                     \ | ||||
|       if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE;  \ | ||||
|    }while(0);              \ | ||||
| 
 | ||||
| #define CHECK_SOCKINIT()   \ | ||||
|    do{                     \ | ||||
|       if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ | ||||
|    }while(0);              \ | ||||
| 
 | ||||
| #define CHECK_SOCKDATA()   \ | ||||
|    do{                     \ | ||||
|       if(len == 0) return SOCKERR_DATALEN;   \ | ||||
|    }while(0);              \ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) | ||||
| { | ||||
| 	CHECK_SOCKNUM(); | ||||
| 	switch(protocol) | ||||
| 	{ | ||||
|       case Sn_MR_TCP : | ||||
|          { | ||||
|             //M20150601 : Fixed the warning - taddr will never be NULL
 | ||||
| 		    /*
 | ||||
|             uint8_t taddr[4]; | ||||
|             getSIPR(taddr); | ||||
|             */ | ||||
|             uint32_t taddr; | ||||
|             getSIPR((uint8_t*)&taddr); | ||||
|             if(taddr == 0) return SOCKERR_SOCKINIT; | ||||
|          } | ||||
|       case Sn_MR_UDP : | ||||
|       case Sn_MR_MACRAW : | ||||
| 	  case Sn_MR_IPRAW : | ||||
|          break; | ||||
|    #if ( _WIZCHIP_ < 5200 ) | ||||
|       case Sn_MR_PPPoE : | ||||
|          break; | ||||
|    #endif | ||||
|       default : | ||||
|          return SOCKERR_SOCKMODE; | ||||
| 	} | ||||
| 	//M20150601 : For SF_TCP_ALIGN & W5300
 | ||||
| 	//if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG;
 | ||||
| 	if((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; | ||||
| #if _WIZCHIP_ == 5200 | ||||
|    if(flag & 0x10) return SOCKERR_SOCKFLAG; | ||||
| #endif | ||||
| 	    | ||||
| 	if(flag != 0) | ||||
| 	{ | ||||
|    	switch(protocol) | ||||
|    	{ | ||||
|    	   case Sn_MR_TCP: | ||||
|    		  //M20150601 :  For SF_TCP_ALIGN & W5300
 | ||||
|           #if _WIZCHIP_ == 5300 | ||||
|    		     if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK|SF_TCP_ALIGN))==0) return SOCKERR_SOCKFLAG; | ||||
|           #else | ||||
|    		     if((flag & (SF_TCP_NODELAY|SF_IO_NONBLOCK))==0) return SOCKERR_SOCKFLAG; | ||||
|           #endif | ||||
| 
 | ||||
|    	      break; | ||||
|    	   case Sn_MR_UDP: | ||||
|    	      if(flag & SF_IGMP_VER2) | ||||
|    	      { | ||||
|    	         if((flag & SF_MULTI_ENABLE)==0) return SOCKERR_SOCKFLAG; | ||||
|    	      } | ||||
|    	      #if _WIZCHIP_ == 5500 | ||||
|       	      if(flag & SF_UNI_BLOCK) | ||||
|       	      { | ||||
|       	         if((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; | ||||
|       	      } | ||||
|    	      #endif | ||||
|    	      break; | ||||
|    	   default: | ||||
|    	      break; | ||||
|    	} | ||||
|    } | ||||
| 	close(sn); | ||||
| 	//M20150601
 | ||||
| 	#if _WIZCHIP_ == 5300 | ||||
| 	   setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | (((uint16_t)(flag & 0x02)) << 7) ); | ||||
|     #else | ||||
| 	   setSn_MR(sn, (protocol | (flag & 0xF0))); | ||||
|     #endif | ||||
| 	if(!port) | ||||
| 	{ | ||||
| 	   port = sock_any_port++; | ||||
| 	   if(sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; | ||||
| 	} | ||||
|    setSn_PORT(sn,port);	 | ||||
|    setSn_CR(sn,Sn_CR_OPEN); | ||||
|    while(getSn_CR(sn)); | ||||
|    //A20150401 : For release the previous sock_io_mode
 | ||||
|    sock_io_mode &= ~(1 <<sn); | ||||
|    //
 | ||||
| 	sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn);    | ||||
|    sock_is_sending &= ~(1<<sn); | ||||
|    sock_remained_size[sn] = 0; | ||||
|    //M20150601 : repalce 0 with PACK_COMPLETED
 | ||||
|    //sock_pack_info[sn] = 0;
 | ||||
|    sock_pack_info[sn] = PACK_COMPLETED; | ||||
|    //
 | ||||
|    while(getSn_SR(sn) == SOCK_CLOSED); | ||||
|    return (int8_t)sn; | ||||
| }	    | ||||
| 
 | ||||
| int8_t close(uint8_t sn) | ||||
| { | ||||
| 	CHECK_SOCKNUM(); | ||||
| //A20160426 : Applied the erratum 1 of W5300
 | ||||
| #if   (_WIZCHIP_ == 5300)  | ||||
|    //M20160503 : Wrong socket parameter. s -> sn 
 | ||||
|    //if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) ) 
 | ||||
|    if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )  | ||||
|    {  | ||||
|       uint8_t destip[4] = {0, 0, 0, 1}; | ||||
|       // TODO
 | ||||
|       // You can wait for completing to sending data;
 | ||||
|       // wait about 1 second;
 | ||||
|       // if you have completed to send data, skip the code of erratum 1
 | ||||
|       // ex> wait_1s();
 | ||||
|       //     if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
 | ||||
|       // 
 | ||||
|       //M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
 | ||||
|       //socket(s,Sn_MR_UDP,0x3000,0);
 | ||||
|       //sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
 | ||||
|       setSn_MR(sn,Sn_MR_UDP); | ||||
|       setSn_PORTR(sn, 0x3000); | ||||
|       setSn_CR(sn,Sn_CR_OPEN); | ||||
|       while(getSn_CR(sn) != 0); | ||||
|       while(getSn_SR(sn) != SOCK_UDP); | ||||
|       sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
 | ||||
|    };    | ||||
| #endif  | ||||
| 	setSn_CR(sn,Sn_CR_CLOSE); | ||||
|    /* wait to process the command... */ | ||||
| 	while( getSn_CR(sn) ); | ||||
| 	/* clear all interrupt of the socket. */ | ||||
| 	setSn_IR(sn, 0xFF); | ||||
| 	//A20150401 : Release the sock_io_mode of socket n.
 | ||||
| 	sock_io_mode &= ~(1<<sn); | ||||
| 	//
 | ||||
| 	sock_is_sending &= ~(1<<sn); | ||||
| 	sock_remained_size[sn] = 0; | ||||
| 	sock_pack_info[sn] = 0; | ||||
| 	while(getSn_SR(sn) != SOCK_CLOSED); | ||||
| 	return SOCK_OK; | ||||
| } | ||||
| 
 | ||||
| int8_t listen(uint8_t sn) | ||||
| { | ||||
| 	CHECK_SOCKNUM(); | ||||
|    CHECK_SOCKMODE(Sn_MR_TCP); | ||||
| 	CHECK_SOCKINIT(); | ||||
| 	setSn_CR(sn,Sn_CR_LISTEN); | ||||
| 	while(getSn_CR(sn)); | ||||
|    while(getSn_SR(sn) != SOCK_LISTEN) | ||||
|    { | ||||
|          close(sn); | ||||
|          return SOCKERR_SOCKCLOSED; | ||||
|    } | ||||
|    return SOCK_OK; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int8_t connect(uint8_t sn, uint8_t * addr, uint16_t port) | ||||
| { | ||||
|    CHECK_SOCKNUM(); | ||||
|    CHECK_SOCKMODE(Sn_MR_TCP); | ||||
|    CHECK_SOCKINIT(); | ||||
|    //M20140501 : For avoiding fatal error on memory align mismatched
 | ||||
|    //if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
 | ||||
|    { | ||||
|       uint32_t taddr; | ||||
|       taddr = ((uint32_t)addr[0] & 0x000000FF); | ||||
|       taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); | ||||
|       taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); | ||||
|       taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); | ||||
|       if( taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; | ||||
|    } | ||||
|    //
 | ||||
| 	 | ||||
| 	if(port == 0) return SOCKERR_PORTZERO; | ||||
| 	setSn_DIPR(sn,addr); | ||||
| 	setSn_DPORT(sn,port); | ||||
| 	setSn_CR(sn,Sn_CR_CONNECT); | ||||
|    while(getSn_CR(sn)); | ||||
|    if(sock_io_mode & (1<<sn)) return SOCK_BUSY; | ||||
|    while(getSn_SR(sn) != SOCK_ESTABLISHED) | ||||
|    { | ||||
| 		if (getSn_IR(sn) & Sn_IR_TIMEOUT) | ||||
| 		{ | ||||
| 			setSn_IR(sn, Sn_IR_TIMEOUT); | ||||
|             return SOCKERR_TIMEOUT; | ||||
| 		} | ||||
| 
 | ||||
| 		if (getSn_SR(sn) == SOCK_CLOSED) | ||||
| 		{ | ||||
| 			return SOCKERR_SOCKCLOSED; | ||||
| 		} | ||||
| 	} | ||||
|     | ||||
|    return SOCK_OK; | ||||
| } | ||||
| 
 | ||||
| int8_t disconnect(uint8_t sn) | ||||
| { | ||||
|    CHECK_SOCKNUM(); | ||||
|    CHECK_SOCKMODE(Sn_MR_TCP); | ||||
| 	setSn_CR(sn,Sn_CR_DISCON); | ||||
| 	/* wait to process the command... */ | ||||
| 	while(getSn_CR(sn)); | ||||
| 	sock_is_sending &= ~(1<<sn); | ||||
|    if(sock_io_mode & (1<<sn)) return SOCK_BUSY; | ||||
| 	while(getSn_SR(sn) != SOCK_CLOSED) | ||||
| 	{ | ||||
| 	   if(getSn_IR(sn) & Sn_IR_TIMEOUT) | ||||
| 	   { | ||||
| 	      close(sn); | ||||
| 	      return SOCKERR_TIMEOUT; | ||||
| 	   } | ||||
| 	} | ||||
| 	return SOCK_OK; | ||||
| } | ||||
| 
 | ||||
| int32_t send(uint8_t sn, uint8_t * buf, uint16_t len) | ||||
| { | ||||
|    uint8_t tmp=0; | ||||
|    uint16_t freesize=0; | ||||
|     | ||||
|    CHECK_SOCKNUM(); | ||||
|    CHECK_SOCKMODE(Sn_MR_TCP); | ||||
|    CHECK_SOCKDATA(); | ||||
|    tmp = getSn_SR(sn); | ||||
|    if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS; | ||||
|    if( sock_is_sending & (1<<sn) ) | ||||
|    { | ||||
|       tmp = getSn_IR(sn); | ||||
|       if(tmp & Sn_IR_SENDOK) | ||||
|       { | ||||
|          setSn_IR(sn, Sn_IR_SENDOK); | ||||
|          //M20150401 : Typing Error
 | ||||
|          //#if _WZICHIP_ == 5200
 | ||||
|          #if _WIZCHIP_ == 5200 | ||||
|             if(getSn_TX_RD(sn) != sock_next_rd[sn]) | ||||
|             { | ||||
|                setSn_CR(sn,Sn_CR_SEND); | ||||
|                while(getSn_CR(sn)); | ||||
|                return SOCK_BUSY; | ||||
|             } | ||||
|          #endif | ||||
|          sock_is_sending &= ~(1<<sn);          | ||||
|       } | ||||
|       else if(tmp & Sn_IR_TIMEOUT) | ||||
|       { | ||||
|          close(sn); | ||||
|          return SOCKERR_TIMEOUT; | ||||
|       } | ||||
|       else return SOCK_BUSY; | ||||
|    } | ||||
|    freesize = getSn_TxMAX(sn); | ||||
|    if (len > freesize) len = freesize; // check size not to exceed MAX size.
 | ||||
|    while(1) | ||||
|    { | ||||
|       freesize = getSn_TX_FSR(sn); | ||||
|       tmp = getSn_SR(sn); | ||||
|       if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) | ||||
|       { | ||||
|          close(sn); | ||||
|          return SOCKERR_SOCKSTATUS; | ||||
|       } | ||||
|       if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; | ||||
|       if(len <= freesize) break; | ||||
|    } | ||||
|    wiz_send_data(sn, buf, len); | ||||
|    #if _WIZCHIP_ == 5200 | ||||
|       sock_next_rd[sn] = getSn_TX_RD(sn) + len; | ||||
|    #endif | ||||
| 
 | ||||
|    #if _WIZCHIP_ == 5300 | ||||
|       setSn_TX_WRSR(sn,len); | ||||
|    #endif | ||||
|     | ||||
|    setSn_CR(sn,Sn_CR_SEND); | ||||
|    /* wait to process the command... */ | ||||
|    while(getSn_CR(sn)); | ||||
|    sock_is_sending |= (1 << sn); | ||||
|    //M20150409 : Explicit Type Casting
 | ||||
|    //return len;
 | ||||
|    return (int32_t)len; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) | ||||
| { | ||||
|    uint8_t  tmp = 0; | ||||
|    uint16_t recvsize = 0; | ||||
| //A20150601 : For integarating with W5300
 | ||||
| #if   _WIZCHIP_ == 5300 | ||||
|    uint8_t head[2]; | ||||
|    uint16_t mr; | ||||
| #endif | ||||
| //
 | ||||
|    CHECK_SOCKNUM(); | ||||
|    CHECK_SOCKMODE(Sn_MR_TCP); | ||||
|    CHECK_SOCKDATA(); | ||||
|     | ||||
|    recvsize = getSn_RxMAX(sn); | ||||
|    if(recvsize < len) len = recvsize; | ||||
|        | ||||
| //A20150601 : For Integrating with W5300
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    //sock_pack_info[sn] = PACK_COMPLETED;    // for clear      
 | ||||
|    if(sock_remained_size[sn] == 0) | ||||
|    { | ||||
| #endif | ||||
| //
 | ||||
|       while(1) | ||||
|       { | ||||
|          recvsize = getSn_RX_RSR(sn); | ||||
|          tmp = getSn_SR(sn); | ||||
|          if (tmp != SOCK_ESTABLISHED) | ||||
|          { | ||||
|             if(tmp == SOCK_CLOSE_WAIT) | ||||
|             { | ||||
|                if(recvsize != 0) break; | ||||
|                else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) | ||||
|                { | ||||
|                   close(sn); | ||||
|                   return SOCKERR_SOCKSTATUS; | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                close(sn); | ||||
|                return SOCKERR_SOCKSTATUS; | ||||
|             } | ||||
|          } | ||||
|          if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; | ||||
|          if(recvsize != 0) break; | ||||
|       }; | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    } | ||||
| #endif | ||||
| 
 | ||||
| //A20150601 : For integrating with W5300
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    if((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) | ||||
|    { | ||||
|       mr = getMR(); | ||||
|       if((getSn_MR(sn) & Sn_MR_ALIGN)==0) | ||||
|       { | ||||
|          wiz_recv_data(sn,head,2); | ||||
|          if(mr & MR_FS) | ||||
|             recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); | ||||
|          else | ||||
|             recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); | ||||
|          sock_pack_info[sn] = PACK_FIRST; | ||||
|       } | ||||
|       sock_remained_size[sn] = recvsize; | ||||
|    } | ||||
|    if(len > sock_remained_size[sn]) len = sock_remained_size[sn]; | ||||
|    recvsize = len;    | ||||
|    if(sock_pack_info[sn] & PACK_FIFOBYTE) | ||||
|    { | ||||
|       *buf = sock_remained_byte[sn]; | ||||
|       buf++; | ||||
|       sock_pack_info[sn] &= ~(PACK_FIFOBYTE); | ||||
|       recvsize -= 1; | ||||
|       sock_remained_size[sn] -= 1; | ||||
|    } | ||||
|    if(recvsize != 0) | ||||
|    { | ||||
|       wiz_recv_data(sn, buf, recvsize); | ||||
|       setSn_CR(sn,Sn_CR_RECV); | ||||
|       while(getSn_CR(sn)); | ||||
|    } | ||||
|    sock_remained_size[sn] -= recvsize; | ||||
|    if(sock_remained_size[sn] != 0) | ||||
|    { | ||||
|       sock_pack_info[sn] |= PACK_REMAINED; | ||||
|       if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; | ||||
|    } | ||||
|    else sock_pack_info[sn] = PACK_COMPLETED; | ||||
|    if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; | ||||
|    //len = recvsize;
 | ||||
| #else    | ||||
|    if(recvsize < len) len = recvsize;    | ||||
|    wiz_recv_data(sn, buf, len); | ||||
|    setSn_CR(sn,Sn_CR_RECV); | ||||
|    while(getSn_CR(sn)); | ||||
| #endif | ||||
|       | ||||
|    //M20150409 : Explicit Type Casting
 | ||||
|    //return len;
 | ||||
|    return (int32_t)len; | ||||
| } | ||||
| 
 | ||||
| int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port) | ||||
| { | ||||
|    uint8_t tmp = 0; | ||||
|    uint16_t freesize = 0; | ||||
|    uint32_t taddr; | ||||
| 
 | ||||
|    CHECK_SOCKNUM(); | ||||
|    switch(getSn_MR(sn) & 0x0F) | ||||
|    { | ||||
|       case Sn_MR_UDP: | ||||
|       case Sn_MR_MACRAW: | ||||
| //         break;
 | ||||
| //   #if ( _WIZCHIP_ < 5200 )
 | ||||
|       case Sn_MR_IPRAW: | ||||
|          break; | ||||
| //   #endif
 | ||||
|       default: | ||||
|          return SOCKERR_SOCKMODE; | ||||
|    } | ||||
|    CHECK_SOCKDATA(); | ||||
|    //M20140501 : For avoiding fatal error on memory align mismatched
 | ||||
|    //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
 | ||||
|    //{
 | ||||
|       //uint32_t taddr;
 | ||||
|       taddr = ((uint32_t)addr[0]) & 0x000000FF; | ||||
|       taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); | ||||
|       taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); | ||||
|       taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); | ||||
|    //}
 | ||||
|    //
 | ||||
|    //if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID;
 | ||||
|    if((taddr == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_IPINVALID; | ||||
|    if((port  == 0) && ((getSn_MR(sn)&Sn_MR_MACRAW) != Sn_MR_MACRAW)) return SOCKERR_PORTZERO; | ||||
|    tmp = getSn_SR(sn); | ||||
| //#if ( _WIZCHIP_ < 5200 )
 | ||||
|    if((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) return SOCKERR_SOCKSTATUS; | ||||
| //#else
 | ||||
| //   if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS;
 | ||||
| //#endif
 | ||||
|        | ||||
|    setSn_DIPR(sn,addr); | ||||
|    setSn_DPORT(sn,port);       | ||||
|    freesize = getSn_TxMAX(sn); | ||||
|    if (len > freesize) len = freesize; // check size not to exceed MAX size.
 | ||||
|    while(1) | ||||
|    { | ||||
|       freesize = getSn_TX_FSR(sn); | ||||
|       if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; | ||||
|       if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY; | ||||
|       if(len <= freesize) break; | ||||
|    }; | ||||
| 	wiz_send_data(sn, buf, len); | ||||
| 
 | ||||
|    #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
 | ||||
|       getSIPR((uint8_t*)&taddr); | ||||
|       if(taddr == 0) | ||||
|       { | ||||
|          getSUBR((uint8_t*)&taddr); | ||||
|          setSUBR((uint8_t*)"\x00\x00\x00\x00"); | ||||
|       } | ||||
|       else taddr = 0; | ||||
|    #endif | ||||
| 
 | ||||
| //A20150601 : For W5300
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    setSn_TX_WRSR(sn, len); | ||||
| #endif | ||||
| //   
 | ||||
| 	setSn_CR(sn,Sn_CR_SEND); | ||||
| 	/* wait to process the command... */ | ||||
| 	while(getSn_CR(sn)); | ||||
|    while(1) | ||||
|    { | ||||
|       tmp = getSn_IR(sn); | ||||
|       if(tmp & Sn_IR_SENDOK) | ||||
|       { | ||||
|          setSn_IR(sn, Sn_IR_SENDOK); | ||||
|          break; | ||||
|       } | ||||
|       //M:20131104
 | ||||
|       //else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT;
 | ||||
|       else if(tmp & Sn_IR_TIMEOUT) | ||||
|       { | ||||
|          setSn_IR(sn, Sn_IR_TIMEOUT); | ||||
|          //M20150409 : Fixed the lost of sign bits by type casting.
 | ||||
|          //len = (uint16_t)SOCKERR_TIMEOUT;
 | ||||
|          //break;
 | ||||
|          #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
 | ||||
|             if(taddr) setSUBR((uint8_t*)&taddr); | ||||
|          #endif | ||||
|          return SOCKERR_TIMEOUT; | ||||
|       } | ||||
|       ////////////
 | ||||
|    } | ||||
|    #if _WIZCHIP_ < 5500   //M20150401 : for WIZCHIP Errata #4, #5 (ARP errata)
 | ||||
|       if(taddr) setSUBR((uint8_t*)&taddr); | ||||
|    #endif | ||||
|    //M20150409 : Explicit Type Casting
 | ||||
|    //return len;
 | ||||
|    return (int32_t)len; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) | ||||
| { | ||||
| //M20150601 : For W5300   
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    uint16_t mr; | ||||
|    uint16_t mr1; | ||||
| #else    | ||||
|    uint8_t  mr; | ||||
| #endif | ||||
| //   
 | ||||
|    uint8_t  head[8]; | ||||
| 	uint16_t pack_len=0; | ||||
| 
 | ||||
|    CHECK_SOCKNUM(); | ||||
|    //CHECK_SOCKMODE(Sn_MR_UDP);
 | ||||
| //A20150601
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    mr1 = getMR(); | ||||
| #endif    | ||||
| 
 | ||||
|    switch((mr=getSn_MR(sn)) & 0x0F) | ||||
|    { | ||||
|       case Sn_MR_UDP: | ||||
| 	  case Sn_MR_IPRAW: | ||||
|       case Sn_MR_MACRAW: | ||||
|          break; | ||||
|    #if ( _WIZCHIP_ < 5200 )          | ||||
|       case Sn_MR_PPPoE: | ||||
|          break; | ||||
|    #endif | ||||
|       default: | ||||
|          return SOCKERR_SOCKMODE; | ||||
|    } | ||||
|    CHECK_SOCKDATA(); | ||||
|    if(sock_remained_size[sn] == 0) | ||||
|    { | ||||
|       while(1) | ||||
|       { | ||||
|          pack_len = getSn_RX_RSR(sn); | ||||
|          if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; | ||||
|          if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; | ||||
|          if(pack_len != 0) break; | ||||
|       }; | ||||
|    } | ||||
| //D20150601 : Move it to bottom
 | ||||
| // sock_pack_info[sn] = PACK_COMPLETED;
 | ||||
| 	switch (mr & 0x07) | ||||
| 	{ | ||||
| 	   case Sn_MR_UDP : | ||||
| 	      if(sock_remained_size[sn] == 0) | ||||
| 	      { | ||||
|    			wiz_recv_data(sn, head, 8); | ||||
|    			setSn_CR(sn,Sn_CR_RECV); | ||||
|    			while(getSn_CR(sn)); | ||||
|    			// read peer's IP address, port number & packet length
 | ||||
|    	   //A20150601 : For W5300
 | ||||
|    		#if _WIZCHIP_ == 5300 | ||||
|    		   if(mr1 & MR_FS) | ||||
|    		   { | ||||
|    		      addr[0] = head[1]; | ||||
|    		      addr[1] = head[0]; | ||||
|    		      addr[2] = head[3]; | ||||
|    		      addr[3] = head[2]; | ||||
|    		      *port = head[5]; | ||||
|    		      *port = (*port << 8) + head[4]; | ||||
|       			sock_remained_size[sn] = head[7]; | ||||
|       			sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; | ||||
|    		   } | ||||
|             else | ||||
|             { | ||||
|          #endif | ||||
|                addr[0] = head[0]; | ||||
|       			addr[1] = head[1]; | ||||
|       			addr[2] = head[2]; | ||||
|       			addr[3] = head[3]; | ||||
|       			*port = head[4]; | ||||
|       			*port = (*port << 8) + head[5]; | ||||
|       			sock_remained_size[sn] = head[6]; | ||||
|       			sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; | ||||
|          #if _WIZCHIP_ == 5300 | ||||
|             } | ||||
|          #endif | ||||
|    			sock_pack_info[sn] = PACK_FIRST; | ||||
|    	   } | ||||
| 			if(len < sock_remained_size[sn]) pack_len = len; | ||||
| 			else pack_len = sock_remained_size[sn]; | ||||
| 			//A20150601 : For W5300
 | ||||
| 			len = pack_len; | ||||
| 			#if _WIZCHIP_ == 5300 | ||||
| 			   if(sock_pack_info[sn] & PACK_FIFOBYTE) | ||||
| 			   { | ||||
| 			      *buf++ = sock_remained_byte[sn]; | ||||
| 			      pack_len -= 1; | ||||
| 			      sock_remained_size[sn] -= 1; | ||||
| 			      sock_pack_info[sn] &= ~PACK_FIFOBYTE; | ||||
| 			   } | ||||
| 			#endif | ||||
| 			//
 | ||||
| 			// Need to packet length check (default 1472)
 | ||||
| 			//
 | ||||
|    		wiz_recv_data(sn, buf, pack_len); // data copy.
 | ||||
| 			break; | ||||
| 	   case Sn_MR_MACRAW : | ||||
| 	      if(sock_remained_size[sn] == 0) | ||||
| 	      { | ||||
|    			wiz_recv_data(sn, head, 2); | ||||
|    			setSn_CR(sn,Sn_CR_RECV); | ||||
|    			while(getSn_CR(sn)); | ||||
|    			// read peer's IP address, port number & packet length
 | ||||
|     			sock_remained_size[sn] = head[0]; | ||||
|    			sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1] -2; | ||||
|    			#if _WIZCHIP_ == W5300 | ||||
|    			if(sock_remained_size[sn] & 0x01) | ||||
|    				sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; | ||||
|    			else | ||||
|    				sock_remained_size[sn] -= 4; | ||||
| 			#endif | ||||
|    			if(sock_remained_size[sn] > 1514)  | ||||
|    			{ | ||||
|    			   close(sn); | ||||
|    			   return SOCKFATAL_PACKLEN; | ||||
|    			} | ||||
|    			sock_pack_info[sn] = PACK_FIRST; | ||||
|    	   } | ||||
| 			if(len < sock_remained_size[sn]) pack_len = len; | ||||
| 			else pack_len = sock_remained_size[sn]; | ||||
| 			wiz_recv_data(sn,buf,pack_len); | ||||
| 		   break; | ||||
|    //#if ( _WIZCHIP_ < 5200 )
 | ||||
| 		case Sn_MR_IPRAW: | ||||
| 		   if(sock_remained_size[sn] == 0) | ||||
| 		   { | ||||
|    			wiz_recv_data(sn, head, 6); | ||||
|    			setSn_CR(sn,Sn_CR_RECV); | ||||
|    			while(getSn_CR(sn)); | ||||
|    			addr[0] = head[0]; | ||||
|    			addr[1] = head[1]; | ||||
|    			addr[2] = head[2]; | ||||
|    			addr[3] = head[3]; | ||||
|    			sock_remained_size[sn] = head[4]; | ||||
|    			//M20150401 : For Typing Error
 | ||||
|    			//sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5];
 | ||||
|    			sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; | ||||
|    			sock_pack_info[sn] = PACK_FIRST; | ||||
|          } | ||||
| 			//
 | ||||
| 			// Need to packet length check
 | ||||
| 			//
 | ||||
| 			if(len < sock_remained_size[sn]) pack_len = len; | ||||
| 			else pack_len = sock_remained_size[sn]; | ||||
|    		wiz_recv_data(sn, buf, pack_len); // data copy.
 | ||||
| 			break; | ||||
|    //#endif
 | ||||
|       default: | ||||
|          wiz_recv_ignore(sn, pack_len); // data copy.
 | ||||
|          sock_remained_size[sn] = pack_len; | ||||
|          break; | ||||
|    } | ||||
| 	setSn_CR(sn,Sn_CR_RECV); | ||||
| 	/* wait to process the command... */ | ||||
| 	while(getSn_CR(sn)) ; | ||||
| 	sock_remained_size[sn] -= pack_len; | ||||
| 	//M20150601 : 
 | ||||
| 	//if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01;
 | ||||
| 	if(sock_remained_size[sn] != 0) | ||||
| 	{ | ||||
| 	   sock_pack_info[sn] |= PACK_REMAINED; | ||||
|    #if _WIZCHIP_ == 5300	    | ||||
| 	   if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; | ||||
|    #endif	       | ||||
| 	} | ||||
| 	else sock_pack_info[sn] = PACK_COMPLETED; | ||||
| #if _WIZCHIP_ == 5300	    | ||||
|    pack_len = len; | ||||
| #endif | ||||
|    //
 | ||||
|    //M20150409 : Explicit Type Casting
 | ||||
|    //return pack_len;
 | ||||
|    return (int32_t)pack_len; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int8_t  ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg) | ||||
| { | ||||
|    uint8_t tmp = 0; | ||||
|    CHECK_SOCKNUM(); | ||||
|    switch(cstype) | ||||
|    { | ||||
|       case CS_SET_IOMODE: | ||||
|          tmp = *((uint8_t*)arg); | ||||
|          if(tmp == SOCK_IO_NONBLOCK)  sock_io_mode |= (1<<sn); | ||||
|          else if(tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1<<sn); | ||||
|          else return SOCKERR_ARG; | ||||
|          break; | ||||
|       case CS_GET_IOMODE:    | ||||
|          //M20140501 : implict type casting -> explict type casting
 | ||||
|          //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001;
 | ||||
|          *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); | ||||
|          //
 | ||||
|          break; | ||||
|       case CS_GET_MAXTXBUF: | ||||
|          *((uint16_t*)arg) = getSn_TxMAX(sn); | ||||
|          break; | ||||
|       case CS_GET_MAXRXBUF:     | ||||
|          *((uint16_t*)arg) = getSn_RxMAX(sn); | ||||
|          break; | ||||
|       case CS_CLR_INTERRUPT: | ||||
|          if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; | ||||
|          setSn_IR(sn,*(uint8_t*)arg); | ||||
|          break; | ||||
|       case CS_GET_INTERRUPT: | ||||
|          *((uint8_t*)arg) = getSn_IR(sn); | ||||
|          break; | ||||
|    #if _WIZCHIP_ != 5100 | ||||
|       case CS_SET_INTMASK:   | ||||
|          if( (*(uint8_t*)arg) > SIK_ALL) return SOCKERR_ARG; | ||||
|          setSn_IMR(sn,*(uint8_t*)arg); | ||||
|          break; | ||||
|       case CS_GET_INTMASK:    | ||||
|          *((uint8_t*)arg) = getSn_IMR(sn); | ||||
|          break; | ||||
|    #endif | ||||
|       default: | ||||
|          return SOCKERR_ARG; | ||||
|    } | ||||
|    return SOCK_OK; | ||||
| } | ||||
| 
 | ||||
| int8_t  setsockopt(uint8_t sn, sockopt_type sotype, void* arg) | ||||
| { | ||||
|  // M20131220 : Remove warning
 | ||||
|  //uint8_t tmp;
 | ||||
|    CHECK_SOCKNUM(); | ||||
|    switch(sotype) | ||||
|    { | ||||
|       case SO_TTL: | ||||
|          setSn_TTL(sn,*(uint8_t*)arg); | ||||
|          break; | ||||
|       case SO_TOS: | ||||
|          setSn_TOS(sn,*(uint8_t*)arg); | ||||
|          break; | ||||
|       case SO_MSS: | ||||
|          setSn_MSSR(sn,*(uint16_t*)arg); | ||||
|          break; | ||||
|       case SO_DESTIP: | ||||
|          setSn_DIPR(sn, (uint8_t*)arg); | ||||
|          break; | ||||
|       case SO_DESTPORT: | ||||
|          setSn_DPORT(sn, *(uint16_t*)arg); | ||||
|          break; | ||||
| #if _WIZCHIP_ != 5100 | ||||
|       case SO_KEEPALIVESEND: | ||||
|          CHECK_SOCKMODE(Sn_MR_TCP); | ||||
|          #if _WIZCHIP_ > 5200 | ||||
|             if(getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; | ||||
|          #endif | ||||
|             setSn_CR(sn,Sn_CR_SEND_KEEP); | ||||
|             while(getSn_CR(sn) != 0) | ||||
|             { | ||||
|                // M20131220
 | ||||
|          		//if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT)
 | ||||
|                if (getSn_IR(sn) & Sn_IR_TIMEOUT) | ||||
|          		{ | ||||
|          			setSn_IR(sn, Sn_IR_TIMEOUT); | ||||
|                   return SOCKERR_TIMEOUT; | ||||
|          		} | ||||
|             } | ||||
|          break; | ||||
|    #if _WIZCHIP_ > 5200 | ||||
|       case SO_KEEPALIVEAUTO: | ||||
|          CHECK_SOCKMODE(Sn_MR_TCP); | ||||
|          setSn_KPALVTR(sn,*(uint8_t*)arg); | ||||
|          break; | ||||
|    #endif       | ||||
| #endif    | ||||
|       default: | ||||
|          return SOCKERR_ARG; | ||||
|    }    | ||||
|    return SOCK_OK; | ||||
| } | ||||
| 
 | ||||
| int8_t  getsockopt(uint8_t sn, sockopt_type sotype, void* arg) | ||||
| { | ||||
|    CHECK_SOCKNUM(); | ||||
|    switch(sotype) | ||||
|    { | ||||
|       case SO_FLAG: | ||||
|          *(uint8_t*)arg = getSn_MR(sn) & 0xF0; | ||||
|          break; | ||||
|       case SO_TTL: | ||||
|          *(uint8_t*) arg = getSn_TTL(sn); | ||||
|          break; | ||||
|       case SO_TOS: | ||||
|          *(uint8_t*) arg = getSn_TOS(sn); | ||||
|          break; | ||||
|       case SO_MSS:    | ||||
|          *(uint16_t*) arg = getSn_MSSR(sn); | ||||
|          break; | ||||
|       case SO_DESTIP: | ||||
|          getSn_DIPR(sn, (uint8_t*)arg); | ||||
|          break; | ||||
|       case SO_DESTPORT:   | ||||
|          *(uint16_t*) arg = getSn_DPORT(sn); | ||||
|          break; | ||||
|    #if _WIZCHIP_ > 5200    | ||||
|       case SO_KEEPALIVEAUTO: | ||||
|          CHECK_SOCKMODE(Sn_MR_TCP); | ||||
|          *(uint16_t*) arg = getSn_KPALVTR(sn); | ||||
|          break; | ||||
|    #endif       | ||||
|       case SO_SENDBUF: | ||||
|          *(uint16_t*) arg = getSn_TX_FSR(sn); | ||||
|          break; | ||||
|       case SO_RECVBUF: | ||||
|          *(uint16_t*) arg = getSn_RX_RSR(sn); | ||||
|          break; | ||||
|       case SO_STATUS: | ||||
|          *(uint8_t*) arg = getSn_SR(sn); | ||||
|          break; | ||||
|       case SO_REMAINSIZE: | ||||
|          if(getSn_MR(sn) & Sn_MR_TCP) | ||||
|             *(uint16_t*)arg = getSn_RX_RSR(sn); | ||||
|          else | ||||
|             *(uint16_t*)arg = sock_remained_size[sn]; | ||||
|          break; | ||||
|       case SO_PACKINFO: | ||||
|          //CHECK_SOCKMODE(Sn_MR_TCP);
 | ||||
| #if _WIZCHIP_ != 5300 | ||||
|          if((getSn_MR(sn) == Sn_MR_TCP)) | ||||
|              return SOCKERR_SOCKMODE; | ||||
| #endif | ||||
|          *(uint8_t*)arg = sock_pack_info[sn]; | ||||
|          break; | ||||
|       default: | ||||
|          return SOCKERR_SOCKOPT; | ||||
|    } | ||||
|    return SOCK_OK; | ||||
| } | ||||
| @ -0,0 +1,489 @@ | ||||
| //*****************************************************************************
 | ||||
| //
 | ||||
| //! \file socket.h
 | ||||
| //! \brief SOCKET APIs Header file.
 | ||||
| //! \details SOCKET APIs like as berkeley socket api. 
 | ||||
| //! \version 1.0.2
 | ||||
| //! \date 2013/10/21
 | ||||
| //! \par  Revision history
 | ||||
| //!       <2015/02/05> Notice
 | ||||
| //!        The version history is not updated after this point.
 | ||||
| //!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
 | ||||
| //!        >> https://github.com/Wiznet/ioLibrary_Driver
 | ||||
| //!       <2014/05/01> V1.0.2. Refer to M20140501
 | ||||
| //!         1. Modify the comment : SO_REMAINED -> PACK_REMAINED
 | ||||
| //!         2. Add the comment as zero byte udp data reception in getsockopt(). 
 | ||||
| //!       <2013/10/21> 1st Release
 | ||||
| //! \author MidnightCow
 | ||||
| //! \copyright
 | ||||
| //!
 | ||||
| //! Copyright (c)  2013, WIZnet Co., LTD.
 | ||||
| //! All rights reserved.
 | ||||
| //! 
 | ||||
| //! Redistribution and use in source and binary forms, with or without 
 | ||||
| //! modification, are permitted provided that the following conditions 
 | ||||
| //! are met: 
 | ||||
| //! 
 | ||||
| //!     * Redistributions of source code must retain the above copyright 
 | ||||
| //! notice, this list of conditions and the following disclaimer. 
 | ||||
| //!     * Redistributions in binary form must reproduce the above copyright
 | ||||
| //! notice, this list of conditions and the following disclaimer in the
 | ||||
| //! documentation and/or other materials provided with the distribution. 
 | ||||
| //!     * Neither the name of the <ORGANIZATION> nor the names of its 
 | ||||
| //! contributors may be used to endorse or promote products derived 
 | ||||
| //! from this software without specific prior written permission. 
 | ||||
| //! 
 | ||||
| //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | ||||
| //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | ||||
| //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | ||||
| //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 | ||||
| //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 | ||||
| //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 | ||||
| //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | ||||
| //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 | ||||
| //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 | ||||
| //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 | ||||
| //! THE POSSIBILITY OF SUCH DAMAGE.
 | ||||
| //
 | ||||
| //*****************************************************************************
 | ||||
| /**
 | ||||
|  * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs | ||||
|  * @brief WIZnet socket APIs are based on Berkeley socket APIs,  thus it has much similar name and interface. | ||||
|  *        But there is a little bit of difference. | ||||
|  * @details | ||||
|  * <b> Comparison between WIZnet and Berkeley SOCKET APIs </b> | ||||
|  * <table> | ||||
|  *    <tr>   <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td>   </tr> | ||||
|  *    <tr>   <td>socket()</td> <td>O</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>bind()</b></td> <td>X</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>listen()</b></td> <td>O</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>connect()</b></td> <td>O</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>accept()</b></td> <td>X</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>recv()</b></td> <td>O</td> <td>O</td>    </tr> | ||||
|  *    <tr>   <td><b>send()</b></td> <td>O</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>recvfrom()</b></td> <td>O</td> <td>O</td>   </tr> | ||||
|  *    <tr>   <td><b>sendto()</b></td> <td>O</td> <td>O</td>    </tr> | ||||
|  *    <tr>   <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td>   </tr> | ||||
|  * </table> | ||||
|  * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, | ||||
|  * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating a SOCKET but also binding a local port number, | ||||
|  * and listen() of WIZnet is not only listening to connection request from client but also accepting the connection request. \n | ||||
|  * When you program "TCP SERVER" with Berkeley SOCKET API, you can use only one listen port. | ||||
|  * When the listen SOCKET accepts a connection request from a client, it keeps listening. | ||||
|  * After accepting the connection request, a new SOCKET is created and the new SOCKET is used in communication with the client. \n | ||||
|  * Following figure shows network flow diagram by Berkeley SOCKET API. | ||||
|  * @image html Berkeley_SOCKET.jpg "<Berkeley SOCKET API>" | ||||
|  * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as many as 8 listen SOCKET with same port number. \n | ||||
|  * Because there's no accept() in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request from a client, | ||||
|  * it is changed in order to communicate with the client. | ||||
|  * And the changed SOCKET is not listening any more and is dedicated for communicating with the client. \n | ||||
|  * If there're many listen SOCKET with same listen port number and a client requests a connection, | ||||
|  * the SOCKET which has the smallest SOCKET number accepts the request and is changed as communication SOCKET. \n | ||||
|  * Following figure shows network flow diagram by WIZnet SOCKET API. | ||||
|  * @image html WIZnet_SOCKET.jpg "<WIZnet SOCKET API>" | ||||
|  */ | ||||
| #ifndef _SOCKET_H_ | ||||
| #define _SOCKET_H_ | ||||
| #ifdef __cplusplus | ||||
|  extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include "wizchip_conf.h" | ||||
| 
 | ||||
| #define SOCKET                uint8_t  ///< SOCKET type define for legacy driver
 | ||||
| 
 | ||||
| #define SOCK_OK               1        ///< Result is OK about socket process.
 | ||||
| #define SOCK_BUSY             0        ///< Socket is busy on processing the operation. Valid only Non-block IO Mode.
 | ||||
| #define SOCK_FATAL            -1000    ///< Result is fatal error about socket process.
 | ||||
| 
 | ||||
| #define SOCK_ERROR            0         | ||||
| #define SOCKERR_SOCKNUM       (SOCK_ERROR - 1)     ///< Invalid socket number
 | ||||
| #define SOCKERR_SOCKOPT       (SOCK_ERROR - 2)     ///< Invalid socket option
 | ||||
| #define SOCKERR_SOCKINIT      (SOCK_ERROR - 3)     ///< Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP
 | ||||
| #define SOCKERR_SOCKCLOSED    (SOCK_ERROR - 4)     ///< Socket unexpectedly closed.
 | ||||
| #define SOCKERR_SOCKMODE      (SOCK_ERROR - 5)     ///< Invalid socket mode for socket operation.
 | ||||
| #define SOCKERR_SOCKFLAG      (SOCK_ERROR - 6)     ///< Invalid socket flag
 | ||||
| #define SOCKERR_SOCKSTATUS    (SOCK_ERROR - 7)     ///< Invalid socket status for socket operation.
 | ||||
| #define SOCKERR_ARG           (SOCK_ERROR - 10)    ///< Invalid argument.
 | ||||
| #define SOCKERR_PORTZERO      (SOCK_ERROR - 11)    ///< Port number is zero
 | ||||
| #define SOCKERR_IPINVALID     (SOCK_ERROR - 12)    ///< Invalid IP address
 | ||||
| #define SOCKERR_TIMEOUT       (SOCK_ERROR - 13)    ///< Timeout occurred
 | ||||
| #define SOCKERR_DATALEN       (SOCK_ERROR - 14)    ///< Data length is zero or greater than buffer max size.
 | ||||
| #define SOCKERR_BUFFER        (SOCK_ERROR - 15)    ///< Socket buffer is not enough for data communication.
 | ||||
| 
 | ||||
| #define SOCKFATAL_PACKLEN     (SOCK_FATAL - 1)     ///< Invalid packet length. Fatal Error.
 | ||||
| 
 | ||||
| /*
 | ||||
|  * SOCKET FLAG | ||||
|  */ | ||||
| #define SF_ETHER_OWN           (Sn_MR_MFEN)        ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, multicast and own packet
 | ||||
| #define SF_IGMP_VER2           (Sn_MR_MC)          ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP version 2.   
 | ||||
| #define SF_TCP_NODELAY         (Sn_MR_ND)          ///< In @ref Sn_MR_TCP, Use to nodelayed ack.
 | ||||
| #define SF_MULTI_ENABLE        (Sn_MR_MULTI)       ///< In @ref Sn_MR_UDP, Enable multicast mode.
 | ||||
| 
 | ||||
| #if _WIZCHIP_ == 5500 | ||||
|    #define SF_BROAD_BLOCK         (Sn_MR_BCASTB)   ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast packet. Valid only in W5500
 | ||||
|    #define SF_MULTI_BLOCK         (Sn_MR_MMB)      ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in W5500
 | ||||
|    #define SF_IPv6_BLOCK          (Sn_MR_MIP6B)    ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in W5500
 | ||||
|    #define SF_UNI_BLOCK           (Sn_MR_UCASTB)   ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only in W5500
 | ||||
| #endif | ||||
| 
 | ||||
| //A201505 : For W5300
 | ||||
| #if _WIZCHIP_ == 5300 | ||||
|    #define SF_TCP_ALIGN		     0x02			   ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN
 | ||||
| #endif | ||||
| 
 | ||||
| #define SF_IO_NONBLOCK           0x01              ///< Socket nonblock io mode. It used parameter in \ref socket().
 | ||||
| 
 | ||||
| /*
 | ||||
|  * UDP & MACRAW Packet Infomation | ||||
|  */ | ||||
| #define PACK_FIRST               0x80              ///< In Non-TCP packet, It indicates to start receiving a packet. (When W5300, This flag can be applied)
 | ||||
| #define PACK_REMAINED            0x01              ///< In Non-TCP packet, It indicates to remain a packet to be received. (When W5300, This flag can be applied)
 | ||||
| #define PACK_COMPLETED           0x00              ///< In Non-TCP packet, It indicates to complete to receive a packet. (When W5300, This flag can be applied)
 | ||||
| //A20150601 : For Integrating with W5300
 | ||||
| #define PACK_FIFOBYTE            0x02              ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR.
 | ||||
| //
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief Open a socket. | ||||
|  * @details Initializes the socket with 'sn' passed as parameter and open. | ||||
|  * | ||||
|  * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. | ||||
|  * @param port Port number to be bined. | ||||
|  * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n | ||||
|  *             Valid flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. | ||||
|  * @sa Sn_MR | ||||
|  * | ||||
|  * @return @b Success : The socket number @b 'sn' passed as parameter\n | ||||
|  *         @b Fail    :\n @ref SOCKERR_SOCKNUM     - Invalid socket number\n | ||||
|  *                        @ref SOCKERR_SOCKMODE    - Not support socket mode as TCP, UDP, and so on. \n | ||||
|  *                        @ref SOCKERR_SOCKFLAG    - Invaild socket flag. | ||||
|  */ | ||||
| int8_t  socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief Close a socket. | ||||
|  * @details It closes the socket  with @b'sn' passed as parameter. | ||||
|  * | ||||
|  * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * | ||||
|  * @return @b Success : @ref SOCK_OK \n | ||||
|  *         @b Fail    : @ref SOCKERR_SOCKNUM - Invalid socket number | ||||
|  */ | ||||
| int8_t  close(uint8_t sn); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief Listen to a connection request from a client. | ||||
|  * @details It is listening to a connection request from a client. | ||||
|  * If connection request is accepted successfully, the connection is established. Socket sn is used in passive(server) mode. | ||||
|  * | ||||
|  * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @return @b Success : @ref SOCK_OK \n | ||||
|  *         @b Fail    :\n @ref SOCKERR_SOCKINIT   - Socket is not initialized \n | ||||
|  *                        @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. | ||||
|  */ | ||||
| int8_t  listen(uint8_t sn); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief Try to connect a server. | ||||
|  * @details It requests connection to the server with destination IP address and port number passed as parameter.\n | ||||
|  * @note It is valid only in TCP client mode.  | ||||
|  *       In block io mode, it does not return until connection is completed. | ||||
|  *       In Non-block io mode, it return @ref SOCK_BUSY immediately. | ||||
|  * | ||||
|  * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. | ||||
|  * @param port Destination port number. | ||||
|  * | ||||
|  * @return @b Success : @ref SOCK_OK \n | ||||
|  * @b Fail    :\n @ref SOCKERR_SOCKNUM   - Invalid socket number\n | ||||
|  *                @ref SOCKERR_SOCKMODE  - Invalid socket mode\n | ||||
|  *                @ref SOCKERR_SOCKINIT  - Socket is not initialized\n | ||||
|  *                @ref SOCKERR_IPINVALID - Wrong server IP address\n | ||||
|  *                @ref SOCKERR_PORTZERO  - Server port zero\n | ||||
|  *                @ref SOCKERR_TIMEOUT   - Timeout occurred during request connection\n | ||||
|  *                @ref SOCK_BUSY         - In non-block io mode, it returned immediately\n | ||||
|  */ | ||||
| int8_t  connect(uint8_t sn, uint8_t * addr, uint16_t port); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief Try to disconnect a connection socket. | ||||
|  * @details It sends request message to disconnect the TCP socket 'sn' passed as parameter to the server or client. | ||||
|  * @note It is valid only in TCP server or client mode. \n | ||||
|  *       In block io mode, it does not return until disconnection is completed. \n | ||||
|  *       In Non-block io mode, it return @ref SOCK_BUSY immediately. \n | ||||
| 
 | ||||
|  * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @return @b Success :   @ref SOCK_OK \n | ||||
|  *         @b Fail    :\n @ref SOCKERR_SOCKNUM  - Invalid socket number \n | ||||
|  *                        @ref SOCKERR_SOCKMODE - Invalid operation in the socket \n | ||||
|  *                        @ref SOCKERR_TIMEOUT  - Timeout occurred \n | ||||
|  *                        @ref SOCK_BUSY        - Socket is busy. | ||||
|  */ | ||||
| int8_t  disconnect(uint8_t sn); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief	Send data to the connected peer in TCP socket. | ||||
|  * @details It is used to send outgoing data to the connected socket. | ||||
|  * @note    It is valid only in TCP server or client mode. It can't send data greater than socket buffer size. \n | ||||
|  *          In block io mode, It doesn't return until data send is completed - socket buffer size is greater than data. \n | ||||
|  *          In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. \n | ||||
|  * @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @param buf Pointer buffer containing data to be sent. | ||||
|  * @param len The byte length of data in buf. | ||||
|  * @return	@b Success : The sent data size \n | ||||
|  *          @b Fail    : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n | ||||
|  *                          @ref SOCKERR_TIMEOUT    - Timeout occurred \n | ||||
|  *                          @ref SOCKERR_SOCKMODE 	- Invalid operation in the socket \n | ||||
|  *                          @ref SOCKERR_SOCKNUM    - Invalid socket number \n | ||||
|  *                          @ref SOCKERR_DATALEN    - zero data length \n | ||||
|  *                          @ref SOCK_BUSY          - Socket is busy. | ||||
|  */ | ||||
| int32_t send(uint8_t sn, uint8_t * buf, uint16_t len); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief	Receive data from the connected peer. | ||||
|  * @details It is used to read incoming data from the connected socket.\n | ||||
|  *          It waits for data as much as the application wants to receive. | ||||
|  * @note    It is valid only in TCP server or client mode. It can't receive data greater than socket buffer size. \n | ||||
|  *          In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer. \n | ||||
|  *          In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer. \n | ||||
|  * | ||||
|  * @param sn  Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @param buf Pointer buffer to read incoming data. | ||||
|  * @param len The max data length of data in buf. | ||||
|  * @return	@b Success : The real received data size \n | ||||
|  *          @b Fail    :\n | ||||
|  *                     @ref SOCKERR_SOCKSTATUS - Invalid socket status for socket operation \n | ||||
|  *                     @ref SOCKERR_SOCKMODE   - Invalid operation in the socket \n | ||||
|  *                     @ref SOCKERR_SOCKNUM    - Invalid socket number \n | ||||
|  *                     @ref SOCKERR_DATALEN    - zero data length \n | ||||
|  *                     @ref SOCK_BUSY          - Socket is busy. | ||||
|  */ | ||||
| int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief	Sends datagram to the peer with destination IP address and port number passed as parameter. | ||||
|  * @details It sends datagram of UDP or MACRAW to the peer with destination IP address and port number passed as parameter.\n | ||||
|  *          Even if the connectionless socket has been previously connected to a specific address, | ||||
|  *          the address and port number parameters override the destination address for that particular datagram only. | ||||
|  * @note    In block io mode, It doesn't return until data send is completed - socket buffer size is greater than <I>len</I>. | ||||
|  *          In non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is not enough. | ||||
|  * | ||||
|  * @param sn    Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @param buf   Pointer buffer to send outgoing data. | ||||
|  * @param len   The byte length of data in buf. | ||||
|  * @param addr  Pointer variable of destination IP address. It should be allocated 4 bytes. | ||||
|  * @param port  Destination port number. | ||||
|  * | ||||
|  * @return @b Success : The sent data size \n | ||||
|  *         @b Fail    :\n @ref SOCKERR_SOCKNUM     - Invalid socket number \n | ||||
|  *                        @ref SOCKERR_SOCKMODE    - Invalid operation in the socket \n | ||||
|  *                        @ref SOCKERR_SOCKSTATUS  - Invalid socket status for socket operation \n | ||||
|  *                        @ref SOCKERR_DATALEN     - zero data length \n | ||||
|  *                        @ref SOCKERR_IPINVALID   - Wrong server IP address\n | ||||
|  *                        @ref SOCKERR_PORTZERO    - Server port zero\n | ||||
|  *                        @ref SOCKERR_SOCKCLOSED  - Socket unexpectedly closed \n | ||||
|  *                        @ref SOCKERR_TIMEOUT     - Timeout occurred \n | ||||
|  *                        @ref SOCK_BUSY           - Socket is busy.  | ||||
|  */ | ||||
| int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  * @brief Receive datagram of UDP or MACRAW | ||||
|  * @details This function is an application I/F function which is used to receive the data in other then TCP mode. \n | ||||
|  *          This function is used to receive UDP and MAC_RAW mode, and handle the header as well.  | ||||
|  *          This function can divide to received the packet data. | ||||
|  *          On the MACRAW SOCKET, the addr and port parameters are ignored. | ||||
|  * @note    In block io mode, it doesn't return until data reception is completed - data is filled as <I>len</I> in socket buffer | ||||
|  *          In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than data size in socket buffer. | ||||
|  * | ||||
|  * @param sn   Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>. | ||||
|  * @param buf  Pointer buffer to read incoming data. | ||||
|  * @param len  The max data length of data in buf.  | ||||
|  *             When the received packet size <= len, receives data as packet sized. | ||||
|  *             When others, receives data as len. | ||||
|  * @param addr Pointer variable of destination IP address. It should be allocated 4 bytes. | ||||
|  *             It is valid only when the first call recvfrom for receiving the packet. | ||||
|  *             When it is valid, @ref  packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). | ||||
|  * @param port Pointer variable of destination port number. | ||||
|  *             It is valid only when the first call recvform for receiving the packet. | ||||
| *             When it is valid, @ref  packinfo[7] should be set as '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). | ||||
|  * | ||||
|  * @return	@b Success : This function return real received data size for success.\n | ||||
|  *          @b Fail    : @ref SOCKERR_DATALEN    - zero data length \n | ||||
|  *                       @ref SOCKERR_SOCKMODE   - Invalid operation in the socket \n | ||||
|  *                       @ref SOCKERR_SOCKNUM    - Invalid socket number \n | ||||
|  *                       @ref SOCKBUSY           - Socket is busy. | ||||
|  */ | ||||
| int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); | ||||
| 
 | ||||
| 
 | ||||
| /////////////////////////////
 | ||||
| // SOCKET CONTROL & OPTION //
 | ||||
| /////////////////////////////
 | ||||
| #define SOCK_IO_BLOCK         0  ///< Socket Block IO Mode in @ref setsockopt().
 | ||||
| #define SOCK_IO_NONBLOCK      1  ///< Socket Non-block IO Mode in @ref setsockopt().
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @defgroup DATA_TYPE DATA TYPE | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  * @brief The kind of Socket Interrupt. | ||||
|  * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|    SIK_CONNECTED     = (1 << 0),    ///< connected
 | ||||
|    SIK_DISCONNECTED  = (1 << 1),    ///< disconnected
 | ||||
|    SIK_RECEIVED      = (1 << 2),    ///< data received
 | ||||
|    SIK_TIMEOUT       = (1 << 3),    ///< timeout occurred
 | ||||
|    SIK_SENT          = (1 << 4),    ///< send ok
 | ||||
|    //M20150410 : Remove the comma of last member
 | ||||
|    //SIK_ALL           = 0x1F,        ///< all interrupt
 | ||||
|    SIK_ALL           = 0x1F         ///< all interrupt
 | ||||
| }sockint_kind; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  * @brief The type of @ref ctlsocket(). | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|    CS_SET_IOMODE,          ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref SOCK_IO_NONBLOCK
 | ||||
|    CS_GET_IOMODE,          ///< get socket IO mode
 | ||||
|    CS_GET_MAXTXBUF,        ///< get the size of socket buffer allocated in TX memory
 | ||||
|    CS_GET_MAXRXBUF,        ///< get the size of socket buffer allocated in RX memory
 | ||||
|    CS_CLR_INTERRUPT,       ///< clear the interrupt of socket with @ref sockint_kind
 | ||||
|    CS_GET_INTERRUPT,       ///< get the socket interrupt. refer to @ref sockint_kind
 | ||||
| #if _WIZCHIP_ > 5100 | ||||
|    CS_SET_INTMASK,         ///< set the interrupt mask of socket with @ref sockint_kind, Not supported in W5100
 | ||||
|    CS_GET_INTMASK          ///< get the masked interrupt of socket. refer to @ref sockint_kind, Not supported in W5100
 | ||||
| #endif | ||||
| }ctlsock_type; | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() | ||||
|  */  | ||||
| typedef enum | ||||
| { | ||||
|    SO_FLAG,           ///< Valid only in getsockopt(), For set flag of socket refer to <I>flag</I> in @ref socket().
 | ||||
|    SO_TTL,              ///< Set TTL. @ref Sn_TTL  ( @ref setSn_TTL(), @ref getSn_TTL() )
 | ||||
|    SO_TOS,              ///< Set TOS. @ref Sn_TOS  ( @ref setSn_TOS(), @ref getSn_TOS() )
 | ||||
|    SO_MSS,              ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() )
 | ||||
|    SO_DESTIP,           ///< Set the destination IP address. @ref Sn_DIPR ( @ref setSn_DIPR(), @ref getSn_DIPR() )
 | ||||
|    SO_DESTPORT,         ///< Set the destination Port number. @ref Sn_DPORT ( @ref setSn_DPORT(), @ref getSn_DPORT() )
 | ||||
| #if _WIZCHIP_ != 5100    | ||||
|    SO_KEEPALIVESEND,    ///< Valid only in setsockopt. Manually send keep-alive packet in TCP mode, Not supported in W5100
 | ||||
|    #if _WIZCHIP_ > 5200    | ||||
|       SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP mode, Not supported in W5100, W5200
 | ||||
|    #endif       | ||||
| #endif | ||||
|    SO_SENDBUF,          ///< Valid only in getsockopt. Get the free data size of Socekt TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR()
 | ||||
|    SO_RECVBUF,          ///< Valid only in getsockopt. Get the received data size in socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR()
 | ||||
|    SO_STATUS,           ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, @ref getSn_SR()
 | ||||
|    SO_REMAINSIZE,       ///< Valid only in getsockopt. Get the remained packet size in other then TCP mode.
 | ||||
|    SO_PACKINFO          ///< Valid only in getsockopt. Get the packet information as @ref PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in other then TCP mode.
 | ||||
| }sockopt_type; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  *  @brief Control socket. | ||||
|  *  @details Control IO mode, Interrupt & Mask of socket and get the socket buffer information. | ||||
|  *           Refer to @ref ctlsock_type. | ||||
|  *  @param sn socket number | ||||
|  *  @param cstype type of control socket. refer to @ref ctlsock_type. | ||||
|  *  @param arg Data type and value is determined according to @ref ctlsock_type. \n | ||||
|  *             <table> | ||||
|  *                  <tr> <td> @b cstype </td> <td> @b data type</td><td>@b value</td></tr> | ||||
|  *                  <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td> uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr> | ||||
|  *                  <tr> <td> @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0 ~ 16K </td></tr> | ||||
|  *                  <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind </td><td> @ref SIK_CONNECTED, etc.  </td></tr>  | ||||
|  *             </table> | ||||
|  *  @return @b Success @ref SOCK_OK \n | ||||
|  *          @b fail    @ref SOCKERR_ARG         - Invalid argument\n | ||||
|  */ | ||||
| int8_t  ctlsocket(uint8_t sn, ctlsock_type cstype, void* arg); | ||||
| 
 | ||||
| /** 
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  *  @brief set socket options | ||||
|  *  @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref sockopt_type. | ||||
|  *                | ||||
|  *  @param sn socket number | ||||
|  *  @param sotype socket option type. refer to @ref sockopt_type | ||||
|  *  @param arg Data type and value is determined according to <I>sotype</I>. \n | ||||
|  *             <table> | ||||
|  *                  <tr> <td> @b sotype </td> <td> @b data type</td><td>@b value</td></tr>  | ||||
|  *                  <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> | ||||
|  *                  <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> | ||||
|  *                  <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr> | ||||
|  *                  <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td>  </td></tr>  | ||||
|  *                  <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>  | ||||
|  *                  <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td> null </td></tr>  | ||||
|  *                  <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>  | ||||
|  *             </table> | ||||
|  * @return  | ||||
|  * - @b Success : @ref SOCK_OK \n | ||||
|  * - @b Fail  | ||||
|  *  - @ref SOCKERR_SOCKNUM     - Invalid Socket number \n | ||||
|  *  - @ref SOCKERR_SOCKMODE    - Invalid socket mode \n | ||||
|  *  - @ref SOCKERR_SOCKOPT     - Invalid socket option or its value \n | ||||
|  *  - @ref SOCKERR_TIMEOUT     - Timeout occurred when sending keep-alive packet \n | ||||
|  */ | ||||
| int8_t  setsockopt(uint8_t sn, sockopt_type sotype, void* arg); | ||||
| 
 | ||||
| /** 
 | ||||
|  * @ingroup WIZnet_socket_APIs | ||||
|  *  @brief get socket options | ||||
|  *  @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref sockopt_type | ||||
|  *  @param sn socket number | ||||
|  *  @param sotype socket option type. refer to @ref sockopt_type | ||||
|  *  @param arg Data type and value is determined according to <I>sotype</I>. \n | ||||
|  *             <table> | ||||
|  *                  <tr> <td> @b sotype </td> <td>@b data type</td><td>@b value</td></tr> | ||||
|  *                  <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref SF_ETHER_OWN, etc... </td> </tr> | ||||
|  *                  <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td> </tr> | ||||
|  *                  <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td> </tr> | ||||
|  *                  <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td>  </td></tr>  | ||||
|  *                  <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td>  </td></tr>  | ||||
|  *                  <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td> 0 ~ 255 </td></tr>  | ||||
|  *                  <tr> <td> @ref SO_SENDBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>   | ||||
|  *                  <tr> <td> @ref SO_RECVBUF </td> <td> uint16_t </td><td> 0 ~ 65535 </td></tr>   | ||||
|  *                  <tr> <td> @ref SO_STATUS </td> <td> uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr>   | ||||
|  *                  <tr> <td> @ref SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr> | ||||
|  *                  <tr> <td> @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc... </td></tr> | ||||
|  *             </table> | ||||
|  * @return  | ||||
|  * - @b Success : @ref SOCK_OK \n | ||||
|  * - @b Fail  | ||||
|  *  - @ref SOCKERR_SOCKNUM     - Invalid Socket number \n | ||||
|  *  - @ref SOCKERR_SOCKOPT     - Invalid socket option or its value \n | ||||
|  *  - @ref SOCKERR_SOCKMODE    - Invalid socket mode \n | ||||
|  * @note | ||||
|  *   The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode and after call @ref recvfrom(). \n | ||||
|  *   When SO_PACKINFO value is PACK_FIRST and the return value of recvfrom() is zero,  | ||||
|  *   This means the zero byte UDP data(UDP Header only) received. | ||||
|   */ | ||||
| int8_t  getsockopt(uint8_t sn, sockopt_type sotype, void* arg); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
| #endif | ||||
| 
 | ||||
| #endif   // _SOCKET_H_
 | ||||
| @ -0,0 +1,903 @@ | ||||
| //****************************************************************************/ 
 | ||||
| //!
 | ||||
| //! \file wizchip_conf.c
 | ||||
| //! \brief WIZCHIP Config Header File.
 | ||||
| //! \version 1.0.1
 | ||||
| //! \date 2013/10/21
 | ||||
| //! \par  Revision history
 | ||||
| //!       <2015/02/05> Notice
 | ||||
| //!        The version history is not updated after this point.
 | ||||
| //!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
 | ||||
| //!        >> https://github.com/Wiznet/ioLibrary_Driver
 | ||||
| //!       <2014/05/01> V1.0.1  Refer to M20140501
 | ||||
| //!        1. Explicit type casting in wizchip_bus_readdata() & wizchip_bus_writedata()
 | ||||
| //            Issued by Mathias ClauBen.
 | ||||
| //!           uint32_t type converts into ptrdiff_t first. And then recoverting it into uint8_t*
 | ||||
| //!           For remove the warning when pointer type size is not 32bit.
 | ||||
| //!           If ptrdiff_t doesn't support in your complier, You should must replace ptrdiff_t into your suitable pointer type.
 | ||||
| //!       <2013/10/21> 1st Release
 | ||||
| //! \author MidnightCow
 | ||||
| //! \copyright
 | ||||
| //!
 | ||||
| //! Copyright (c)  2013, WIZnet Co., LTD.
 | ||||
| //! All rights reserved.
 | ||||
| //! 
 | ||||
| //! Redistribution and use in source and binary forms, with or without 
 | ||||
| //! modification, are permitted provided that the following conditions 
 | ||||
| //! are met: 
 | ||||
| //! 
 | ||||
| //!     * Redistributions of source code must retain the above copyright 
 | ||||
| //! notice, this list of conditions and the following disclaimer. 
 | ||||
| //!     * Redistributions in binary form must reproduce the above copyright
 | ||||
| //! notice, this list of conditions and the following disclaimer in the
 | ||||
| //! documentation and/or other materials provided with the distribution. 
 | ||||
| //!     * Neither the name of the <ORGANIZATION> nor the names of its 
 | ||||
| //! contributors may be used to endorse or promote products derived 
 | ||||
| //! from this software without specific prior written permission. 
 | ||||
| //! 
 | ||||
| //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | ||||
| //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | ||||
| //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | ||||
| //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 | ||||
| //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 | ||||
| //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 | ||||
| //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | ||||
| //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 | ||||
| //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 | ||||
| //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 | ||||
| //! THE POSSIBILITY OF SUCH DAMAGE.
 | ||||
| //
 | ||||
| //*****************************************************************************/
 | ||||
| //A20140501 : for use the type - ptrdiff_t
 | ||||
| #include <stddef.h> | ||||
| //
 | ||||
| 
 | ||||
| #include "wizchip_conf.h" | ||||
| 
 | ||||
| /////////////
 | ||||
| //M20150401 : Remove ; in the default callback function such as wizchip_cris_enter(), wizchip_cs_select() and etc.
 | ||||
| /////////////
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to enable interrupt. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	  wizchip_cris_enter(void)           {};
 | ||||
| void 	  wizchip_cris_enter(void)           {} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to disable interrupt. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	  wizchip_cris_exit(void)          {};
 | ||||
| void 	  wizchip_cris_exit(void)          {} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to select chip. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	wizchip_cs_select(void)            {};
 | ||||
| void 	wizchip_cs_select(void)            {} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to deselect chip. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	wizchip_cs_deselect(void)          {};
 | ||||
| void 	wizchip_cs_deselect(void)          {} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to read in direct or indirect interface. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
|  //M20150601 : Rename the function for integrating with W5300
 | ||||
| //uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t *)((ptrdiff_t) AddrSel)); }
 | ||||
| iodata_t wizchip_bus_readdata(uint32_t AddrSel) { return * ((volatile iodata_t *)((ptrdiff_t) AddrSel)); } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to write in direct or indirect interface. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //M20150601 : Rename the function for integrating with W5300
 | ||||
| //void 	wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb)  { *((volatile uint8_t*)((ptrdiff_t)AddrSel)) = wb; }
 | ||||
| void 	wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb)  { *((volatile iodata_t*)((ptrdiff_t)AddrSel)) = wb; } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to read in SPI interface. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //uint8_t wizchip_spi_readbyte(void)        {return 0;};
 | ||||
| uint8_t wizchip_spi_readbyte(void)        {return 0;} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to write in SPI interface. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	wizchip_spi_writebyte(uint8_t wb) {};
 | ||||
| void 	wizchip_spi_writebyte(uint8_t wb) {} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to burst read in SPI interface. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) 	{}; 
 | ||||
| void 	wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) 	{} | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Default function to burst write in SPI interface. | ||||
|  * @note This function help not to access wrong address. If you do not describe this function or register any functions, | ||||
|  * null function is called. | ||||
|  */ | ||||
| //void 	wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {};
 | ||||
| void 	wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {} | ||||
| 
 | ||||
| /**
 | ||||
|  * @\ref _WIZCHIP instance | ||||
|  */ | ||||
| //
 | ||||
| //M20150401 : For a compiler didnot support a member of structure
 | ||||
| //            Replace the assignment of struct members with the assingment of array
 | ||||
| //
 | ||||
| /*
 | ||||
| _WIZCHIP  WIZCHIP = | ||||
|       { | ||||
|       .id                  = _WIZCHIP_ID_, | ||||
|       .if_mode             = _WIZCHIP_IO_MODE_, | ||||
|       .CRIS._enter         = wizchip_cris_enter, | ||||
|       .CRIS._exit          = wizchip_cris_exit, | ||||
|       .CS._select          = wizchip_cs_select, | ||||
|       .CS._deselect        = wizchip_cs_deselect, | ||||
|       .IF.BUS._read_byte   = wizchip_bus_readbyte, | ||||
|       .IF.BUS._write_byte  = wizchip_bus_writebyte | ||||
| //    .IF.SPI._read_byte   = wizchip_spi_readbyte,
 | ||||
| //    .IF.SPI._write_byte  = wizchip_spi_writebyte
 | ||||
|       }; | ||||
| */       | ||||
| _WIZCHIP  WIZCHIP = | ||||
| { | ||||
|     _WIZCHIP_IO_MODE_, | ||||
|     _WIZCHIP_ID_ , | ||||
|     { | ||||
|         wizchip_cris_enter, | ||||
|         wizchip_cris_exit | ||||
|     }, | ||||
|     { | ||||
|         wizchip_cs_select, | ||||
|         wizchip_cs_deselect | ||||
|     }, | ||||
|     { | ||||
|         { | ||||
|             //M20150601 : Rename the function 
 | ||||
|             //wizchip_bus_readbyte,
 | ||||
|             //wizchip_bus_writebyte
 | ||||
|             wizchip_bus_readdata, | ||||
|             wizchip_bus_writedata | ||||
|         }, | ||||
| 
 | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| static uint8_t    _DNS_[4];      // DNS server ip address
 | ||||
| static dhcp_mode  _DHCP_;        // DHCP mode
 | ||||
| 
 | ||||
| void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)) | ||||
| { | ||||
|    if(!cris_en || !cris_ex) | ||||
|    { | ||||
|       WIZCHIP.CRIS._enter = wizchip_cris_enter; | ||||
|       WIZCHIP.CRIS._exit  = wizchip_cris_exit; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       WIZCHIP.CRIS._enter = cris_en; | ||||
|       WIZCHIP.CRIS._exit  = cris_ex; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)) | ||||
| { | ||||
|    if(!cs_sel || !cs_desel) | ||||
|    { | ||||
|       WIZCHIP.CS._select   = wizchip_cs_select; | ||||
|       WIZCHIP.CS._deselect = wizchip_cs_deselect; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       WIZCHIP.CS._select   = cs_sel; | ||||
|       WIZCHIP.CS._deselect = cs_desel; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| //M20150515 : For integrating with W5300
 | ||||
| //void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb))
 | ||||
| void reg_wizchip_bus_cbfunc(iodata_t(*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb)) | ||||
| { | ||||
|    while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)); | ||||
|    //M20150601 : Rename call back function for integrating with W5300
 | ||||
|    /*
 | ||||
|    if(!bus_rb || !bus_wb) | ||||
|    { | ||||
|       WIZCHIP.IF.BUS._read_byte   = wizchip_bus_readbyte; | ||||
|       WIZCHIP.IF.BUS._write_byte  = wizchip_bus_writebyte; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       WIZCHIP.IF.BUS._read_byte   = bus_rb; | ||||
|       WIZCHIP.IF.BUS._write_byte  = bus_wb; | ||||
|    } | ||||
|    */ | ||||
|    if(!bus_rb || !bus_wb) | ||||
|    { | ||||
|       WIZCHIP.IF.BUS._read_data   = wizchip_bus_readdata; | ||||
|       WIZCHIP.IF.BUS._write_data  = wizchip_bus_writedata; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       WIZCHIP.IF.BUS._read_data   = bus_rb; | ||||
|       WIZCHIP.IF.BUS._write_data  = bus_wb; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)) | ||||
| { | ||||
|    while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); | ||||
|     | ||||
|    if(!spi_rb || !spi_wb) | ||||
|    { | ||||
|       WIZCHIP.IF.SPI._read_byte   = wizchip_spi_readbyte; | ||||
|       WIZCHIP.IF.SPI._write_byte  = wizchip_spi_writebyte; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       WIZCHIP.IF.SPI._read_byte   = spi_rb; | ||||
|       WIZCHIP.IF.SPI._write_byte  = spi_wb; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| // 20140626 Eric Added for SPI burst operations
 | ||||
| void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len)) | ||||
| { | ||||
|    while(!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)); | ||||
| 
 | ||||
|    if(!spi_rb || !spi_wb) | ||||
|    { | ||||
|       WIZCHIP.IF.SPI._read_burst   = wizchip_spi_readburst; | ||||
|       WIZCHIP.IF.SPI._write_burst  = wizchip_spi_writeburst; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       WIZCHIP.IF.SPI._read_burst   = spi_rb; | ||||
|       WIZCHIP.IF.SPI._write_burst  = spi_wb; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg) | ||||
| { | ||||
| #if	_WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 | ||||
|    uint8_t tmp = 0; | ||||
| #endif | ||||
|    uint8_t* ptmp[2] = {0,0}; | ||||
|    switch(cwtype) | ||||
|    { | ||||
|       case CW_RESET_WIZCHIP: | ||||
|          wizchip_sw_reset(); | ||||
|          break; | ||||
|       case CW_INIT_WIZCHIP: | ||||
|          if(arg != 0)  | ||||
|          { | ||||
|             ptmp[0] = (uint8_t*)arg; | ||||
|             ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; | ||||
|          } | ||||
|          return wizchip_init(ptmp[0], ptmp[1]); | ||||
|       case CW_CLR_INTERRUPT: | ||||
|          wizchip_clrinterrupt(*((intr_kind*)arg)); | ||||
|          break; | ||||
|       case CW_GET_INTERRUPT: | ||||
|         *((intr_kind*)arg) = wizchip_getinterrupt(); | ||||
|          break; | ||||
|       case CW_SET_INTRMASK: | ||||
|          wizchip_setinterruptmask(*((intr_kind*)arg)); | ||||
|          break;          | ||||
|       case CW_GET_INTRMASK: | ||||
|          *((intr_kind*)arg) = wizchip_getinterruptmask(); | ||||
|          break; | ||||
|    //M20150601 : This can be supported by W5200, W5500
 | ||||
|    //#if _WIZCHIP_ > W5100
 | ||||
|    #if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) | ||||
|       case CW_SET_INTRTIME: | ||||
|          setINTLEVEL(*(uint16_t*)arg); | ||||
|          break; | ||||
|       case CW_GET_INTRTIME: | ||||
|          *(uint16_t*)arg = getINTLEVEL(); | ||||
|          break; | ||||
|    #endif | ||||
|       case CW_GET_ID: | ||||
|          ((uint8_t*)arg)[0] = WIZCHIP.id[0]; | ||||
|          ((uint8_t*)arg)[1] = WIZCHIP.id[1]; | ||||
|          ((uint8_t*)arg)[2] = WIZCHIP.id[2]; | ||||
|          ((uint8_t*)arg)[3] = WIZCHIP.id[3]; | ||||
|          ((uint8_t*)arg)[4] = WIZCHIP.id[4]; | ||||
|          ((uint8_t*)arg)[5] = 0; | ||||
|          break; | ||||
|    #if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 | ||||
|       case CW_RESET_PHY: | ||||
|          wizphy_reset(); | ||||
|          break; | ||||
|       case CW_SET_PHYCONF: | ||||
|          wizphy_setphyconf((wiz_PhyConf*)arg); | ||||
|          break; | ||||
|       case CW_GET_PHYCONF: | ||||
|          wizphy_getphyconf((wiz_PhyConf*)arg); | ||||
|          break; | ||||
|       case CW_GET_PHYSTATUS: | ||||
|          break; | ||||
|       case CW_SET_PHYPOWMODE: | ||||
|          return wizphy_setphypmode(*(uint8_t*)arg); | ||||
|    #endif | ||||
|    #if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 | ||||
|       case CW_GET_PHYPOWMODE: | ||||
|          tmp = wizphy_getphypmode(); | ||||
|          if((int8_t)tmp == -1) return -1; | ||||
|          *(uint8_t*)arg = tmp; | ||||
|          break; | ||||
|       case CW_GET_PHYLINK: | ||||
|          tmp = wizphy_getphylink(); | ||||
|          if((int8_t)tmp == -1) return -1; | ||||
|          *(uint8_t*)arg = tmp; | ||||
|          break; | ||||
|    #endif       | ||||
|       default: | ||||
|          return -1; | ||||
|    } | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int8_t ctlnetwork(ctlnetwork_type cntype, void* arg) | ||||
| { | ||||
|     | ||||
|    switch(cntype) | ||||
|    { | ||||
|       case CN_SET_NETINFO: | ||||
|          wizchip_setnetinfo((wiz_NetInfo*)arg); | ||||
|          break; | ||||
|       case CN_GET_NETINFO: | ||||
|          wizchip_getnetinfo((wiz_NetInfo*)arg); | ||||
|          break; | ||||
|       case CN_SET_NETMODE: | ||||
|          return wizchip_setnetmode(*(netmode_type*)arg); | ||||
|       case CN_GET_NETMODE: | ||||
|          *(netmode_type*)arg = wizchip_getnetmode(); | ||||
|          break; | ||||
|       case CN_SET_TIMEOUT: | ||||
|          wizchip_settimeout((wiz_NetTimeout*)arg); | ||||
|          break; | ||||
|       case CN_GET_TIMEOUT: | ||||
|          wizchip_gettimeout((wiz_NetTimeout*)arg); | ||||
|          break; | ||||
|       default: | ||||
|          return -1; | ||||
|    } | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
| void wizchip_sw_reset(void) | ||||
| { | ||||
|    uint8_t gw[4], sn[4], sip[4]; | ||||
|    uint8_t mac[6]; | ||||
| //A20150601
 | ||||
| #if _WIZCHIP_IO_MODE_  == _WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
|    uint16_t mr = (uint16_t)getMR(); | ||||
|    setMR(mr | MR_IND); | ||||
| #endif | ||||
| //
 | ||||
|    getSHAR(mac); | ||||
|    getGAR(gw);  getSUBR(sn);  getSIPR(sip); | ||||
|    setMR(MR_RST); | ||||
|    getMR(); // for delay
 | ||||
| //A2015051 : For indirect bus mode 
 | ||||
| #if _WIZCHIP_IO_MODE_  == _WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
|    setMR(mr | MR_IND); | ||||
| #endif | ||||
| //
 | ||||
|    setSHAR(mac); | ||||
|    setGAR(gw); | ||||
|    setSUBR(sn); | ||||
|    setSIPR(sip); | ||||
| } | ||||
| 
 | ||||
| int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize) | ||||
| { | ||||
|    int8_t i; | ||||
| #if _WIZCHIP_ < W5200 | ||||
|    int8_t j; | ||||
| #endif | ||||
|    int8_t tmp = 0; | ||||
|    wizchip_sw_reset(); | ||||
|    if(txsize) | ||||
|    { | ||||
|       tmp = 0; | ||||
|    //M20150601 : For integrating with W5300
 | ||||
|    #if _WIZCHIP_ == W5300 | ||||
| 		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) | ||||
| 		{ | ||||
| 			if(txsize[i] >= 64) return -1;   //No use 64KB even if W5300 support max 64KB memory allocation
 | ||||
| 			tmp += txsize[i]; | ||||
| 			if(tmp > 128) return -1; | ||||
| 		} | ||||
| 		if(tmp % 8) return -1; | ||||
|    #else | ||||
| 		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) | ||||
| 		{ | ||||
| 			tmp += txsize[i]; | ||||
| 
 | ||||
| 		#if _WIZCHIP_ < W5200	//2016.10.28 peter add condition for w5100 and w5100s
 | ||||
| 			if(tmp > 8) return -1; | ||||
| 		#else | ||||
| 			if(tmp > 16) return -1; | ||||
| 		#endif | ||||
| 		} | ||||
| 		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) | ||||
| 		{ | ||||
| 		#if _WIZCHIP_ < W5200	//2016.10.28 peter add condition for w5100
 | ||||
| 			j = 0; | ||||
| 			while((txsize[i] >> j != 1)&&(txsize[i] !=0)){j++;} | ||||
| 			setSn_TXBUF_SIZE(i, j); | ||||
| 		#else | ||||
| 			setSn_TXBUF_SIZE(i, txsize[i]); | ||||
| 		#endif | ||||
| 		} | ||||
| 
 | ||||
| 	#endif | ||||
|    } | ||||
| 
 | ||||
|    if(rxsize) | ||||
|    { | ||||
|       tmp = 0; | ||||
|    #if _WIZCHIP_ == W5300 | ||||
|       for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) | ||||
| 		{ | ||||
| 			if(rxsize[i] >= 64) return -1;   //No use 64KB even if W5300 support max 64KB memory allocation
 | ||||
| 			tmp += rxsize[i]; | ||||
| 			if(tmp > 128) return -1; | ||||
| 		} | ||||
| 		if(tmp % 8) return -1; | ||||
|    #else | ||||
| 		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) | ||||
| 		{ | ||||
| 			tmp += rxsize[i]; | ||||
| 		#if _WIZCHIP_ < W5200	//2016.10.28 peter add condition for w5100 and w5100s
 | ||||
| 			if(tmp > 8) return -1; | ||||
| 		#else | ||||
| 			if(tmp > 16) return -1; | ||||
| 		#endif | ||||
| 		} | ||||
| 
 | ||||
| 		for(i = 0 ; i < _WIZCHIP_SOCK_NUM_; i++) | ||||
| 		{ | ||||
| 		#if _WIZCHIP_ < W5200	// add condition for w5100
 | ||||
| 			j = 0; | ||||
| 			while((rxsize[i] >> j != 1)&&(txsize[i] !=0)){j++;} | ||||
| 			setSn_RXBUF_SIZE(i, j); | ||||
| 		#else | ||||
| 			setSn_RXBUF_SIZE(i, rxsize[i]); | ||||
| 		#endif | ||||
| 		} | ||||
| 	#endif | ||||
|    } | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
| void wizchip_clrinterrupt(intr_kind intr) | ||||
| { | ||||
|    uint8_t ir  = (uint8_t)intr; | ||||
|    uint8_t sir = (uint8_t)((uint16_t)intr >> 8); | ||||
| #if _WIZCHIP_ < W5500 | ||||
|    ir |= (1<<4); // IK_WOL
 | ||||
| #endif | ||||
| #if _WIZCHIP_ == W5200 | ||||
|    ir |= (1 << 6); | ||||
| #endif | ||||
|     | ||||
| #if _WIZCHIP_ < W5200 | ||||
|    sir &= 0x0F; | ||||
| #endif | ||||
| 
 | ||||
| #if _WIZCHIP_ <= W5100S | ||||
|    ir |= sir; | ||||
|    setIR(ir); | ||||
| //A20150601 : For integrating with W5300
 | ||||
| #elif _WIZCHIP_ == W5300 | ||||
|    setIR( ((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF)) ); | ||||
| #else | ||||
|    setIR(ir); | ||||
|    setSIR(sir); | ||||
| #endif    | ||||
| } | ||||
| 
 | ||||
| intr_kind wizchip_getinterrupt(void) | ||||
| { | ||||
|    uint8_t ir  = 0; | ||||
|    uint8_t sir = 0; | ||||
|    uint16_t ret = 0; | ||||
| #if _WIZCHIP_ <= W5100S | ||||
|    ir = getIR(); | ||||
|    sir = ir & 0x0F; | ||||
| //A20150601 : For integrating with W5300
 | ||||
| #elif _WIZCHIP_  == W5300 | ||||
|    ret = getIR(); | ||||
|    ir = (uint8_t)(ret >> 8); | ||||
|    sir = (uint8_t)ret; | ||||
| #else | ||||
|    ir  = getIR(); | ||||
|    sir = getSIR(); | ||||
| #endif          | ||||
| 
 | ||||
| //M20150601 : For Integrating with W5300
 | ||||
| //#if _WIZCHIP_ < W5500
 | ||||
| #if _WIZCHIP_ < W5200 | ||||
|    ir &= ~(1<<4); // IK_WOL
 | ||||
| #endif | ||||
| #if _WIZCHIP_ == W5200 | ||||
|    ir &= ~(1 << 6); | ||||
| #endif | ||||
|   ret = sir; | ||||
|   ret = (ret << 8) + ir; | ||||
|   return (intr_kind)ret; | ||||
| } | ||||
| 
 | ||||
| void wizchip_setinterruptmask(intr_kind intr) | ||||
| { | ||||
|    uint8_t imr  = (uint8_t)intr; | ||||
|    uint8_t simr = (uint8_t)((uint16_t)intr >> 8); | ||||
| #if _WIZCHIP_ < W5500 | ||||
|    imr &= ~(1<<4); // IK_WOL
 | ||||
| #endif | ||||
| #if _WIZCHIP_ == W5200 | ||||
|    imr &= ~(1 << 6); | ||||
| #endif | ||||
|     | ||||
| #if _WIZCHIP_ < W5200 | ||||
|    simr &= 0x0F; | ||||
|    imr |= simr; | ||||
|    setIMR(imr); | ||||
| //A20150601 : For integrating with W5300
 | ||||
| #elif _WIZCHIP_ == W5300 | ||||
|    setIMR( ((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF)) ); | ||||
| #else | ||||
|    setIMR(imr); | ||||
|    setSIMR(simr); | ||||
| #endif    | ||||
| } | ||||
| 
 | ||||
| intr_kind wizchip_getinterruptmask(void) | ||||
| { | ||||
|    uint8_t imr  = 0; | ||||
|    uint8_t simr = 0; | ||||
|    uint16_t ret = 0; | ||||
| #if _WIZCHIP_ < W5200 | ||||
|    imr  = getIMR(); | ||||
|    simr = imr & 0x0F; | ||||
| //A20150601 : For integrating with W5300
 | ||||
| #elif _WIZCHIP_ == W5300 | ||||
|    ret = getIMR(); | ||||
|    imr = (uint8_t)(ret >> 8); | ||||
|    simr = (uint8_t)ret; | ||||
| #else | ||||
|    imr  = getIMR(); | ||||
|    simr = getSIMR(); | ||||
| #endif          | ||||
| 
 | ||||
| #if _WIZCHIP_ < W5500 | ||||
|    imr &= ~(1<<4); // IK_WOL
 | ||||
| #endif | ||||
| #if _WIZCHIP_ == W5200 | ||||
|    imr &= ~(1 << 6);  // IK_DEST_UNREACH
 | ||||
| #endif | ||||
|   ret = simr; | ||||
|   ret = (ret << 8) + imr; | ||||
|   return (intr_kind)ret; | ||||
| } | ||||
| 
 | ||||
| int8_t wizphy_getphylink(void) | ||||
| { | ||||
|    int8_t tmp = PHY_LINK_OFF; | ||||
| #if _WIZCHIP_ == W5100S | ||||
|    if(getPHYSR() & PHYSR_LNK) | ||||
| 	   tmp = PHY_LINK_ON; | ||||
| #elif   _WIZCHIP_ == W5200 | ||||
|    if(getPHYSTATUS() & PHYSTATUS_LINK) | ||||
|       tmp = PHY_LINK_ON; | ||||
| #elif _WIZCHIP_ == W5500 | ||||
|    if(getPHYCFGR() & PHYCFGR_LNK_ON) | ||||
|       tmp = PHY_LINK_ON; | ||||
| 
 | ||||
| #else | ||||
|    tmp = -1; | ||||
| #endif | ||||
|    return tmp; | ||||
| } | ||||
| 
 | ||||
| #if _WIZCHIP_ > W5100 | ||||
| 
 | ||||
| int8_t wizphy_getphypmode(void) | ||||
| { | ||||
|    int8_t tmp = 0; | ||||
|    #if   _WIZCHIP_ == W5200 | ||||
|       if(getPHYSTATUS() & PHYSTATUS_POWERDOWN) | ||||
|          tmp = PHY_POWER_DOWN; | ||||
|       else           | ||||
|          tmp = PHY_POWER_NORM; | ||||
|    #elif _WIZCHIP_ == 5500 | ||||
|       if((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) | ||||
|          tmp = PHY_POWER_DOWN; | ||||
|       else  | ||||
|          tmp = PHY_POWER_NORM; | ||||
|    #else | ||||
|       tmp = -1; | ||||
|    #endif | ||||
|    return tmp; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if _WIZCHIP_ == W5100S | ||||
| void wizphy_reset(void) | ||||
| { | ||||
| 	uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); | ||||
| 	tmp |= BMCR_RESET; | ||||
| 	wiz_mdio_write(PHYMDIO_BMCR, tmp); | ||||
| 	while(wiz_mdio_read(PHYMDIO_BMCR)&BMCR_RESET){} | ||||
| } | ||||
| 
 | ||||
| void wizphy_setphyconf(wiz_PhyConf* phyconf) | ||||
| { | ||||
|    uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); | ||||
|    if(phyconf->mode == PHY_MODE_AUTONEGO) | ||||
|       tmp |= BMCR_AUTONEGO; | ||||
|    else | ||||
|    { | ||||
| 	  tmp &= ~BMCR_AUTONEGO; | ||||
|       if(phyconf->duplex == PHY_DUPLEX_FULL) | ||||
|       { | ||||
|     	  tmp |= BMCR_DUP; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|     	  tmp &= ~BMCR_DUP; | ||||
|       } | ||||
|       if(phyconf->speed == PHY_SPEED_100) | ||||
|       { | ||||
|     	  tmp |= BMCR_SPEED; | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|     	  tmp &= ~BMCR_SPEED; | ||||
|       } | ||||
|    } | ||||
|    wiz_mdio_write(PHYMDIO_BMCR, tmp); | ||||
| } | ||||
| 
 | ||||
| void wizphy_getphyconf(wiz_PhyConf* phyconf) | ||||
| { | ||||
|    uint16_t tmp = 0; | ||||
|    tmp = wiz_mdio_read(PHYMDIO_BMCR); | ||||
|    phyconf->by   = PHY_CONFBY_SW; | ||||
|    if(tmp & BMCR_AUTONEGO) | ||||
|    { | ||||
| 	   phyconf->mode = PHY_MODE_AUTONEGO; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
| 	   phyconf->mode = PHY_MODE_MANUAL; | ||||
| 	   if(tmp&BMCR_DUP) phyconf->duplex = PHY_DUPLEX_FULL; | ||||
| 	   else phyconf->duplex = PHY_DUPLEX_HALF; | ||||
| 	   if(tmp&BMCR_SPEED) phyconf->speed = PHY_SPEED_100; | ||||
| 	   else phyconf->speed = PHY_SPEED_10; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| int8_t wizphy_setphypmode(uint8_t pmode) | ||||
| { | ||||
|    uint16_t tmp = 0; | ||||
|    tmp = wiz_mdio_read(PHYMDIO_BMCR); | ||||
|    if( pmode == PHY_POWER_DOWN) | ||||
|    { | ||||
|       tmp |= BMCR_PWDN; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
| 	   tmp &= ~BMCR_PWDN; | ||||
|    } | ||||
|    wiz_mdio_write(PHYMDIO_BMCR, tmp); | ||||
|    tmp = wiz_mdio_read(PHYMDIO_BMCR); | ||||
|    if( pmode == PHY_POWER_DOWN) | ||||
|    { | ||||
|       if(tmp & BMCR_PWDN) return 0; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       if((tmp & BMCR_PWDN) != BMCR_PWDN) return 0; | ||||
|    } | ||||
|    return -1; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| #if _WIZCHIP_ == W5500 | ||||
| void wizphy_reset(void) | ||||
| { | ||||
|    uint8_t tmp = getPHYCFGR(); | ||||
|    tmp &= PHYCFGR_RST; | ||||
|    setPHYCFGR(tmp); | ||||
|    tmp = getPHYCFGR(); | ||||
|    tmp |= ~PHYCFGR_RST; | ||||
|    setPHYCFGR(tmp); | ||||
| } | ||||
| 
 | ||||
| void wizphy_setphyconf(wiz_PhyConf* phyconf) | ||||
| { | ||||
|    uint8_t tmp = 0; | ||||
|    if(phyconf->by == PHY_CONFBY_SW) | ||||
|       tmp |= PHYCFGR_OPMD; | ||||
|    else | ||||
|       tmp &= ~PHYCFGR_OPMD; | ||||
|    if(phyconf->mode == PHY_MODE_AUTONEGO) | ||||
|       tmp |= PHYCFGR_OPMDC_ALLA; | ||||
|    else | ||||
|    { | ||||
|       if(phyconf->duplex == PHY_DUPLEX_FULL) | ||||
|       { | ||||
|          if(phyconf->speed == PHY_SPEED_100) | ||||
|             tmp |= PHYCFGR_OPMDC_100F; | ||||
|          else | ||||
|             tmp |= PHYCFGR_OPMDC_10F; | ||||
|       }    | ||||
|       else | ||||
|       { | ||||
|          if(phyconf->speed == PHY_SPEED_100) | ||||
|             tmp |= PHYCFGR_OPMDC_100H; | ||||
|          else | ||||
|             tmp |= PHYCFGR_OPMDC_10H; | ||||
|       } | ||||
|    } | ||||
|    setPHYCFGR(tmp); | ||||
|    wizphy_reset(); | ||||
| } | ||||
| 
 | ||||
| void wizphy_getphyconf(wiz_PhyConf* phyconf) | ||||
| { | ||||
|    uint8_t tmp = 0; | ||||
|    tmp = getPHYCFGR(); | ||||
|    phyconf->by   = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; | ||||
|    switch(tmp & PHYCFGR_OPMDC_ALLA) | ||||
|    { | ||||
|       case PHYCFGR_OPMDC_ALLA: | ||||
|       case PHYCFGR_OPMDC_100FA:  | ||||
|          phyconf->mode = PHY_MODE_AUTONEGO; | ||||
|          break; | ||||
|       default: | ||||
|          phyconf->mode = PHY_MODE_MANUAL; | ||||
|          break; | ||||
|    } | ||||
|    switch(tmp & PHYCFGR_OPMDC_ALLA) | ||||
|    { | ||||
|       case PHYCFGR_OPMDC_100FA: | ||||
|       case PHYCFGR_OPMDC_100F: | ||||
|       case PHYCFGR_OPMDC_100H: | ||||
|          phyconf->speed = PHY_SPEED_100; | ||||
|          break; | ||||
|       default: | ||||
|          phyconf->speed = PHY_SPEED_10; | ||||
|          break; | ||||
|    } | ||||
|    switch(tmp & PHYCFGR_OPMDC_ALLA) | ||||
|    { | ||||
|       case PHYCFGR_OPMDC_100FA: | ||||
|       case PHYCFGR_OPMDC_100F: | ||||
|       case PHYCFGR_OPMDC_10F: | ||||
|          phyconf->duplex = PHY_DUPLEX_FULL; | ||||
|          break; | ||||
|       default: | ||||
|          phyconf->duplex = PHY_DUPLEX_HALF; | ||||
|          break; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void wizphy_getphystat(wiz_PhyConf* phyconf) | ||||
| { | ||||
|    uint8_t tmp = getPHYCFGR(); | ||||
|    phyconf->duplex = (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; | ||||
|    phyconf->speed  = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; | ||||
| } | ||||
| 
 | ||||
| int8_t wizphy_setphypmode(uint8_t pmode) | ||||
| { | ||||
|    uint8_t tmp = 0; | ||||
|    tmp = getPHYCFGR(); | ||||
|    if((tmp & PHYCFGR_OPMD)== 0) return -1; | ||||
|    tmp &= ~PHYCFGR_OPMDC_ALLA;          | ||||
|    if( pmode == PHY_POWER_DOWN) | ||||
|       tmp |= PHYCFGR_OPMDC_PDOWN; | ||||
|    else | ||||
|       tmp |= PHYCFGR_OPMDC_ALLA; | ||||
|    setPHYCFGR(tmp); | ||||
|    wizphy_reset(); | ||||
|    tmp = getPHYCFGR(); | ||||
|    if( pmode == PHY_POWER_DOWN) | ||||
|    { | ||||
|       if(tmp & PHYCFGR_OPMDC_PDOWN) return 0; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       if(tmp & PHYCFGR_OPMDC_ALLA) return 0; | ||||
|    } | ||||
|    return -1; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| void wizchip_setnetinfo(wiz_NetInfo* pnetinfo) | ||||
| { | ||||
|    setSHAR(pnetinfo->mac); | ||||
|    setGAR(pnetinfo->gw); | ||||
|    setSUBR(pnetinfo->sn); | ||||
|    setSIPR(pnetinfo->ip); | ||||
|    _DNS_[0] = pnetinfo->dns[0]; | ||||
|    _DNS_[1] = pnetinfo->dns[1]; | ||||
|    _DNS_[2] = pnetinfo->dns[2]; | ||||
|    _DNS_[3] = pnetinfo->dns[3]; | ||||
|    _DHCP_   = pnetinfo->dhcp; | ||||
| } | ||||
| 
 | ||||
| void wizchip_getnetinfo(wiz_NetInfo* pnetinfo) | ||||
| { | ||||
|    getSHAR(pnetinfo->mac); | ||||
|    getGAR(pnetinfo->gw); | ||||
|    getSUBR(pnetinfo->sn); | ||||
|    getSIPR(pnetinfo->ip); | ||||
|    pnetinfo->dns[0]= _DNS_[0]; | ||||
|    pnetinfo->dns[1]= _DNS_[1]; | ||||
|    pnetinfo->dns[2]= _DNS_[2]; | ||||
|    pnetinfo->dns[3]= _DNS_[3]; | ||||
|    pnetinfo->dhcp  = _DHCP_; | ||||
| } | ||||
| 
 | ||||
| int8_t wizchip_setnetmode(netmode_type netmode) | ||||
| { | ||||
|    uint8_t tmp = 0; | ||||
| #if _WIZCHIP_ != W5500 | ||||
|    if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) return -1; | ||||
| #else | ||||
|    if(netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) return -1; | ||||
| #endif       | ||||
|    tmp = getMR(); | ||||
|    tmp |= (uint8_t)netmode; | ||||
|    setMR(tmp); | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
| netmode_type wizchip_getnetmode(void) | ||||
| { | ||||
|    return (netmode_type) getMR(); | ||||
| } | ||||
| 
 | ||||
| void wizchip_settimeout(wiz_NetTimeout* nettime) | ||||
| { | ||||
|    setRCR(nettime->retry_cnt); | ||||
|    setRTR(nettime->time_100us); | ||||
| } | ||||
| 
 | ||||
| void wizchip_gettimeout(wiz_NetTimeout* nettime) | ||||
| { | ||||
|    nettime->retry_cnt = getRCR(); | ||||
|    nettime->time_100us = getRTR(); | ||||
| } | ||||
| @ -0,0 +1,660 @@ | ||||
| //*****************************************************************************
 | ||||
| //
 | ||||
| //! \file wizchip_conf.h
 | ||||
| //! \brief WIZCHIP Config Header File.
 | ||||
| //! \version 1.0.0
 | ||||
| //! \date 2013/10/21
 | ||||
| //! \par  Revision history
 | ||||
| //!       <2015/02/05> Notice
 | ||||
| //!        The version history is not updated after this point.
 | ||||
| //!        Download the latest version directly from GitHub. Please visit the our GitHub repository for ioLibrary.
 | ||||
| //!        >> https://github.com/Wiznet/ioLibrary_Driver
 | ||||
| //!       <2013/10/21> 1st Release
 | ||||
| //! \author MidnightCow
 | ||||
| //! \copyright
 | ||||
| //!
 | ||||
| //! Copyright (c)  2013, WIZnet Co., LTD.
 | ||||
| //! All rights reserved.
 | ||||
| //! 
 | ||||
| //! Redistribution and use in source and binary forms, with or without 
 | ||||
| //! modification, are permitted provided that the following conditions 
 | ||||
| //! are met: 
 | ||||
| //! 
 | ||||
| //!     * Redistributions of source code must retain the above copyright 
 | ||||
| //! notice, this list of conditions and the following disclaimer. 
 | ||||
| //!     * Redistributions in binary form must reproduce the above copyright
 | ||||
| //! notice, this list of conditions and the following disclaimer in the
 | ||||
| //! documentation and/or other materials provided with the distribution. 
 | ||||
| //!     * Neither the name of the <ORGANIZATION> nor the names of its 
 | ||||
| //! contributors may be used to endorse or promote products derived 
 | ||||
| //! from this software without specific prior written permission. 
 | ||||
| //! 
 | ||||
| //! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | ||||
| //! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | ||||
| //! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | ||||
| //! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 | ||||
| //! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 | ||||
| //! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 | ||||
| //! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | ||||
| //! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | ||||
| //! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 | ||||
| //! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 | ||||
| //! THE POSSIBILITY OF SUCH DAMAGE.
 | ||||
| //
 | ||||
| //*****************************************************************************
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @defgroup extra_functions 2. WIZnet Extra Functions | ||||
|  * | ||||
|  * @brief These functions is optional function. It could be replaced at WIZCHIP I/O function because they were made by WIZCHIP I/O functions.   | ||||
|  * @details There are functions of configuring WIZCHIP, network, interrupt, phy, network information and timer. \n | ||||
|  *  | ||||
|  */ | ||||
| 
 | ||||
| #ifndef  _WIZCHIP_CONF_H_ | ||||
| #define  _WIZCHIP_CONF_H_ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| /**
 | ||||
|  * @brief Select WIZCHIP. | ||||
|  * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b W5500 or etc. \n\n | ||||
|  *       ex> <code> #define \_WIZCHIP_      W5500 </code> | ||||
|  */ | ||||
| 
 | ||||
| #define W5100						5100 | ||||
| #define W5100S						5100+5 | ||||
| #define W5200						5200 | ||||
| #define W5300						5300 | ||||
| #define W5500						5500 | ||||
| 
 | ||||
| #ifndef _WIZCHIP_ | ||||
| #define _WIZCHIP_                      W5500   // W5100, W5100S, W5200, W5300, W5500
 | ||||
| #endif | ||||
| 
 | ||||
| #define _WIZCHIP_IO_MODE_NONE_         0x0000 | ||||
| #define _WIZCHIP_IO_MODE_BUS_          0x0100 /**< Bus interface mode */ | ||||
| #define _WIZCHIP_IO_MODE_SPI_          0x0200 /**< SPI interface mode */ | ||||
| //#define _WIZCHIP_IO_MODE_IIC_          0x0400
 | ||||
| //#define _WIZCHIP_IO_MODE_SDIO_         0x0800
 | ||||
| // Add to
 | ||||
| //
 | ||||
| 
 | ||||
| #define _WIZCHIP_IO_MODE_BUS_DIR_      (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct  */ | ||||
| #define _WIZCHIP_IO_MODE_BUS_INDIR_    (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ | ||||
| 
 | ||||
| #define _WIZCHIP_IO_MODE_SPI_VDM_      (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length data*/ | ||||
| #define _WIZCHIP_IO_MODE_SPI_FDM_      (_WIZCHIP_IO_MODE_SPI_ + 2) /**< SPI interface mode for fixed length data mode*/ | ||||
| #define _WIZCHIP_IO_MODE_SPI_5500_     (_WIZCHIP_IO_MODE_SPI_ + 3) /**< SPI interface mode for fixed length data mode*/ | ||||
| 
 | ||||
| #if   (_WIZCHIP_ == W5100) | ||||
|    #define _WIZCHIP_ID_                "W5100\0" | ||||
| /**
 | ||||
|  * @brief Define interface mode. | ||||
|  * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
|  */ | ||||
| // 	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_DIR_
 | ||||
| //	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
 | ||||
|    	   #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_ | ||||
| 
 | ||||
| //A20150601 : Define the unit of IO DATA.   
 | ||||
|    typedef   uint8_t   iodata_t; | ||||
| //A20150401 : Indclude W5100.h file
 | ||||
|    #include "W5100/w5100.h" | ||||
| 
 | ||||
| #elif (_WIZCHIP_ == W5100S) | ||||
| #define _WIZCHIP_ID_                "W5100S\0" | ||||
| /**
 | ||||
| * @brief Define interface mode. | ||||
| * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
| */ | ||||
| //	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
 | ||||
| 	//#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_5500_
 | ||||
| 	#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_ | ||||
| 
 | ||||
| //A20150601 : Define the unit of IO DATA.
 | ||||
|    typedef   uint8_t   iodata_t; | ||||
| //A20150401 : Indclude W5100.h file
 | ||||
| 	#include "W5100S/w5100s.h" | ||||
| #elif (_WIZCHIP_ == W5200) | ||||
|    #define _WIZCHIP_ID_                "W5200\0" | ||||
| /**
 | ||||
|  * @brief Define interface mode. | ||||
|  * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ or @ref \	_WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
|  */ | ||||
| #ifndef _WIZCHIP_IO_MODE_ | ||||
| // #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_
 | ||||
|    #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_ | ||||
| #endif | ||||
| //A20150601 : Define the unit of IO DATA.   
 | ||||
|    typedef   uint8_t   iodata_t; | ||||
|    #include "W5200/w5200.h" | ||||
| #elif (_WIZCHIP_ == W5500) | ||||
|   #define _WIZCHIP_ID_                 "W5500\0" | ||||
|    | ||||
| /**
 | ||||
|  * @brief Define interface mode. \n | ||||
|  * @todo Should select interface mode as chip.  | ||||
|  *        - @ref \_WIZCHIP_IO_MODE_SPI_ \n | ||||
|  *          -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n | ||||
|  *          -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == W5500 \n | ||||
|  *        - @ref \_WIZCHIP_IO_MODE_BUS_ \n | ||||
|  *          - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n | ||||
|  *          - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n | ||||
|  *        - Others will be defined in future. \n\n | ||||
|  *        ex> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ </code> | ||||
|  *        | ||||
|  */ | ||||
| #ifndef _WIZCHIP_IO_MODE_ | ||||
|    //#define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_FDM_
 | ||||
|    #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_SPI_VDM_ | ||||
| #endif | ||||
| //A20150601 : Define the unit of IO DATA.   
 | ||||
|    typedef   uint8_t   iodata_t; | ||||
|    #include "W5500/w5500.h" | ||||
| #elif ( _WIZCHIP_ == W5300) | ||||
|    #define _WIZCHIP_ID_                 "W5300\0" | ||||
| /**
 | ||||
|  * @brief Define interface mode. | ||||
|  * @todo you should select interface mode as chip. Select one of @ref \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
|  */ | ||||
| #ifndef _WIZCHIP_IO_MODE_ | ||||
| //   #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_DIR_
 | ||||
|  #define _WIZCHIP_IO_MODE_           _WIZCHIP_IO_MODE_BUS_INDIR_ | ||||
| #endif | ||||
| 
 | ||||
| //A20150601 : Define the unit and bus width of IO DATA. 
 | ||||
|    /**
 | ||||
|     * @brief Select the data width 8 or 16 bits. | ||||
|     * @todo you should select the bus width. Select one of 8 or 16. | ||||
|     */ | ||||
|    #ifndef _WIZCHIP_IO_BUS_WIDTH_ | ||||
|    #define _WIZCHIP_IO_BUS_WIDTH_       8  // 16
 | ||||
|    #endif | ||||
|    #if _WIZCHIP_IO_BUS_WIDTH_ == 8 | ||||
|       typedef   uint8_t   iodata_t; | ||||
|    #elif _WIZCHIP_IO_BUS_WIDTH_ == 16 | ||||
|       typedef   uint16_t   iodata_t; | ||||
|    #else | ||||
|       #error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16."	 | ||||
|    #endif | ||||
| //
 | ||||
|    #include "W5300/w5300.h" | ||||
| #else | ||||
|    #error "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" | ||||
| #endif | ||||
| 
 | ||||
| #ifndef _WIZCHIP_IO_MODE_ | ||||
|    #error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Define I/O base address when BUS IF mode. | ||||
|  * @todo Should re-define it to fit your system when BUS IF Mode (@ref \_WIZCHIP_IO_MODE_BUS_, | ||||
|  *       @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). \n\n | ||||
|  *       ex> <code> #define \_WIZCHIP_IO_BASE_      0x00008000 </code> | ||||
|  */ | ||||
| #if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ | ||||
| 	#define _WIZCHIP_IO_BASE_				0x60000000	// for 5100S IND
 | ||||
| #elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ | ||||
| 	#define _WIZCHIP_IO_BASE_				0x00000000	// for 5100S SPI
 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef _WIZCHIP_IO_BASE_ | ||||
| #define _WIZCHIP_IO_BASE_              0x00000000  // 0x8000
 | ||||
| #endif | ||||
| 
 | ||||
| //M20150401 : Typing Error
 | ||||
| //#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS
 | ||||
| #if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ | ||||
|    #ifndef _WIZCHIP_IO_BASE_ | ||||
|       #error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." | ||||
|    #endif | ||||
| #endif    | ||||
| 
 | ||||
| #if _WIZCHIP_ >= W5200 | ||||
|    #define _WIZCHIP_SOCK_NUM_   8   ///< The count of independant socket of @b WIZCHIP
 | ||||
| #else | ||||
|    #define _WIZCHIP_SOCK_NUM_   4   ///< The count of independant socket of @b WIZCHIP
 | ||||
| #endif       | ||||
| 
 | ||||
| 
 | ||||
| /********************************************************
 | ||||
| * WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. | ||||
| *********************************************************/ | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions W5200:@ref WIZCHIP_IO_Functions_W5200 | ||||
|  */ | ||||
| typedef struct __WIZCHIP | ||||
| { | ||||
|    uint16_t  if_mode;               ///< host interface mode
 | ||||
|    uint8_t   id[6];                 ///< @b WIZCHIP ID such as @b 5100, @b 5200, @b 5500, and so on.
 | ||||
|    /**
 | ||||
|     * The set of critical section callback func. | ||||
|     */ | ||||
|    struct _CRIS | ||||
|    { | ||||
|       void (*_enter)  (void);       ///< crtical section enter 
 | ||||
|       void (*_exit) (void);         ///< critial section exit  
 | ||||
|    }CRIS;   | ||||
|    /**
 | ||||
|     *  The set of @ref \_WIZCHIP_ select control callback func. | ||||
|     */ | ||||
|    struct _CS | ||||
|    { | ||||
|       void (*_select)  (void);      ///< @ref \_WIZCHIP_ selected
 | ||||
|       void (*_deselect)(void);      ///< @ref \_WIZCHIP_ deselected
 | ||||
|    }CS;   | ||||
|    /**
 | ||||
|     * The set of interface IO callback func. | ||||
|     */ | ||||
|    union _IF | ||||
|    {	  | ||||
|       /**
 | ||||
|        * For BUS interface IO | ||||
|        */ | ||||
|       //M20156501 : Modify the function name for integrating with W5300
 | ||||
|       //struct
 | ||||
|       //{
 | ||||
|       //   uint8_t  (*_read_byte)  (uint32_t AddrSel);
 | ||||
|       //   void     (*_write_byte) (uint32_t AddrSel, uint8_t wb);
 | ||||
|       //}BUS;      
 | ||||
|       struct | ||||
|       { | ||||
|          iodata_t  (*_read_data)   (uint32_t AddrSel); | ||||
|          void      (*_write_data)  (uint32_t AddrSel, iodata_t wb); | ||||
|       }BUS;       | ||||
| 
 | ||||
|       /**
 | ||||
|        * For SPI interface IO | ||||
|        */ | ||||
|       struct | ||||
|       { | ||||
|          uint8_t (*_read_byte)   (void); | ||||
|          void    (*_write_byte)  (uint8_t wb); | ||||
|          void    (*_read_burst)  (uint8_t* pBuf, uint16_t len); | ||||
|          void    (*_write_burst) (uint8_t* pBuf, uint16_t len); | ||||
|       }SPI; | ||||
|       // To be added
 | ||||
|       //
 | ||||
|    }IF; | ||||
| }_WIZCHIP; | ||||
| 
 | ||||
| extern _WIZCHIP  WIZCHIP; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  WIZCHIP control type enumration used in @ref ctlwizchip(). | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|    CW_RESET_WIZCHIP,   ///< Resets WIZCHIP by softly
 | ||||
|    CW_INIT_WIZCHIP,    ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 dimension array typed uint8_t.
 | ||||
|    CW_GET_INTERRUPT,   ///< Get Interrupt status of WIZCHIP
 | ||||
|    CW_CLR_INTERRUPT,   ///< Clears interrupt
 | ||||
|    CW_SET_INTRMASK,    ///< Masks interrupt
 | ||||
|    CW_GET_INTRMASK,    ///< Get interrupt mask
 | ||||
|    CW_SET_INTRTIME,    ///< Set interval time between the current and next interrupt. 
 | ||||
|    CW_GET_INTRTIME,    ///< Set interval time between the current and next interrupt. 
 | ||||
|    CW_GET_ID,          ///< Gets WIZCHIP name.
 | ||||
| 
 | ||||
| //D20150601 : For no modification your application code
 | ||||
| //#if _WIZCHIP_ ==  W5500
 | ||||
|    CW_RESET_PHY,       ///< Resets internal PHY. Valid Only W5500
 | ||||
|    CW_SET_PHYCONF,     ///< When PHY configured by internal register, PHY operation mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000
 | ||||
|    CW_GET_PHYCONF,     ///< Get PHY operation mode in internal register. Valid Only W5500
 | ||||
|    CW_GET_PHYSTATUS,   ///< Get real PHY status on operating. Valid Only W5500
 | ||||
|    CW_SET_PHYPOWMODE,  ///< Set PHY power mode as normal and down when PHYSTATUS.OPMD == 1. Valid Only W5500
 | ||||
| //#endif
 | ||||
| //D20150601 : For no modification your application code
 | ||||
| //#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500
 | ||||
|    CW_GET_PHYPOWMODE,  ///< Get PHY Power mode as down or normal, Valid Only W5100, W5200
 | ||||
|    CW_GET_PHYLINK      ///< Get PHY Link status, Valid Only W5100, W5200
 | ||||
| //#endif
 | ||||
| }ctlwizchip_type; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  Network control type enumration used in @ref ctlnetwork(). | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|    CN_SET_NETINFO,  ///< Set Network with @ref wiz_NetInfo
 | ||||
|    CN_GET_NETINFO,  ///< Get Network with @ref wiz_NetInfo
 | ||||
|    CN_SET_NETMODE,  ///< Set network mode as WOL, PPPoE, Ping Block, and Force ARP mode
 | ||||
|    CN_GET_NETMODE,  ///< Get network mode as WOL, PPPoE, Ping Block, and Force ARP mode
 | ||||
|    CN_SET_TIMEOUT,  ///< Set network timeout as retry count and time.
 | ||||
|    CN_GET_TIMEOUT,  ///< Get network timeout as retry count and time.
 | ||||
| }ctlnetwork_type; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK | ||||
|  *  and CW_GET_INTRMASK is used in @ref ctlnetwork(). | ||||
|  *  It can be used with OR operation. | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
| #if   _WIZCHIP_ == W5500 | ||||
|    IK_WOL               = (1 << 4),   ///< Wake On Lan by receiving the magic packet. Valid in W500.
 | ||||
| #elif _WIZCHIP_ == W5300 | ||||
|    IK_FMTU              = (1 << 4),   ///< Received a ICMP message (Fragment MTU)   
 | ||||
| #endif    | ||||
| 
 | ||||
|    IK_PPPOE_TERMINATED  = (1 << 5),   ///< PPPoE Disconnected
 | ||||
| 
 | ||||
| #if _WIZCHIP_ != W5200 | ||||
|    IK_DEST_UNREACH      = (1 << 6),   ///< Destination IP & Port Unreachable, No use in W5200
 | ||||
| #endif    | ||||
| 
 | ||||
|    IK_IP_CONFLICT       = (1 << 7),   ///< IP conflict occurred
 | ||||
| 
 | ||||
|    IK_SOCK_0            = (1 << 8),   ///< Socket 0 interrupt
 | ||||
|    IK_SOCK_1            = (1 << 9),   ///< Socket 1 interrupt
 | ||||
|    IK_SOCK_2            = (1 << 10),  ///< Socket 2 interrupt
 | ||||
|    IK_SOCK_3            = (1 << 11),  ///< Socket 3 interrupt
 | ||||
| #if _WIZCHIP_ > W5100S | ||||
|    IK_SOCK_4            = (1 << 12),  ///< Socket 4 interrupt, No use in 5100
 | ||||
|    IK_SOCK_5            = (1 << 13),  ///< Socket 5 interrupt, No use in 5100
 | ||||
|    IK_SOCK_6            = (1 << 14),  ///< Socket 6 interrupt, No use in 5100
 | ||||
|    IK_SOCK_7            = (1 << 15),  ///< Socket 7 interrupt, No use in 5100
 | ||||
| #endif    | ||||
| 
 | ||||
| #if _WIZCHIP_ > W5100S | ||||
|    IK_SOCK_ALL          = (0xFF << 8) ///< All Socket interrupt
 | ||||
| #else | ||||
|    IK_SOCK_ALL          = (0x0F << 8) ///< All Socket interrupt
 | ||||
| #endif       | ||||
| }intr_kind; | ||||
| 
 | ||||
| #define PHY_CONFBY_HW            0     ///< Configured PHY operation mode by HW pin
 | ||||
| #define PHY_CONFBY_SW            1     ///< Configured PHY operation mode by SW register   
 | ||||
| #define PHY_MODE_MANUAL          0     ///< Configured PHY operation mode with user setting.
 | ||||
| #define PHY_MODE_AUTONEGO        1     ///< Configured PHY operation mode with auto-negotiation
 | ||||
| #define PHY_SPEED_10             0     ///< Link Speed 10
 | ||||
| #define PHY_SPEED_100            1     ///< Link Speed 100
 | ||||
| #define PHY_DUPLEX_HALF          0     ///< Link Half-Duplex
 | ||||
| #define PHY_DUPLEX_FULL          1     ///< Link Full-Duplex
 | ||||
| #define PHY_LINK_OFF             0     ///< Link Off
 | ||||
| #define PHY_LINK_ON              1     ///< Link On
 | ||||
| #define PHY_POWER_NORM           0     ///< PHY power normal mode
 | ||||
| #define PHY_POWER_DOWN           1     ///< PHY power down mode 
 | ||||
| 
 | ||||
| 
 | ||||
| #if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in W5500,   | ||||
|  *  and it indicates the real PHY status configured by HW or SW in all WIZCHIP. \n | ||||
|  *  Valid only in W5500. | ||||
|  */ | ||||
| typedef struct wiz_PhyConf_t | ||||
| { | ||||
|       uint8_t by;       ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW
 | ||||
|       uint8_t mode;     ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO
 | ||||
|       uint8_t speed;    ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100
 | ||||
|       uint8_t duplex;   ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL 
 | ||||
|       //uint8_t power;  ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN
 | ||||
|       //uint8_t link;   ///< Valid only in CW_GET_PHYSTATUS. set by @ref PHY_LINK_ON or PHY_DUPLEX_OFF 
 | ||||
|    }wiz_PhyConf; | ||||
| #endif    | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  It used in setting dhcp_mode of @ref wiz_NetInfo. | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
|    NETINFO_STATIC = 1,    ///< Static IP configuration by manually.
 | ||||
|    NETINFO_DHCP           ///< Dynamic IP configruation from a DHCP sever
 | ||||
| }dhcp_mode; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  Network Information for WIZCHIP | ||||
|  */ | ||||
| typedef struct wiz_NetInfo_t | ||||
| { | ||||
|    uint8_t mac[6];  ///< Source Mac Address
 | ||||
|    uint8_t ip[4];   ///< Source IP Address
 | ||||
|    uint8_t sn[4];   ///< Subnet Mask 
 | ||||
|    uint8_t gw[4];   ///< Gateway IP Address
 | ||||
|    uint8_t dns[4];  ///< DNS server IP Address
 | ||||
|    dhcp_mode dhcp;  ///< 1 - Static, 2 - DHCP
 | ||||
| }wiz_NetInfo; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  Network mode | ||||
|  */ | ||||
| typedef enum | ||||
| { | ||||
| #if _WIZCHIP_ == W5500 | ||||
|    NM_FORCEARP    = (1<<1),  ///< Force to APP send whenever udp data is sent. Valid only in W5500
 | ||||
| #endif    | ||||
|    NM_WAKEONLAN   = (1<<5),  ///< Wake On Lan 
 | ||||
|    NM_PINGBLOCK   = (1<<4),  ///< Block ping-request
 | ||||
|    NM_PPPOE       = (1<<3),  ///< PPPoE mode
 | ||||
| }netmode_type; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup DATA_TYPE | ||||
|  *  Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout configruation. | ||||
|  */ | ||||
| typedef struct wiz_NetTimeout_t | ||||
| { | ||||
|    uint8_t  retry_cnt;     ///< retry count 
 | ||||
|    uint16_t time_100us;    ///< time unit 100us
 | ||||
| }wiz_NetTimeout; | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief Registers call back function for critical section of I/O functions such as | ||||
|  *\ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref WIZCHIP_WRITE_BUF. | ||||
|  *@param cris_en : callback function for critical section enter. | ||||
|  *@param cris_ex : callback function for critical section exit. | ||||
|  *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT marco or register your functions. | ||||
|  *@note If you do not describe or register, default functions(@ref wizchip_cris_enter & @ref wizchip_cris_exit) is called. | ||||
|  */ | ||||
| void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief Registers call back function for WIZCHIP select & deselect. | ||||
|  *@param cs_sel : callback function for WIZCHIP select | ||||
|  *@param cs_desel : callback fucntion for WIZCHIP deselect | ||||
|  *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or register your functions. | ||||
|  *@note If you do not describe or register, null function is called. | ||||
|  */ | ||||
| void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief Registers call back function for bus interface. | ||||
|  *@param bus_rb   : callback function to read byte data using system bus | ||||
|  *@param bus_wb   : callback function to write byte data using system bus | ||||
|  *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte function | ||||
|  *or register your functions. | ||||
|  *@note If you do not describe or register, null function is called. | ||||
|  */ | ||||
| //M20150601 : For integrating with W5300
 | ||||
| //void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, uint8_t wb));
 | ||||
| void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb)); | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief Registers call back function for SPI interface. | ||||
|  *@param spi_rb : callback function to read byte using SPI | ||||
|  *@param spi_wb : callback function to write byte using SPI | ||||
|  *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function | ||||
|  *or register your functions. | ||||
|  *@note If you do not describe or register, null function is called. | ||||
|  */ | ||||
| void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)); | ||||
| 
 | ||||
| /**
 | ||||
|  *@brief Registers call back function for SPI interface. | ||||
|  *@param spi_rb : callback function to burst read using SPI | ||||
|  *@param spi_wb : callback function to burst write using SPI | ||||
|  *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte function | ||||
|  *or register your functions. | ||||
|  *@note If you do not describe or register, null function is called. | ||||
|  */ | ||||
| void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t* pBuf, uint16_t len), void (*spi_wb)(uint8_t* pBuf, uint16_t len)); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Controls to the WIZCHIP. | ||||
|  * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor PHY(Link,Speed,Half/Full/Auto), | ||||
|  * controls interrupt & mask and so on. | ||||
|  * @param cwtype : Decides to the control type | ||||
|  * @param arg : arg type is dependent on cwtype. | ||||
|  * @return  0 : Success \n | ||||
|  *         -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref ctlwizchip_type in WIZCHIP  | ||||
|  */           | ||||
| int8_t ctlwizchip(ctlwizchip_type cwtype, void* arg); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Controls to network. | ||||
|  * @details Controls to network environment, mode, timeout and so on. | ||||
|  * @param cntype : Input. Decides to the control type | ||||
|  * @param arg : Inout. arg type is dependent on cntype. | ||||
|  * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref ctlnetwork_type in WIZCHIP \n | ||||
|  *          0 : Success       | ||||
|  */           | ||||
| int8_t ctlnetwork(ctlnetwork_type cntype, void* arg); | ||||
| 
 | ||||
| 
 | ||||
| /* 
 | ||||
|  * The following functions are implemented for internal use.  | ||||
|  * but You can call these functions for code size reduction instead of ctlwizchip() and ctlnetwork(). | ||||
|  */ | ||||
|   | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Reset WIZCHIP by softly. | ||||
|  */  | ||||
| void   wizchip_sw_reset(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Initializes WIZCHIP with socket buffer size | ||||
|  * @param txsize Socket tx buffer sizes. If null, initialized the default size 2KB. | ||||
|  * @param rxsize Socket rx buffer sizes. If null, initialized the default size 2KB. | ||||
|  * @return 0 : succcess \n | ||||
|  *        -1 : fail. Invalid buffer size | ||||
|  */ | ||||
| int8_t wizchip_init(uint8_t* txsize, uint8_t* rxsize); | ||||
| 
 | ||||
| /** 
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Clear Interrupt of WIZCHIP. | ||||
|  * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. | ||||
|  */ | ||||
| void wizchip_clrinterrupt(intr_kind intr); | ||||
| 
 | ||||
| /** 
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get Interrupt of WIZCHIP. | ||||
|  * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. | ||||
|  */ | ||||
| intr_kind wizchip_getinterrupt(void); | ||||
| 
 | ||||
| /** 
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Mask or Unmask Interrupt of WIZCHIP. | ||||
|  * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. | ||||
|  */ | ||||
| void wizchip_setinterruptmask(intr_kind intr); | ||||
| 
 | ||||
| /** 
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get Interrupt mask of WIZCHIP. | ||||
|  * @return : The operated OR vaule of @ref intr_kind. It can type-cast to uint16_t. | ||||
|  */ | ||||
| intr_kind wizchip_getinterruptmask(void); | ||||
| 
 | ||||
| //todo
 | ||||
| #if _WIZCHIP_ > W5100 | ||||
|    int8_t wizphy_getphylink(void);              ///< get the link status of phy in WIZCHIP. No use in W5100
 | ||||
|    int8_t wizphy_getphypmode(void);             ///< get the power mode of PHY in WIZCHIP. No use in W5100
 | ||||
| #endif | ||||
| 
 | ||||
| #if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 | ||||
|    void   wizphy_reset(void);                   ///< Reset phy. Vailid only in W5500
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Set the phy information for WIZCHIP without power mode | ||||
|  * @param phyconf : @ref wiz_PhyConf | ||||
|  */ | ||||
|    void   wizphy_setphyconf(wiz_PhyConf* phyconf);   | ||||
|  /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get phy configuration information. | ||||
|  * @param phyconf : @ref wiz_PhyConf | ||||
|  */ | ||||
|    void   wizphy_getphyconf(wiz_PhyConf* phyconf);  | ||||
|  /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get phy status. | ||||
|  * @param phyconf : @ref wiz_PhyConf | ||||
|  */  | ||||
|    void   wizphy_getphystat(wiz_PhyConf* phyconf); | ||||
|  /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in W5500, @ref PHYSTATUS in W5200 | ||||
|  * @param pmode Settig value of power down mode. | ||||
|  */    | ||||
|    int8_t wizphy_setphypmode(uint8_t pmode);     | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
| * @ingroup extra_functions | ||||
|  * @brief Set the network information for WIZCHIP | ||||
|  * @param pnetinfo : @ref wizNetInfo | ||||
|  */ | ||||
| void wizchip_setnetinfo(wiz_NetInfo* pnetinfo); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get the network information for WIZCHIP | ||||
|  * @param pnetinfo : @ref wizNetInfo | ||||
|  */ | ||||
| void wizchip_getnetinfo(wiz_NetInfo* pnetinfo); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc.  | ||||
|  * @param pnetinfo Value of network mode. Refer to @ref netmode_type. | ||||
|  */ | ||||
| int8_t wizchip_setnetmode(netmode_type netmode); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc.  | ||||
|  * @return Value of network mode. Refer to @ref netmode_type. | ||||
|  */ | ||||
| netmode_type wizchip_getnetmode(void); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). | ||||
|  * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.   | ||||
|  * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.  | ||||
|  */ | ||||
| void wizchip_settimeout(wiz_NetTimeout* nettime); | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup extra_functions | ||||
|  * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). | ||||
|  * @details @ref _RTR_ configures the retransmission timeout period and @ref _RCR_ configures the number of time of retransmission.   | ||||
|  * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref wiz_NetTimeout.  | ||||
|  */ | ||||
| void wizchip_gettimeout(wiz_NetTimeout* nettime); | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
| #endif | ||||
| 
 | ||||
| #endif   // _WIZCHIP_CONF_H_
 | ||||
| @ -0,0 +1,39 @@ | ||||
| /*
 | ||||
|  * globals.h | ||||
|  * | ||||
|  *  Created on: 29 íîÿá. 2018 ã. | ||||
|  *      Author: maxx | ||||
|  */ | ||||
| 
 | ||||
| #ifndef GLOBALS_H_ | ||||
| #define GLOBALS_H_ | ||||
| 
 | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #include <avr/pgmspace.h> | ||||
| #include "avr/wdt.h" // WatchDog | ||||
| 
 | ||||
| 
 | ||||
| #define PRINTF_EN 1 | ||||
| #if PRINTF_EN | ||||
| #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) | ||||
| #else | ||||
| #define PRINTF(...) | ||||
| #endif | ||||
| 
 | ||||
| extern unsigned long millis(void); | ||||
| extern int freeRam (void); | ||||
| 
 | ||||
| //M644P/M1284p Users LEDS:
 | ||||
| //LED1/PORTC.4- m644p/m1284p maxxir
 | ||||
| #define led1_conf()      DDRC |= (1<<DDC4) | ||||
| #define led1_high()      PORTC |= (1<<PORTC4) | ||||
| #define led1_low()       PORTC &= ~(1<<PORTC4) | ||||
| #define led1_tgl()     PORTC ^= (1<<PORTC4) | ||||
| #define led1_read()     (PORTC & (1<<PORTC4)) | ||||
| 
 | ||||
| #define sw1_conf()      {DDRC &= ~(1<<DDC5); PORTC |= (1<<PORTC5);} | ||||
| #define sw1_read()     (PINC & (1<<PINC5)) | ||||
| 
 | ||||
| 
 | ||||
| #endif /* GLOBALS_H_ */ | ||||
| @ -0,0 +1,433 @@ | ||||
| /*
 | ||||
|  * main.c | ||||
|  * | ||||
|  *  Created on: 22 íîÿá. 2018 ã. | ||||
|  *      Author: maxx | ||||
|  */ | ||||
| #include <avr/io.h> | ||||
| #include <util/delay.h> | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/pgmspace.h> | ||||
| #include <compat/deprecated.h>  //sbi, cbi etc.. | ||||
| #include "avr/wdt.h" // WatchDog | ||||
| #include <stdio.h>  // printf etc.. | ||||
| #include "uart_extd.h" | ||||
| #include "spi.h" | ||||
| 
 | ||||
| #include "globals.h" | ||||
| #include "Ethernet/socket.h" | ||||
| #include "Ethernet/wizchip_conf.h" | ||||
| #include "Application/loopback/loopback.h" | ||||
| #include "Application/telnet/telnet.h" | ||||
| 
 | ||||
| //#include <stdlib.h> // itoa etc..
 | ||||
| /*
 | ||||
|  * (7)Add Telnet simple server (23) - unblocking type via telnet_srv(..) (v2.0) | ||||
|  * (7)Add Telnet authorization (v2.1) (24) - unblocking type via telnet_auth_srv(..) (v2.1) | ||||
|  *  Use telnet to connect to defined IP and port.  In this example, connect to 192.168.1.192 port 23.  The telnet client will receive a message and port closed. | ||||
|  * XP/Windows_7 | ||||
|  * > telnet 192.168.1.192 23 | ||||
|  * | ||||
|  * Windows 10 | ||||
|  * run telnet client | ||||
|  * open 192.168.1.192 23 | ||||
|  * | ||||
|  * (3) Trying WIZNET5500 init with using official Wiznet ioLibrary_Driver | ||||
|  * working ping on static IP | ||||
|  * LED1 = ON when phy_link detected | ||||
|  * and loopback test on TCP-IP:5000 and UDP:3000 ports. | ||||
|  * use Hercules terminal utility to check network connection see: | ||||
|  * | ||||
|  * https://wizwiki.net/wiki/doku.php?id=osh:cookie:loopback_test
 | ||||
|  * https://www.hw-group.com/software/hercules-setup-utility
 | ||||
|  * | ||||
|  */ | ||||
| /*
 | ||||
|  * m1284p minimum template, with one button & one led | ||||
|  */ | ||||
| 
 | ||||
| //*********Global vars
 | ||||
| #define TICK_PER_SEC 1000UL | ||||
| volatile unsigned long _millis; // for millis tick !! Overflow every ~49.7 days
 | ||||
| 
 | ||||
| //*********Program metrics
 | ||||
| const char compile_date[] PROGMEM    = __DATE__;     // Mmm dd yyyy - Äàòà êîìïèëÿöèè
 | ||||
| const char compile_time[] PROGMEM    = __TIME__;     // hh:mm:ss - Âðåìÿ êîìïèëÿöèè
 | ||||
| const char str_prog_name[] PROGMEM   = "\r\nAtMega1284p v2.1 Static IP Telnet server WIZNET_5500 ETHERNET 01/12/2018\r\n"; // Program name
 | ||||
| 
 | ||||
| #if defined(__AVR_ATmega128__) | ||||
| const char PROGMEM str_mcu[] = "ATmega128"; //CPU is m128
 | ||||
| #elif defined (__AVR_ATmega2560__) | ||||
| const char PROGMEM str_mcu[] = "ATmega2560"; //CPU is m2560
 | ||||
| #elif defined (__AVR_ATmega2561__) | ||||
| const char PROGMEM str_mcu[] = "ATmega2561"; //CPU is m2561
 | ||||
| #elif defined (__AVR_ATmega328P__) | ||||
| const char PROGMEM str_mcu[] = "ATmega328P"; //CPU is m328p
 | ||||
| #elif defined (__AVR_ATmega32U4__) | ||||
| const char PROGMEM str_mcu[] = "ATmega32u4"; //CPU is m32u4
 | ||||
| #elif defined (__AVR_ATmega644P__) | ||||
| const char PROGMEM str_mcu[] = "ATmega644p"; //CPU is m644p
 | ||||
| #elif defined (__AVR_ATmega1284P__) | ||||
| const char PROGMEM str_mcu[] = "ATmega1284p"; //CPU is m1284p
 | ||||
| #else | ||||
| const char PROGMEM str_mcu[] = "Unknown CPU"; //CPU is unknown
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| //FUNC headers
 | ||||
| static void avr_init(void); | ||||
| void timer0_init(void); | ||||
| 
 | ||||
| //Wiznet FUNC headers
 | ||||
| void print_network_information(void); | ||||
| 
 | ||||
| // RAM Memory usage test
 | ||||
| int freeRam (void) | ||||
| { | ||||
| 	extern int __heap_start, *__brkval; | ||||
| 	int v; | ||||
| 	int _res = (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); | ||||
| 	return _res; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //******************* MILLIS ENGINE: BEGIN
 | ||||
| //ISR (TIMER0_COMP_vect )
 | ||||
| ISR (TIMER0_COMPA_vect) | ||||
| { | ||||
| 	// Compare match Timer0
 | ||||
| 	// Here every 1ms
 | ||||
| 	_millis++; // INC millis tick
 | ||||
| 	// Òåñò ìèãàåì ïðè â õîäå â ïðåðûâàíèå
 | ||||
| 	// 500Hz FREQ OUT
 | ||||
| 	// LED_TGL;
 | ||||
| } | ||||
| 
 | ||||
| unsigned long millis(void) | ||||
| { | ||||
| 	unsigned long i; | ||||
| 	cli(); | ||||
| 	// Atomic tick reading
 | ||||
| 	i = _millis; | ||||
| 	sei(); | ||||
| 	return i; | ||||
| } | ||||
| //******************* MILLIS ENGINE: END
 | ||||
| 
 | ||||
| //***************** UART0: BEGIN
 | ||||
| // Assign I/O stream to UART
 | ||||
| /* define CPU frequency in Mhz here if not defined in Makefile */ | ||||
| //#ifndef F_CPU
 | ||||
| //#define F_CPU 16000000UL
 | ||||
| //#endif
 | ||||
| 
 | ||||
| /* 19200 baud */ | ||||
| #define UART_BAUD_RATE      19200 | ||||
| //#define UART_BAUD_RATE      38400
 | ||||
| 
 | ||||
| static int uart0_putchar(char ch,FILE *stream); | ||||
| static void uart0_rx_flash(void); | ||||
| 
 | ||||
| static FILE uart0_stdout = FDEV_SETUP_STREAM(uart0_putchar, NULL, _FDEV_SETUP_WRITE); | ||||
| //PS. stdin íå ïåðåíàçíà÷àþ, ò.ê. óäîáíåå ñ íèì ðàáîòàòü ÷åðåç uart.h - api:
 | ||||
| 
 | ||||
| /*
 | ||||
|  * Ò.å. íàïðèìåð òàê | ||||
|         c = uart1_getc(); | ||||
|         if (( c & UART_NO_DATA ) == 0) | ||||
|         { | ||||
|            uart1_putc( (unsigned char)c ); | ||||
|         } | ||||
|  Ïðè ýòîì ÷åêàåì ÷òî áóôåð ïðèåìà íå ïóñò è îïðîñ èäåò íåáëîêèðóþùèé (+ ðàáîòàåì ÷åðåç UART RX RINGBUFFER), | ||||
|  à åñëè ðàáîòàåì â ñòèëå stdin->getchar() òàì îïðîñ áëîêèðóåòñÿ ïîêà ñèìâîë íå áóäåò ïðèíÿò (ïîëëèíã) | ||||
|  ÷åðåç UART1_RX, ò.å. íåóäîáíî. | ||||
|  */ | ||||
| 
 | ||||
| // STDOUT UART0 TX handler
 | ||||
| static int uart0_putchar(char ch,FILE *stream) | ||||
| { | ||||
| 	uart_putc(ch); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| // Î÷èùàåì áóôåð ïðèåìà UART1 RX (èíîãäà íóæíî)
 | ||||
| static void uart0_rx_flash(void) | ||||
| { | ||||
| 	// Ñ÷èòûâàåì âñå èç ring-buffer UART1 RX
 | ||||
| 	unsigned int c; | ||||
| 	do | ||||
| 	{ | ||||
| 		c = uart_getc(); | ||||
| 	} while (( c & UART_NO_DATA ) == 0); // Check RX1 none-empty
 | ||||
| 
 | ||||
| } | ||||
| //***************** UART0: END
 | ||||
| 
 | ||||
| //***************** ADC: BEGIN
 | ||||
| 
 | ||||
| #ifndef ADC_DIV | ||||
| //12.5MHz or over use this ADC reference clock
 | ||||
| #define ADC_DIV (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) //:128 ADC Prescaler
 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ADC_REF | ||||
| // vcc voltage ref default
 | ||||
| #define ADC_REF (1<<REFS0) | ||||
| #endif | ||||
| 
 | ||||
| void adc_init(void) | ||||
| { | ||||
| 	ADCSRA = 0; | ||||
| 	ADCSRA |= (ADC_DIV);    // ADC reference clock
 | ||||
| 	ADMUX |= (ADC_REF);     // Voltage reference
 | ||||
| 	ADCSRA |= (1<<ADEN);    // Turn on ADC
 | ||||
| 	ADCSRA |= (1<<ADSC);    // Do an initial conversion because this one is the
 | ||||
| 	// slowest and to ensure that everything is up
 | ||||
| 	// and running
 | ||||
| } | ||||
| 
 | ||||
| uint16_t adc_read(uint8_t channel) | ||||
| { | ||||
| 	ADMUX &= 0b11100000;                    //Clear the older channel that was read
 | ||||
| 	ADMUX |= channel;                //Defines the new ADC channel to be read
 | ||||
| 	ADCSRA |= (1<<ADSC);                //Starts a new conversion
 | ||||
| 	while(ADCSRA & (1<<ADSC));            //Wait until the conversion is done
 | ||||
| 
 | ||||
| 	return ADCW;                    //Returns the ADC value of the chosen channel
 | ||||
| } | ||||
| //***************** ADC: END
 | ||||
| 
 | ||||
| 
 | ||||
| //***************** WIZCHIP INIT: BEGIN
 | ||||
| #define ETH_MAX_BUF_SIZE	2048 | ||||
| 
 | ||||
| unsigned char ethBuf0[ETH_MAX_BUF_SIZE]; | ||||
| unsigned char ethBuf1[ETH_MAX_BUF_SIZE]; | ||||
| unsigned char ethBut3_TELNET[TELNET_BUF_SIZE]; | ||||
| unsigned char ethBut4_TELNET[TELNET_BUF_SIZE]; | ||||
| 
 | ||||
| wiz_NetInfo netInfo = { .mac  = {0x00, 0x08, 0xdc, 0xab, 0xcd, 0xef}, // Mac address
 | ||||
| 		.ip   = {192, 168, 0, 199},         // IP address
 | ||||
| 		.sn   = {255, 255, 255, 0},         // Subnet mask
 | ||||
| 		.dns =  {8,8,8,8},			  // DNS address (google dns)
 | ||||
| 		.gw   = {192, 168, 0, 1}, // Gateway address
 | ||||
| 		.dhcp = NETINFO_STATIC};    //Dynamic IP configruation from a DHCP sever
 | ||||
| 
 | ||||
| void cs_sel() { | ||||
| 	SPI_WIZNET_ENABLE(); | ||||
| } | ||||
| 
 | ||||
| void cs_desel() { | ||||
| 	SPI_WIZNET_DISABLE(); | ||||
| } | ||||
| 
 | ||||
| uint8_t spi_rb(void) { | ||||
| 	uint8_t rbuf; | ||||
| 	//HAL_SPI_Receive(&hspi1, &rbuf, 1, HAL_MAX_DELAY);
 | ||||
| 	SPI_READ(rbuf); | ||||
| 	return rbuf; | ||||
| } | ||||
| 
 | ||||
| void spi_wb(uint8_t b) { | ||||
| 	//HAL_SPI_Transmit(&hspi1, &b, 1, HAL_MAX_DELAY);
 | ||||
| 	SPI_WRITE(b); | ||||
| } | ||||
| 
 | ||||
| void spi_rb_burst(uint8_t *buf, uint16_t len) { | ||||
| 	//HAL_SPI_Receive_DMA(&hspi1, buf, len);
 | ||||
| 	//while(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY_RX);
 | ||||
| 	for (uint16_t var = 0; var < len; var++) { | ||||
| 		SPI_READ(*buf++); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void spi_wb_burst(uint8_t *buf, uint16_t len) { | ||||
| 	//HAL_SPI_Transmit_DMA(&hspi1, buf, len);
 | ||||
| 	//while(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY_TX);
 | ||||
| 	for (uint16_t var = 0; var < len; var++) { | ||||
| 		SPI_WRITE(*buf++); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void IO_LIBRARY_Init(void) { | ||||
| 	uint8_t bufSize[] = {2, 2, 2, 2, 2, 2, 2, 2}; | ||||
| 
 | ||||
| 	reg_wizchip_cs_cbfunc(cs_sel, cs_desel); | ||||
| 	reg_wizchip_spi_cbfunc(spi_rb, spi_wb); | ||||
| 	reg_wizchip_spiburst_cbfunc(spi_rb_burst, spi_wb_burst); | ||||
| 
 | ||||
| 	wizchip_init(bufSize, bufSize); | ||||
| 	wizchip_setnetinfo(&netInfo); | ||||
| 	//wizchip_setinterruptmask(IK_SOCK_0);
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //***************** WIZCHIP INIT: END
 | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
| 	uint8_t prev_sw1 = 1; // VAR for sw1 pressing detect
 | ||||
| 
 | ||||
| 	// INIT MCU
 | ||||
| 	avr_init(); | ||||
| 	spi_init(); //SPI Master, MODE0, 4Mhz(DIV4), CS_PB.3=HIGH - suitable for WIZNET 5x00(1/2/5)
 | ||||
| 
 | ||||
| 
 | ||||
| 	// Print program metrics
 | ||||
| 	PRINTF("%S", str_prog_name);// Íàçâàíèå ïðîãðàììû
 | ||||
| 	PRINTF("Compiled at: %S %S\r\n", compile_time, compile_date);// Âðåìÿ Äàòà êîìïèëÿöèè
 | ||||
| 	PRINTF(">> MCU is: %S; CLK is: %luHz\r\n", str_mcu, F_CPU);// MCU Name && FREQ
 | ||||
| 	PRINTF(">> Free RAM is: %d bytes\r\n", freeRam()); | ||||
| 
 | ||||
| 	//Short Blink LED 3 times on startup
 | ||||
| 	unsigned char i = 3; | ||||
| 	while(i--) | ||||
| 	{ | ||||
| 		led1_high(); | ||||
| 		_delay_ms(100); | ||||
| 		led1_low(); | ||||
| 		_delay_ms(400); | ||||
| 		wdt_reset(); | ||||
| 	} | ||||
| 
 | ||||
| 	//Wizchip WIZ5500 Ethernet initialize
 | ||||
| 	IO_LIBRARY_Init(); //After that ping must working
 | ||||
| 	print_network_information(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 *To run blocking telnet server (deprecated) | ||||
| 	while(1) | ||||
| 	{ | ||||
| 		_telnet_srv(TELNET_PORT); | ||||
| 	} | ||||
| 	 */ | ||||
| 	PRINTF("> Telnet server is running on port %u\r\n", TELNET_PORT); | ||||
| 	PRINTF("> Telnet AUTH server is running on port %u\r\n", TELNET_AUTH_PORT); | ||||
| 
 | ||||
| 
 | ||||
| 	//Telnet SERVER (23) +  Loopback Test: TCP Server (5000) and UDP (3000)
 | ||||
| 	// Test for Ethernet data transfer validation
 | ||||
| 	uint32_t timer_link_1sec = millis(); | ||||
| 	while(1) | ||||
| 	{ | ||||
| 		//Here at least every 1sec
 | ||||
| 		wdt_reset(); // WDT reset at least every sec
 | ||||
| 
 | ||||
| 		//Use Hercules Terminal to check loopback tcp:5000 and udp:3000
 | ||||
| 
 | ||||
| 		 /*
 | ||||
| 		 * https://www.hw-group.com/software/hercules-setup-utility
 | ||||
| 		 * | ||||
| 		 */ | ||||
| 		telnet_srv(3, ethBut3_TELNET, TELNET_PORT); | ||||
| 		telnet_auth_srv(4, ethBut4_TELNET, TELNET_AUTH_PORT); | ||||
| 		loopback_tcps(0,ethBuf0,5000); | ||||
| 		loopback_udps(1, ethBuf0, 3000); | ||||
| 
 | ||||
| 		//loopback_ret = loopback_tcpc(SOCK_TCPS, gDATABUF, destip, destport);
 | ||||
| 		//if(loopback_ret < 0) printf("loopback ret: %ld\r\n", loopback_ret); // TCP Socket Error code
 | ||||
| 
 | ||||
| 		//Shouldn't use LED for ethernet link here, because it used on telnet command processor
 | ||||
| 		/*
 | ||||
| 		if((millis()-timer_link_1sec)> 1000) | ||||
| 		{ | ||||
| 			//here every 1 sec
 | ||||
| 			timer_link_1sec = millis(); | ||||
| 			if(wizphy_getphylink() == PHY_LINK_ON) | ||||
| 			{ | ||||
| 				led1_high(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				led1_low(); | ||||
| 			} | ||||
| 		} | ||||
| 		*/ | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| // Timer0
 | ||||
| // 1ms IRQ
 | ||||
| // Used for millis() timing
 | ||||
| void timer0_init(void) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * | ||||
| 	 * For M128 | ||||
| 	TCCR0 = (1<<CS02)|(1<<WGM01); //TIMER0 SET-UP: CTC MODE & PS 1:64
 | ||||
| 	OCR0 = 249; // 1ms reach for clear (16mz:64=>250kHz:250-=>1kHz)
 | ||||
| 	TIMSK |= 1<<OCIE0;	 //IRQ on TIMER0 output compare
 | ||||
| 	 */ | ||||
| 	//For M664p
 | ||||
| 	TCCR0A = (1<<WGM01); //TIMER0 SET-UP: CTC MODE
 | ||||
| 	TCCR0B = (1<<CS01)|(1<<CS00); // PS 1:64
 | ||||
| 	OCR0A = 249; // 1ms reach for clear (16mz:64=>250kHz:250-=>1kHz)
 | ||||
| 	TIMSK0 |= 1<<OCIE0A;	 //IRQ on TIMER0 output compareA
 | ||||
| } | ||||
| 
 | ||||
| static void avr_init(void) | ||||
| { | ||||
| 	// Initialize device here.
 | ||||
| 	// WatchDog INIT
 | ||||
| 	wdt_enable(WDTO_8S);  // set up wdt reset interval 2 second
 | ||||
| 	wdt_reset(); // wdt reset ~ every <2000ms
 | ||||
| 
 | ||||
| 	timer0_init();// Timer0 millis engine init
 | ||||
| 
 | ||||
| 	// Initial UART Peripheral
 | ||||
| 	/*
 | ||||
| 	 *  Initialize uart11 library, pass baudrate and AVR cpu clock | ||||
| 	 *  with the macro | ||||
| 	 *  uart1_BAUD_SELECT() (normal speed mode ) | ||||
| 	 *  or | ||||
| 	 *  uart1_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode) | ||||
| 	 */ | ||||
| #if	(UART_BAUD_RATE == 115200) | ||||
| 	uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE,F_CPU) ); // To works without error on 115200 bps/F_CPU=16Mhz
 | ||||
| #else | ||||
| 	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); | ||||
| #endif | ||||
| 	// Define Output/Input Stream
 | ||||
| 	stdout = &uart0_stdout; | ||||
| 
 | ||||
| 	//ADC init
 | ||||
| 	adc_init(); | ||||
| 	adc_read(0); //Dummy read
 | ||||
| 
 | ||||
| 
 | ||||
| 	led1_conf(); | ||||
| 	led1_low();// LED1 is OFF
 | ||||
| 
 | ||||
| 
 | ||||
| 	sw1_conf();//SW1 internal pull-up
 | ||||
| 
 | ||||
| 	sei(); //re-enable global interrupts
 | ||||
| 
 | ||||
| 	return; | ||||
| } | ||||
| 
 | ||||
| void print_network_information(void) | ||||
| { | ||||
| 
 | ||||
| 	uint8_t tmpstr[6] = {0,}; | ||||
| 	ctlwizchip(CW_GET_ID,(void*)tmpstr); // Get WIZCHIP name
 | ||||
|     PRINTF("\r\n=======================================\r\n"); | ||||
|     PRINTF(" WIZnet chip:  %s \r\n", tmpstr); | ||||
|     PRINTF("=======================================\r\n"); | ||||
| 
 | ||||
| 	wiz_NetInfo gWIZNETINFO; | ||||
| 	wizchip_getnetinfo(&gWIZNETINFO); | ||||
| 	if (gWIZNETINFO.dhcp == NETINFO_STATIC) | ||||
| 		PRINTF("STATIC IP\r\n"); | ||||
| 	else | ||||
| 		PRINTF("DHCP IP\r\n"); | ||||
| 	printf("Mac address: %02x:%02x:%02x:%02x:%02x:%02x\n\r",gWIZNETINFO.mac[0],gWIZNETINFO.mac[1],gWIZNETINFO.mac[2],gWIZNETINFO.mac[3],gWIZNETINFO.mac[4],gWIZNETINFO.mac[5]); | ||||
| 	printf("IP address : %d.%d.%d.%d\n\r",gWIZNETINFO.ip[0],gWIZNETINFO.ip[1],gWIZNETINFO.ip[2],gWIZNETINFO.ip[3]); | ||||
| 	printf("SM Mask	   : %d.%d.%d.%d\n\r",gWIZNETINFO.sn[0],gWIZNETINFO.sn[1],gWIZNETINFO.sn[2],gWIZNETINFO.sn[3]); | ||||
| 	printf("Gate way   : %d.%d.%d.%d\n\r",gWIZNETINFO.gw[0],gWIZNETINFO.gw[1],gWIZNETINFO.gw[2],gWIZNETINFO.gw[3]); | ||||
| 	printf("DNS Server : %d.%d.%d.%d\n\r",gWIZNETINFO.dns[0],gWIZNETINFO.dns[1],gWIZNETINFO.dns[2],gWIZNETINFO.dns[3]); | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,83 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2007, Swedish Institute of Computer Science | ||||
|  * All rights reserved.  | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without  | ||||
|  * modification, are permitted provided that the following conditions  | ||||
|  * are met:  | ||||
|  * 1. Redistributions of source code must retain the above copyright  | ||||
|  *    notice, this list of conditions and the following disclaimer.  | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright  | ||||
|  *    notice, this list of conditions and the following disclaimer in the  | ||||
|  *    documentation and/or other materials provided with the distribution.  | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors  | ||||
|  *    may be used to endorse or promote products derived from this software  | ||||
|  *    without specific prior written permission.  | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  | ||||
|  * SUCH DAMAGE.  | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include <avr/io.h> | ||||
| #include "spi.h" | ||||
| //#include "contiki-conf.h"
 | ||||
| 
 | ||||
| /*
 | ||||
|  * On the Tmote sky access to I2C/SPI/UART0 must always be | ||||
|  * exclusive. Set spi_busy so that interrupt handlers can check if | ||||
|  * they are allowed to use the bus or not. Only the CC2420 radio needs | ||||
|  * this in practice. | ||||
|  *  | ||||
|  */ | ||||
| unsigned char spi_busy = 0; | ||||
| 
 | ||||
| /*
 | ||||
|  * Initialize SPI bus. | ||||
|  */ | ||||
| 
 | ||||
| //~ // From working SPI ENC28J60 driver
 | ||||
| //~ #define ENC28J60_CONTROL_PORT   PORTB
 | ||||
| //~ #define ENC28J60_CONTROL_DDR    DDRB
 | ||||
| //~ 
 | ||||
| //~ #define ENC28J60_CONTROL_CS PORTB6
 | ||||
| //~ #define ENC28J60_CONTROL_SO PORTB3
 | ||||
| //~ #define ENC28J60_CONTROL_SI PORTB2
 | ||||
| //~ #define ENC28J60_CONTROL_SCK PORTB1
 | ||||
| //~ #define ENC28J60_CONTROL_SS PORTB0
 | ||||
| //~ 
 | ||||
| //~ // set CS to 0 = active
 | ||||
| //~ #define CSACTIVE ENC28J60_CONTROL_PORT&=~(1<<ENC28J60_CONTROL_CS)
 | ||||
| //~ // set CS to 1 = passive
 | ||||
| //~ #define CSPASSIVE ENC28J60_CONTROL_PORT|=(1<<ENC28J60_CONTROL_CS)
 | ||||
| //
 | ||||
| //~ #define waitspi() while(!(SPSR&(1<<SPIF)))
 | ||||
|   | ||||
| 
 | ||||
| void | ||||
| spi_init(void) | ||||
| { | ||||
|   // CS PIN for FLASH
 | ||||
|   DDRB	|= _BV(WIZNET_CS); // CS to OUT && Disable
 | ||||
|   SPI_WIZNET_DISABLE(); | ||||
|    | ||||
|   /* Initalize ports for communication with SPI units. */ | ||||
|   /* CSN=SS and must be output when master! */ | ||||
|   DDRB  |= _BV(MOSI) | _BV(SCK) | _BV(CSN); | ||||
|   PORTB |= _BV(MOSI) | _BV(SCK); | ||||
|   | ||||
|   /* Enables SPI, selects "master", clock rate FCK / 4 - 4Mhz, and SPI mode 0 */ | ||||
|   SPCR = _BV(SPE) | _BV(MSTR); | ||||
|   //SPSR = _BV(SPI2X); //FCK / 2 - 8Mhz
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,132 @@ | ||||
| /*
 | ||||
|  * Copyright (c) 2010, Swedish Institute of Computer Science. | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. Neither the name of the Institute nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|  * \file | ||||
|  *         Basic SPI macros | ||||
|  * \author | ||||
|  *         Joakim Eriksson <joakime@sics.se> | ||||
|  *         Niclas Finne <nfi@sics.se> | ||||
|  */ | ||||
| 
 | ||||
| #ifndef SPI_H_ | ||||
| #define SPI_H_ | ||||
| 
 | ||||
| /* SPI input/output registers. */ | ||||
| #define SPI_TXBUF SPDR | ||||
| #define SPI_RXBUF SPDR | ||||
| 
 | ||||
| #define BV(bitno) _BV(bitno) | ||||
| 
 | ||||
| #define SPI_WAITFOREOTx() do { while (!(SPSR & BV(SPIF))); } while (0) | ||||
| #define SPI_WAITFOREORx() do { while (!(SPSR & BV(SPIF))); } while (0) | ||||
| 
 | ||||
| //M128
 | ||||
| //#define SCK            1  /* - Output: SPI Serial Clock (SCLK) - ATMEGA128 PORTB, PIN1 */
 | ||||
| //#define MOSI           2  /* - Output: SPI Master out - slave in (MOSI) - ATMEGA128 PORTB, PIN2 */
 | ||||
| //#define MISO           3  /* - Input:  SPI Master in - slave out (MISO) - ATMEGA128 PORTB, PIN3 */
 | ||||
| //#define CSN            0  /*SPI - SS*/
 | ||||
| //#define FLASH_CS       6       /* PB.6 Output as CS*/
 | ||||
| 
 | ||||
| //M644p/M1284p
 | ||||
| #define SCK            7  /* - Output: SPI Serial Clock (SCLK) - ATMEGA644/1284 PORTB, PIN7 */ | ||||
| #define MOSI           5  /* - Output: SPI Master out - slave in (MOSI) -  ATMEGA644/1284 PORTB, PIN5 */ | ||||
| #define MISO           6  /* - Input:  SPI Master in - slave out (MISO) -  ATMEGA644/1284 PORTB, PIN6 */ | ||||
| #define CSN            4  /*SPI - SS*/ | ||||
| 
 | ||||
| //#define FLASH_CS       3       /* PB.2 Output as CS*/
 | ||||
| //#define FLASH_CS       2       /* PB.2 Output as CS*/
 | ||||
| //#define CAN_CS         1       /* PB.1 Output as CS for CAN MCP2515*/
 | ||||
| 
 | ||||
| //#define SPI_FLASH_ENABLE()  ( PORTB &= ~BV(FLASH_CS) )
 | ||||
| //#define SPI_FLASH_DISABLE() ( PORTB |=  BV(FLASH_CS) )
 | ||||
| 
 | ||||
| #define WIZNET_CS       3       /* PB.3 Output as CS for Wiznet ETHERNET*/ | ||||
| #define SPI_WIZNET_ENABLE()  ( PORTB &= ~BV(WIZNET_CS) ) | ||||
| #define SPI_WIZNET_DISABLE() ( PORTB |=  BV(WIZNET_CS) ) | ||||
| 
 | ||||
| #define SD_CS       0       /* PB.0 Output as CS for SD-reader*/ | ||||
| #define SPI_SD_ENABLE()  ( PORTB &= ~BV(SD_CS) ) | ||||
| #define SPI_SD_DISABLE() ( PORTB |=  BV(SD_CS) ) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* Define macros to use for checking SPI transmission status depending
 | ||||
|    on if it is possible to wait for TX buffer ready. This is possible | ||||
|    on for example MSP430 but not on AVR. */ | ||||
| #ifdef SPI_WAITFORTxREADY | ||||
| #define SPI_WAITFORTx_BEFORE() SPI_WAITFORTxREADY() | ||||
| #define SPI_WAITFORTx_AFTER() | ||||
| #define SPI_WAITFORTx_ENDED() SPI_WAITFOREOTx() | ||||
| #else /* SPI_WAITFORTxREADY */ | ||||
| #define SPI_WAITFORTx_BEFORE() | ||||
| #define SPI_WAITFORTx_AFTER() SPI_WAITFOREOTx() | ||||
| #define SPI_WAITFORTx_ENDED() | ||||
| #endif /* SPI_WAITFORTxREADY */ | ||||
| 
 | ||||
| extern unsigned char spi_busy; | ||||
| 
 | ||||
| void spi_init(void); | ||||
| 
 | ||||
| /* Write one character to SPI */ | ||||
| #define SPI_WRITE(data)                         \ | ||||
|   do {                                          \ | ||||
|     SPI_WAITFORTx_BEFORE();                     \ | ||||
|     SPI_TXBUF = data;                           \ | ||||
|     SPI_WAITFOREOTx();                          \ | ||||
|   } while(0) | ||||
| 
 | ||||
| /* Write one character to SPI - will not wait for end
 | ||||
|    useful for multiple writes with wait after final */ | ||||
| #define SPI_WRITE_FAST(data)                    \ | ||||
|   do {                                          \ | ||||
|     SPI_WAITFORTx_BEFORE();                     \ | ||||
|     SPI_TXBUF = data;                           \ | ||||
|     SPI_WAITFORTx_AFTER();                      \ | ||||
|   } while(0) | ||||
| 
 | ||||
| /* Read one character from SPI */ | ||||
| #define SPI_READ(data)   \ | ||||
|   do {                   \ | ||||
|     SPI_TXBUF = 0;       \ | ||||
|     SPI_WAITFOREORx();   \ | ||||
|     data = SPI_RXBUF;    \ | ||||
|   } while(0) | ||||
| 
 | ||||
| /* Flush the SPI read register */ | ||||
| #ifndef SPI_FLUSH | ||||
| #define SPI_FLUSH() \ | ||||
|   do {              \ | ||||
|     SPI_RXBUF;      \ | ||||
|   } while(0); | ||||
| #endif | ||||
| 
 | ||||
| #endif /* SPI_H_ */ | ||||
| @ -0,0 +1,706 @@ | ||||
| /*
 | ||||
|  * Modified  for different BUFFER_SIZE for UART0 && UART1 | ||||
|  * see below: UART0_RX_BUFFER_SIZE/UART1_RX_BUFFER_SIZE && UART0_TX_BUFFER_SIZE/UART1_TX_BUFFER_SIZE | ||||
|  * Ibragimov M. 7/03/2015 | ||||
| */ | ||||
| /*************************************************************************
 | ||||
| Title:    Interrupt UART library with receive/transmit circular buffers | ||||
| Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
 | ||||
| File:     $Id: uart.c,v 1.12 2014/01/08 21:58:12 peter Exp $ | ||||
| Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher | ||||
| Hardware: any AVR with built-in UART,  | ||||
| License:  GNU General Public License  | ||||
|            | ||||
| DESCRIPTION: | ||||
|     An interrupt is generated when the UART has finished transmitting or | ||||
|     receiving a byte. The interrupt handling routines use circular buffers | ||||
|     for buffering received and transmitted data. | ||||
|      | ||||
|     The UART0[1]_RX_BUFFER_SIZE and UART0[1]_TX_BUFFER_SIZE variables define | ||||
|     the buffer size in bytes. Note that these variables must be a  | ||||
|     power of 2. | ||||
|      | ||||
| USAGE: | ||||
|     Refere to the header file uart.h for a description of the routines.  | ||||
|     See also example test_uart.c. | ||||
| 
 | ||||
| NOTES: | ||||
|     Based on Atmel Application Note AVR306 | ||||
|                      | ||||
| LICENSE: | ||||
|     Copyright (C) 2006 Peter Fleury | ||||
| 
 | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|                          | ||||
| *************************************************************************/ | ||||
| #include <avr/io.h> | ||||
| #include <avr/interrupt.h> | ||||
| #include <avr/pgmspace.h> | ||||
| #include "uart_extd.h" | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  *  constants and macros | ||||
|  */ | ||||
| 
 | ||||
| /* size of RX0/TX0 buffers */ | ||||
| #define UART0_RX_BUFFER_MASK ( UART0_RX_BUFFER_SIZE - 1) | ||||
| #define UART0_TX_BUFFER_MASK ( UART0_TX_BUFFER_SIZE - 1) | ||||
| 
 | ||||
| #if ( UART0_RX_BUFFER_SIZE & UART0_RX_BUFFER_MASK ) | ||||
| #error RX0 buffer size is not a power of 2 | ||||
| #endif | ||||
| #if ( UART0_TX_BUFFER_SIZE & UART0_TX_BUFFER_MASK ) | ||||
| #error TX0 buffer size is not a power of 2 | ||||
| #endif | ||||
| 
 | ||||
| /* size of RX1/TX1 buffers */ | ||||
| #define UART1_RX_BUFFER_MASK ( UART1_RX_BUFFER_SIZE - 1) | ||||
| #define UART1_TX_BUFFER_MASK ( UART1_TX_BUFFER_SIZE - 1) | ||||
| 
 | ||||
| #if ( UART1_RX_BUFFER_SIZE & UART1_RX_BUFFER_MASK ) | ||||
| #error RX1 buffer size is not a power of 2 | ||||
| #endif | ||||
| #if ( UART1_TX_BUFFER_SIZE & UART1_TX_BUFFER_MASK ) | ||||
| #error TX1 buffer size is not a power of 2 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #if defined(__AVR_AT90S2313__) \ | ||||
|  || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \ | ||||
|  || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \ | ||||
|  || defined(__AVR_ATmega103__) | ||||
|  /* old AVR classic or ATmega103 with one UART */ | ||||
|  #define AT90_UART | ||||
|  #define UART0_RECEIVE_INTERRUPT   UART_RX_vect  | ||||
|  #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect | ||||
|  #define UART0_STATUS   USR | ||||
|  #define UART0_CONTROL  UCR | ||||
|  #define UART0_DATA     UDR   | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__) | ||||
|  /* old AVR classic with one UART */ | ||||
|  #define AT90_UART | ||||
|  #define UART0_RECEIVE_INTERRUPT   UART_RX_vect  | ||||
|  #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect | ||||
|  #define UART0_STATUS   UCSRA | ||||
|  #define UART0_CONTROL  UCSRB | ||||
|  #define UART0_DATA     UDR  | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif  defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ | ||||
|   || defined(__AVR_ATmega323__) | ||||
|   /* ATmega with one USART */ | ||||
|  #define ATMEGA_USART | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART_RXC_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect | ||||
|  #define UART0_STATUS   UCSRA | ||||
|  #define UART0_CONTROL  UCSRB | ||||
|  #define UART0_DATA     UDR | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif defined (__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) | ||||
|  #define ATMEGA_USART | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect | ||||
|  #define UART0_STATUS   UCSRA | ||||
|  #define UART0_CONTROL  UCSRB | ||||
|  #define UART0_DATA     UDR | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif defined(__AVR_ATmega163__) | ||||
|   /* ATmega163 with one UART */ | ||||
|  #define ATMEGA_UART | ||||
|  #define UART0_RECEIVE_INTERRUPT   UART_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  UART_UDRE_vect | ||||
|  #define UART0_STATUS   UCSRA | ||||
|  #define UART0_CONTROL  UCSRB | ||||
|  #define UART0_DATA     UDR | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif defined(__AVR_ATmega162__)  | ||||
|  /* ATmega with two USART */ | ||||
|  #define ATMEGA_USART0 | ||||
|  #define ATMEGA_USART1 | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART0_RXC_vect | ||||
|  #define UART1_RECEIVE_INTERRUPT   USART1_RXC_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|  #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect | ||||
|  #define UART0_STATUS   UCSR0A | ||||
|  #define UART0_CONTROL  UCSR0B | ||||
|  #define UART0_DATA     UDR0 | ||||
|  #define UART0_UDRIE    UDRIE0 | ||||
|  #define UART1_STATUS   UCSR1A | ||||
|  #define UART1_CONTROL  UCSR1B | ||||
|  #define UART1_DATA     UDR1 | ||||
|  #define UART1_UDRIE    UDRIE1 | ||||
| #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)  | ||||
|  /* ATmega with two USART */ | ||||
|  #define ATMEGA_USART0 | ||||
|  #define ATMEGA_USART1 | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect | ||||
|  #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|  #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect | ||||
|  #define UART0_STATUS   UCSR0A | ||||
|  #define UART0_CONTROL  UCSR0B | ||||
|  #define UART0_DATA     UDR0 | ||||
|  #define UART0_UDRIE    UDRIE0 | ||||
|  #define UART1_STATUS   UCSR1A | ||||
|  #define UART1_CONTROL  UCSR1B | ||||
|  #define UART1_DATA     UDR1 | ||||
|  #define UART1_UDRIE    UDRIE1 | ||||
| #elif defined(__AVR_ATmega161__) | ||||
|  /* ATmega with UART */ | ||||
|  #error "AVR ATmega161 currently not supported by this libaray !" | ||||
| #elif defined(__AVR_ATmega169__)  | ||||
|  /* ATmega with one USART */ | ||||
|  #define ATMEGA_USART | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|  #define UART0_STATUS   UCSRA | ||||
|  #define UART0_CONTROL  UCSRB | ||||
|  #define UART0_DATA     UDR | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif defined(__AVR_ATmega48__) || defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) \ | ||||
|  || defined(__AVR_ATmega3250__) || defined(__AVR_ATmega3290__) ||defined(__AVR_ATmega6450__) || defined(__AVR_ATmega6490__) | ||||
|  /* ATmega with one USART */ | ||||
|  #define ATMEGA_USART0 | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect | ||||
|  #define UART0_STATUS   UCSR0A | ||||
|  #define UART0_CONTROL  UCSR0B | ||||
|  #define UART0_DATA     UDR0 | ||||
|  #define UART0_UDRIE    UDRIE0 | ||||
| #elif defined(__AVR_ATtiny2313__)  | ||||
|  #define ATMEGA_USART | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART_UDRE_vect | ||||
|  #define UART0_STATUS   UCSRA | ||||
|  #define UART0_CONTROL  UCSRB | ||||
|  #define UART0_DATA     UDR | ||||
|  #define UART0_UDRIE    UDRIE | ||||
| #elif defined(__AVR_ATmega329__) || \ | ||||
|       defined(__AVR_ATmega649__) || \ | ||||
|       defined(__AVR_ATmega325__) || \ | ||||
|       defined(__AVR_ATmega645__)  | ||||
|   /* ATmega with one USART */ | ||||
|   #define ATMEGA_USART0 | ||||
|   #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect | ||||
|   #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|   #define UART0_STATUS   UCSR0A | ||||
|   #define UART0_CONTROL  UCSR0B | ||||
|   #define UART0_DATA     UDR0 | ||||
|   #define UART0_UDRIE    UDRIE0 | ||||
| #elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega1280__)  || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega640__) | ||||
| /* ATmega with two USART */ | ||||
|   #define ATMEGA_USART0 | ||||
|   #define ATMEGA_USART1 | ||||
|   #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect | ||||
|   #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect | ||||
|   #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|   #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect | ||||
|   #define UART0_STATUS   UCSR0A | ||||
|   #define UART0_CONTROL  UCSR0B | ||||
|   #define UART0_DATA     UDR0 | ||||
|   #define UART0_UDRIE    UDRIE0 | ||||
|   #define UART1_STATUS   UCSR1A | ||||
|   #define UART1_CONTROL  UCSR1B | ||||
|   #define UART1_DATA     UDR1 | ||||
|   #define UART1_UDRIE    UDRIE1   | ||||
| #elif defined(__AVR_ATmega644__) | ||||
|  /* ATmega with one USART */ | ||||
|  #define ATMEGA_USART0 | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|  #define UART0_STATUS   UCSR0A | ||||
|  #define UART0_CONTROL  UCSR0B | ||||
|  #define UART0_DATA     UDR0 | ||||
|  #define UART0_UDRIE    UDRIE0 | ||||
| #elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) | ||||
|  /* ATmega with two USART */ | ||||
|  #define ATMEGA_USART0 | ||||
|  #define ATMEGA_USART1 | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART0_RX_vect | ||||
|  #define UART1_RECEIVE_INTERRUPT   USART1_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART0_UDRE_vect | ||||
|  #define UART1_TRANSMIT_INTERRUPT  USART1_UDRE_vect | ||||
|  #define UART0_STATUS   UCSR0A | ||||
|  #define UART0_CONTROL  UCSR0B | ||||
|  #define UART0_DATA     UDR0 | ||||
|  #define UART0_UDRIE    UDRIE0 | ||||
|  #define UART1_STATUS   UCSR1A | ||||
|  #define UART1_CONTROL  UCSR1B | ||||
|  #define UART1_DATA     UDR1 | ||||
|  #define UART1_UDRIE    UDRIE1 | ||||
| #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__) | ||||
|  /* AT90USBxx with one USART */ | ||||
|  #define AT90USB_USART | ||||
|  #define UART0_RECEIVE_INTERRUPT   USART1_RX_vect | ||||
|  #define UART0_TRANSMIT_INTERRUPT  USART1_UDRE_vect | ||||
|  #define UART0_STATUS   UCSR1A | ||||
|  #define UART0_CONTROL  UCSR1B | ||||
|  #define UART0_DATA     UDR1 | ||||
|  #define UART0_UDRIE    UDRIE1 | ||||
| #else | ||||
|  #error "no UART definition for MCU available" | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  *  module global variables | ||||
|  */ | ||||
| static volatile unsigned char UART_TxBuf[UART0_TX_BUFFER_SIZE]; | ||||
| static volatile unsigned char UART_RxBuf[UART0_RX_BUFFER_SIZE]; | ||||
| static volatile unsigned char UART_TxHead; | ||||
| static volatile unsigned char UART_TxTail; | ||||
| static volatile unsigned char UART_RxHead; | ||||
| static volatile unsigned char UART_RxTail; | ||||
| static volatile unsigned char UART_LastRxError; | ||||
| 
 | ||||
| #if defined( ATMEGA_USART1 ) | ||||
| static volatile unsigned char UART1_TxBuf[UART1_TX_BUFFER_SIZE]; | ||||
| static volatile unsigned char UART1_RxBuf[UART1_RX_BUFFER_SIZE]; | ||||
| static volatile unsigned char UART1_TxHead; | ||||
| static volatile unsigned char UART1_TxTail; | ||||
| static volatile unsigned char UART1_RxHead; | ||||
| static volatile unsigned char UART1_RxTail; | ||||
| static volatile unsigned char UART1_LastRxError; | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ISR (UART0_RECEIVE_INTERRUPT)	 | ||||
| /*************************************************************************
 | ||||
| Function: UART Receive Complete interrupt | ||||
| Purpose:  called when the UART has received a character | ||||
| **************************************************************************/ | ||||
| { | ||||
|     unsigned char tmphead; | ||||
|     unsigned char data; | ||||
|     unsigned char usr; | ||||
|     unsigned char lastRxError; | ||||
|   | ||||
|   | ||||
|     /* read UART status register and UART data register */  | ||||
|     usr  = UART0_STATUS; | ||||
|     data = UART0_DATA; | ||||
|      | ||||
|     /* */ | ||||
| #if defined( AT90_UART ) | ||||
|     lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); | ||||
| #elif defined( ATMEGA_USART ) | ||||
|     lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); | ||||
| #elif defined( ATMEGA_USART0 ) | ||||
|     lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) ); | ||||
| #elif defined ( ATMEGA_UART ) | ||||
|     lastRxError = (usr & (_BV(FE)|_BV(DOR)) ); | ||||
| #elif defined( AT90USB_USART ) | ||||
|     lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) ); | ||||
| #endif | ||||
|          | ||||
|     /* calculate buffer index */  | ||||
|     tmphead = ( UART_RxHead + 1) & UART0_RX_BUFFER_MASK; | ||||
|      | ||||
|     if ( tmphead == UART_RxTail ) { | ||||
|         /* error: receive buffer overflow */ | ||||
|         lastRxError = UART_BUFFER_OVERFLOW >> 8; | ||||
|     }else{ | ||||
|         /* store new index */ | ||||
|         UART_RxHead = tmphead; | ||||
|         /* store received data in buffer */ | ||||
|         UART_RxBuf[tmphead] = data; | ||||
|     } | ||||
|     UART_LastRxError |= lastRxError;    | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ISR (UART0_TRANSMIT_INTERRUPT) | ||||
| /*************************************************************************
 | ||||
| Function: UART Data Register Empty interrupt | ||||
| Purpose:  called when the UART is ready to transmit the next byte | ||||
| **************************************************************************/ | ||||
| { | ||||
|     unsigned char tmptail; | ||||
| 
 | ||||
|      | ||||
|     if ( UART_TxHead != UART_TxTail) { | ||||
|         /* calculate and store new buffer index */ | ||||
|         tmptail = (UART_TxTail + 1) & UART0_TX_BUFFER_MASK; | ||||
|         UART_TxTail = tmptail; | ||||
|         /* get one byte from buffer and write it to UART */ | ||||
|         UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */ | ||||
|     }else{ | ||||
|         /* tx buffer empty, disable UDRE interrupt */ | ||||
|         UART0_CONTROL &= ~_BV(UART0_UDRIE); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart_init() | ||||
| Purpose:  initialize UART and set baudrate | ||||
| Input:    baudrate using macro UART_BAUD_SELECT() | ||||
| Returns:  none | ||||
| **************************************************************************/ | ||||
| void uart_init(unsigned int baudrate) | ||||
| { | ||||
|     UART_TxHead = 0; | ||||
|     UART_TxTail = 0; | ||||
|     UART_RxHead = 0; | ||||
|     UART_RxTail = 0; | ||||
|      | ||||
| #if defined( AT90_UART ) | ||||
|     /* set baud rate */ | ||||
|     UBRR = (unsigned char)baudrate;  | ||||
| 
 | ||||
|     /* enable UART receiver and transmmitter and receive complete interrupt */ | ||||
|     UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN); | ||||
| 
 | ||||
| #elif defined (ATMEGA_USART) | ||||
|     /* Set baud rate */ | ||||
|     if ( baudrate & 0x8000 ) | ||||
|     { | ||||
|     	 UART0_STATUS = (1<<U2X);  //Enable 2x speed 
 | ||||
|     	 baudrate &= ~0x8000; | ||||
|     } | ||||
|     UBRRH = (unsigned char)(baudrate>>8); | ||||
|     UBRRL = (unsigned char) baudrate; | ||||
|     | ||||
|     /* Enable USART receiver and transmitter and receive complete interrupt */ | ||||
|     UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); | ||||
|      | ||||
|     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ | ||||
|     #ifdef URSEL | ||||
|     UCSRC = (1<<URSEL)|(3<<UCSZ0); | ||||
|     #else | ||||
|     UCSRC = (3<<UCSZ0); | ||||
|     #endif  | ||||
|      | ||||
| #elif defined (ATMEGA_USART0 ) | ||||
|     /* Set baud rate */ | ||||
|     if ( baudrate & 0x8000 )  | ||||
|     { | ||||
|    		UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
 | ||||
|    		baudrate &= ~0x8000; | ||||
|    	} | ||||
|     UBRR0H = (unsigned char)(baudrate>>8); | ||||
|     UBRR0L = (unsigned char) baudrate; | ||||
| 
 | ||||
|     /* Enable USART receiver and transmitter and receive complete interrupt */ | ||||
|     UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0); | ||||
|      | ||||
|     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ | ||||
|     #ifdef URSEL0 | ||||
|     UCSR0C = (1<<URSEL0)|(3<<UCSZ00); | ||||
|     #else | ||||
|     UCSR0C = (3<<UCSZ00); | ||||
|     #endif  | ||||
| 
 | ||||
| #elif defined ( ATMEGA_UART ) | ||||
|     /* set baud rate */ | ||||
|     if ( baudrate & 0x8000 )  | ||||
|     { | ||||
|     	UART0_STATUS = (1<<U2X);  //Enable 2x speed 
 | ||||
|     	baudrate &= ~0x8000; | ||||
|     } | ||||
|     UBRRHI = (unsigned char)(baudrate>>8); | ||||
|     UBRR   = (unsigned char) baudrate; | ||||
| 
 | ||||
|     /* Enable UART receiver and transmitter and receive complete interrupt */ | ||||
|     UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN); | ||||
| 
 | ||||
| #elif defined ( AT90USB_USART ) | ||||
|    /* set baud rate */ | ||||
|     if ( baudrate & 0x8000 )  | ||||
|     { | ||||
|     	UART0_STATUS = (1<<U2X1 );  //Enable 2x speed 
 | ||||
|     	baudrate &= ~0x8000; | ||||
|     } | ||||
|     UBRR1H = (unsigned char)(baudrate>>8); | ||||
|     UBRR1L = (unsigned char) baudrate; | ||||
| 
 | ||||
|     /* Enable UART receiver and transmitter and receive complete interrupt */ | ||||
|     UART0_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1); | ||||
|      | ||||
|     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */ | ||||
|     UCSR1C = (1<<UCSZ11)|(1<<UCSZ10); | ||||
| #endif | ||||
| 
 | ||||
| }/* uart_init */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart_getc() | ||||
| Purpose:  return byte from ringbuffer   | ||||
| Returns:  lower byte:  received byte from ringbuffer | ||||
|           higher byte: last receive error | ||||
| **************************************************************************/ | ||||
| unsigned int uart_getc(void) | ||||
| {     | ||||
|     unsigned char tmptail; | ||||
|     unsigned char data; | ||||
| 
 | ||||
| 
 | ||||
|     if ( UART_RxHead == UART_RxTail ) { | ||||
|         return UART_NO_DATA;   /* no data available */ | ||||
|     } | ||||
|      | ||||
|     /* calculate /store buffer index */ | ||||
|     tmptail = (UART_RxTail + 1) & UART0_RX_BUFFER_MASK; | ||||
|     UART_RxTail = tmptail;  | ||||
|      | ||||
|     /* get data from receive buffer */ | ||||
|     data = UART_RxBuf[tmptail]; | ||||
|      | ||||
|     data = (UART_LastRxError << 8) + data; | ||||
|     UART_LastRxError = 0; | ||||
|     return data; | ||||
| 
 | ||||
| }/* uart_getc */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart_putc() | ||||
| Purpose:  write byte to ringbuffer for transmitting via UART | ||||
| Input:    byte to be transmitted | ||||
| Returns:  none           | ||||
| **************************************************************************/ | ||||
| void uart_putc(unsigned char data) | ||||
| { | ||||
|     unsigned char tmphead; | ||||
| 
 | ||||
|      | ||||
|     tmphead  = (UART_TxHead + 1) & UART0_TX_BUFFER_MASK; | ||||
|      | ||||
|     while ( tmphead == UART_TxTail ){ | ||||
|         ;/* wait for free space in buffer */ | ||||
|     } | ||||
|      | ||||
|     UART_TxBuf[tmphead] = data; | ||||
|     UART_TxHead = tmphead; | ||||
| 
 | ||||
|     /* enable UDRE interrupt */ | ||||
|     UART0_CONTROL    |= _BV(UART0_UDRIE); | ||||
| 
 | ||||
| }/* uart_putc */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart_puts() | ||||
| Purpose:  transmit string to UART | ||||
| Input:    string to be transmitted | ||||
| Returns:  none           | ||||
| **************************************************************************/ | ||||
| void uart_puts(const char *s ) | ||||
| { | ||||
|     while (*s)  | ||||
|       uart_putc(*s++); | ||||
| 
 | ||||
| }/* uart_puts */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart_puts_p() | ||||
| Purpose:  transmit string from program memory to UART | ||||
| Input:    program memory string to be transmitted | ||||
| Returns:  none | ||||
| **************************************************************************/ | ||||
| void uart_puts_p(const char *progmem_s ) | ||||
| { | ||||
|     register char c; | ||||
|      | ||||
|     while ( (c = pgm_read_byte(progmem_s++)) )  | ||||
|       uart_putc(c); | ||||
| 
 | ||||
| }/* uart_puts_p */ | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * these functions are only for ATmegas with two USART | ||||
|  */ | ||||
| #if defined( ATMEGA_USART1 ) | ||||
| 
 | ||||
| ISR(UART1_RECEIVE_INTERRUPT) | ||||
| /*************************************************************************
 | ||||
| Function: UART1 Receive Complete interrupt | ||||
| Purpose:  called when the UART1 has received a character | ||||
| **************************************************************************/ | ||||
| { | ||||
|     unsigned char tmphead; | ||||
|     unsigned char data; | ||||
|     unsigned char usr; | ||||
|     unsigned char lastRxError; | ||||
|   | ||||
|   | ||||
|     /* read UART status register and UART data register */  | ||||
|     usr  = UART1_STATUS; | ||||
|     data = UART1_DATA; | ||||
|      | ||||
|     /* */ | ||||
|     lastRxError = (usr & (_BV(FE1)|_BV(DOR1)) ); | ||||
|          | ||||
|     /* calculate buffer index */  | ||||
|     tmphead = ( UART1_RxHead + 1) & UART1_RX_BUFFER_MASK; | ||||
|      | ||||
|     if ( tmphead == UART1_RxTail ) { | ||||
|         /* error: receive buffer overflow */ | ||||
|         lastRxError = UART_BUFFER_OVERFLOW >> 8; | ||||
|     }else{ | ||||
|         /* store new index */ | ||||
|         UART1_RxHead = tmphead; | ||||
|         /* store received data in buffer */ | ||||
|         UART1_RxBuf[tmphead] = data; | ||||
|     } | ||||
|     UART1_LastRxError |= lastRxError;    | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| ISR(UART1_TRANSMIT_INTERRUPT) | ||||
| /*************************************************************************
 | ||||
| Function: UART1 Data Register Empty interrupt | ||||
| Purpose:  called when the UART1 is ready to transmit the next byte | ||||
| **************************************************************************/ | ||||
| { | ||||
|     unsigned char tmptail; | ||||
| 
 | ||||
|      | ||||
|     if ( UART1_TxHead != UART1_TxTail) { | ||||
|         /* calculate and store new buffer index */ | ||||
|         tmptail = (UART1_TxTail + 1) & UART1_TX_BUFFER_MASK; | ||||
|         UART1_TxTail = tmptail; | ||||
|         /* get one byte from buffer and write it to UART */ | ||||
|         UART1_DATA = UART1_TxBuf[tmptail];  /* start transmission */ | ||||
|     }else{ | ||||
|         /* tx buffer empty, disable UDRE interrupt */ | ||||
|         UART1_CONTROL &= ~_BV(UART1_UDRIE); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart1_init() | ||||
| Purpose:  initialize UART1 and set baudrate | ||||
| Input:    baudrate using macro UART_BAUD_SELECT() | ||||
| Returns:  none | ||||
| **************************************************************************/ | ||||
| void uart1_init(unsigned int baudrate) | ||||
| { | ||||
|     UART1_TxHead = 0; | ||||
|     UART1_TxTail = 0; | ||||
|     UART1_RxHead = 0; | ||||
|     UART1_RxTail = 0; | ||||
|      | ||||
| 
 | ||||
|     /* Set baud rate */ | ||||
|     if ( baudrate & 0x8000 )  | ||||
|     { | ||||
|     	UART1_STATUS = (1<<U2X1);  //Enable 2x speed 
 | ||||
|       baudrate &= ~0x8000; | ||||
|     } | ||||
|     UBRR1H = (unsigned char)(baudrate>>8); | ||||
|     UBRR1L = (unsigned char) baudrate; | ||||
| 
 | ||||
|     /* Enable USART receiver and transmitter and receive complete interrupt */ | ||||
|     UART1_CONTROL = _BV(RXCIE1)|(1<<RXEN1)|(1<<TXEN1); | ||||
|      | ||||
|     /* Set frame format: asynchronous, 8data, no parity, 1stop bit */    | ||||
|     #ifdef URSEL1 | ||||
|     UCSR1C = (1<<URSEL1)|(3<<UCSZ10); | ||||
|     #else | ||||
|     UCSR1C = (3<<UCSZ10); | ||||
|     #endif  | ||||
| }/* uart_init */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart1_getc() | ||||
| Purpose:  return byte from ringbuffer   | ||||
| Returns:  lower byte:  received byte from ringbuffer | ||||
|           higher byte: last receive error | ||||
| **************************************************************************/ | ||||
| unsigned int uart1_getc(void) | ||||
| {     | ||||
|     unsigned char tmptail; | ||||
|     unsigned char data; | ||||
| 
 | ||||
| 
 | ||||
|     if ( UART1_RxHead == UART1_RxTail ) { | ||||
|         return UART_NO_DATA;   /* no data available */ | ||||
|     } | ||||
|      | ||||
|     /* calculate /store buffer index */ | ||||
|     tmptail = (UART1_RxTail + 1) & UART1_RX_BUFFER_MASK; | ||||
|     UART1_RxTail = tmptail;  | ||||
|      | ||||
|     /* get data from receive buffer */ | ||||
|     data = UART1_RxBuf[tmptail]; | ||||
|      | ||||
|     data = (UART1_LastRxError << 8) + data; | ||||
|     UART1_LastRxError = 0; | ||||
|     return data; | ||||
| 
 | ||||
| }/* uart1_getc */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart1_putc() | ||||
| Purpose:  write byte to ringbuffer for transmitting via UART | ||||
| Input:    byte to be transmitted | ||||
| Returns:  none           | ||||
| **************************************************************************/ | ||||
| void uart1_putc(unsigned char data) | ||||
| { | ||||
|     unsigned char tmphead; | ||||
| 
 | ||||
|      | ||||
|     tmphead  = (UART1_TxHead + 1) & UART1_TX_BUFFER_MASK; | ||||
|      | ||||
|     while ( tmphead == UART1_TxTail ){ | ||||
|         ;/* wait for free space in buffer */ | ||||
|     } | ||||
|      | ||||
|     UART1_TxBuf[tmphead] = data; | ||||
|     UART1_TxHead = tmphead; | ||||
| 
 | ||||
|     /* enable UDRE interrupt */ | ||||
|     UART1_CONTROL    |= _BV(UART1_UDRIE); | ||||
| 
 | ||||
| }/* uart1_putc */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart1_puts() | ||||
| Purpose:  transmit string to UART1 | ||||
| Input:    string to be transmitted | ||||
| Returns:  none           | ||||
| **************************************************************************/ | ||||
| void uart1_puts(const char *s ) | ||||
| { | ||||
|     while (*s)  | ||||
|       uart1_putc(*s++); | ||||
| 
 | ||||
| }/* uart1_puts */ | ||||
| 
 | ||||
| 
 | ||||
| /*************************************************************************
 | ||||
| Function: uart1_puts_p() | ||||
| Purpose:  transmit string from program memory to UART1 | ||||
| Input:    program memory string to be transmitted | ||||
| Returns:  none | ||||
| **************************************************************************/ | ||||
| void uart1_puts_p(const char *progmem_s ) | ||||
| { | ||||
|     register char c; | ||||
|      | ||||
|     while ( (c = pgm_read_byte(progmem_s++)) )  | ||||
|       uart1_putc(c); | ||||
| 
 | ||||
| }/* uart1_puts_p */ | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| @ -0,0 +1,209 @@ | ||||
| #ifndef UART_H | ||||
| #define UART_H | ||||
| /*
 | ||||
|  * Modified  for different BUFFER_SIZE for UART0 && UART1 | ||||
|  * see below: UART0_RX_BUFFER_SIZE/UART1_RX_BUFFER_SIZE && UART0_TX_BUFFER_SIZE/UART1_TX_BUFFER_SIZE | ||||
|  * Ibragimov M. 7/03/2015 | ||||
| */ | ||||
| /************************************************************************
 | ||||
| Title:    Interrupt UART library with receive/transmit circular buffers | ||||
| Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
 | ||||
| File:     $Id: uart.h,v 1.12 2012/11/19 19:52:27 peter Exp $ | ||||
| Software: AVR-GCC 4.1, AVR Libc 1.4 | ||||
| Hardware: any AVR with built-in UART, tested on AT90S8515 & ATmega8 at 4 Mhz | ||||
| License:  GNU General Public License  | ||||
| Usage:    see Doxygen manual | ||||
| 
 | ||||
| LICENSE: | ||||
|     Copyright (C) 2006 Peter Fleury | ||||
| 
 | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|      | ||||
| ************************************************************************/ | ||||
| 
 | ||||
| /** 
 | ||||
|  *  @defgroup pfleury_uart UART Library | ||||
|  *  @code #include <uart.h> @endcode | ||||
|  *  | ||||
|  *  @brief Interrupt UART library using the built-in UART with transmit and receive circular buffers.  | ||||
|  * | ||||
|  *  This library can be used to transmit and receive data through the built in UART.  | ||||
|  * | ||||
|  *  An interrupt is generated when the UART has finished transmitting or | ||||
|  *  receiving a byte. The interrupt handling routines use circular buffers | ||||
|  *  for buffering received and transmitted data. | ||||
|  * | ||||
|  *  The UART0[1]_RX_BUFFER_SIZE and UART0[1]_TX_BUFFER_SIZE constants define | ||||
|  *  the size of the circular buffers in bytes. Note that these constants must be a power of 2. | ||||
|  *  You may need to adapt this constants to your target and your application by adding  | ||||
|  *  CDEFS += -DUART0[1]_RX_BUFFER_SIZE=nn -DUART0[1]_RX_BUFFER_SIZE=nn to your Makefile. | ||||
|  * | ||||
|  *  @note Based on Atmel Application Note AVR306 | ||||
|  *  @author Peter Fleury pfleury@gmx.ch  http://jump.to/fleury
 | ||||
|  */ | ||||
|   | ||||
| /**@{*/ | ||||
| 
 | ||||
| 
 | ||||
| #if (__GNUC__ * 100 + __GNUC_MINOR__) < 304 | ||||
| #error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !" | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
| ** constants and macros | ||||
| */ | ||||
| 
 | ||||
| /** @brief  UART Baudrate Expression
 | ||||
|  *  @param  xtalcpu  system clock in Mhz, e.g. 4000000UL for 4Mhz           | ||||
|  *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600      | ||||
|  */ | ||||
| #define UART_BAUD_SELECT(baudRate,xtalCpu)  (((xtalCpu) + 8UL * (baudRate)) / (16UL * (baudRate)) -1UL) | ||||
| 
 | ||||
| /** @brief  UART Baudrate Expression for ATmega double speed mode
 | ||||
|  *  @param  xtalcpu  system clock in Mhz, e.g. 4000000UL for 4Mhz            | ||||
|  *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600      | ||||
|  */ | ||||
| #define UART_BAUD_SELECT_DOUBLE_SPEED(baudRate,xtalCpu) ( ((((xtalCpu) + 4UL * (baudRate)) / (8UL * (baudRate)) -1UL)) | 0x8000) | ||||
| 
 | ||||
| 
 | ||||
| /** Size of the circular receive buffer UART0, must be power of 2 */ | ||||
| #ifndef UART0_RX_BUFFER_SIZE | ||||
| #define UART0_RX_BUFFER_SIZE 32 | ||||
| #endif | ||||
| /** Size of the circular transmit buffer UART0, must be power of 2 */ | ||||
| #ifndef UART0_TX_BUFFER_SIZE | ||||
| #define UART0_TX_BUFFER_SIZE 32 | ||||
| #endif | ||||
| 
 | ||||
| /** Size of the circular receive buffer UART1, must be power of 2 */ | ||||
| #ifndef UART1_RX_BUFFER_SIZE | ||||
| #define UART1_RX_BUFFER_SIZE 128 | ||||
| #endif | ||||
| /** Size of the circular transmit buffer UART1, must be power of 2 */ | ||||
| #ifndef UART1_TX_BUFFER_SIZE | ||||
| #define UART1_TX_BUFFER_SIZE 128 | ||||
| #endif | ||||
| 
 | ||||
| /* test if the size of the circular buffers fits into SRAM */ | ||||
| #if ( (UART0_RX_BUFFER_SIZE+UART0_TX_BUFFER_SIZE+UART1_RX_BUFFER_SIZE+UART1_TX_BUFFER_SIZE) >= (RAMEND-0x60 ) ) | ||||
| #error "size of UART0[1]_RX_BUFFER_SIZE + UART0[1]_TX_BUFFER_SIZE larger than size of SRAM" | ||||
| #endif | ||||
| 
 | ||||
| /* 
 | ||||
| ** high byte error return code of uart_getc() | ||||
| */ | ||||
| #define UART_FRAME_ERROR      0x1000              /* Framing Error by UART       */ | ||||
| #define UART_OVERRUN_ERROR    0x0800              /* Overrun condition by UART   */ | ||||
| #define UART_PARITY_ERROR     0x0400              /* Parity Error by UART        */  | ||||
| #define UART_BUFFER_OVERFLOW  0x0200              /* receive ringbuffer overflow */ | ||||
| #define UART_NO_DATA          0x0100              /* no receive data available   */ | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
| ** function prototypes | ||||
| */ | ||||
| 
 | ||||
| /**
 | ||||
|    @brief   Initialize UART and set baudrate  | ||||
|    @param   baudrate Specify baudrate using macro UART_BAUD_SELECT() | ||||
|    @return  none | ||||
| */ | ||||
| extern void uart_init(unsigned int baudrate); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief   Get received byte from ringbuffer | ||||
|  * | ||||
|  * Returns in the lower byte the received character and in the  | ||||
|  * higher byte the last receive error. | ||||
|  * UART_NO_DATA is returned when no data is available. | ||||
|  * | ||||
|  *  @param   void | ||||
|  *  @return  lower byte:  received byte from ringbuffer | ||||
|  *  @return  higher byte: last receive status | ||||
|  *           - \b 0 successfully received data from UART | ||||
|  *           - \b UART_NO_DATA            | ||||
|  *             <br>no receive data available | ||||
|  *           - \b UART_BUFFER_OVERFLOW    | ||||
|  *             <br>Receive ringbuffer overflow. | ||||
|  *             We are not reading the receive buffer fast enough,  | ||||
|  *             one or more received character have been dropped  | ||||
|  *           - \b UART_OVERRUN_ERROR      | ||||
|  *             <br>Overrun condition by UART. | ||||
|  *             A character already present in the UART UDR register was  | ||||
|  *             not read by the interrupt handler before the next character arrived, | ||||
|  *             one or more received characters have been dropped. | ||||
|  *           - \b UART_FRAME_ERROR        | ||||
|  *             <br>Framing Error by UART | ||||
|  */ | ||||
| extern unsigned int uart_getc(void); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief   Put byte to ringbuffer for transmitting via UART | ||||
|  *  @param   data byte to be transmitted | ||||
|  *  @return  none | ||||
|  */ | ||||
| extern void uart_putc(unsigned char data); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief   Put string to ringbuffer for transmitting via UART | ||||
|  * | ||||
|  *  The string is buffered by the uart library in a circular buffer | ||||
|  *  and one character at a time is transmitted to the UART using interrupts. | ||||
|  *  Blocks if it can not write the whole string into the circular buffer. | ||||
|  *  | ||||
|  *  @param   s string to be transmitted | ||||
|  *  @return  none | ||||
|  */ | ||||
| extern void uart_puts(const char *s ); | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief    Put string from program memory to ringbuffer for transmitting via UART. | ||||
|  * | ||||
|  * The string is buffered by the uart library in a circular buffer | ||||
|  * and one character at a time is transmitted to the UART using interrupts. | ||||
|  * Blocks if it can not write the whole string into the circular buffer. | ||||
|  * | ||||
|  * @param    s program memory string to be transmitted | ||||
|  * @return   none | ||||
|  * @see      uart_puts_P | ||||
|  */ | ||||
| extern void uart_puts_p(const char *s ); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief    Macro to automatically put a string constant into program memory | ||||
|  */ | ||||
| #define uart_puts_P(__s)       uart_puts_p(PSTR(__s)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** @brief  Initialize USART1 (only available on selected ATmegas) @see uart_init */ | ||||
| extern void uart1_init(unsigned int baudrate); | ||||
| /** @brief  Get received byte of USART1 from ringbuffer. (only available on selected ATmega) @see uart_getc */ | ||||
| extern unsigned int uart1_getc(void); | ||||
| /** @brief  Put byte to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_putc */ | ||||
| extern void uart1_putc(unsigned char data); | ||||
| /** @brief  Put string to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts */ | ||||
| extern void uart1_puts(const char *s ); | ||||
| /** @brief  Put string from program memory to ringbuffer for transmitting via USART1 (only available on selected ATmega) @see uart_puts_p */ | ||||
| extern void uart1_puts_p(const char *s ); | ||||
| /** @brief  Macro to automatically put a string constant into program memory */ | ||||
| #define uart1_puts_P(__s)       uart1_puts_p(PSTR(__s)) | ||||
| 
 | ||||
| /**@}*/ | ||||
| 
 | ||||
| 
 | ||||
| #endif // UART_H 
 | ||||
| 
 | ||||
		Reference in New Issue